strc-doc.lua /size: 43 Kb    last modification: 2021-10-28 13:50
1
if
not
modules
then
modules
=
{
}
end
modules
[
'
strc-doc
'
]
=
{
2
version
=
1
.
001
,
3
comment
=
"
companion to strc-doc.mkiv
"
,
4
author
=
"
Hans Hagen, PRAGMA-ADE, Hasselt NL
"
,
5
copyright
=
"
PRAGMA ADE / ConTeXt Development Team
"
,
6
license
=
"
see context related readme files
"
7
}
8 9
-- todo: associate counter with head
10
-- we need to better split the lua/tex end
11
-- we need to freeze and document this module
12 13
-- keep this as is:
14
--
15
-- in section titles by default a zero aborts, so there we need: sectionset=bagger with \definestructureprefixset [bagger] [section-2,section-4] []
16
-- in lists however zero's are ignored, so there numbersegments=2:4 gives result
17 18
local
next
,
type
,
tonumber
,
select
=
next
,
type
,
tonumber
,
select
19
local
find
,
match
=
string
.
find
,
string
.
match
20
local
concat
,
fastcopy
,
insert
,
remove
=
table
.
concat
,
table
.
fastcopy
,
table
.
insert
,
table
.
remove
21
local
sortedhash
,
sortedkeys
=
table
.
sortedhash
,
table
.
sortedkeys
22
local
max
,
min
=
math
.
max
,
math
.
min
23
local
allocate
,
mark
,
accesstable
=
utilities
.
storage
.
allocate
,
utilities
.
storage
.
mark
,
utilities
.
tables
.
accesstable
24
local
setmetatableindex
=
table
.
setmetatableindex
25
local
lpegmatch
,
P
,
C
=
lpeg
.
match
,
lpeg
.
P
,
lpeg
.
C
26 27
local
catcodenumbers
=
catcodes
.
numbers
28
local
ctxcatcodes
=
catcodenumbers
.
ctxcatcodes
29
local
variables
=
interfaces
.
variables
30 31
local
implement
=
interfaces
.
implement
32 33
local
v_last
=
variables
.
last
34
local
v_first
=
variables
.
first
35
local
v_previous
=
variables
.
previous
36
local
v_next
=
variables
.
next
37
local
v_auto
=
variables
.
auto
38
local
v_strict
=
variables
.
strict
39
local
v_all
=
variables
.
all
40
local
v_positive
=
variables
.
positive
41
local
v_current
=
variables
.
current
42 43
local
texgetcount
=
tex
.
getcount
44 45
local
trace_sectioning
=
false
trackers
.
register
(
"
structures.sectioning
"
,
function
(
v
)
trace_sectioning
=
v
end
)
46
local
trace_details
=
false
trackers
.
register
(
"
structures.details
"
,
function
(
v
)
trace_details
=
v
end
)
47 48
local
report_structure
=
logs
.
reporter
(
"
structure
"
,
"
sectioning
"
)
49
local
report_used
=
logs
.
reporter
(
"
structure
"
)
50 51
local
context
=
context
52
local
commands
=
commands
53
local
ctx_doifelse
=
commands
.
doifelse
54 55
local
structures
=
structures
56
local
helpers
=
structures
.
helpers
57
local
documents
=
structures
.
documents
58
local
sections
=
structures
.
sections
59
local
lists
=
structures
.
lists
60
local
counters
=
structures
.
counters
61
local
sets
=
structures
.
sets
62
local
tags
=
structures
.
tags
63 64
local
processors
=
typesetters
.
processors
65
local
applyprocessor
=
processors
.
apply
66
local
startapplyprocessor
=
processors
.
startapply
67
local
stopapplyprocessor
=
processors
.
stopapply
68
local
strippedprocessor
=
processors
.
stripped
69 70
local
convertnumber
=
converters
.
convert
71 72
local
ctx_convertnumber
=
context
.
convertnumber
73
local
ctx_sprint
=
context
.
sprint
74
local
ctx_finalizeauto
=
context
.
finalizeautostructurelevel
75 76
-- -- -- document -- -- --
77 78
local
data
-- the current state
79 80
function
documents
.
initialize
(
)
81
data
=
allocate
{
-- whole data is marked
82
numbers
=
{
}
,
83
forced
=
{
}
,
84
ownnumbers
=
{
}
,
85
status
=
{
}
,
86
checkers
=
{
}
,
87
depth
=
0
,
88
blocks
=
{
}
,
89
block
=
"
"
,
90
}
91
documents
.
data
=
data
92
end
93 94
function
documents
.
reset
(
)
95
data
.
numbers
=
{
}
96
data
.
forced
=
{
}
97
data
.
ownnumbers
=
{
}
98
data
.
status
=
{
}
99
-- data.checkers = { }
100
data
.
depth
=
0
101
end
102 103
documents
.
initialize
(
)
104 105
-- -- -- components -- -- --
106 107
function
documents
.
preset
(
numbers
)
108
local
nofnumbers
=
#
numbers
109
local
ownnumbers
=
{
}
110
data
.
numbers
=
numbers
111
data
.
ownnumbers
=
ownnumbers
112
data
.
depth
=
nofnumbers
113
for
i
=
1
,
nofnumbers
do
114
ownnumbers
[
i
]
=
"
"
115
end
116
sections
.
setnumber
(
nofnumbers
,
"
-1
"
)
117
end
118 119
-- -- -- sections -- -- --
120 121
-- This is just a quick way to have access to prefixes and the numbers (section entry in a ref)
122
-- is not the list entry. An alternative is to use the list index of the last numbered section. In
123
-- that case we should check a buse of the current structure.
124 125
local
collected
=
allocate
(
)
126
local
tobesaved
=
allocate
(
)
127 128
sections
.
collected
=
collected
129
sections
.
tobesaved
=
tobesaved
130 131
-- We have to save this mostly redundant list because we can have (rare)
132
-- cases with own numbers that don't end up in the list so we get out of
133
-- sync when we use (*).
134 135
local
function
initializer
(
)
136
collected
=
sections
.
collected
137
tobesaved
=
sections
.
tobesaved
138
end
139 140
job
.
register
(
'
structures.sections.collected
'
,
tobesaved
,
initializer
)
141 142
local
registered
=
sections
.
registered
or
allocate
(
)
143
sections
.
registered
=
registered
144 145
storage
.
register
(
"
structures/sections/registered
"
,
registered
,
"
structures.sections.registered
"
)
146 147
local
function
update
(
name
,
level
,
section
)
148
for
k
,
v
in
next
,
registered
do
149
if
k
~
=
name
and
v
.
coupling
=
=
name
then
150
report_structure
(
"
updating section level %a to level of %a
"
,
k
,
name
)
151
context
.
doredefinehead
(
k
,
name
)
152
update
(
k
,
level
,
section
)
153
end
154
end
155
end
156 157
function
sections
.
register
(
name
,
specification
)
158
registered
[
name
]
=
specification
159
local
level
=
specification
.
level
160
local
section
=
specification
.
section
161
update
(
name
,
level
,
section
)
162
end
163 164
function
sections
.
currentid
(
)
165
return
#
tobesaved
166
end
167 168
local
lastsaved
=
0
169 170
function
sections
.
save
(
sectiondata
)
171
local
sectiondata
=
helpers
.
simplify
(
sectiondata
)
-- maybe done earlier
172
local
numberdata
=
sectiondata
.
numberdata
173
local
ntobesaved
=
#
tobesaved
174
if
not
numberdata
or
sectiondata
.
metadata
.
nolist
then
175
-- stay
176
else
177
ntobesaved
=
ntobesaved
+
1
178
tobesaved
[
ntobesaved
]
=
numberdata
179
if
not
collected
[
ntobesaved
]
then
180
collected
[
ntobesaved
]
=
numberdata
181
end
182
end
183
lastsaved
=
ntobesaved
184
return
ntobesaved
185
end
186 187
function
sections
.
currentsectionindex
(
)
188
return
lastsaved
-- only for special controlled situations
189
end
190 191
-- See comment above (*). We cannot use the following space optimization:
192
--
193
-- function sections.load()
194
-- setmetatableindex(collected,nil)
195
-- local lists = lists.collected
196
-- for i=1,#lists do
197
-- local list = lists[i]
198
-- local metadata = list.metadata
199
-- if metadata and metadata.kind == "section" and not metadata.nolist then
200
-- local numberdata = list.numberdata
201
-- if numberdata then
202
-- collected[#collected+1] = numberdata
203
-- end
204
-- end
205
-- end
206
-- sections.load = functions.dummy
207
-- end
208
--
209
-- table.setmetatableindex(collected, function(t,i)
210
-- sections.load()
211
-- return collected[i] or { }
212
-- end)
213 214
sections
.
verbose
=
true
215 216
local
sectionblockdata
=
sections
.
sectionblockdata
or
{
}
217
sections
.
sectionblockdata
=
sectionblockdata
218 219
local
levelmap
=
sections
.
levelmap
or
{
}
220
sections
.
levelmap
=
levelmap
221
levelmap
.
block
=
-1
222 223
storage
.
register
(
"
structures/sections/levelmap
"
,
sections
.
levelmap
,
"
structures.sections.levelmap
"
)
224 225
function
sections
.
setlevel
(
name
,
level
)
-- level can be number or parent (=string)
226
local
l
=
tonumber
(
level
)
227
if
not
l
then
228
l
=
levelmap
[
level
]
229
end
230
if
l
and
l
>
0
then
231
levelmap
[
name
]
=
l
232
else
233
-- error
234
end
235
end
236 237
function
sections
.
getlevel
(
name
)
238
return
levelmap
[
name
]
or
0
239
end
240 241
table
.
setmetatableindex
(
sectionblockdata
,
"
table
"
)
242 243
function
sections
.
setblock
(
name
,
settings
)
244
local
block
=
name
or
data
.
block
or
"
unknown
"
-- can be used to set the default
245
data
.
block
=
block
246
sectionblockdata
[
block
]
=
settings
247
return
block
248
end
249 250
local
jobvariables
=
job
.
variables
251
local
pushed_order
=
{
}
252
local
pushed_done
=
{
}
253 254
jobvariables
.
tobesaved
.
sectionblockorder
=
pushed_order
255 256
-- function sections.order()
257
-- return jobvariables.collected.sectionblockorder or pushed_order -- so we have a first pass list too
258
-- end
259 260
function
sections
.
setinitialblock
(
default
)
261
local
order
=
jobvariables
.
collected
.
sectionblockorder
or
pushed_order
262
local
name
=
#
order
>
0
and
order
[
1
]
or
default
or
"
bodypart
"
263
context
.
setsectionblock
{
name
}
264
-- interfaces.setmacro("currentsectionblock",name)
265
-- sections.setblock(name,{})
266
end
267 268
function
sections
.
pushblock
(
name
,
settings
)
269
counters
.
check
(
0
)
-- we assume sane usage of \page between blocks
270
local
block
=
name
or
data
.
block
271
insert
(
data
.
blocks
,
block
)
272
data
.
block
=
block
273
sectionblockdata
[
block
]
=
settings
274
documents
.
reset
(
)
275
if
not
pushed_done
[
name
]
then
276
pushed_done
[
name
]
=
true
277
local
nofpushed
=
#
pushed_order
+
1
278
pushed_order
[
nofpushed
]
=
name
279
end
280
return
block
281
end
282 283
function
sections
.
popblock
(
)
284
local
block
=
remove
(
data
.
blocks
)
or
data
.
block
285
data
.
block
=
block
286
documents
.
reset
(
)
287
return
block
288
end
289 290
local
function
getcurrentblock
(
)
291
return
data
.
block
or
data
.
blocks
[
#
data
.
blocks
]
or
"
unknown
"
292
end
293 294
sections
.
currentblock
=
getcurrentblock
295 296
function
sections
.
currentlevel
(
)
297
return
data
.
depth
298
end
299 300
function
sections
.
getcurrentlevel
(
)
301
context
(
data
.
depth
)
302
end
303 304
local
saveset
=
{
}
-- experiment, see sections/tricky-001.tex
305 306
function
sections
.
setentry
(
given
)
307
-- old number
308
local
numbers
=
data
.
numbers
309
--
310
local
metadata
=
given
.
metadata
311
local
numberdata
=
given
.
numberdata
312
local
references
=
given
.
references
313
local
directives
=
given
.
directives
314
local
userdata
=
given
.
userdata
315 316
if
not
metadata
then
317
metadata
=
{
}
318
given
.
metadata
=
metadata
319
end
320
if
not
numberdata
then
321
numberdata
=
{
}
322
given
.
numberdata
=
numberdata
323
end
324
if
not
references
then
325
references
=
{
}
326
given
.
references
=
references
327
end
328 329
local
ownnumbers
=
data
.
ownnumbers
330
local
forced
=
data
.
forced
331
local
status
=
data
.
status
332
local
olddepth
=
data
.
depth
333
local
givenname
=
metadata
.
name
334
local
mappedlevel
=
levelmap
[
givenname
]
335
local
newdepth
=
tonumber
(
mappedlevel
or
(
olddepth
>
0
and
olddepth
)
or
1
)
-- hm, levelmap only works for section-*
336
local
resetset
=
directives
and
directives
.
resetset
or
"
"
337
-- local resetter = sets.getall("structure:resets",data.block,resetset)
338
-- a trick to permit userdata to overload title, ownnumber and reference
339
-- normally these are passed as argument but nowadays we provide several
340
-- interfaces (we need this because we want to be compatible)
341
if
trace_details
then
342
report_structure
(
"
name %a, mapped level %a, old depth %a, new depth %a, reset set %a
"
,
343
givenname
,
mappedlevel
,
olddepth
,
newdepth
,
resetset
)
344
end
345
if
userdata
then
346
-- kind of obsolete as we can pass them directly anyway ... NEEDS CHECKING !
347
if
userdata
.
reference
and
userdata
.
reference
~
=
"
"
then
given
.
metadata
.
reference
=
userdata
.
reference
;
userdata
.
reference
=
nil
end
348
if
userdata
.
ownnumber
and
userdata
.
ownnumber
~
=
"
"
then
given
.
numberdata
.
ownnumber
=
userdata
.
ownnumber
;
userdata
.
ownnumber
=
nil
end
349
if
userdata
.
title
and
userdata
.
title
~
=
"
"
then
given
.
titledata
.
title
=
userdata
.
title
;
userdata
.
title
=
nil
end
350
if
userdata
.
bookmark
and
userdata
.
bookmark
~
=
"
"
then
given
.
titledata
.
bookmark
=
userdata
.
bookmark
;
userdata
.
bookmark
=
nil
end
351
if
userdata
.
label
and
userdata
.
label
~
=
"
"
then
given
.
titledata
.
label
=
userdata
.
label
;
userdata
.
label
=
nil
end
352
end
353
-- so far for the trick
354
if
saveset
then
355
saveset
[
newdepth
]
=
(
resetset
~
=
"
"
and
resetset
)
or
saveset
[
newdepth
]
or
"
"
356
end
357
if
newdepth
>
olddepth
then
358
for
i
=
olddepth
+
1
,
newdepth
do
359
local
s
=
tonumber
(
sets
.
get
(
"
structure:resets
"
,
data
.
block
,
saveset
and
saveset
[
i
]
or
resetset
,
i
)
)
360
if
trace_details
then
361
report_structure
(
"
new depth %s, old depth %s, reset set %a, reset value %a, current %a
"
,
olddepth
,
newdepth
,
resetset
,
s
,
numbers
[
i
]
)
362
end
363
if
not
s
or
s
=
=
0
then
364
numbers
[
i
]
=
numbers
[
i
]
or
0
365
ownnumbers
[
i
]
=
ownnumbers
[
i
]
or
"
"
366
else
367
numbers
[
i
]
=
s
-
1
368
ownnumbers
[
i
]
=
"
"
369
end
370
status
[
i
]
=
{
}
371
end
372
elseif
newdepth
<
olddepth
then
373
for
i
=
olddepth
,
newdepth
+
1
,
-1
do
374
local
s
=
tonumber
(
sets
.
get
(
"
structure:resets
"
,
data
.
block
,
saveset
and
saveset
[
i
]
or
resetset
,
i
)
)
375
if
trace_details
then
376
report_structure
(
"
new depth %s, old depth %s, reset set %a, reset value %a, current %a
"
,
olddepth
,
newdepth
,
resetset
,
s
,
numbers
[
i
]
)
377
end
378
if
not
s
or
s
=
=
0
then
379
numbers
[
i
]
=
numbers
[
i
]
or
0
380
ownnumbers
[
i
]
=
ownnumbers
[
i
]
or
"
"
381
else
382
numbers
[
i
]
=
s
-
1
383
ownnumbers
[
i
]
=
"
"
384
end
385
status
[
i
]
=
nil
386
end
387
end
388
counters
.
check
(
newdepth
)
389
ownnumbers
[
newdepth
]
=
numberdata
.
ownnumber
or
"
"
390
numberdata
.
ownnumber
=
nil
391
data
.
depth
=
newdepth
392
-- new number
393
olddepth
=
newdepth
394
if
metadata
.
increment
then
395
local
oldn
=
numbers
[
newdepth
]
or
0
396
local
newn
=
0
397
local
fd
=
forced
[
newdepth
]
398
if
fd
then
399
if
fd
[
1
]
=
=
"
add
"
then
400
newn
=
oldn
+
fd
[
2
]
+
1
401
else
402
newn
=
fd
[
2
]
+
1
403
end
404
if
newn
<
0
then
405
newn
=
1
-- maybe zero is nicer
406
end
407
forced
[
newdepth
]
=
nil
408
if
trace_details
then
409
report_structure
(
"
old depth %a, new depth %a, old n %a, new n %a, forced %t
"
,
olddepth
,
newdepth
,
oldn
,
newn
,
fd
)
410
end
411
else
412
newn
=
oldn
+
1
413
if
trace_details
then
414
report_structure
(
"
old depth %a, new depth %a, old n %a, new n %a, increment
"
,
olddepth
,
newdepth
,
oldn
,
newn
)
415
end
416
end
417
numbers
[
newdepth
]
=
newn
418
end
419
status
[
newdepth
]
=
given
or
{
}
420
for
k
,
v
in
next
,
data
.
checkers
do
421
if
v
[
1
]
=
=
newdepth
and
v
[
2
]
then
422
v
[
2
]
(
k
)
423
end
424
end
425
numberdata
.
numbers
=
{
unpack
(
numbers
,
1
,
newdepth
)
}
426
if
not
numberdata
.
block
then
427
numberdata
.
block
=
getcurrentblock
(
)
-- also in references
428
end
429
if
#
ownnumbers
>
0
then
430
numberdata
.
ownnumbers
=
fastcopy
(
ownnumbers
)
-- { unpack(ownnumbers) }
431
end
432
if
trace_details
then
433
report_structure
(
"
name %a, numbers % a, own numbers % a
"
,
givenname
,
numberdata
.
numbers
,
numberdata
.
ownnumbers
)
434
end
435
if
not
references
.
block
then
436
references
.
block
=
getcurrentblock
(
)
-- also in numberdata
437
end
438
local
tag
=
references
.
tag
or
tags
.
getid
(
metadata
.
kind
,
metadata
.
name
)
439
if
tag
and
tag
~
=
"
"
and
tag
~
=
"
?
"
then
440
references
.
tag
=
tag
441
end
442
local
setcomponent
=
structures
.
references
.
setcomponent
443
if
setcomponent
then
444
setcomponent
(
given
)
-- might move to the tex end
445
end
446
references
.
section
=
sections
.
save
(
given
)
447
-- given.numberdata = nil
448
end
449 450
function
sections
.
reportstructure
(
)
451
if
sections
.
verbose
then
452
local
numbers
=
data
.
numbers
453
local
ownnumbers
=
data
.
ownnumbers
454
local
status
=
data
.
status
455
local
depth
=
data
.
depth
456
local
d
=
status
[
depth
]
457
local
o
=
concat
(
ownnumbers
,
"
.
"
,
1
,
depth
)
458
local
n
=
(
numbers
and
concat
(
numbers
,
"
.
"
,
1
,
min
(
depth
,
#
numbers
)
)
)
or
0
459
local
t
=
d
.
titledata
.
title
460
local
l
=
t
or
"
"
461
local
t
=
(
l
~
=
"
"
and
l
)
or
t
or
"
[no title]
"
462
local
m
=
d
.
metadata
.
name
463
if
o
and
not
find
(
o
,
"
^%.*$
"
)
then
464
report_structure
(
"
%s @ level %i : (%s) %s -> %s
"
,
m
,
depth
,
n
,
o
,
t
)
465
elseif
d
.
directives
and
d
.
directives
.
hidenumber
then
466
report_structure
(
"
%s @ level %i : (%s) -> %s
"
,
m
,
depth
,
n
,
t
)
467
else
468
report_structure
(
"
%s @ level %i : %s -> %s
"
,
m
,
depth
,
n
,
t
)
469
end
470
end
471
end
472 473
-- function sections.setnumber(depth,n)
474
-- local forced, depth, new = data.forced, depth or data.depth, tonumber(n) or 0
475
-- if type(n) == "string" then
476
-- if find(n,"^[%+%-]") then
477
-- forced[depth] = { "add", new }
478
-- else
479
-- forced[depth] = { "set", new }
480
-- end
481
-- else
482
-- forced[depth] = { "set", new }
483
-- end
484
-- end
485 486
function
sections
.
setnumber
(
depth
,
n
)
487
data
.
forced
[
depth
or
data
.
depth
]
=
{
488
type
(
n
)
=
=
"
string
"
and
find
(
n
,
"
^[%+%-]
"
)
and
"
add
"
or
"
set
"
,
489
tonumber
(
n
)
or
0
490
}
491
end
492 493
function
sections
.
numberatdepth
(
depth
)
494
return
data
.
numbers
[
tonumber
(
depth
)
or
sections
.
getlevel
(
depth
)
or
0
]
or
0
495
end
496 497
function
sections
.
numbers
(
)
498
return
data
.
numbers
499
end
500 501
function
sections
.
matchingtilldepth
(
depth
,
numbers
,
parentnumbers
)
502
local
dn
=
parentnumbers
or
data
.
numbers
503
local
ok
=
false
504
for
i
=
1
,
depth
do
505
if
dn
[
i
]
=
=
numbers
[
i
]
then
506
ok
=
true
507
else
508
return
false
509
end
510
end
511
return
ok
512
end
513 514
function
sections
.
getnumber
(
depth
)
-- redefined later ...
515
context
(
data
.
numbers
[
depth
]
or
0
)
516
end
517 518
function
sections
.
set
(
key
,
value
)
519
data
.
status
[
data
.
depth
]
[
key
]
=
value
-- may be nil for a reset
520
end
521 522
function
sections
.
cct
(
)
523
local
metadata
=
data
.
status
[
data
.
depth
]
.
metadata
524
context
(
metadata
and
metadata
.
catcodes
or
ctxcatcodes
)
525
end
526 527
-- this one will become: return catcode, d (etc)
528 529
function
sections
.
structuredata
(
depth
,
key
,
default
,
honorcatcodetable
)
-- todo: spec table and then also depth
530
if
depth
then
531
depth
=
levelmap
[
depth
]
or
tonumber
(
depth
)
532
end
533
if
not
depth
or
depth
=
=
0
then
534
depth
=
data
.
depth
535
end
536
local
data
=
data
.
status
[
depth
]
537
local
d
538
if
data
then
539
if
find
(
key
,
"
.
"
,
1
,
true
)
then
540
d
=
accesstable
(
key
,
data
)
541
else
542
d
=
data
.
titledata
543
d
=
d
and
d
[
key
]
544
end
545
end
546
if
d
and
type
(
d
)
~
=
"
table
"
then
547
if
honorcatcodetable
=
=
true
or
honorcatcodetable
=
=
v_auto
then
548
local
metadata
=
data
.
metadata
549
local
catcodes
=
metadata
and
metadata
.
catcodes
550
if
catcodes
then
551
ctx_sprint
(
catcodes
,
d
)
552
else
553
context
(
d
)
554
end
555
elseif
not
honorcatcodetable
or
honorcatcodetable
=
=
"
"
then
556
context
(
d
)
557
else
558
local
catcodes
=
catcodenumbers
[
honorcatcodetable
]
559
if
catcodes
then
560
ctx_sprint
(
catcodes
,
d
)
561
else
562
context
(
d
)
563
end
564
end
565
elseif
default
then
566
context
(
default
)
567
end
568
end
569 570
function
sections
.
userdata
(
depth
,
key
,
default
)
571
if
depth
then
572
depth
=
levelmap
[
depth
]
or
tonumber
(
depth
)
573
end
574
if
not
depth
or
depth
=
=
0
then
575
depth
=
data
.
depth
576
end
577
if
depth
>
0
then
578
local
userdata
=
data
.
status
[
depth
]
579
userdata
=
userdata
and
userdata
.
userdata
580
userdata
=
(
userdata
and
userdata
[
key
]
)
or
default
581
if
userdata
then
582
context
(
userdata
)
583
end
584
end
585
end
586 587
function
sections
.
setchecker
(
name
,
level
,
command
)
-- hm, checkers are not saved
588
data
.
checkers
[
name
]
=
(
name
and
command
and
level
>
=
0
and
{
level
,
command
}
)
or
nil
589
end
590 591
function
sections
.
current
(
)
592
return
data
.
status
[
data
.
depth
]
593
end
594 595
local
function
depthnumber
(
n
)
596
local
depth
=
data
.
depth
597
if
not
n
or
n
=
=
0
then
598
n
=
depth
599
elseif
n
<
0
then
600
n
=
depth
+
n
601
end
602
return
data
.
numbers
[
n
]
or
0
603
end
604 605
sections
.
depthnumber
=
depthnumber
606 607
function
sections
.
autodepth
(
numbers
)
608
for
i
=
#
numbers
,
1
,
-1
do
609
if
numbers
[
i
]
~
=
0
then
610
return
i
611
end
612
end
613
return
0
614
end
615 616
--
617 618
function
structures
.
currentsectionnumber
(
)
-- brr, namespace wrong
619
local
sc
=
sections
.
current
(
)
620
return
sc
and
sc
.
numberdata
621
end
622 623
-- \dorecurse{3} {
624
-- \chapter{Blabla} \subsection{bla 1 1} \subsection{bla 1 2}
625
-- \section{bla 2} \subsection{bla 2 1} \subsection{bla 2 2}
626
-- }
627 628
-- sign=all => also zero and negative
629
-- sign=positive => also zero
630
-- sign=hang => llap sign
631 632
-- this can be a local function
633 634
local
function
process
(
index
,
numbers
,
ownnumbers
,
criterium
,
separatorset
,
conversion
,
conversionset
,
entry
,
result
,
preceding
,
done
,
language
)
635
-- todo: too much (100 steps)
636
local
number
=
numbers
and
(
numbers
[
index
]
or
0
)
637
local
ownnumber
=
ownnumbers
and
ownnumbers
[
index
]
or
"
"
638
if
number
>
criterium
or
(
ownnumber
~
=
"
"
)
then
639
local
block
=
(
entry
.
block
~
=
"
"
and
entry
.
block
)
or
sections
.
currentblock
(
)
-- added
640
if
preceding
then
641
local
separator
=
sets
.
get
(
"
structure:separators
"
,
block
,
separatorset
,
preceding
,
"
.
"
)
642
if
separator
then
643
if
result
then
644
result
[
#
result
+
1
]
=
strippedprocessor
(
separator
)
645
else
646
applyprocessor
(
separator
)
647
end
648
end
649
preceding
=
false
650
end
651
if
result
then
652
if
ownnumber
~
=
"
"
then
653
result
[
#
result
+
1
]
=
ownnumber
654
elseif
conversion
and
conversion
~
=
"
"
then
-- traditional (e.g. used in itemgroups) .. inherited!
655
result
[
#
result
+
1
]
=
convertnumber
(
conversion
,
number
,
language
)
656
else
657
local
theconversion
=
sets
.
get
(
"
structure:conversions
"
,
block
,
conversionset
,
index
,
"
numbers
"
)
658
result
[
#
result
+
1
]
=
convertnumber
(
theconversion
,
number
,
language
)
659
end
660
else
661
if
ownnumber
~
=
"
"
then
662
applyprocessor
(
ownnumber
)
663
elseif
conversion
and
conversion
~
=
"
"
then
-- traditional (e.g. used in itemgroups)
664
ctx_convertnumber
(
conversion
,
number
)
665
else
666
local
theconversion
=
sets
.
get
(
"
structure:conversions
"
,
block
,
conversionset
,
index
,
"
numbers
"
)
667
local
data
=
startapplyprocessor
(
theconversion
)
668
ctx_convertnumber
(
data
or
"
numbers
"
,
number
)
669
stopapplyprocessor
(
)
670
end
671
end
672
return
index
,
true
673
else
674
return
preceding
or
false
,
done
675
end
676
end
677 678
-- kind : section number prefix
679 680
function
sections
.
typesetnumber
(
entry
,
kind
,
...
)
681
--
682
-- Maybe the hiding becomes an option .. after all this test was there
683
-- for a reason, but for now we have this:
684
--
685
-- if entry and entry.hidenumber ~= true then
686
if
entry
then
687
local
separatorset
=
"
"
688
local
conversionset
=
"
"
689
local
conversion
=
"
"
690
local
groupsuffix
=
"
"
691
local
stopper
=
"
"
692
local
starter
=
"
"
693
local
connector
=
"
"
694
local
set
=
"
"
695
local
segments
=
"
"
696
local
criterium
=
"
"
697
local
language
=
"
"
698
for
d
=
1
,
select
(
"
#
"
,
...
)
do
699
local
data
=
select
(
d
,
...
)
-- can be multiple parametersets
700
if
data
then
701
if
separatorset
=
=
"
"
then
separatorset
=
data
.
separatorset
or
"
"
end
702
if
conversionset
=
=
"
"
then
conversionset
=
data
.
conversionset
or
"
"
end
703
if
conversion
=
=
"
"
then
conversion
=
data
.
conversion
or
"
"
end
704
if
groupsuffix
=
=
"
"
then
groupsuffix
=
data
.
groupsuffix
or
"
"
end
705
if
stopper
=
=
"
"
then
stopper
=
data
.
stopper
or
"
"
end
706
if
starter
=
=
"
"
then
starter
=
data
.
starter
or
"
"
end
707
if
connector
=
=
"
"
then
connector
=
data
.
connector
or
"
"
end
708
if
set
=
=
"
"
then
set
=
data
.
set
or
"
"
end
709
if
segments
=
=
"
"
then
segments
=
data
.
segments
or
"
"
end
710
if
criterium
=
=
"
"
then
criterium
=
data
.
criterium
or
"
"
end
711
if
language
=
=
"
"
then
language
=
data
.
language
or
"
"
end
712
end
713
end
714
if
separatorset
=
=
"
"
then
separatorset
=
"
default
"
end
715
if
conversionset
=
=
"
"
then
conversionset
=
"
default
"
end
-- not used
716
if
conversion
=
=
"
"
then
conversion
=
nil
end
717
if
groupsuffix
=
=
"
"
then
groupsuffix
=
nil
end
718
if
stopper
=
=
"
"
then
stopper
=
nil
end
719
if
starter
=
=
"
"
then
starter
=
nil
end
720
if
connector
=
=
"
"
then
connector
=
nil
end
721
if
set
=
=
"
"
then
set
=
"
default
"
end
722
if
segments
=
=
"
"
then
segments
=
nil
end
723
if
language
=
=
"
"
then
language
=
nil
end
724
--
725
if
criterium
=
=
v_strict
then
726
criterium
=
0
727
elseif
criterium
=
=
v_positive
then
728
criterium
=
-1
729
elseif
criterium
=
=
v_all
then
730
criterium
=
-1000000
731
else
732
criterium
=
0
733
end
734
--
735
local
firstprefix
=
0
736
local
lastprefix
=
16
-- too much, could max found level
737
if
segments
=
=
v_current
then
738
firstprefix
=
data
.
depth
739
lastprefix
=
firstprefix
740
elseif
segments
then
741
local
f
,
l
=
match
(
tostring
(
segments
)
,
"
^(.-):(.+)$
"
)
742
if
l
=
=
"
*
"
or
l
=
=
v_all
then
743
l
=
100
-- new
744
end
745
if
f
and
l
then
746
-- 0:100, chapter:subsubsection
747
firstprefix
=
tonumber
(
f
)
or
sections
.
getlevel
(
f
)
or
0
748
lastprefix
=
tonumber
(
l
)
or
sections
.
getlevel
(
l
)
or
100
749
else
750
-- 3, section
751
local
fl
=
tonumber
(
segments
)
or
sections
.
getlevel
(
segments
)
-- generalize
752
if
fl
then
753
firstprefix
=
fl
754
lastprefix
=
fl
755
end
756
end
757
end
758
--
759
local
numbers
=
entry
.
numbers
760
local
ownnumbers
=
entry
.
ownnumbers
761
if
numbers
then
762
local
done
=
false
763
local
preceding
=
false
764
--
765
local
result
=
kind
=
=
"
direct
"
and
{
}
766
if
result
then
767
connector
=
false
768
end
769
--
770
local
prefixlist
=
set
and
sets
.
getall
(
"
structure:prefixes
"
,
"
"
,
set
)
-- "" == block
771
if
starter
then
772
if
result
then
773
result
[
#
result
+
1
]
=
strippedprocessor
(
starter
)
774
else
775
applyprocessor
(
starter
)
776
end
777
end
778
-- inspect(entry)
779
if
prefixlist
and
(
kind
=
=
"
section
"
or
kind
=
=
"
prefix
"
or
kind
=
=
"
direct
"
)
then
780
-- find valid set (problem: for sectionnumber we should pass the level)
781
-- no holes
782
local
b
=
1
783
local
e
=
#
prefixlist
784
local
bb
=
0
785
local
ee
=
0
786
-- find last valid number
787
-- print("index >>",b,e)
788
-- inspect(prefixlist)
789
for
k
=
e
,
b
,
-1
do
790
local
prefix
=
prefixlist
[
k
]
791
local
index
=
sections
.
getlevel
(
prefix
)
or
k
792
if
index
>
=
firstprefix
and
index
<
=
lastprefix
then
793
local
number
=
numbers
and
numbers
[
index
]
794
if
number
then
795
local
ownnumber
=
ownnumbers
and
ownnumbers
[
index
]
or
"
"
796
if
number
>
0
or
(
ownnumber
~
=
"
"
)
then
797
break
798
else
799
e
=
k
-1
800
end
801
end
802
end
803
end
804
-- find valid range
805
for
k
=
b
,
e
do
806
local
prefix
=
prefixlist
[
k
]
807
local
index
=
sections
.
getlevel
(
prefix
)
or
k
808
if
index
>
=
firstprefix
and
index
<
=
lastprefix
then
809
local
number
=
numbers
and
numbers
[
index
]
810
if
number
then
811
local
ownnumber
=
ownnumbers
and
ownnumbers
[
index
]
or
"
"
812
if
number
>
0
or
(
ownnumber
~
=
"
"
)
then
813
if
bb
=
=
0
then
814
bb
=
k
815
end
816
ee
=
k
817
elseif
criterium
>
=
0
then
818
bb
=
0
819
ee
=
0
820
end
821
else
822
break
823
end
824
end
825
end
826
-- print valid range
827
for
k
=
bb
,
ee
do
828
local
prefix
=
prefixlist
[
k
]
829
local
index
=
sections
.
getlevel
(
prefix
)
or
k
830
if
index
>
=
firstprefix
and
index
<
=
lastprefix
then
831
preceding
,
done
=
process
(
index
,
numbers
,
ownnumbers
,
criterium
,
separatorset
,
conversion
,
conversionset
,
entry
,
result
,
preceding
,
done
,
language
)
832
end
833
end
834
else
835
-- also holes check
836
for
index
=
firstprefix
,
lastprefix
do
837
preceding
,
done
=
process
(
index
,
numbers
,
ownnumbers
,
criterium
,
separatorset
,
conversion
,
conversionset
,
entry
,
result
,
preceding
,
done
,
language
)
838
end
839
end
840
--
841
if
done
then
842
if
connector
and
kind
=
=
'
prefix
'
then
843
if
result
then
844
-- can't happen as we're in 'direct'
845
else
846
applyprocessor
(
connector
)
847
end
848
else
849
if
groupsuffix
and
kind
~
=
"
prefix
"
then
850
if
result
then
851
result
[
#
result
+
1
]
=
strippedprocessor
(
groupsuffix
)
852
else
853
applyprocessor
(
groupsuffix
)
854
end
855
end
856
if
stopper
then
857
if
result
then
858
result
[
#
result
+
1
]
=
strippedprocessor
(
stopper
)
859
else
860
applyprocessor
(
stopper
)
861
end
862
end
863
end
864
end
865
return
result
-- a table !
866
else
867
-- report_structure("error: no numbers")
868
end
869
end
870
end
871 872
function
sections
.
title
(
)
873
local
sc
=
sections
.
current
(
)
874
if
sc
then
875
helpers
.
title
(
sc
.
titledata
.
title
,
sc
.
metadata
)
876
end
877
end
878 879
function
sections
.
findnumber
(
depth
,
what
)
-- needs checking (looks wrong and slow too)
880
local
data
=
data
.
status
[
depth
or
data
.
depth
]
881
if
not
data
then
882
return
883
end
884
local
references
=
data
.
references
885
if
not
references
then
886
return
887
end
888
local
index
=
references
.
section
889
local
collected
=
sections
.
collected
890
local
sectiondata
=
collected
[
index
]
891
if
sectiondata
and
sectiondata
.
hidenumber
~
=
true
then
-- can be nil
892
local
quit
=
what
=
=
v_previous
or
what
=
=
v_next
893
if
what
=
=
v_first
or
what
=
=
v_previous
then
894
for
i
=
index
-1
,
1
,
-1
do
895
local
s
=
collected
[
i
]
896
if
s
then
897
local
n
=
s
.
numbers
898
if
#
n
=
=
depth
and
n
[
depth
]
and
n
[
depth
]
~
=
0
then
899
sectiondata
=
s
900
if
quit
then
901
break
902
end
903
elseif
#
n
<
depth
then
904
break
905
end
906
end
907
end
908
elseif
what
=
=
v_last
or
what
=
=
v_next
then
909
for
i
=
index
+
1
,
#
collected
do
910
local
s
=
collected
[
i
]
911
if
s
then
912
local
n
=
s
.
numbers
913
if
#
n
=
=
depth
and
n
[
depth
]
and
n
[
depth
]
~
=
0
then
914
sectiondata
=
s
915
if
quit
then
916
break
917
end
918
elseif
#
n
<
depth
then
919
break
920
end
921
end
922
end
923
end
924
return
sectiondata
925
end
926
end
927 928
function
sections
.
finddata
(
depth
,
what
)
929
local
data
=
data
.
status
[
depth
or
data
.
depth
]
930
if
not
data
then
931
return
932
end
933
local
references
=
data
.
references
934
if
not
references
then
935
return
936
end
937
local
index
=
references
.
listindex
938
if
not
index
then
939
return
940
end
941
local
collected
=
structures
.
lists
.
collected
942
local
quit
=
what
=
=
v_previous
or
what
=
=
v_next
943
if
what
=
=
v_first
or
what
=
=
v_previous
then
944
for
i
=
index
-1
,
1
,
-1
do
945
local
s
=
collected
[
i
]
946
if
not
s
then
947
break
948
elseif
s
.
metadata
.
kind
=
=
"
section
"
then
-- maybe check on name
949
local
n
=
s
.
numberdata
.
numbers
950
if
#
n
=
=
depth
and
n
[
depth
]
and
n
[
depth
]
~
=
0
then
951
data
=
s
952
if
quit
then
953
break
954
end
955
elseif
#
n
<
depth
then
956
break
957
end
958
end
959
end
960
elseif
what
=
=
v_last
or
what
=
=
v_next
then
961
for
i
=
index
+
1
,
#
collected
do
962
local
s
=
collected
[
i
]
963
if
not
s
then
964
break
965
elseif
s
.
metadata
.
kind
=
=
"
section
"
then
-- maybe check on name
966
local
n
=
s
.
numberdata
.
numbers
967
if
#
n
=
=
depth
and
n
[
depth
]
and
n
[
depth
]
~
=
0
then
968
data
=
s
969
if
quit
then
970
break
971
end
972
elseif
#
n
<
depth
then
973
break
974
end
975
end
976
end
977
end
978
return
data
979
end
980 981
function
sections
.
internalreference
(
sectionname
,
what
)
-- to be used in pagebuilder (no marks used)
982
local
r
=
type
(
sectionname
)
=
=
"
number
"
and
sectionname
or
registered
[
sectionname
]
983
if
r
then
984
local
data
=
sections
.
finddata
(
r
.
level
,
what
)
985
return
data
and
data
.
references
and
data
.
references
.
internal
986
end
987
end
988 989
function
sections
.
fullnumber
(
depth
,
what
)
990
local
sectiondata
=
sections
.
findnumber
(
depth
,
what
)
991
if
sectiondata
then
992
sections
.
typesetnumber
(
sectiondata
,
'
section
'
,
sectiondata
)
993
end
994
end
995 996
function
sections
.
getnumber
(
depth
,
what
)
-- redefined here
997
local
sectiondata
=
sections
.
findnumber
(
depth
,
what
)
998
local
askednumber
=
0
999
if
sectiondata
then
1000
local
numbers
=
sectiondata
.
numbers
1001
if
numbers
then
1002
askednumber
=
numbers
[
depth
]
or
0
1003
end
1004
end
1005
context
(
askednumber
)
1006
end
1007 1008
-- maybe handy
1009 1010
function
sections
.
showstructure
(
)
1011 1012
local
tobesaved
=
structures
.
lists
.
tobesaved
1013 1014
if
not
tobesaved
then
1015
return
1016
end
1017 1018
local
levels
=
setmetatableindex
(
"
table
"
)
1019
local
names
=
setmetatableindex
(
"
table
"
)
1020 1021
report_used
(
)
1022
report_used
(
"
sections
"
)
1023
for
i
=
1
,
#
tobesaved
do
1024
local
si
=
tobesaved
[
i
]
1025
local
md
=
si
.
metadata
1026
if
md
and
md
.
kind
=
=
"
section
"
then
1027
local
level
=
md
.
level
1028
local
name
=
md
.
name
1029
local
numbers
=
si
.
numberdata
.
numbers
1030
local
title
=
si
.
titledata
.
title
1031
report_used
(
"
%i : %-10s %-20s %s
"
,
level
,
concat
(
numbers
,
"
.
"
)
,
name
,
title
)
1032
levels
[
level
]
[
name
]
=
true
1033
names
[
name
]
[
level
]
=
true
1034
end
1035
end
1036
report_used
(
)
1037
report_used
(
"
levels
"
)
1038
for
level
,
list
in
sortedhash
(
levels
)
do
1039
report_used
(
"
%s : % t
"
,
level
,
sortedkeys
(
list
)
)
1040
end
1041
report_used
(
)
1042
report_used
(
"
names
"
)
1043
for
name
,
list
in
sortedhash
(
names
)
do
1044
report_used
(
"
%-10s : % t
"
,
name
,
sortedkeys
(
list
)
)
1045
end
1046
report_used
(
)
1047
end
1048 1049
-- experimental
1050 1051
local
levels
=
{
}
1052 1053
local
function
autonextstructurelevel
(
level
)
1054
if
level
>
#
levels
then
1055
for
i
=
#
levels
+
1
,
level
do
1056
levels
[
i
]
=
false
1057
end
1058
else
1059
for
i
=
level
,
#
levels
do
1060
if
levels
[
i
]
then
1061
ctx_finalizeauto
(
)
1062
levels
[
i
]
=
false
1063
end
1064
end
1065
end
1066
levels
[
level
]
=
true
1067
end
1068 1069
local
function
autofinishstructurelevels
(
)
1070
for
i
=
1
,
#
levels
do
1071
if
levels
[
i
]
then
1072
ctx_finalizeauto
(
)
1073
end
1074
end
1075
levels
=
{
}
1076
end
1077 1078
implement
{
1079
name
=
"
autonextstructurelevel
"
,
1080
actions
=
autonextstructurelevel
,
1081
arguments
=
"
integer
"
,
1082
}
1083 1084
implement
{
1085
name
=
"
autofinishstructurelevels
"
,
1086
actions
=
autofinishstructurelevels
,
1087
}
1088 1089
-- interface (some are actually already commands, like sections.fullnumber)
1090 1091
implement
{
1092
name
=
"
depthnumber
"
,
1093
actions
=
{
depthnumber
,
context
}
,
1094
arguments
=
"
integer
"
,
1095
}
1096 1097
implement
{
name
=
"
structurenumber
"
,
actions
=
sections
.
fullnumber
}
1098
implement
{
name
=
"
structuretitle
"
,
actions
=
sections
.
title
}
1099 1100
implement
{
name
=
"
structurevariable
"
,
actions
=
sections
.
structuredata
,
arguments
=
{
false
,
"
string
"
}
}
1101
implement
{
name
=
"
structureuservariable
"
,
actions
=
sections
.
userdata
,
arguments
=
{
false
,
"
string
"
}
}
1102
implement
{
name
=
"
structurecatcodedget
"
,
actions
=
sections
.
structuredata
,
arguments
=
{
false
,
"
string
"
,
false
,
true
}
}
1103
implement
{
name
=
"
structuregivencatcodedget
"
,
actions
=
sections
.
structuredata
,
arguments
=
{
false
,
"
string
"
,
false
,
"
integer
"
}
}
1104
implement
{
name
=
"
structureautocatcodedget
"
,
actions
=
sections
.
structuredata
,
arguments
=
{
false
,
"
string
"
,
false
,
"
string
"
}
}
1105 1106
implement
{
name
=
"
namedstructurevariable
"
,
actions
=
sections
.
structuredata
,
arguments
=
"
2 strings
"
}
1107
implement
{
name
=
"
namedstructureuservariable
"
,
actions
=
sections
.
userdata
,
arguments
=
"
2 strings
"
}
1108 1109
implement
{
name
=
"
setstructurelevel
"
,
actions
=
sections
.
setlevel
,
arguments
=
"
2 strings
"
}
1110
implement
{
name
=
"
getstructurelevel
"
,
actions
=
sections
.
getcurrentlevel
,
arguments
=
"
string
"
}
1111
implement
{
name
=
"
setstructurenumber
"
,
actions
=
sections
.
setnumber
,
arguments
=
{
"
integer
"
,
"
string
"
}
}
-- string as we support +-
1112
implement
{
name
=
"
getstructurenumber
"
,
actions
=
sections
.
getnumber
,
arguments
=
"
integer
"
}
1113
implement
{
name
=
"
getsomestructurenumber
"
,
actions
=
sections
.
getnumber
,
arguments
=
{
"
integer
"
,
"
string
"
}
}
1114
implement
{
name
=
"
getfullstructurenumber
"
,
actions
=
sections
.
fullnumber
,
arguments
=
"
integer
"
}
1115
implement
{
name
=
"
getsomefullstructurenumber
"
,
actions
=
sections
.
fullnumber
,
arguments
=
{
"
integer
"
,
"
string
"
}
}
1116
implement
{
name
=
"
getspecificstructuretitle
"
,
actions
=
sections
.
structuredata
,
arguments
=
{
"
string
"
,
"
'titledata.title'
"
,
false
,
"
string
"
}
}
1117 1118
implement
{
name
=
"
reportstructure
"
,
actions
=
sections
.
reportstructure
}
1119
implement
{
name
=
"
showstructure
"
,
actions
=
sections
.
showstructure
}
1120 1121
implement
{
1122
name
=
"
registersection
"
,
1123
actions
=
sections
.
register
,
1124
arguments
=
{
1125
"
string
"
,
1126
{
1127
{
"
coupling
"
}
,
1128
{
"
section
"
}
,
1129
{
"
level
"
,
"
integer
"
}
,
1130
{
"
parent
"
}
,
1131
}
1132
}
1133
}
1134 1135
implement
{
1136
name
=
"
setsectionentry
"
,
1137
actions
=
sections
.
setentry
,
1138
arguments
=
{
1139
{
1140
{
"
references
"
,
{
1141
{
"
internal
"
,
"
integer
"
}
,
1142
{
"
block
"
}
,
1143
{
"
backreference
"
}
,
1144
{
"
prefix
"
}
,
1145
{
"
reference
"
}
,
1146
}
1147
}
,
1148
{
"
directives
"
,
{
1149
{
"
resetset
"
}
1150
}
1151
}
,
1152
{
"
metadata
"
,
{
1153
{
"
kind
"
}
,
1154
{
"
name
"
}
,
1155
{
"
catcodes
"
,
"
integer
"
}
,
1156
{
"
coding
"
}
,
1157
{
"
xmlroot
"
}
,
1158
{
"
xmlsetup
"
}
,
1159
{
"
nolist
"
,
"
boolean
"
}
,
1160
{
"
increment
"
}
,
1161
}
1162
}
,
1163
{
"
titledata
"
,
{
1164
{
"
label
"
}
,
1165
{
"
title
"
}
,
1166
{
"
bookmark
"
}
,
1167
{
"
marking
"
}
,
1168
{
"
list
"
}
,
1169
{
"
reference
"
}
,
1170
}
1171
}
,
1172
{
"
numberdata
"
,
{
1173
{
"
block
"
}
,
1174
{
"
hidenumber
"
,
"
boolean
"
}
,
1175
{
"
separatorset
"
}
,
1176
{
"
conversionset
"
}
,
1177
{
"
conversion
"
}
,
1178
{
"
starter
"
}
,
1179
{
"
stopper
"
}
,
1180
{
"
set
"
}
,
1181
{
"
segments
"
}
,
1182
{
"
ownnumber
"
}
,
1183
{
"
language
"
}
,
1184
{
"
criterium
"
}
,
1185
}
,
1186
}
,
1187
{
"
userdata
"
}
,
1188
}
1189
}
1190
}
1191 1192
-- os.exit()
1193 1194
implement
{
1195
name
=
"
setsectionblock
"
,
1196
actions
=
sections
.
setblock
,
1197
arguments
=
{
"
string
"
,
{
{
"
bookmark
"
}
}
}
1198
}
1199 1200
implement
{
1201
name
=
"
setinitialsectionblock
"
,
1202
actions
=
sections
.
setinitialblock
,
1203
arguments
=
"
string
"
,
1204
-- onlyonce = true,
1205
}
1206 1207
implement
{
1208
name
=
"
pushsectionblock
"
,
1209
actions
=
sections
.
pushblock
,
1210
arguments
=
{
"
string
"
,
{
{
"
bookmark
"
}
}
}
1211
}
1212 1213
implement
{
1214
name
=
"
popsectionblock
"
,
1215
actions
=
sections
.
popblock
,
1216
}
1217 1218
interfaces
.
implement
{
1219
name
=
"
doifelsefirstsectionpage
"
,
1220
arguments
=
"
1 argument
"
,
1221
public
=
true
,
1222
protected
=
true
,
1223
actions
=
function
(
name
)
1224
local
found
=
false
1225
-- local list = structures.lists.collected
1226
local
list
=
lists
.
collected
1227
if
list
then
1228
local
realpage
=
texgetcount
(
"
realpageno
"
)
1229
for
i
=
1
,
#
list
do
1230
local
listdata
=
list
[
i
]
1231
local
metadata
=
listdata
.
metadata
1232
if
metadata
and
metadata
.
kind
=
=
"
section
"
and
metadata
.
name
=
=
name
then
1233
-- local current = structures.documents.data.status[metadata.level]
1234
local
current
=
data
.
status
[
metadata
.
level
]
1235
if
current
and
current
.
references
.
internal
=
=
listdata
.
references
.
internal
then
1236
found
=
listdata
.
references
.
realpage
=
=
realpage
1237
break
1238
end
1239
end
1240
end
1241
end
1242
ctx_doifelse
(
found
)
1243
end
,
1244
}
1245 1246
-- could be faster (in huge lists)
1247 1248
-- local firstpages = table.setmetatableindex(function(t,name)
1249
-- -- local list = structures.lists.collected
1250
-- local list = lists.collected
1251
-- local pages = { }
1252
-- if list then
1253
-- for i=1,#list do
1254
-- local listdata = list[i]
1255
-- local metadata = listdata.metadata
1256
-- if metadata and metadata.kind == "section" and metadata.name == name then
1257
-- local references = listdata.references
1258
-- if references then
1259
-- pages[references.internal] = listdata
1260
-- end
1261
-- end
1262
-- end
1263
-- end
1264
-- t[name] = pages
1265
-- return pages
1266
-- end)
1267
--
1268
-- interfaces.implement {
1269
-- name = "doifelsefirstsectionpage",
1270
-- arguments = "1 argument",
1271
-- public = true,
1272
-- protected = true,
1273
-- actions = function(name)
1274
-- local found = firstpages[name]
1275
-- if found then
1276
-- local level = structures.sections.levelmap[name]
1277
-- if level then
1278
-- -- local current = structures.documents.data.status[level]
1279
-- local current = data.status[level]
1280
-- if current then
1281
-- local realpage = texgetcount("realpageno")
1282
-- found = found[current.references.internal]
1283
-- found = found and found.references.realpage == realpage
1284
-- else
1285
-- found = false
1286
-- end
1287
-- else
1288
-- found = false
1289
-- end
1290
-- end
1291
-- ctx_doifelse(found)
1292
-- end,
1293
-- }
1294