page-flt.lua /size: 11 Kb    last modification: 2020-07-01 14:35
1
if
not
modules
then
modules
=
{
}
end
modules
[
'
page-flt
'
]
=
{
2
version
=
1
.
001
,
3
comment
=
"
companion to page-flt.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
-- floats -> managers.floats
10
-- some functions are a tex/lua mix so we need a separation
11 12
local
next
=
next
13
local
tostring
=
tostring
14
local
insert
,
remove
=
table
.
insert
,
table
.
remove
15
local
find
=
string
.
find
16
local
abs
=
math
.
abs
17 18
local
trace_floats
=
false
trackers
.
register
(
"
floats.caching
"
,
function
(
v
)
trace_floats
=
v
end
)
19
local
trace_collecting
=
false
trackers
.
register
(
"
floats.collecting
"
,
function
(
v
)
trace_collecting
=
v
end
)
20 21
local
report_floats
=
logs
.
reporter
(
"
floats
"
,
"
caching
"
)
22
local
report_collecting
=
logs
.
reporter
(
"
floats
"
,
"
collecting
"
)
23 24
local
C
,
S
,
P
,
lpegmatch
=
lpeg
.
C
,
lpeg
.
S
,
lpeg
.
P
,
lpeg
.
match
25 26
-- we use floatbox, floatwidth, floatheight
27
-- text page leftpage rightpage (todo: top, bottom, margin, order)
28 29
local
setdimen
=
tex
.
setdimen
30
local
getdimen
=
tex
.
getdimen
31
local
setcount
=
tex
.
setcount
32
local
texsetbox
=
tex
.
setbox
33
local
textakebox
=
nodes
.
takebox
34 35
floats
=
floats
or
{
}
36
local
floats
=
floats
37 38
local
context
=
context
39
local
commands
=
commands
40
local
interfaces
=
interfaces
41
local
showmessage
=
interfaces
.
showmessage
42
local
implement
=
interfaces
.
implement
43
local
setmacro
=
interfaces
.
setmacro
44 45
local
noffloats
=
0
46
local
last
=
nil
47
local
default
=
"
text
"
48
local
pushed
=
{
}
49 50
local
function
initialize
(
)
51
return
{
52
text
=
{
}
,
53
page
=
{
}
,
54
leftpage
=
{
}
,
55
rightpage
=
{
}
,
56
somewhere
=
{
}
,
57
}
58
end
59 60
local
stacks
=
initialize
(
)
61 62
-- list location
63 64
function
floats
.
stacked
(
which
)
-- floats.thenofstacked
65
return
#
stacks
[
which
or
default
]
66
end
67 68
function
floats
.
push
(
)
69
insert
(
pushed
,
stacks
)
70
stacks
=
initialize
(
)
71
setcount
(
"
global
"
,
"
savednoffloats
"
,
0
)
72
end
73 74
function
floats
.
pop
(
)
75
local
popped
=
remove
(
pushed
)
76
if
popped
then
77
for
which
,
stack
in
next
,
stacks
do
78
for
i
=
1
,
#
stack
do
79
insert
(
popped
[
which
]
,
stack
[
i
]
)
80
end
81
end
82
stacks
=
popped
83
setcount
(
"
global
"
,
"
savednoffloats
"
,
#
stacks
[
default
]
)
84
end
85
end
86 87
local
function
setdimensions
(
t
,
b
)
88
local
bw
,
bh
,
bd
=
0
,
0
,
0
89
local
nw
,
nh
,
nd
=
0
,
0
,
0
90
local
cw
,
ch
,
cd
=
0
,
0
,
0
91
if
b
then
92
bw
=
b
.
width
93
bh
=
b
.
height
94
bd
=
b
.
depth
95
cw
=
b
.
cwidth
96
ch
=
b
.
cheight
97
cd
=
b
.
cdepth
98
end
99
if
t
then
100
nw
=
t
.
width
or
bw
101
nh
=
t
.
height
or
bh
102
nd
=
t
.
depth
or
bd
103
cw
=
t
.
cwidth
or
cw
104
ch
=
t
.
cheight
or
ch
105
cd
=
t
.
cdepth
or
cd
106
end
107
setdimen
(
"
global
"
,
"
floatwidth
"
,
bw
)
108
setdimen
(
"
global
"
,
"
floatheight
"
,
bh
+
bd
)
109
setdimen
(
"
global
"
,
"
naturalfloatwd
"
,
nw
)
110
setdimen
(
"
global
"
,
"
naturalfloatht
"
,
nh
)
111
setdimen
(
"
global
"
,
"
naturalfloatdp
"
,
nd
)
112
setdimen
(
"
global
"
,
"
floatcaptionwd
"
,
cw
)
113
setdimen
(
"
global
"
,
"
floatcaptionht
"
,
ch
)
114
setdimen
(
"
global
"
,
"
floatcaptiondp
"
,
cd
)
115
return
bw
,
bh
,
bd
,
nw
,
nh
,
dp
,
cw
,
xh
,
xp
116
end
117 118
local
function
get
(
stack
,
n
,
bylabel
)
119
if
bylabel
then
120
for
i
=
1
,
#
stack
do
121
local
s
=
stack
[
i
]
122
local
n
=
string
.
topattern
(
tostring
(
n
)
)
-- to be sure
123
if
find
(
s
.
data
.
label
,
n
)
then
124
return
s
,
s
.
box
,
i
125
end
126
end
127
else
128
n
=
n
or
#
stack
129
if
n
>
0
then
130
local
t
=
stack
[
n
]
131
if
t
then
132
return
t
,
t
.
box
,
n
133
end
134
end
135
end
136
end
137 138
function
floats
.
save
(
which
,
data
)
-- todo: just pass
139
which
=
which
or
default
140
local
b
=
textakebox
(
"
floatbox
"
)
141
if
b
then
142
local
stack
=
stacks
[
which
]
143
noffloats
=
noffloats
+
1
144
local
t
=
{
145
n
=
noffloats
,
146
data
=
data
or
{
}
,
147
width
=
getdimen
(
"
naturalfloatwd
"
)
,
148
height
=
getdimen
(
"
naturalfloatht
"
)
,
149
depth
=
getdimen
(
"
naturalfloatdp
"
)
,
150
cwidth
=
getdimen
(
"
floatcaptionwd
"
)
,
151
cheight
=
getdimen
(
"
floatcaptionht
"
)
,
152
cdepth
=
getdimen
(
"
floatcaptiondp
"
)
,
153
box
=
b
,
154
}
155
insert
(
stack
,
t
)
156
-- inspect(stacks)
157
setcount
(
"
global
"
,
"
savednoffloats
"
,
#
stacks
[
default
]
)
158
if
trace_floats
then
159
report_floats
(
"
%s, category %a, number %a, slot %a, width %p, height %p, depth %p
"
,
"
saving
"
,
160
which
,
noffloats
,
#
stack
,
b
.
width
,
b
.
height
,
b
.
depth
)
161
else
162
showmessage
(
"
floatblocks
"
,
2
,
noffloats
)
163
end
164
else
165
report_floats
(
"
ignoring empty, category %a, number %a
"
,
which
,
noffloats
)
166
end
167
end
168 169
function
floats
.
resave
(
which
)
170
if
last
then
171
which
=
which
or
default
172
local
stack
=
stacks
[
which
]
173
local
b
=
textakebox
(
"
floatbox
"
)
174
if
not
b
then
175
report_floats
(
"
resaved float is empty
"
)
176
end
177
last
.
box
=
b
178
insert
(
stack
,
1
,
last
)
179
setcount
(
"
global
"
,
"
savednoffloats
"
,
#
stacks
[
default
]
)
180
if
trace_floats
then
181
report_floats
(
"
%s, category %a, number %a, slot %a width %p, height %p, depth %p
"
,
"
resaving
"
,
182
which
,
noffloats
,
#
stack
,
b
.
width
,
b
.
height
,
b
.
depth
)
183
else
184
showmessage
(
"
floatblocks
"
,
2
,
noffloats
)
185
end
186
else
187
report_floats
(
"
unable to resave float
"
)
188
end
189
end
190 191
function
floats
.
flush
(
which
,
n
,
bylabel
)
192
which
=
which
or
default
193
local
stack
=
stacks
[
which
]
194
local
t
,
b
,
n
=
get
(
stack
,
n
or
1
,
bylabel
)
195
if
t
then
196
if
not
b
then
197
showmessage
(
"
floatblocks
"
,
1
,
t
.
n
)
198
end
199
local
w
,
h
,
d
=
setdimensions
(
t
,
b
)
200
if
trace_floats
then
201
report_floats
(
"
%s, category %a, number %a, slot %a width %p, height %p, depth %p
"
,
"
flushing
"
,
202
which
,
t
.
n
,
n
,
w
,
h
,
d
)
203
else
204
showmessage
(
"
floatblocks
"
,
3
,
t
.
n
)
205
end
206
texsetbox
(
"
floatbox
"
,
b
)
207
last
=
remove
(
stack
,
n
)
208
last
.
box
=
nil
209
setcount
(
"
global
"
,
"
savednoffloats
"
,
#
stacks
[
which
]
)
-- default?
210
else
211
setdimensions
(
)
212
end
213
end
214 215
function
floats
.
consult
(
which
,
n
)
216
which
=
which
or
default
217
local
stack
=
stacks
[
which
]
218
local
t
,
b
,
n
=
get
(
stack
,
n
)
219
if
t
then
220
local
w
,
h
,
d
=
setdimensions
(
t
,
b
)
221
if
trace_floats
then
222
report_floats
(
"
%s, category %a, number %a, slot %a width %p, height %p, depth %p
"
,
"
consulting
"
,
223
which
,
t
.
n
,
n
,
w
,
h
,
d
)
224
end
225
return
t
,
b
,
n
226
else
227
if
trace_floats
then
228
report_floats
(
"
nothing to consult
"
)
229
end
230
setdimensions
(
)
231
end
232
end
233 234
function
floats
.
collect
(
which
,
maxwidth
,
distance
)
235
local
usedwhich
=
which
or
default
236
local
stack
=
stacks
[
usedwhich
]
237
local
stacksize
=
#
stack
238
local
collected
=
0
239
local
maxheight
=
0
240
local
maxdepth
=
0
241 242
local
function
register
(
)
243
collected
=
collected
+
1
244
maxwidth
=
rest
245
if
h
>
maxheight
then
246
maxheight
=
h
247
end
248
if
d
>
maxdepth
then
249
maxdepth
=
d
250
end
251
end
252 253
for
i
=
1
,
stacksize
do
254
local
t
,
b
,
n
=
get
(
stack
,
i
)
255
if
t
then
256
local
w
,
h
,
d
,
nw
,
nh
,
nd
,
cw
,
ch
,
cd
=
setdimensions
(
t
,
b
)
257
-- we use the real width
258
if
cw
>
nw
then
259
w
=
cw
260
else
261
w
=
nw
262
end
263
-- which could be an option
264
local
rest
=
maxwidth
-
w
-
distance
265
local
fits
=
rest
>
-10
266
if
trace_collecting
then
267
report_collecting
(
"
%s, category %a, number %a, slot %a width %p, rest %p, fit %a
"
,
"
collecting
"
,
268
usedwhich
,
t
.
n
,
n
,
w
,
rest
,
fits
)
269
end
270
if
fits
then
271
collected
=
collected
+
1
272
maxwidth
=
rest
273
if
h
>
maxheight
then
274
maxheight
=
h
275
end
276
if
d
>
maxdepth
then
277
maxdepth
=
d
278
end
279
else
280
break
281
end
282
else
283
break
284
end
285
end
286
setcount
(
"
global
"
,
"
nofcollectedfloats
"
,
collected
)
287
setdimen
(
"
global
"
,
"
maxcollectedfloatstotal
"
,
maxheight
+
maxdepth
)
288
end
289 290
function
floats
.
getvariable
(
name
,
default
)
291
local
value
=
last
and
last
.
data
[
name
]
or
default
292
return
value
~
=
"
"
and
value
293
end
294 295
function
floats
.
checkedpagefloat
(
packed
)
296
if
structures
.
pages
.
is_odd
(
)
then
297
if
#
stacks
.
rightpage
>
0
then
298
return
"
rightpage
"
299
elseif
#
stacks
.
page
>
0
then
300
return
"
page
"
301
elseif
#
stacks
.
leftpage
>
0
then
302
if
packed
then
303
return
"
leftpage
"
304
end
305
end
306
else
307
if
#
stacks
.
leftpage
>
0
then
308
return
"
leftpage
"
309
elseif
#
stacks
.
page
>
0
then
310
return
"
page
"
311
elseif
#
stacks
.
rightpage
>
0
then
312
if
packed
then
313
return
"
rightpage
"
314
end
315
end
316
end
317
end
318 319
function
floats
.
nofstacked
(
which
)
320
return
#
stacks
[
which
or
default
]
or
0
321
end
322 323
function
floats
.
hasstacked
(
which
)
324
return
(
#
stacks
[
which
or
default
]
or
0
)
>
0
325
end
326 327
-- todo: check for digits !
328 329
local
method
=
C
(
(
1
-
S
(
"
, :
"
)
)
^
1
)
330
local
position
=
P
(
"
:
"
)
*
C
(
(
1
-
S
(
"
*,
"
)
)
^
1
)
*
(
P
(
"
*
"
)
*
C
(
(
1
-
S
(
"
,
"
)
)
^
1
)
)
^
0
331
local
label
=
P
(
"
:
"
)
*
C
(
(
1
-
S
(
"
,*:
"
)
)
^
0
)
332 333
local
pattern
=
method
*
(
334
label
*
position
*
C
(
"
"
)
335
+
C
(
"
"
)
*
position
*
C
(
"
"
)
336
+
label
*
C
(
"
"
)
*
C
(
"
"
)
337
+
C
(
"
"
)
*
C
(
"
"
)
*
C
(
"
"
)
338
)
+
C
(
"
"
)
*
C
(
"
"
)
*
C
(
"
"
)
*
C
(
"
"
)
339 340
-- inspect { lpegmatch(pattern,"somewhere:blabla,crap") }
341
-- inspect { lpegmatch(pattern,"somewhere:1*2") }
342
-- inspect { lpegmatch(pattern,"somewhere:blabla:1*2") }
343
-- inspect { lpegmatch(pattern,"somewhere::1*2") }
344
-- inspect { lpegmatch(pattern,"somewhere,") }
345
-- inspect { lpegmatch(pattern,"somewhere") }
346
-- inspect { lpegmatch(pattern,"") }
347 348
function
floats
.
analysemethod
(
str
)
-- will become a more extensive parser
349
return
lpegmatch
(
pattern
,
str
or
"
"
)
350
end
351 352
-- interface
353 354
implement
{
355
name
=
"
flushfloat
"
,
356
actions
=
floats
.
flush
,
357
arguments
=
{
"
string
"
,
"
integer
"
}
,
358
}
359 360
implement
{
361
name
=
"
flushlabeledfloat
"
,
362
actions
=
floats
.
flush
,
363
arguments
=
{
"
string
"
,
"
string
"
,
true
}
,
364
}
365 366
implement
{
367
name
=
"
savefloat
"
,
368
actions
=
floats
.
save
,
369
arguments
=
"
string
"
370
}
371 372
implement
{
373
name
=
"
savespecificfloat
"
,
374
actions
=
floats
.
save
,
375
arguments
=
{
376
"
string
"
,
377
{
378
{
"
specification
"
}
,
379
{
"
label
"
}
,
380
}
381
}
382
}
383 384
implement
{
385
name
=
"
resavefloat
"
,
386
actions
=
floats
.
resave
,
387
arguments
=
"
string
"
388
}
389 390
implement
{
391
name
=
"
pushfloat
"
,
392
actions
=
floats
.
push
393
}
394 395
implement
{
396
name
=
"
popfloat
"
,
397
actions
=
floats
.
pop
398
}
399 400
implement
{
401
name
=
"
consultfloat
"
,
402
actions
=
floats
.
consult
,
403
arguments
=
"
string
"
,
404
}
405 406
implement
{
407
name
=
"
collectfloat
"
,
408
actions
=
floats
.
collect
,
409
arguments
=
{
"
string
"
,
"
dimen
"
,
"
dimen
"
}
410
}
411 412
implement
{
413
name
=
"
getfloatvariable
"
,
414
actions
=
{
floats
.
getvariable
,
context
}
,
415
arguments
=
"
string
"
416
}
417 418
implement
{
419
name
=
"
checkedpagefloat
"
,
420
actions
=
{
floats
.
checkedpagefloat
,
context
}
,
421
arguments
=
"
string
"
422
}
423 424
implement
{
425
name
=
"
nofstackedfloats
"
,
426
actions
=
{
floats
.
nofstacked
,
context
}
,
427
arguments
=
"
string
"
428
}
429 430
implement
{
431
name
=
"
doifelsestackedfloats
"
,
432
actions
=
{
floats
.
hasstacked
,
commands
.
doifelse
}
,
433
arguments
=
"
string
"
434
}
435 436
implement
{
437
name
=
"
analysefloatmethod
"
,
438
actions
=
function
(
str
)
439
local
method
,
label
,
column
,
row
=
floats
.
analysemethod
(
str
)
440
setmacro
(
"
floatmethod
"
,
method
or
"
"
)
441
setmacro
(
"
floatlabel
"
,
label
or
"
"
)
442
setmacro
(
"
floatrow
"
,
row
or
"
"
)
443
setmacro
(
"
floatcolumn
"
,
column
or
"
"
)
444
end
,
445
arguments
=
"
string
"
446
}
447