1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
|
--[[
-- This filter creates the ToC from the headings so if it's applied before
-- heading transformations, transformations do not appear in the ToC.
--
-- It's useful for HTML output where the anchors are added in an extra filter.
-- Default ToC included the anchor. Using this filter anchor is not included.
--
-- It supports toc-depth metadata field.
--]]
pandoc.utils = require 'pandoc.utils'
list_of_headers = {}
if FORMAT:match 'html' then
function headers2link_and_level(headers)
local links = {}
for i, v in ipairs(headers) do
local l = pandoc.Link( pandoc.utils.stringify(v), "#"..v.identifier )
table.insert(links,{ v.level, pandoc.Plain( l ) })
end
return links
end
function create_ol(headers, toc_depth)
if #headers == 0 then
return pandoc.Null()
end
local links = headers2link_and_level(headers)
-- min_level doesn't have to be 1, it could be larger
local min_level = -1
for i, v in ipairs(links) do
if min_level == -1 or v[1] < min_level then min_level = v[1] end
end
-- max level needed for grouping
local max_level = 0
if toc_depth >= 1 then
-- toc_depth is set, so remove elements with larger level than
-- max_level
max_level = min_level + toc_depth - 1
local i = 1
while i <= #links do
if links[i][1] > max_level then
table.remove(links, i)
i = i - 1
end
i = i + 1
end
else
-- toc_depth not set so get the max_level from the contents
for i, v in ipairs(links) do
if v[1] > max_level then max_level = v[1] end
end
end
-- Iterate trough valid levels
while max_level > min_level do
local i = 1
local tmp = {}
while i <= #links do
local level = links[i][1] -- Element's level
if level == max_level then -- Found group
-- If group is found, it usually has a parent
local parent = links[i-1]
if parent[1] == level - 1 then
-- It's the direct parent, add it's contents
parent = parent[2]
else
-- Not direct parent, warn and discard
io.stderr:write("[WARNING] Element of level ")
io.stderr:write(tostring(parent[1]))
io.stderr:write(" has no direct children: ")
io.stderr:write(pandoc.utils.stringify(parent[2]))
io.stderr:write("\n")
parent = pandoc.Null()
end
while i <= #links and links[i][1] == level do
-- Capture the group
table.insert(tmp, table.remove(links, i)[2])
end
if #tmp ~= 0 then
-- There was a group, convert it to
-- {parent, OrderedList(group)}
local children = pandoc.OrderedList(tmp)
local pos = i
if parent.t ~= "Null" then
-- There was a parent: extract it from links
table.remove(links, i-1)
pos = i - 1
end
table.insert(links, pos, {level-1, {parent, children}})
tmp = {}
end
end
i = i + 1
end
max_level = max_level - 1
end
local lis = {}
for i,v in pairs(links) do
_,lis[i] = table.unpack(v)
end
return pandoc.OrderedList(lis)
end
function Meta(m)
local toc_depth = -1
if m["toc-depth"] ~= nil then
toc_depth = tonumber(m["toc-depth"][1].text)
else
toc_depth = -1
end
m["table-of-contents"] = pandoc.MetaBlocks({create_ol(list_of_headers, toc_depth)})
return m
end
function Header(el)
table.insert(list_of_headers, el)
return el
end
end
|