hledger/tools/pandoc-toc.lua
2019-08-26 09:37:03 -07:00

66 lines
1.9 KiB
Lua

-- Replace a $TOC$ marker with a table of contents generated from the document's headings.
local headers = {}
function Header(h)
table.insert(headers, h)
return h
end
function markupLink(hAttr, headerText)
local headerId = hAttr.identifier
local headerProperties = hAttr.attributes
return pandoc.Link(headerText, "#" .. headerId, headerId)
end
function markupElement(elem)
local hAttr = elem.attr
local hText = elem.label
local hNested = elem.contents
local link = pandoc.Plain(markupLink(hAttr, hText))
if not hNested[1] then return {link} end
return {link, markupElements(hNested)}
end
function markupElements(elems)
local newElems = {}
for _,e in pairs(elems) do
table.insert(newElems, markupElement(e))
end
return pandoc.OrderedList(newElems, {"1", "Decimal", "Period"})
end
function createTable(elems)
local navBegin = pandoc.RawBlock("html", "<nav id=\"toc\" class=\"right-toc\">")
local navEnd = pandoc.RawBlock("html", "</nav>")
local contentsP = pandoc.Para(pandoc.Str("Contents"))
return {navBegin, contentsP, markupElements(elems), navEnd}
end
function isTocMarker(blk)
local tocMarker = "$TOC$"
if not (blk.t == "Para") then return false end
if not blk.content[1] then return false end
if not (blk.content[1].t == "Str") then return false end
return blk.content[1].text == tocMarker
end
function Pandoc(doc)
newBlocks = {}
tocBlocks = createTable(pandoc.utils.hierarchicalize(headers))
for _,blk in pairs(doc.blocks) do
-- replace a TOC placeholder with the table of contents,
-- or nothing if there's less than two headings
if isTocMarker(blk) then
if #headers > 1 then
for _,tocBlk in pairs(tocBlocks) do
table.insert(newBlocks, tocBlk)
end
end
else
table.insert(newBlocks, blk)
end
end
return pandoc.Doc(newBlocks, doc.meta)
end