-- Replace an empty `::: {.article-toc}` block with the current article's -- table of contents. The block can appear anywhere in the article. local function escape_html(text) return text:gsub("&", "&") :gsub("<", "<") :gsub(">", ">") :gsub('"', """) :gsub("'", "'") end local function make_toc(entries) if #entries == 0 then return nil end local lines = { '') return pandoc.RawBlock('html', table.concat(lines, '\n')) end function Pandoc(doc) local output = pandoc.List() local article = pandoc.List() local function flush_article() if #article == 0 then return end local entries = pandoc.List() for _, block in ipairs(article) do if block.t == 'Header' and block.level == 2 then entries:insert({ level = block.level, id = block.identifier, title = pandoc.utils.stringify(block.content), }) end end for _, block in ipairs(article) do if block.t == 'Div' and block.classes:includes('article-toc') then local toc = make_toc(entries) if toc then output:insert(toc) end else output:insert(block) end end end for _, block in ipairs(doc.blocks) do if block.t == 'Header' and block.level == 1 then flush_article() article = pandoc.List() end article:insert(block) end flush_article() doc.blocks = output return doc end