136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
...
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
...
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
|
end;
[true] = function (job, ctx, words)
local _, op, val = words(2)
if op == nil then
local toc = {kind='toc'}
ctx:insert(toc)
-- same deal here -- directives are processed as part of
-- the parse job, which is forked off the document job,
-- so we need to climb the jobstack
job:unwind(1).state.toc_custom_position = true
job:hook('ext_toc_position', ctx, toc)
else
ctx:fail 'bad %toc directive'
end
end;
};
................................................................................
-- each node.
local stack = {lst}
local top = function() return stack[#stack] end
-- job.doc is the document the render job is bound to, and
-- its secorder field is a list of all the doc's sections in
-- the order they occur ("doc.sections" is a hashmap from name
-- to section object)
local all = job.doc.secorder
for i, sec in ipairs(all) do
if sec.heading_node then -- does this section have a label?
local ent = tag('li',nil,
catenate{tag('a', {href='#'..getSafeID(sec)},
sr.htmlSpan(sec.heading_node.spans, sec.heading_node, sec))})
if sec.depth > #stack then
local n = {tag = 'ol', attrs={}, nodes={ent}}
table.insert(top().nodes[#top().nodes].nodes, n)
table.insert(stack, n)
else
if sec.depth < #stack then
for j=#stack,sec.depth+1,-1 do stack[j] = nil end
end
table.insert(top().nodes, ent)
end
-- now we need to assemble a list of items within the
-- section worthy of an entry on their own. currently
-- this is only anchors created with %toc mark|name
................................................................................
local nn = {
tag = 'a';
attrs = {href = '#' .. l.id};
nodes = {sr.htmlSpan(l.label, l.block, sec)};
}
table.insert(n.nodes, {tag = 'li', attrs = {}, nodes={nn}})
end
table.insert(ent.nodes, n)
end
end
end
return lst
end;
[true] = function() end; -- fallback // convert to different node types
};
};
}
|
|
>
|
|
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
|
>
|
|
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
...
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
...
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
|
end;
[true] = function (job, ctx, words)
local _, op, val = words(2)
if op == nil then
local toc = {kind='toc'}
ctx:insert(toc)
-- same deal here -- directives are processed as part of
-- the parse job, which is forked off the document job;
-- if we want state that can persist into the render job,
-- we need to climb the jobstack
job:unwind(1).state.toc_custom_position = true
job:hook('ext_toc_position', ctx, toc)
else
ctx:fail 'bad %toc directive'
end
end;
};
................................................................................
-- each node.
local stack = {lst}
local top = function() return stack[#stack] end
-- job.doc is the document the render job is bound to, and
-- its secorder field is a list of all the doc's sections in
-- the order they occur ("doc.sections" is a hashmap from name
-- to section object)
local all = {}
local function blockHasSubdoc(b)
local subdocBlockKinds = {
quote = true;
embed = true;
macro = true;
}
return subdocBlockKinds[b.kind] and ct.doc.is(b.doc)
end
local function scandoc(doc, depth)
for i, sec in ipairs(doc.secorder) do
table.insert(all, {ref = sec, depth = sec.depth + depth})
for j, block in ipairs(sec.blocks) do
if blockHasSubdoc(block) then
scandoc(block.doc, depth + sec.depth-1)
end
end
end
end
scandoc(job.doc,0)
for i, secptr in ipairs(all) do
local sec = secptr.ref
if sec.heading_node then -- does this section have a label?
local ent = tag('li',nil,
catenate{tag('a', {href='#'..getSafeID(sec)},
sr.htmlSpan(sec.heading_node.spans, sec.heading_node, sec))})
if secptr.depth > #stack then
local n = {tag = 'ol', attrs={}, nodes={ent}}
table.insert(top().nodes[#top().nodes].nodes, n)
table.insert(stack, n)
else
if secptr.depth < #stack then
for j=#stack,secptr.depth+1,-1 do stack[j] = nil end
end
table.insert(top().nodes, ent)
end
-- now we need to assemble a list of items within the
-- section worthy of an entry on their own. currently
-- this is only anchors created with %toc mark|name
................................................................................
local nn = {
tag = 'a';
attrs = {href = '#' .. l.id};
nodes = {sr.htmlSpan(l.label, l.block, sec)};
}
table.insert(n.nodes, {tag = 'li', attrs = {}, nodes={nn}})
end
table.insert(top().nodes, n)
table.insert(stack, n)
end
end
end
return lst
end;
[true] = function() end; -- fallback // convert to different node types
};
};
}
|