bavbavhaus.net/pandoc/sitemap.lua

164 lines
4.0 KiB
Lua
Raw Normal View History

2024-05-17 15:26:37 +02:00
-- local l = require("pandoc.logging")
2024-05-16 23:13:00 +02:00
local read = pandoc.read
assert(#arg == 2, "\n" ..
"[ERROR] usage: pandoc lua sitemap.lua <index file> <output file>")
2024-05-17 15:26:37 +02:00
local index_file, output_file = table.unpack(arg)
2024-05-16 23:13:00 +02:00
2024-05-17 15:26:37 +02:00
local node_list, node_map = {}, {}
2024-05-16 23:13:00 +02:00
local function collect (fp)
local f = assert(io.open(fp), "\n" ..
"[ERROR] could not open " .. fp .. " for reading.")
table.insert(node_list, fp)
2024-05-17 15:26:37 +02:00
node_map[fp] = { order = #node_list, nodes = {} }
2024-05-16 23:13:00 +02:00
local data = f:read("a")
f:close()
local visited = {}
read(data):walk({ Link = function (link)
2024-05-17 15:26:37 +02:00
if not link.target:find(".%.md$") then return end
2024-05-16 23:13:00 +02:00
local f = io.open(link.target)
if f == nil then return else f:close() end
if visited[link.target] then return end
visited[link.target] = true
2024-05-17 15:26:37 +02:00
table.insert(node_map[fp]["nodes"], link.target)
if not node_map[link.target] then collect(link.target) end
2024-05-16 23:13:00 +02:00
end })
end
2024-05-17 15:26:37 +02:00
collect(index_file)
2024-05-16 23:13:00 +02:00
local L = {
2024-05-17 15:26:37 +02:00
L = "<",
R = ">",
NW = ",", N = "-", NE = ".",
W = "|", X = " ", E = "|",
SW = "'", S = "-", SE = "'",
2024-05-16 23:13:00 +02:00
}
2024-05-17 15:26:37 +02:00
local arma = {}
local list = {}
local armb = {}
2024-05-16 23:13:00 +02:00
for i,node in ipairs(node_list) do
2024-05-17 15:26:37 +02:00
arma[i] = {}
list[i] = node
armb[i] = {}
2024-05-16 23:13:00 +02:00
end
local function reverse (t)
for i=1,#t//2 do
t[i],t[#t-i+1] = t[#t-i+1],t[i]
end
return t
end
local function find_free_col(wing, a, b)
local col = 1
while true do
for i=a,b do
local cell = wing[i][col]
2024-05-17 15:26:37 +02:00
if cell ~= nil and cell ~= L.X then
2024-05-16 23:13:00 +02:00
goto continue
end
end
do return col end
::continue::
col = col + 1
end
return col
end
for _,node in ipairs(node_list) do
2024-05-17 15:26:37 +02:00
local a_node = node_map[node]
2024-05-16 23:13:00 +02:00
for _,node in ipairs(a_node["nodes"]) do
local a = a_node["order"]
2024-05-17 15:26:37 +02:00
local b = node_map[node]["order"]
2024-05-16 23:13:00 +02:00
local i1 = 1
local ia = math.min(a,b)
local ib = math.max(a,b)
local iz = #node_list
2024-05-17 15:26:37 +02:00
local wing = a < b and arma or armb
local col = 1
while true do
for i=ia,ib do
local cell = wing[i][col]
if cell ~= nil and cell ~= L.X then
goto continue
end
end
break
::continue::
col = col + 1
end
2024-05-16 23:13:00 +02:00
if col == 1 then col = 2 end
local a_row = wing[ia]
2024-05-17 15:26:37 +02:00
if a_row[1] == nil or a_row[1] == L.X then
a_row[1] = a < b and L.N or L.L
2024-05-16 23:13:00 +02:00
end
for i=1,col-1 do
2024-05-17 15:26:37 +02:00
if a_row[i] == nil or a_row[i] == L.X then a_row[i] = L.N end
2024-05-16 23:13:00 +02:00
end
2024-05-17 15:26:37 +02:00
a_row[col] = a < b and L.NW or L.NE
2024-05-16 23:13:00 +02:00
for i=ia+1,ib-1 do
for j=1,col-1 do
2024-05-17 15:26:37 +02:00
if wing[i][j] == nil then wing[i][j] = L.X end
2024-05-16 23:13:00 +02:00
end
2024-05-17 15:26:37 +02:00
wing[i][col] = L.W
2024-05-16 23:13:00 +02:00
end
local b_row = wing[ib]
2024-05-17 15:26:37 +02:00
if b_row[1] == nil or b_row[1] == L.X then
b_row[1] = a < b and L.R or L.S
2024-05-16 23:13:00 +02:00
end
for i=1,col-1 do
2024-05-17 15:26:37 +02:00
if b_row[i] == nil or b_row[i] == L.X then b_row[i] = L.S end
2024-05-16 23:13:00 +02:00
end
2024-05-17 15:26:37 +02:00
b_row[col] = L.SW
2024-05-16 23:13:00 +02:00
end
end
2024-05-17 15:26:37 +02:00
-- construct data lines
local lines = {}
table.insert(lines, "<article id=\"sitemap\" class=\"post tail\">")
table.insert(lines, "<header>")
table.insert(lines, "<h1>sitemap</h1>")
table.insert(lines, "</header>")
table.insert(lines, "<pre>")
2024-05-16 23:13:00 +02:00
-- pad right wing
2024-05-17 15:26:37 +02:00
local arma_pad = 1
for _,len in pairs(arma) do
if #len > arma_pad then arma_pad = #len end
2024-05-16 23:13:00 +02:00
end
-- pad node names
local node_pad = 1
2024-05-17 15:26:37 +02:00
for _,s in pairs(list) do
2024-05-16 23:13:00 +02:00
if s:len() > node_pad then node_pad = s:len() end
end
2024-05-17 15:26:37 +02:00
for i,v in ipairs(list) do
2024-05-16 23:13:00 +02:00
local row = {}
local v = ("%-"..node_pad.."s"):format(v)
local a = v:gsub("(.+)%.md", "<a href=\"%1.html\">%0</a>")
2024-05-17 15:26:37 +02:00
table.insert(row, (("%"..arma_pad.."s"):format(table.concat(reverse(arma[i])))))
table.insert(row, ((" %s "):format(a)))
table.insert(row, (table.concat(armb[i])))
2024-05-16 23:13:00 +02:00
2024-05-17 15:26:37 +02:00
table.insert(lines, table.concat(row))
2024-05-16 23:13:00 +02:00
end
2024-05-17 15:26:37 +02:00
table.insert(lines, "</pre>")
table.insert(lines, "</article>")
local data = table.concat(lines, "\n")
-- read existing data from output_file
2024-05-17 15:35:50 +02:00
local f = io.open(output_file)
local data_old
if f then data_old = f:read("a"); f:close() end
2024-05-17 15:26:37 +02:00
-- write to output_file if data changed
2024-05-17 15:35:50 +02:00
if not data_old or data ~= data_old then
2024-05-17 15:26:37 +02:00
local f = assert(io.open(output_file, "w"), "\n" ..
"[ERROR] could not open " .. output_file .. " for writing.")
f:write(data)
f:close()
end