I believe a change has been made so that Lua filters now traverse the document in linear order. If this is the case in the latest version of Pandoc it should be doable with a two-pass filter: first a pass which collects the headings and then a pass which inserts the TsoC. If you want hierarchical section numbering you probably also need to do a first pandoc run which inserts the numbering and then a second pandoc run with the filter to insert the TsoC. Something like this:
Warning 3: Assumes that all chapters are heading level 2 — change the chapter_level and toc_level variables to match!
local chapter_level = 2
local toc_level = 3
local headings = {}
local current_chapter = nil
local function collect_headings (head)
if head.level == chapter_level then
local id = head.identifier
current_chapter = {
chapter = id
toc = {}
}
headings[id] = current_chapter
elseif head.level = toc_level then
if current_chapter then
local toc = current_chapter.toc
toc[#toc+1] = head
end
end
return nil
end
local function build_toc (heads)
local toc = {}
for _,head in ipairs(heads) do
local entry = {
pandoc.Plain{
pandoc.Link(
head.content:clone(), -- text
head.identifier, -- target
"", -- empty title
pandoc.Attr(
"", -- empty identifier
{'local-toc-link'} -- class
)
)
}
}
toc[#toc+1] = entry
end
return pandoc.Div(
{ pandoc.BulletList(toc) },
pandoc.Attr( "", {'local-toc'} )
)
end
local function insert_toc (head)
if head.level = chapter_level then
local id = head.identifier
if headings[id] then
local toc = build_toc(
headings[id].toc
)
return {head,toc}
end
end
return nil
end
return {
{ Header = collect_headings },
{ Header = insert_toc },
}