-- local l = require("pandoc.logging") local read = pandoc.read assert(#arg == 2, "\n" .. "[ERROR] usage: pandoc lua sitemap.lua ") local index_file, output_file = table.unpack(arg) local node_list, node_map = {}, {} local function collect (fp) local f = assert(io.open(fp), "\n" .. "[ERROR] could not open " .. fp .. " for reading.") table.insert(node_list, fp) node_map[fp] = { order = #node_list, nodes = {} } local data = f:read("a") f:close() local visited = {} read(data):walk({ Link = function (link) if not link.target:find(".%.md$") then return end 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 table.insert(node_map[fp]["nodes"], link.target) if not node_map[link.target] then collect(link.target) end end }) end collect(index_file) local L = { L = "<", R = ">", NW = ",", N = "-", NE = ".", W = "|", X = " ", E = "|", SW = "'", S = "-", SE = "'", } local arma = {} local list = {} local armb = {} for i,node in ipairs(node_list) do arma[i] = {} list[i] = node armb[i] = {} 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] if cell ~= nil and cell ~= L.X then goto continue end end do return col end ::continue:: col = col + 1 end return col end for _,node in ipairs(node_list) do local a_node = node_map[node] for _,node in ipairs(a_node["nodes"]) do local a = a_node["order"] local b = node_map[node]["order"] local i1 = 1 local ia = math.min(a,b) local ib = math.max(a,b) local iz = #node_list 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 if col == 1 then col = 2 end local a_row = wing[ia] if a_row[1] == nil or a_row[1] == L.X then a_row[1] = a < b and L.N or L.L end for i=1,col-1 do if a_row[i] == nil or a_row[i] == L.X then a_row[i] = L.N end end a_row[col] = a < b and L.NW or L.NE for i=ia+1,ib-1 do for j=1,col-1 do if wing[i][j] == nil then wing[i][j] = L.X end end wing[i][col] = L.W end local b_row = wing[ib] if b_row[1] == nil or b_row[1] == L.X then b_row[1] = a < b and L.R or L.S end for i=1,col-1 do if b_row[i] == nil or b_row[i] == L.X then b_row[i] = L.S end end b_row[col] = L.SW end end -- construct data lines local lines = {} table.insert(lines, "
") table.insert(lines, "
") table.insert(lines, "

sitemap

") table.insert(lines, "
") table.insert(lines, "
")

-- pad right wing
local arma_pad = 1
for _,len in pairs(arma) do
  if #len > arma_pad then arma_pad = #len end
end
-- pad node names
local node_pad = 1
for _,s in pairs(list) do
  if s:len() > node_pad then node_pad = s:len() end
end

for i,v in ipairs(list) do
  local row = {}
  local v = ("%-"..node_pad.."s"):format(v)
  local a = v:gsub("(.+)%.md", "%0")
  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])))

  table.insert(lines, table.concat(row))
end
table.insert(lines, "
") table.insert(lines, "
") local data = table.concat(lines, "\n") -- read existing data from output_file local f = assert(io.open(output_file), "\n" .. "[ERROR] could not open " .. output_file .. " for reading.") local data_old = f:read("a") f:close() -- write to output_file if data changed if data ~= data_old then local f = assert(io.open(output_file, "w"), "\n" .. "[ERROR] could not open " .. output_file .. " for writing.") f:write(data) f:close() end