anch-pgr.lua /size: 38 Kb    last modification: 2020-07-01 14:35
1
if
not
modules
then
modules
=
{
}
end
modules
[
'
anch-pgr
'
]
=
{
2
version
=
1
.
001
,
3
comment
=
"
companion to anch-pgr.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
-- This is a bit messy module but backgrounds are messy anyway. Especially when we want to
10
-- follow shapes. This will always be work in progress as it also depends on new features
11
-- in context.
12
--
13
-- Alas, shapes and inline didn't work as expected end of 2016 so I had to pick up this
14
-- thread again. But with regular excursions to listening to Brad Mehldau's Mehliana I
15
-- could keep myself motivated. Some old stuff has been removed, some suboptimal code has
16
-- been replaced. Background code is still not perfect, but some day ... the details manual
17
-- will discuss this issue.
18 19
local
tonumber
=
tonumber
20
local
sort
,
concat
=
table
.
sort
,
table
.
concat
21
local
splitter
=
lpeg
.
splitat
(
"
:
"
)
22
local
lpegmatch
=
lpeg
.
match
23 24
local
jobpositions
=
job
.
positions
25
local
formatters
=
string
.
formatters
26
local
setmetatableindex
=
table
.
setmetatableindex
27 28
local
enableaction
=
nodes
.
tasks
.
enableaction
29 30
local
commands
=
commands
31
local
context
=
context
32 33
local
implement
=
interfaces
.
implement
34 35
local
report_graphics
=
logs
.
reporter
(
"
backgrounds
"
)
36
local
report_shapes
=
logs
.
reporter
(
"
backgrounds
"
,
"
shapes
"
)
37
local
report_free
=
logs
.
reporter
(
"
backgrounds
"
,
"
free
"
)
38 39
local
trace_shapes
=
false
trackers
.
register
(
"
backgrounds.shapes
"
,
function
(
v
)
trace_shapes
=
v
end
)
40
local
trace_ranges
=
false
trackers
.
register
(
"
backgrounds.shapes.ranges
"
,
function
(
v
)
trace_ranges
=
v
end
)
41
local
trace_free
=
false
trackers
.
register
(
"
backgrounds.shapes.free
"
,
function
(
v
)
trace_free
=
v
end
)
42 43
local
f_b_tag
=
formatters
[
"
b:%s
"
]
44
local
f_e_tag
=
formatters
[
"
e:%s
"
]
45
local
f_p_tag
=
formatters
[
"
p:%s
"
]
46 47
local
f_tag_two
=
formatters
[
"
%s:%s
"
]
48 49
local
f_point
=
formatters
[
"
%p
"
]
50
local
f_pair
=
formatters
[
"
(%p,%p)
"
]
51
local
f_path
=
formatters
[
"
%--t--cycle
"
]
52
local
f_pair_i
=
formatters
[
"
(%r,%r)
"
]
-- rounded
53 54
graphics
=
graphics
or
{
}
55
local
backgrounds
=
{
}
56
graphics
.
backgrounds
=
backgrounds
57 58
-- -- --
59 60
local
texsetattribute
=
tex
.
setattribute
61 62
local
a_textbackground
=
attributes
.
private
(
"
textbackground
"
)
63 64
local
nuts
=
nodes
.
nuts
65 66
local
new_latelua
=
nuts
.
pool
.
latelua
67
local
new_rule
=
nuts
.
pool
.
rule
68
local
new_kern
=
nuts
.
pool
.
kern
69
local
new_hlist
=
nuts
.
pool
.
hlist
70 71
local
getbox
=
nuts
.
getbox
72
local
getid
=
nuts
.
getid
73
----- getlist = nuts.getlist
74
local
setlink
=
nuts
.
setlink
75
local
getheight
=
nuts
.
getheight
76
local
getdepth
=
nuts
.
getdepth
77 78
local
nodecodes
=
nodes
.
nodecodes
79
local
localpar_code
=
nodecodes
.
localpar
80 81
local
start_of_par
=
nuts
.
start_of_par
82
local
insert_before
=
nuts
.
insert_before
83
local
insert_after
=
nuts
.
insert_after
84 85
local
processranges
=
nuts
.
processranges
86 87
local
unsetvalue
=
attributes
.
unsetvalue
88 89
local
jobpositions
=
job
.
positions
90
local
getpos
=
jobpositions
.
getpos
91
local
getfree
=
jobpositions
.
getfree
92 93
local
data
=
{
}
94
local
realpage
=
1
95
local
recycle
=
1000
-- only tables can overflow this
96
local
enabled
=
false
97 98
-- Freeing the data is somewhat tricky as we can have backgrounds spanning
99
-- many pages but for an arbitrary background shape that is not so common.
100 101
local
function
check
(
specification
)
102
local
a
=
specification
.
attribute
103
local
index
=
specification
.
index
104
local
depth
=
specification
.
depth
105
local
d
=
specification
.
data
106
local
where
=
specification
.
where
107
local
ht
=
specification
.
ht
108
local
dp
=
specification
.
dp
109
-- this is not yet r2l ready
110
local
w
=
d
.
shapes
[
realpage
]
111
local
x
,
y
=
getpos
(
)
112
if
trace_ranges
then
113
report_shapes
(
"
attribute %i, index %i, depth %i, location %s, position (%p,%p)
"
,
114
a
,
index
,
depth
,
where
,
x
,
y
)
115
end
116
local
n
=
#
w
117
if
d
.
index
~
=
index
then
118
n
=
n
+
1
119
d
.
index
=
index
120
d
.
depth
=
depth
121
-- w[n] = { x, x, y, ht, dp }
122
w
[
n
]
=
{
y
,
ht
,
dp
,
x
,
x
}
123
else
124
local
wn
=
w
[
n
]
125
local
wh
=
wn
[
2
]
126
local
wd
=
wn
[
3
]
127
if
depth
<
d
.
depth
then
128
local
wy
=
wn
[
1
]
129
wn
[
1
]
=
y
130
d
.
depth
=
depth
131
local
dy
=
wy
-
y
132
wh
=
wh
-
dy
133
wd
=
wd
-
dy
134
end
135
if
where
=
=
"
r
"
then
136
if
x
>
wn
[
5
]
then
137
wn
[
5
]
=
x
138
end
139
else
140
if
x
<
wn
[
4
]
then
141
wn
[
4
]
=
x
142
end
143
end
144
if
ht
>
wh
then
145
wn
[
2
]
=
ht
146
end
147
if
dp
>
wd
then
148
wn
[
3
]
=
dp
149
end
150
end
151
-- inspect(w)
152
end
153 154
local
index
=
0
155 156
local
function
flush
(
head
,
f
,
l
,
a
,
parent
,
depth
)
157
local
d
=
data
[
a
]
158
if
d
then
159
local
ix
=
index
160
local
ht
=
getheight
(
parent
)
161
local
dp
=
getdepth
(
parent
)
162
local
ln
=
new_latelua
{
action
=
check
,
attribute
=
a
,
index
=
ix
,
depth
=
depth
,
data
=
d
,
where
=
"
l
"
,
ht
=
ht
,
dp
=
dp
}
163
local
rn
=
new_latelua
{
action
=
check
,
attribute
=
a
,
index
=
ix
,
depth
=
depth
,
data
=
d
,
where
=
"
r
"
,
ht
=
ht
,
dp
=
dp
}
164
if
trace_ranges
then
165
ln
=
new_hlist
(
setlink
(
new_rule
(
65536
,
65536
*
4
,
0
)
,
new_kern
(
-65536
)
,
ln
)
)
166
rn
=
new_hlist
(
setlink
(
new_rule
(
65536
,
0
,
65536
*
4
)
,
new_kern
(
-65536
)
,
rn
)
)
167
end
168
if
getid
(
f
)
=
=
localpar_code
and
start_of_par
(
f
)
then
-- we need to clean this mess
169
insert_after
(
head
,
f
,
ln
)
170
else
171
head
,
f
=
insert_before
(
head
,
f
,
ln
)
172
end
173
insert_after
(
head
,
l
,
rn
)
174
end
175
return
head
,
true
176
end
177 178
local
function
registerbackground
(
name
)
179
local
n
=
#
data
+
1
180
if
n
>
recycle
then
181
-- we could also free all e: that are beyond a page but we don't always
182
-- know the page so a recycle is nicer and the s lists are kept anyway
183
-- so the amount of kept data is not that large
184
n
=
1
185
end
186
local
b
=
jobpositions
.
tobesaved
[
"
b:
"
.
.
name
]
187
if
b
then
188
local
s
=
setmetatableindex
(
"
table
"
)
189
b
.
s
=
s
190
data
[
n
]
=
{
191
bpos
=
b
,
192
name
=
name
,
193
n
=
n
,
194
shapes
=
s
,
195
count
=
0
,
196
sindex
=
0
,
197
}
198
texsetattribute
(
a_textbackground
,
n
)
199
if
not
enabled
then
200
enableaction
(
"
contributers
"
,
"
nodes.handlers.textbackgrounds
"
)
201
enabled
=
true
202
end
203
else
204
texsetattribute
(
a_textbackground
,
unsetvalue
)
205
end
206
end
207 208
-- local function collectbackgrounds(r,n)
209
-- if enabled then
210
-- local parent = getbox(n)
211
-- local head = getlist(parent)
212
-- realpage = r
213
-- processranges(a_textbackground,flush,head) -- ,parent)
214
-- end
215
-- end
216
--
217
-- interfaces.implement {
218
-- name = "collectbackgrounds",
219
-- actions = collectbackgrounds,
220
-- arguments = { "integer", "integer" }
221
-- }
222 223
nodes
.
handlers
.
textbackgrounds
=
function
(
head
,
where
,
parent
)
-- we have hlistdir and local dir
224
-- todo enable action in register
225
index
=
index
+
1
226
return
processranges
(
a_textbackground
,
flush
,
head
,
parent
)
227
end
228 229
interfaces
.
implement
{
230
name
=
"
registerbackground
"
,
231
actions
=
registerbackground
,
232
arguments
=
"
string
"
,
233
}
234 235
-- optimized already but we can assume a cycle i.e. prune the last point and then
236
-- even less code .. we could merge some loops but his is more robust
237 238
-- use idiv here
239 240
local
function
topairs
(
t
,
n
)
241
local
r
=
{
}
242
for
i
=
1
,
n
do
243
local
ti
=
t
[
i
]
244
r
[
i
]
=
f_pair_i
(
ti
[
1
]
/
65556
,
ti
[
2
]
/
65536
)
245
end
246
return
concat
(
r
,
"
"
)
247
end
248 249
local
eps
=
65536
/
4
250
local
pps
=
eps
251
local
nps
=
-
pps
252 253
local
function
unitvector
(
x
,
y
)
254
if
x
<
pps
and
x
>
nps
then
255
x
=
0
256
elseif
x
<
0
then
257
x
=
-1
258
else
259
x
=
1
260
end
261
if
y
<
pps
and
y
>
nps
then
262
y
=
0
263
elseif
y
<
0
then
264
y
=
-1
265
else
266
y
=
1
267
end
268
return
x
,
y
269
end
270 271
local
function
finish
(
t
)
272
local
tm
=
#
t
273
if
tm
<
2
then
274
return
275
end
276
if
trace_ranges
then
277
report_shapes
(
"
initial list: %s
"
,
topairs
(
t
,
tm
)
)
278
end
279
-- remove similar points
280
local
n
=
1
281
local
tn
=
tm
282
local
tf
=
t
[
1
]
283
local
tx
=
tf
[
1
]
284
local
ty
=
tf
[
2
]
285
for
i
=
2
,
#
t
do
286
local
ti
=
t
[
i
]
287
local
ix
=
ti
[
1
]
288
local
iy
=
ti
[
2
]
289
local
dx
=
ix
-
tx
290
local
dy
=
iy
-
ty
291
if
dx
>
eps
or
dx
<
-
eps
or
dy
>
eps
or
dy
<
-
eps
then
292
n
=
n
+
1
293
t
[
n
]
=
ti
294
tx
=
ix
295
ty
=
iy
296
end
297
end
298
if
trace_shapes
then
299
report_shapes
(
"
removing similar points: %s
"
,
topairs
(
t
,
n
)
)
300
end
301
if
n
>
2
then
302
-- remove redundant points
303
repeat
304
tn
=
n
305
n
=
0
306
local
tm
=
t
[
tn
]
307
local
tmx
=
tm
[
1
]
308
local
tmy
=
tm
[
2
]
309
local
tp
=
t
[
1
]
310
local
tpx
=
tp
[
1
]
311
local
tpy
=
tp
[
2
]
312
for
i
=
1
,
tn
do
-- while and only step when done
313
local
ti
=
tp
314
local
tix
=
tpx
315
local
tiy
=
tpy
316
if
i
=
=
tn
then
317
tp
=
t
[
1
]
318
else
319
tp
=
t
[
i
+
1
]
320
end
321
tpx
=
tp
[
1
]
322
tpy
=
tp
[
2
]
323 324
local
vx1
,
vx2
=
unitvector
(
tix
-
tmx
,
tpx
-
tix
)
325
if
vx1
~
=
vx2
then
326
n
=
n
+
1
327
t
[
n
]
=
ti
328
else
329
local
vy1
,
vy2
=
unitvector
(
tiy
-
tmy
,
tpy
-
tiy
)
330
if
vy1
~
=
vy2
then
331
n
=
n
+
1
332
t
[
n
]
=
ti
333
end
334
end
335 336
tmx
=
tix
337
tmy
=
tiy
338
end
339
until
n
=
=
tn
or
n
<
=
2
340
if
trace_shapes
then
341
report_shapes
(
"
removing redundant points: %s
"
,
topairs
(
t
,
n
)
)
342
end
343
-- remove spikes
344
if
n
>
2
then
345
repeat
346
tn
=
n
347
n
=
0
348
local
tm
=
t
[
tn
]
349
local
tmx
=
tm
[
1
]
350
local
tmy
=
tm
[
2
]
351
local
tp
=
t
[
1
]
352
local
tpx
=
tp
[
1
]
353
local
tpy
=
tp
[
2
]
354
for
i
=
1
,
tn
do
-- while and only step when done
355
local
ti
=
tp
356
local
tix
=
tpx
357
local
tiy
=
tpy
358
if
i
=
=
tn
then
359
tp
=
t
[
1
]
360
else
361
tp
=
t
[
i
+
1
]
362
end
363
tpx
=
tp
[
1
]
364
tpy
=
tp
[
2
]
365 366
local
vx1
,
vx2
=
unitvector
(
tix
-
tmx
,
tpx
-
tix
)
367
if
vx1
~
=
-
vx2
then
368
n
=
n
+
1
369
t
[
n
]
=
ti
370
else
371
local
vy1
,
vy2
=
unitvector
(
tiy
-
tmy
,
tpy
-
tiy
)
372
if
vy1
~
=
-
vy2
then
373
n
=
n
+
1
374
t
[
n
]
=
ti
375
end
376
end
377 378
tmx
=
tix
379
tmy
=
tiy
380
end
381
until
n
=
=
tn
or
n
<
=
2
382
if
trace_shapes
then
383
report_shapes
(
"
removing spikes: %s
"
,
topairs
(
t
,
n
)
)
384
end
385
end
386
end
387
-- prune trailing points
388
if
tm
>
n
then
389
for
i
=
tm
,
n
+
1
,
-1
do
390
t
[
i
]
=
nil
391
end
392
end
393
if
n
>
1
then
394
local
tf
=
t
[
1
]
395
local
tl
=
t
[
n
]
396
local
dx
=
tf
[
1
]
-
tl
[
1
]
397
local
dy
=
tf
[
2
]
-
tl
[
2
]
398
if
dx
>
eps
or
dx
<
-
eps
or
dy
>
eps
or
dy
<
-
eps
then
399
-- different points
400
else
401
-- saves a point (as we -- cycle anyway)
402
t
[
n
]
=
nil
403
n
=
n
-1
404
end
405
if
trace_shapes
then
406
report_shapes
(
"
removing cyclic endpoints: %s
"
,
topairs
(
t
,
n
)
)
407
end
408
end
409
return
t
410
end
411 412
local
eps
=
65536
413 414
-- The next function can introduce redundant points but these are removed later on
415
-- in the unspiker. It makes checking easier.
416 417
local
function
shape
(
kind
,
b
,
p
,
realpage
,
xmin
,
xmax
,
ymin
,
ymax
,
fh
,
ld
)
418
local
s
=
b
.
s
419
if
not
s
then
420
if
trace_shapes
then
421
report_shapes
(
"
calculating %s area, no shape
"
,
kind
)
422
end
423
return
424
end
425
s
=
s
[
realpage
]
426
if
not
s
then
427
if
trace_shapes
then
428
report_shapes
(
"
calculating %s area, no shape for page %s
"
,
kind
,
realpage
)
429
end
430
return
431
end
432
local
ns
=
#
s
433
if
ns
=
=
0
then
434
if
trace_shapes
then
435
report_shapes
(
"
calculating %s area, empty shape for page %s
"
,
kind
,
realpage
)
436
end
437
return
438
end
439
--
440
if
trace_shapes
then
441
report_shapes
(
"
calculating %s area, using shape for page %s
"
,
kind
,
realpage
)
442
end
443
-- it's a bit inefficient to use the par values and later compensate for b and
444
-- e but this keeps the code (loop) cleaner
445
local
ph
=
p
and
p
.
h
or
0
446
local
pd
=
p
and
p
.
d
or
0
447
--
448
xmax
=
xmax
+
eps
449
xmin
=
xmin
-
eps
450
ymax
=
ymax
+
eps
451
ymin
=
ymin
-
eps
452
local
ls
=
{
}
-- left shape
453
local
rs
=
{
}
-- right shape
454
local
pl
=
nil
-- previous left x
455
local
pr
=
nil
-- previous right x
456
local
n
=
0
457
local
xl
=
nil
458
local
xr
=
nil
459
local
mh
=
ph
-- min
460
local
md
=
pd
-- min
461
for
i
=
1
,
ns
do
462
local
si
=
s
[
i
]
463
local
y
=
si
[
1
]
464
local
ll
=
si
[
4
]
-- can be sparse
465
if
ll
then
466
xl
=
ll
467
local
rr
=
si
[
5
]
-- can be sparse
468
if
rr
then
469
xr
=
rr
470
end
471
end
472
if
trace_ranges
then
473
report_shapes
(
"
original : [%02i] xl=%p xr=%p y=%p
"
,
i
,
xl
,
xr
,
y
)
474
end
475
if
xl
~
=
xr
then
-- could be catched in the finalizer
476
local
xm
=
xl
+
(
xr
-
xl
)
/
2
-- midpoint should be in region
477
if
xm
>
=
xmin
and
xm
<
=
xmax
and
y
>
=
ymin
and
y
<
=
ymax
then
478
local
ht
=
si
[
2
]
-- can be sparse
479
if
ht
then
480
ph
=
ht
481
local
dp
=
si
[
3
]
-- can be sparse
482
if
dp
then
483
pd
=
dp
484
end
485
end
486
local
h
=
y
+
(
ph
<
mh
and
mh
or
ph
)
487
local
d
=
y
-
(
pd
<
md
and
md
or
pd
)
488
if
pl
then
489
n
=
n
+
1
490
ls
[
n
]
=
{
pl
,
h
}
491
rs
[
n
]
=
{
pr
,
h
}
492
if
trace_ranges
then
493
report_shapes
(
"
paragraph : [%02i] xl=%p xr=%p y=%p
"
,
i
,
pl
,
pr
,
h
)
494
end
495
end
496
n
=
n
+
1
497
ls
[
n
]
=
{
xl
,
h
}
498
rs
[
n
]
=
{
xr
,
h
}
499
if
trace_ranges
then
500
report_shapes
(
"
height : [%02i] xl=%p xr=%p y=%p
"
,
i
,
xl
,
xr
,
h
)
501
end
502
n
=
n
+
1
503
ls
[
n
]
=
{
xl
,
d
}
504
rs
[
n
]
=
{
xr
,
d
}
505
if
trace_ranges
then
506
report_shapes
(
"
depth : [%02i] xl=%p xr=%p y=%p
"
,
i
,
xl
,
xr
,
d
)
507
end
508
end
509
pl
,
pr
=
xl
,
xr
510
else
511
if
trace_ranges
then
512
report_shapes
(
"
ignored : [%02i] xl=%p xr=%p y=%p
"
,
i
,
xl
,
xr
,
y
)
513
end
514
end
515
end
516
--
517
if
true
and
n
>
0
then
518
-- use height of b and depth of e, maybe check for weird border
519
-- cases here
520
if
fh
then
521
local
lsf
=
ls
[
1
]
522
local
rsf
=
rs
[
1
]
523
if
lsf
[
2
]
<
fh
then
524
lsf
[
2
]
=
fh
525
end
526
if
rsf
[
2
]
<
fh
then
527
rsf
[
2
]
=
fh
528
end
529
end
530
if
fd
then
531
local
lsl
=
ls
[
n
]
532
local
rsl
=
rs
[
n
]
533
if
lsl
[
2
]
>
fd
then
534
lsl
[
2
]
=
fd
535
end
536
if
rsl
[
2
]
>
fd
then
537
rsl
[
2
]
=
fd
538
end
539
end
540
end
541
--
542
for
i
=
n
,
1
,
-1
do
543
n
=
n
+
1
rs
[
n
]
=
ls
[
i
]
544
end
545
return
rs
546
end
547 548
local
function
singlepart
(
b
,
e
,
p
,
realpage
,
r
,
left
,
right
)
549
local
bx
=
b
.
x
550
local
by
=
b
.
y
551
local
ex
=
e
.
x
552
local
ey
=
e
.
y
553
local
rx
=
r
.
x
554
local
ry
=
r
.
y
555
local
bh
=
by
+
b
.
h
556
local
bd
=
by
-
b
.
d
557
local
eh
=
ey
+
e
.
h
558
local
ed
=
ey
-
e
.
d
559
local
rh
=
ry
+
r
.
h
560
local
rd
=
ry
-
r
.
d
561
local
rw
=
rx
+
r
.
w
562
if
left
then
563
rx
=
rx
+
left
564
rw
=
rw
-
right
565
end
566
if
ex
=
=
rx
then
567
-- We probably have a strut at the next line so we force a width
568
-- although of course it is better to move up. But as we have whitespace
569
-- (at least visually) injected then it's best to stress the issue.
570
ex
=
rw
571
end
572
local
area
573
if
by
=
=
ey
then
574
if
trace_shapes
then
575
report_shapes
(
"
calculating single area, partial line
"
)
576
end
577
area
=
{
578
{
bx
,
bh
}
,
579
{
ex
,
eh
}
,
580
{
ex
,
ed
}
,
581
{
bx
,
bd
}
,
582
}
583
elseif
b
.
k
=
=
2
then
584
area
=
{
585
{
rx
,
bh
}
,
586
{
rw
,
bh
}
,
587
{
rw
,
ed
}
,
588
{
rx
,
ed
}
,
589
}
590
else
591
area
=
shape
(
"
single
"
,
b
,
p
,
realpage
,
rx
,
rw
,
rd
,
rh
,
bh
,
ed
)
592
end
593
if
not
area
then
594
area
=
{
595
{
bx
,
bh
}
,
596
{
rw
,
bh
}
,
597
{
rw
,
eh
}
,
598
{
ex
,
eh
}
,
599
{
ex
,
ed
}
,
600
{
rx
,
ed
}
,
601
{
rx
,
bd
}
,
602
{
bx
,
bd
}
,
603
}
604
end
605
return
{
606
location
=
"
single
"
,
607
region
=
r
,
608
area
=
finish
(
area
)
,
609
}
610
end
611 612
local
function
firstpart
(
b
,
e
,
p
,
realpage
,
r
,
left
,
right
)
613
local
bx
=
b
.
x
614
local
by
=
b
.
y
615
local
rx
=
r
.
x
616
local
ry
=
r
.
y
617
local
bh
=
by
+
b
.
h
618
local
bd
=
by
-
b
.
d
619
local
rh
=
ry
+
r
.
h
620
local
rd
=
ry
-
r
.
d
621
local
rw
=
rx
+
r
.
w
622
if
left
then
623
rx
=
rx
+
left
624
rw
=
rw
-
right
625
end
626
local
area
=
shape
(
"
first
"
,
b
,
p
,
realpage
,
rx
,
rw
,
rd
,
rh
,
bh
,
false
)
627
if
not
area
then
628
if
b
.
k
=
=
2
then
629
area
=
{
630
{
rx
,
bh
}
,
631
{
rw
,
bh
}
,
632
{
rw
,
rd
}
,
633
{
rx
,
rd
}
,
634
}
635
else
636
area
=
{
637
{
bx
,
bh
}
,
638
{
rw
,
bh
}
,
639
{
rw
,
rd
}
,
-- { rw, eh },
640
{
rx
,
rd
}
,
-- { rx, ed },
641
{
rx
,
bd
}
,
642
{
bx
,
bd
}
,
643
}
644
end
645
end
646
return
{
647
location
=
"
first
"
,
648
region
=
r
,
649
area
=
finish
(
area
)
,
650
}
651
end
652 653
local
function
middlepart
(
b
,
e
,
p
,
realpage
,
r
,
left
,
right
)
654
local
rx
=
r
.
x
655
local
ry
=
r
.
y
656
local
rh
=
ry
+
r
.
h
657
local
rd
=
ry
-
r
.
d
658
local
rw
=
rx
+
r
.
w
659
if
left
then
660
rx
=
rx
+
left
661
rw
=
rw
-
right
662
end
663
local
area
=
shape
(
"
middle
"
,
b
,
p
,
realpage
,
rx
,
rw
,
rd
,
rh
,
false
,
false
)
664
if
not
area
then
665
area
=
{
666
{
rw
,
rh
}
,
667
{
rw
,
rd
}
,
668
{
rx
,
rd
}
,
669
{
rx
,
rh
}
,
670
}
671
end
672
return
{
673
location
=
"
middle
"
,
674
region
=
r
,
675
area
=
finish
(
area
)
,
676
}
677
end
678 679
local
function
lastpart
(
b
,
e
,
p
,
realpage
,
r
,
left
,
right
)
680
local
ex
=
e
.
x
681
local
ey
=
e
.
y
682
local
rx
=
r
.
x
683
local
ry
=
r
.
y
684
local
eh
=
ey
+
e
.
h
685
local
ed
=
ey
-
e
.
d
686
local
rh
=
ry
+
r
.
h
687
local
rd
=
ry
-
r
.
d
688
local
rw
=
rx
+
r
.
w
689
if
left
then
690
rx
=
rx
+
left
691
rw
=
rw
-
right
692
end
693
local
area
=
shape
(
"
last
"
,
b
,
p
,
realpage
,
rx
,
rw
,
rd
,
rh
,
false
,
ed
)
694
if
not
area
then
695
if
b
.
k
=
=
2
then
696
area
=
{
697
{
rw
,
rh
}
,
698
{
rw
,
ed
}
,
699
{
rx
,
ed
}
,
700
{
rx
,
rh
}
,
701
}
702
else
703
area
=
{
704
{
rw
,
rh
}
,
-- { rw, bh },
705
{
rw
,
eh
}
,
706
{
ex
,
eh
}
,
707
{
ex
,
ed
}
,
708
{
rx
,
ed
}
,
709
{
rx
,
rh
}
,
-- { rx, bd },
710
}
711
end
712
end
713
return
{
714
location
=
"
last
"
,
715
region
=
r
,
716
area
=
finish
(
area
)
,
717
}
718
end
719 720
local
function
calculatemultipar
(
tag
)
721
local
collected
=
jobpositions
.
collected
722
local
b
=
collected
[
f_b_tag
(
tag
)
]
723
local
e
=
collected
[
f_e_tag
(
tag
)
]
724
if
not
b
or
not
e
then
725
report_shapes
(
"
invalid tag %a
"
,
tag
)
726
return
{
}
727
end
728
local
br
=
b
.
r
729
local
er
=
e
.
r
730
if
not
br
or
not
er
then
731
report_shapes
(
"
invalid region for %a
"
,
tag
)
732
return
{
}
733
end
734
local
btag
,
bindex
=
lpegmatch
(
splitter
,
br
)
735
local
etag
,
eindex
=
lpegmatch
(
splitter
,
er
)
736
if
not
bindex
or
not
eindex
or
btag
~
=
etag
then
737
report_shapes
(
"
invalid indices for %a
"
,
tag
)
738
return
{
}
739
end
740
local
bindex
=
tonumber
(
bindex
)
741
local
eindex
=
tonumber
(
eindex
)
742
-- Here we compensate for columns (in tables): a table can have a set of column
743
-- entries and these are shared. We compensate left/right based on the columns
744
-- x and w but need to take the region into acount where the specification was
745
-- flushed and not the begin pos's region, because otherwise we get the wrong
746
-- compensation for asymetrical doublesided layouts.
747
local
left
=
0
748
local
right
=
0
749
local
bc
=
b
.
c
750
local
rc
=
bc
and
collected
[
bc
]
751
if
rc
then
752
local
tb
=
collected
[
rc
.
r
]
753
if
tb
then
754
left
=
-
(
tb
.
x
-
rc
.
x
)
755
right
=
(
tb
.
w
-
rc
.
w
-
left
)
756
end
757
end
758
-- Obeying intermediate changes of left/rightskip makes no sense as it will
759
-- look bad, so we only look at the begin situation.
760
local
bn
=
b
.
n
761
local
p
=
bn
and
collected
[
f_p_tag
(
bn
)
]
-- par
762
if
p
then
763
left
=
left
+
(
p
.
ls
or
0
)
764
right
=
right
+
(
p
.
rs
or
0
)
765
end
766
--
767
local
bp
=
b
.
p
-- page
768
if
trace_shapes
then
769
report_shapes
(
"
tag %a, left %p, right %p, par %s, page %s, column %s
"
,
770
tag
,
left
,
right
,
bn
or
"
-
"
,
bp
or
"
-
"
,
bc
or
"
-
"
)
771
end
772
--
773
if
bindex
=
=
eindex
then
774
return
{
775
list
=
{
[
bp
]
=
{
singlepart
(
b
,
e
,
p
,
bp
,
collected
[
br
]
,
left
,
right
)
}
}
,
776
bpos
=
b
,
777
epos
=
e
,
778
}
779
else
780
local
list
=
{
781
[
bp
]
=
{
firstpart
(
b
,
e
,
p
,
bp
,
collected
[
br
]
,
left
,
right
)
}
,
782
}
783
for
i
=
bindex
+
1
,
eindex
-1
do
784
br
=
f_tag_two
(
btag
,
i
)
785
local
r
=
collected
[
br
]
786
if
not
r
then
787
report_graphics
(
"
invalid middle for %a
"
,
br
)
788
else
789
local
rp
=
r
.
p
-- page
790
local
pp
=
list
[
rp
]
791
local
mp
=
middlepart
(
b
,
e
,
p
,
rp
,
r
,
left
,
right
)
792
if
pp
then
793
pp
[
#
pp
+
1
]
=
mp
794
else
795
list
[
rp
]
=
{
mp
}
796
end
797
end
798
end
799
local
ep
=
e
.
p
-- page
800
local
pp
=
list
[
ep
]
801
local
lp
=
lastpart
(
b
,
e
,
p
,
ep
,
collected
[
er
]
,
left
,
right
)
802
if
pp
then
803
pp
[
#
pp
+
1
]
=
lp
804
else
805
list
[
ep
]
=
{
lp
}
806
end
807
return
{
808
list
=
list
,
809
bpos
=
b
,
810
epos
=
e
,
811
}
812
end
813
end
814 815
local
pbg
=
{
}
-- will move to pending
816 817
local
multilocs
=
{
818
single
=
1
,
-- maybe 0
819
first
=
1
,
820
middle
=
2
,
821
last
=
3
,
822
}
823 824
-- if unknown context_abck : input mp-abck.mpiv ; fi ;
825 826
local
f_template_a
=
formatters
[
[[
827path multiregs[], multipars[], multibox ; 828string multikind[] ; 829numeric multilocs[], nofmultipars ; 830nofmultipars := %s ; 831multibox := unitsquare xyscaled (%p,%p) ; 832numeric par_strut_height, par_strut_depth, par_line_height ; 833par_strut_height := %p ; 834par_strut_depth := %p ; 835par_line_height := %p ; 836
]]
]
837 838
local
f_template_b
=
formatters
[
[[
839multilocs[%s] := %s ; 840multikind[%s] := "%s" ; 841multipars[%s] := (%--t--cycle) shifted - (%p,%p) ; 842
]]
]
843 844
-- unspiked(simplified(%--t--cycle)) shifted - (%p,%p) ;
845 846
local
f_template_c
=
formatters
[
[[
847setbounds currentpicture to multibox ; 848
]]
]
849 850
local
function
freemultipar
(
pagedata
,
frees
)
-- ,k
851
-- if k == 3 then
852
-- -- tables have local regions
853
-- return
854
-- end
855
if
not
frees
then
856
return
857
end
858
local
nfree
=
#
frees
859
if
nfree
=
=
0
then
860
return
861
end
862
for
i
=
1
,
#
pagedata
do
863
local
data
=
pagedata
[
i
]
864
local
area
=
data
.
area
865 866
if
area
then
867 868
local
region
=
data
.
region
869
local
y
=
0
-- region.y
870
-- local x = region.x
871
local
areas
=
{
}
872
data
.
areas
=
areas
873 874
local
f_1
=
{
}
875
local
n_1
=
0
876
local
f_2
=
{
}
877
local
n_2
=
0
878
for
i
=
1
,
#
frees
do
879
local
f
=
frees
[
i
]
880
local
k
=
f
.
k
881
if
k
=
=
1
then
-- pag
882
n_1
=
n_1
+
1
883
f_1
[
n_1
]
=
f
884
elseif
k
=
=
2
or
k
=
=
3
then
-- par
885
n_2
=
n_2
+
1
886
f_2
[
n_2
]
=
f
887
end
888
end
889 890
local
lineheight
=
tex
.
dimen
.
lineheight
891 892
-- page floats
893 894
local
function
check_one
(
free1
,
free2
)
895
local
temp
=
{
}
896
local
some
=
false
897
local
top
=
(
free2
and
(
y
+
free2
.
y
+
free2
.
h
+
(
free2
.
to
or
0
)
)
)
or
false
898
local
bot
=
(
free1
and
(
y
+
free1
.
y
-
free1
.
d
-
(
free1
.
bo
or
0
)
)
)
or
false
899
for
i
=
1
,
#
area
do
900
local
a
=
area
[
i
]
901
local
x
=
a
[
1
]
902
local
y
=
a
[
2
]
903
if
free2
and
y
<
=
top
then
904
y
=
top
905
end
906
if
free1
and
y
>
=
bot
then
907
y
=
bot
908
end
909
if
not
some
then
910
some
=
y
911
elseif
some
=
=
true
then
912
-- done
913
elseif
y
~
=
some
then
914
some
=
true
915
end
916
temp
[
i
]
=
{
x
,
y
}
917
end
918
if
some
=
=
true
then
919
areas
[
#
areas
+
1
]
=
temp
920
end
921
end
922 923
if
n_1
>
0
then
924
check_one
(
false
,
f_1
[
1
]
)
925
for
i
=
2
,
n_1
do
926
check_one
(
f_1
[
i
-1
]
,
f_1
[
i
]
)
927
end
928
check_one
(
f_1
[
n_1
]
,
false
)
929
end
930 931
-- par floats
932 933
if
#
areas
=
=
0
then
934
areas
[
1
]
=
area
935
end
936 937
-- we can collect the coordinates first
938 939
local
function
check_two
(
area
,
frees
)
940
local
ul
=
area
[
1
]
941
local
ur
=
area
[
2
]
942
local
lr
=
area
[
3
]
943
local
ll
=
area
[
4
]
944
local
ulx
=
ul
[
1
]
945
local
uly
=
ul
[
2
]
946
local
urx
=
ur
[
1
]
947
local
ury
=
ur
[
2
]
948
local
lrx
=
lr
[
1
]
949
local
lry
=
lr
[
2
]
950
local
llx
=
ll
[
1
]
951
local
lly
=
ll
[
2
]
952 953
local
temp
=
{
}
954
local
n
=
0
955
local
done
=
false
956 957
for
i
=
1
,
#
frees
do
958
local
free
=
frees
[
i
]
959
local
fx
=
free
.
x
960
local
fy
=
free
.
y
961
local
ymax
=
y
+
fy
+
free
.
h
+
(
free
.
to
or
0
)
962
local
ymin
=
y
+
fy
-
free
.
d
-
(
free
.
bo
or
0
)
963
local
xmin
=
fx
-
(
free
.
lo
or
0
)
964
local
xmax
=
fx
+
free
.
w
+
(
free
.
ro
or
0
)
965
if
free
.
k
=
=
3
then
966
if
uly
<
=
ymax
and
uly
>
=
ymin
and
lly
<
=
ymin
then
967
if
trace_free
then
968
report_free
(
"
case 1, top, right
"
)
-- ok
969
end
970
n
=
n
+
1
temp
[
n
]
=
{
xmin
,
ury
}
971
n
=
n
+
1
temp
[
n
]
=
{
xmin
,
ymin
}
972
n
=
n
+
1
temp
[
n
]
=
{
lrx
,
ymin
}
973
n
=
n
+
1
temp
[
n
]
=
{
lrx
,
lry
}
974
done
=
true
975
elseif
uly
>
=
ymax
and
lly
<
=
ymin
then
976
if
trace_free
then
977
report_free
(
"
case 2, outside, right
"
)
-- ok
978
end
979
if
uly
-
ymax
<
lineheight
then
980
n
=
n
+
1
temp
[
n
]
=
{
xmin
,
ury
}
981
else
982
n
=
n
+
1
temp
[
n
]
=
{
urx
,
ury
}
983
n
=
n
+
1
temp
[
n
]
=
{
urx
,
ymax
}
984
end
985
n
=
n
+
1
temp
[
n
]
=
{
xmin
,
ymax
}
986
n
=
n
+
1
temp
[
n
]
=
{
xmin
,
ymin
}
987
n
=
n
+
1
temp
[
n
]
=
{
lrx
,
ymin
}
988
n
=
n
+
1
temp
[
n
]
=
{
lrx
,
lry
}
989
done
=
true
990
elseif
lly
<
=
ymax
and
lly
>
=
ymin
and
uly
>
=
ymax
then
991
if
trace_free
then
992
report_free
(
"
case 3, bottom, right
"
)
993
end
994
if
uly
-
ymax
<
lineheight
then
995
n
=
n
+
1
temp
[
n
]
=
{
xmin
,
ury
}
996
else
997
n
=
n
+
1
temp
[
n
]
=
{
urx
,
ury
}
998
n
=
n
+
1
temp
[
n
]
=
{
urx
,
ymax
}
999
end
1000
n
=
n
+
1
temp
[
n
]
=
{
xmin
,
ymax
}
1001
n
=
n
+
1
temp
[
n
]
=
{
xmin
,
lry
}
1002
done
=
true
1003
elseif
uly
<
=
ymax
and
lly
>
=
ymin
then
1004
if
trace_free
then
1005
report_free
(
"
case 4, inside, right
"
)
1006
end
1007
n
=
n
+
1
temp
[
n
]
=
{
xmin
,
uly
}
1008
n
=
n
+
1
temp
[
n
]
=
{
xmin
,
lly
}
1009
done
=
true
1010
else
1011
-- case 0
1012
if
trace_free
then
1013
report_free
(
"
case 0, nothing
"
)
1014
end
1015
end
1016
end
1017
end
1018 1019
if
not
done
then
1020
if
trace_free
then
1021
report_free
(
"
no right shape
"
)
1022
end
1023
n
=
n
+
1
temp
[
n
]
=
{
urx
,
ury
}
1024
n
=
n
+
1
temp
[
n
]
=
{
lrx
,
lry
}
1025
n
=
n
+
1
temp
[
n
]
=
{
llx
,
lly
}
1026
else
1027
done
=
false
1028
end
1029 1030
for
i
=
#
frees
,
1
,
-1
do
1031
local
free
=
frees
[
i
]
1032
local
fx
=
free
.
x
1033
local
fy
=
free
.
y
1034
local
ymax
=
y
+
fy
+
free
.
h
+
(
free
.
to
or
0
)
1035
local
ymin
=
y
+
fy
-
free
.
d
-
(
free
.
bo
or
0
)
1036
local
xmin
=
fx
-
(
free
.
lo
or
0
)
1037
local
xmax
=
fx
+
free
.
w
+
(
free
.
ro
or
0
)
1038
if
free
.
k
=
=
2
then
1039
if
uly
<
=
ymax
and
uly
>
=
ymin
and
lly
<
=
ymin
then
1040
if
trace_free
then
1041
report_free
(
"
case 1, top, left
"
)
-- ok
1042
end
1043
n
=
n
+
1
temp
[
n
]
=
{
ulx
,
ymin
}
1044
n
=
n
+
1
temp
[
n
]
=
{
xmax
,
ymin
}
1045
n
=
n
+
1
temp
[
n
]
=
{
xmax
,
uly
}
1046
done
=
true
1047
elseif
uly
>
=
ymax
and
lly
<
=
ymin
then
1048
if
trace_free
then
1049
report_free
(
"
case 2, outside, left
"
)
-- ok
1050
end
1051
n
=
n
+
1
temp
[
n
]
=
{
llx
,
lly
}
1052
n
=
n
+
1
temp
[
n
]
=
{
llx
,
ymin
}
1053
n
=
n
+
1
temp
[
n
]
=
{
xmax
,
ymin
}
1054
n
=
n
+
1
temp
[
n
]
=
{
xmax
,
ymax
}
1055
if
uly
-
ymax
<
lineheight
then
1056
n
=
n
+
1
temp
[
n
]
=
{
xmax
,
uly
}
1057
else
1058
n
=
n
+
1
temp
[
n
]
=
{
llx
,
ymax
}
1059
n
=
n
+
1
temp
[
n
]
=
{
llx
,
uly
}
1060
end
1061
done
=
true
1062
elseif
lly
<
=
ymax
and
lly
>
=
ymin
and
uly
>
=
ymax
then
1063
if
trace_free
then
1064
report_free
(
"
case 3, bottom, left
"
)
1065
end
1066
n
=
n
+
1
temp
[
n
]
=
{
xmax
,
lly
}
1067
n
=
n
+
1
temp
[
n
]
=
{
xmax
,
ymax
}
1068
if
uly
-
ymax
<
lineheight
then
1069
n
=
n
+
1
temp
[
n
]
=
{
xmax
,
uly
}
1070
else
1071
n
=
n
+
1
temp
[
n
]
=
{
llx
,
ymax
}
1072
n
=
n
+
1
temp
[
n
]
=
{
llx
,
uly
}
1073
end
1074
done
=
true
1075
elseif
uly
<
=
ymax
and
lly
>
=
ymin
then
1076
if
trace_free
then
1077
report_free
(
"
case 4, inside, left
"
)
1078
end
1079
n
=
n
+
1
temp
[
n
]
=
{
xmax
,
lly
}
1080
n
=
n
+
1
temp
[
n
]
=
{
xmax
,
uly
}
1081
done
=
true
1082
else
1083
-- case 0
1084
end
1085
end
1086
end
1087 1088
if
not
done
then
1089
if
trace_free
then
1090
report_free
(
"
no left shape
"
)
1091
end
1092
n
=
n
+
1
temp
[
n
]
=
{
llx
,
lly
}
1093
end
1094
n
=
n
+
1
temp
[
n
]
=
{
ulx
,
uly
}
1095 1096
return
temp
1097
end
1098 1099
if
n_2
>
0
then
1100
for
i
=
1
,
#
areas
do
1101
local
area
=
areas
[
i
]
1102
if
#
area
=
=
4
then
-- and also check type, must be pargaraph
1103
areas
[
i
]
=
check_two
(
area
,
f_2
)
1104
else
1105
-- message that not yet supported
1106
end
1107
end
1108
end
1109 1110
for
i
=
1
,
#
areas
do
1111
finish
(
areas
[
i
]
)
-- again
1112
end
1113 1114
end
1115 1116
end
1117
end
1118 1119
local
function
fetchmultipar
(
n
,
anchor
,
page
)
1120
local
a
=
jobpositions
.
collected
[
anchor
]
1121
if
not
a
then
1122
report_graphics
(
"
missing anchor %a
"
,
anchor
)
1123
else
1124
local
data
=
pbg
[
n
]
1125
if
not
data
then
1126
data
=
calculatemultipar
(
n
)
1127
pbg
[
n
]
=
data
-- can be replaced by register
1128
-- register(data.list,n,anchor)
1129
end
1130
local
list
=
data
and
data
.
list
1131
if
list
then
1132
local
pagedata
=
list
[
page
]
1133
if
pagedata
then
1134
local
k
=
data
.
bpos
.
k
1135
if
k
~
=
3
then
1136
-- to be checked: no need in txt mode
1137
freemultipar
(
pagedata
,
getfree
(
page
)
)
1138
end
1139
local
nofmultipars
=
#
pagedata
1140
if
trace_shapes
then
1141
report_graphics
(
"
fetching %a at page %s using anchor %a containing %s multipars
"
,
1142
n
,
page
,
anchor
,
nofmultipars
)
1143
end
1144
local
x
=
a
.
x
1145
local
y
=
a
.
y
1146
local
w
=
a
.
w
1147
local
h
=
a
.
h
1148
local
d
=
a
.
d
1149
local
bpos
=
data
.
bpos
1150
local
bh
=
bpos
.
h
1151
local
bd
=
bpos
.
d
1152
local
result
=
{
false
}
-- slot 1 will be set later
1153
local
n
=
0
1154
for
i
=
1
,
nofmultipars
do
1155
local
data
=
pagedata
[
i
]
1156
local
location
=
data
.
location
1157
local
region
=
data
.
region
1158
local
areas
=
data
.
areas
1159
if
not
areas
then
1160
areas
=
{
data
.
area
}
1161
end
1162
for
i
=
1
,
#
areas
do
1163
local
area
=
areas
[
i
]
1164
for
i
=
1
,
#
area
do
1165
local
a
=
area
[
i
]
1166
area
[
i
]
=
f_pair
(
a
[
1
]
,
a
[
2
]
)
1167
end
1168
n
=
n
+
1
1169
result
[
n
+
1
]
=
f_template_b
(
n
,
multilocs
[
location
]
,
n
,
location
,
n
,
area
,
x
,
y
)
1170
end
1171
end
1172
data
[
page
]
=
nil
1173
result
[
1
]
=
f_template_a
(
n
,
w
,
h
+
d
,
bh
,
bd
,
bh
+
bd
)
-- was delayed
1174
result
[
n
+
2
]
=
f_template_c
(
)
1175
return
concat
(
result
,
"
\n
"
)
1176
end
1177
end
1178
end
1179
return
f_template_a
(
0
,
0
,
0
,
0
,
0
,
0
)
;
1180
end
1181 1182
backgrounds
.
fetchmultipar
=
fetchmultipar
1183 1184
backgrounds
.
point
=
f_point
1185
backgrounds
.
pair
=
f_pair
1186
backgrounds
.
path
=
f_path
1187 1188
-- n anchor page
1189 1190
implement
{
1191
name
=
"
fetchmultipar
"
,
1192
actions
=
{
fetchmultipar
,
context
}
,
1193
arguments
=
{
"
string
"
,
"
string
"
,
"
integer
"
}
1194
}
1195 1196
local
f_template_a
=
formatters
[
[[
1197path posboxes[], posregions[] ; 1198numeric pospages[] ; 1199numeric nofposboxes ; 1200nofposboxes := %s ; 1201%t ; 1202
]]
]
1203 1204
local
f_template_b
=
formatters
[
[[
1205pospages[%s] := %s ; 1206posboxes[%s] := (%p,%p)--(%p,%p)--(%p,%p)--(%p,%p)--cycle ; 1207posregions[%s] := (%p,%p)--(%p,%p)--(%p,%p)--(%p,%p)--cycle ; 1208
]]
]
1209 1210
implement
{
1211
name
=
"
fetchposboxes
"
,
1212
arguments
=
{
"
string
"
,
"
string
"
,
"
integer
"
}
,
1213
actions
=
function
(
tags
,
anchor
,
page
)
-- no caching (yet) / todo: anchor, page
1214
local
collected
=
jobpositions
.
collected
1215
if
type
(
tags
)
=
=
"
string
"
then
1216
tags
=
utilities
.
parsers
.
settings_to_array
(
tags
)
1217
end
1218
local
list
=
{
}
1219
local
nofboxes
=
0
1220
for
i
=
1
,
#
tags
do
1221
local
tag
=
tags
[
i
]
1222
local
c
=
collected
[
tag
]
1223
if
c
then
1224
local
r
=
c
.
r
1225
if
r
then
1226
r
=
collected
[
r
]
1227
if
r
then
1228
local
rx
=
r
.
x
1229
local
ry
=
r
.
y
1230
local
rw
=
r
.
w
1231
local
rh
=
r
.
h
1232
local
rd
=
r
.
d
1233
local
cx
=
c
.
x
-
rx
1234
local
cy
=
c
.
y
1235
local
cw
=
cx
+
c
.
w
1236
local
ch
=
cy
+
c
.
h
1237
local
cd
=
cy
-
c
.
d
1238
nofboxes
=
nofboxes
+
1
1239
list
[
nofboxes
]
=
f_template_b
(
1240
nofboxes
,
c
.
p
,
1241
nofboxes
,
cx
,
ch
,
cw
,
ch
,
cw
,
cd
,
cx
,
cd
,
1242
nofboxes
,
0
,
rh
,
rw
,
rh
,
rw
,
rd
,
0
,
rd
1243
)
1244
end
1245
end
1246
else
1247
-- print("\n missing",tag)
1248
end
1249
end
1250
context
(
f_template_a
(
nofboxes
,
list
)
)
1251
end
1252
}
1253 1254
local
doifelse
=
commands
.
doifelse
1255 1256
implement
{
1257
name
=
"
doifelserangeonpage
"
,
1258
arguments
=
{
"
string
"
,
"
string
"
,
"
integer
"
}
,
1259
actions
=
function
(
first
,
last
,
page
)
1260
local
c
=
jobpositions
.
collected
1261
local
f
=
c
[
first
]
1262
if
f
then
1263
f
=
f
.
p
1264
if
f
and
f
~
=
true
and
page
>
=
f
then
1265
local
l
=
c
[
last
]
1266
if
l
then
1267
l
=
l
.
p
1268
doifelse
(
l
and
l
~
=
true
and
page
<
=
l
)
1269
return
1270
end
1271
end
1272
end
1273
doifelse
(
false
)
1274
end
1275
}
1276