tabl-xtb.lua /size: 41 Kb    last modification: 2020-07-01 14:35
1
if
not
modules
then
modules
=
{
}
end
modules
[
'
tabl-xtb
'
]
=
{
2
version
=
1
.
001
,
3
comment
=
"
companion to tabl-xtb.mkvi
"
,
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
--[[ 10 11This table mechanism is a combination between TeX and Lua. We do process 12cells at the TeX end and inspect them at the Lua end. After some analysis 13we have a second pass using the calculated widths, and if needed cells 14will go through a third pass to get the heights right. This last pass is 15avoided when possible which is why some code below looks a bit more 16complex than needed. The reason for such optimizations is that each cells 17is actually a framed instance and because tables like this can be hundreds 18of pages we want to keep processing time reasonable. 19 20To a large extend the behaviour is comparable with the way bTABLE/eTABLE 21works and there is a module that maps that one onto this one. Eventually 22this mechamism will be improved so that it can replace its older cousin. 23 24]]
--
25 26
-- todo: use linked list instead of r/c array
27
-- todo: we can use the sum of previously forced widths for column spans
28 29
local
tonumber
,
next
=
tonumber
,
next
30 31
local
commands
=
commands
32
local
context
=
context
33
local
ctxnode
=
context
.
nodes
.
flush
34 35
local
implement
=
interfaces
.
implement
36 37
local
tex
=
tex
38
local
texgetcount
=
tex
.
getcount
39
local
texsetcount
=
tex
.
setcount
40
local
texgetdimen
=
tex
.
getdimen
41
local
texsetdimen
=
tex
.
setdimen
42
local
texget
=
tex
.
get
43 44
local
format
=
string
.
format
45
local
concat
=
table
.
concat
46
local
points
=
number
.
points
47 48
local
todimen
=
string
.
todimen
49 50
local
ctx_beginvbox
=
context
.
beginvbox
51
local
ctx_endvbox
=
context
.
endvbox
52
local
ctx_blank
=
context
.
blank
53
local
ctx_nointerlineskip
=
context
.
nointerlineskip
54
local
ctx_dummyxcell
=
context
.
dummyxcell
55 56
local
variables
=
interfaces
.
variables
57 58
local
setmetatableindex
=
table
.
setmetatableindex
59
local
settings_to_hash
=
utilities
.
parsers
.
settings_to_hash
60 61
local
nuts
=
nodes
.
nuts
-- here nuts gain hardly nothing
62
local
tonut
=
nuts
.
tonut
63
local
tonode
=
nuts
.
tonode
64 65
local
getnext
=
nuts
.
getnext
66
local
getprev
=
nuts
.
getprev
67
local
getlist
=
nuts
.
getlist
68
local
getwidth
=
nuts
.
getwidth
69
local
getbox
=
nuts
.
getbox
70
local
getwhd
=
nuts
.
getwhd
71 72
local
setlink
=
nuts
.
setlink
73
local
setdirection
=
nuts
.
setdirection
74
local
setshift
=
nuts
.
setshift
75 76
local
copy_node_list
=
nuts
.
copy_list
77
local
hpack_node_list
=
nuts
.
hpack
78
local
flush_node_list
=
nuts
.
flush_list
79
local
takebox
=
nuts
.
takebox
80 81
local
nodepool
=
nuts
.
pool
82 83
local
new_glue
=
nodepool
.
glue
84
local
new_kern
=
nodepool
.
kern
85
local
new_hlist
=
nodepool
.
hlist
86 87
local
lefttoright_code
=
nodes
.
dirvalues
.
lefttoright
88 89
local
v_stretch
=
variables
.
stretch
90
local
v_normal
=
variables
.
normal
91
local
v_width
=
variables
.
width
92
local
v_height
=
variables
.
height
93
local
v_repeat
=
variables
[
"
repeat
"
]
94
local
v_max
=
variables
.
max
95
local
v_fixed
=
variables
.
fixed
96
----- v_auto = variables.auto
97
local
v_before
=
variables
.
before
98
local
v_after
=
variables
.
after
99
local
v_both
=
variables
.
both
100
local
v_samepage
=
variables
.
samepage
101
local
v_tight
=
variables
.
tight
102 103
local
xtables
=
{
}
104
typesetters
.
xtables
=
xtables
105 106
local
trace_xtable
=
false
107
local
report_xtable
=
logs
.
reporter
(
"
xtable
"
)
108 109
trackers
.
register
(
"
xtable.construct
"
,
function
(
v
)
trace_xtable
=
v
end
)
110 111
local
null_mode
=
0
112
local
head_mode
=
1
113
local
foot_mode
=
2
114
local
more_mode
=
3
115
local
body_mode
=
4
116 117
local
namedmodes
=
{
[
0
]
=
118
"
null
"
,
119
"
head
"
,
120
"
foot
"
,
121
"
next
"
,
122
"
body
"
,
123
}
124 125
local
stack
,
data
=
{
}
,
nil
126 127
function
xtables
.
create
(
settings
)
128
table
.
insert
(
stack
,
data
)
129
local
rows
=
{
}
130
local
widths
=
{
}
131
local
heights
=
{
}
132
local
depths
=
{
}
133
-- local spans = { }
134
local
distances
=
{
}
135
local
autowidths
=
{
}
136
local
modes
=
{
}
137
local
fixedrows
=
{
}
138
local
fixedcolumns
=
{
}
139
-- local fixedcspans = { }
140
local
frozencolumns
=
{
}
141
local
options
=
{
}
142
local
rowproperties
=
{
}
143
data
=
{
144
rows
=
rows
,
145
widths
=
widths
,
146
heights
=
heights
,
147
depths
=
depths
,
148
-- spans = spans,
149
distances
=
distances
,
150
modes
=
modes
,
151
autowidths
=
autowidths
,
152
fixedrows
=
fixedrows
,
153
fixedcolumns
=
fixedcolumns
,
154
-- fixedcspans = fixedcspans,
155
frozencolumns
=
frozencolumns
,
156
options
=
options
,
157
nofrows
=
0
,
158
nofcolumns
=
0
,
159
currentrow
=
0
,
160
currentcolumn
=
0
,
161
settings
=
settings
or
{
}
,
162
rowproperties
=
rowproperties
,
163
}
164
local
function
add_zero
(
t
,
k
)
165
t
[
k
]
=
0
166
return
0
167
end
168
local
function
add_table
(
t
,
k
)
169
local
v
=
{
}
170
t
[
k
]
=
v
171
return
v
172
end
173
local
function
add_cell
(
row
,
c
)
174
local
cell
=
{
175
nx
=
0
,
176
ny
=
0
,
177
list
=
false
,
178
wd
=
0
,
179
ht
=
0
,
180
dp
=
0
,
181
}
182
row
[
c
]
=
cell
183
if
c
>
data
.
nofcolumns
then
184
data
.
nofcolumns
=
c
185
end
186
return
cell
187
end
188
local
function
add_row
(
rows
,
r
)
189
local
row
=
{
}
190
setmetatableindex
(
row
,
add_cell
)
191
rows
[
r
]
=
row
192
if
r
>
data
.
nofrows
then
193
data
.
nofrows
=
r
194
end
195
return
row
196
end
197
setmetatableindex
(
rows
,
add_row
)
198
setmetatableindex
(
widths
,
add_zero
)
199
setmetatableindex
(
heights
,
add_zero
)
200
setmetatableindex
(
depths
,
add_zero
)
201
setmetatableindex
(
distances
,
add_zero
)
202
setmetatableindex
(
modes
,
add_zero
)
203
setmetatableindex
(
fixedrows
,
add_zero
)
204
setmetatableindex
(
fixedcolumns
,
add_zero
)
205
setmetatableindex
(
options
,
add_table
)
206
-- setmetatableindex(fixedcspans,add_table)
207
--
208
local
globaloptions
=
settings_to_hash
(
settings
.
option
)
209
--
210
settings
.
columndistance
=
tonumber
(
settings
.
columndistance
)
or
0
211
settings
.
rowdistance
=
tonumber
(
settings
.
rowdistance
)
or
0
212
settings
.
leftmargindistance
=
tonumber
(
settings
.
leftmargindistance
)
or
0
213
settings
.
rightmargindistance
=
tonumber
(
settings
.
rightmargindistance
)
or
0
214
settings
.
options
=
globaloptions
215
settings
.
textwidth
=
tonumber
(
settings
.
textwidth
)
or
texget
(
"
hsize
"
)
216
settings
.
lineheight
=
tonumber
(
settings
.
lineheight
)
or
texgetdimen
(
"
lineheight
"
)
217
settings
.
maxwidth
=
tonumber
(
settings
.
maxwidth
)
or
settings
.
textwidth
/
8
218
-- if #stack > 0 then
219
-- settings.textwidth = texget("hsize")
220
-- end
221
data
.
criterium_v
=
2
*
data
.
settings
.
lineheight
222
data
.
criterium_h
=
.
75
*
data
.
settings
.
textwidth
223
--
224
data
.
tight
=
globaloptions
[
v_tight
]
and
true
or
false
225
end
226 227
function
xtables
.
initialize_reflow_width
(
option
,
width
)
228
local
r
=
data
.
currentrow
229
local
c
=
data
.
currentcolumn
+
1
230
local
drc
=
data
.
rows
[
r
]
[
c
]
231
drc
.
nx
=
texgetcount
(
"
c_tabl_x_nx
"
)
232
drc
.
ny
=
texgetcount
(
"
c_tabl_x_ny
"
)
233
local
distances
=
data
.
distances
234
local
distance
=
texgetdimen
(
"
d_tabl_x_distance
"
)
235
if
distance
>
distances
[
c
]
then
236
distances
[
c
]
=
distance
237
end
238
if
option
and
option
~
=
"
"
then
239
local
options
=
settings_to_hash
(
option
)
240
data
.
options
[
r
]
[
c
]
=
options
241
if
options
[
v_fixed
]
then
242
data
.
frozencolumns
[
c
]
=
true
243
end
244
end
245
data
.
currentcolumn
=
c
246
end
247 248
-- todo: we can better set the cell values in one go
249 250
function
xtables
.
set_reflow_width
(
)
251
local
r
=
data
.
currentrow
252
local
c
=
data
.
currentcolumn
253
local
rows
=
data
.
rows
254
local
row
=
rows
[
r
]
255
local
cold
=
c
256
while
row
[
c
]
.
span
do
-- can also be previous row ones
257
c
=
c
+
1
258
end
259
-- bah, we can have a span already
260
if
c
>
cold
then
261
local
ro
=
row
[
cold
]
262
local
rx
=
ro
.
nx
263
local
ry
=
ro
.
ny
264
if
rx
>
1
or
ry
>
1
then
265
local
rn
=
row
[
c
]
266
rn
.
nx
=
rx
267
rn
.
ny
=
ry
268
ro
.
nx
=
1
-- or 0
269
ro
.
ny
=
1
-- or 0
270
-- do we also need to set ro.span and rn.span
271
end
272
end
273
local
tb
=
getbox
(
"
b_tabl_x
"
)
274
local
drc
=
row
[
c
]
275
--
276
drc
.
list
=
true
-- we don't need to keep the content around as we're in trial mode (no: copy_node_list(tb))
277
--
278
local
width
,
height
,
depth
=
getwhd
(
tb
)
279
--
280
local
widths
=
data
.
widths
281
local
heights
=
data
.
heights
282
local
depths
=
data
.
depths
283
local
cspan
=
drc
.
nx
284
if
cspan
<
2
then
285
if
width
>
widths
[
c
]
then
286
widths
[
c
]
=
width
287
end
288
else
289
local
options
=
data
.
options
[
r
]
[
c
]
290
if
data
.
tight
then
291
-- no check
292
elseif
not
options
then
293
if
width
>
widths
[
c
]
then
294
widths
[
c
]
=
width
295
end
296
elseif
not
options
[
v_tight
]
then
297
if
width
>
widths
[
c
]
then
298
widths
[
c
]
=
width
299
end
300
end
301
end
302
-- if cspan > 1 then
303
-- local f = data.fixedcspans[c]
304
-- local w = f[cspan] or 0
305
-- if width > w then
306
-- f[cspan] = width -- maybe some day a solution for autospanmax and so
307
-- end
308
-- end
309
if
drc
.
ny
<
2
then
310
-- report_xtable("set width, old: ht=%p, dp=%p",heights[r],depths[r])
311
-- report_xtable("set width, new: ht=%p, dp=%p",height,depth)
312
if
height
>
heights
[
r
]
then
313
heights
[
r
]
=
height
314
end
315
if
depth
>
depths
[
r
]
then
316
depths
[
r
]
=
depth
317
end
318
end
319
--
320
drc
.
wd
=
width
321
drc
.
ht
=
height
322
drc
.
dp
=
depth
323
--
324
local
dimensionstate
=
texgetcount
(
"
frameddimensionstate
"
)
325
local
fixedcolumns
=
data
.
fixedcolumns
326
local
fixedrows
=
data
.
fixedrows
327
if
dimensionstate
=
=
1
then
328
if
cspan
>
1
then
329
-- ignore width
330
elseif
width
>
fixedcolumns
[
c
]
then
-- how about a span here?
331
fixedcolumns
[
c
]
=
width
332
end
333
elseif
dimensionstate
=
=
2
then
334
fixedrows
[
r
]
=
height
335
elseif
dimensionstate
=
=
3
then
336
fixedrows
[
r
]
=
height
-- width
337
fixedcolumns
[
c
]
=
width
-- height
338
elseif
width
<
=
data
.
criterium_h
and
height
>
=
data
.
criterium_v
then
339
-- somewhat tricky branch
340
if
width
>
fixedcolumns
[
c
]
then
-- how about a span here?
341
-- maybe an image, so let's fix
342
fixedcolumns
[
c
]
=
width
343
end
344
end
345
--
346
-- -- this fails so not good enough predictor
347
--
348
-- -- \startxtable
349
-- -- \startxrow
350
-- -- \startxcell knuth \stopxcell
351
-- -- \startxcell \input knuth \stopxcell
352
-- -- \stopxrow
353
--
354
-- else
355
-- local o = data.options[r][c]
356
-- if o and o[v_auto] then -- new per 5/5/2014 - removed per 15/07/2014
357
-- data.autowidths[c] = true
358
-- else
359
-- -- no dimensions are set in the cell
360
-- if width <= data.criterium_h and height >= data.criterium_v then
361
-- -- somewhat tricky branch
362
-- if width > fixedcolumns[c] then -- how about a span here?
363
-- -- maybe an image, so let's fix
364
-- fixedcolumns[c] = width
365
-- end
366
-- else
367
-- -- safeguard as it could be text that can be recalculated
368
-- -- and the previous branch could have happened in a previous
369
-- -- row and then forces a wrong one-liner in a multiliner
370
-- if width > fixedcolumns[c] then
371
-- data.autowidths[c] = true -- new per 5/5/2014 - removed per 15/07/2014
372
-- end
373
-- end
374
-- end
375
-- end
376
--
377
--
378
drc
.
dimensionstate
=
dimensionstate
379
--
380
local
nx
=
drc
.
nx
381
local
ny
=
drc
.
ny
382
if
nx
>
1
or
ny
>
1
then
383
-- local spans = data.spans -- not used
384
local
self
=
true
385
for
y
=
1
,
ny
do
386
for
x
=
1
,
nx
do
387
if
self
then
388
self
=
false
389
else
390
local
ry
=
r
+
y
-
1
391
local
cx
=
c
+
x
-
1
392
-- if y > 1 then
393
-- spans[ry] = true -- not used
394
-- end
395
rows
[
ry
]
[
cx
]
.
span
=
true
396
end
397
end
398
end
399
c
=
c
+
nx
-
1
400
end
401
if
c
>
data
.
nofcolumns
then
402
data
.
nofcolumns
=
c
403
end
404
data
.
currentcolumn
=
c
405
end
406 407
function
xtables
.
initialize_reflow_height
(
)
408
local
r
=
data
.
currentrow
409
local
c
=
data
.
currentcolumn
+
1
410
local
rows
=
data
.
rows
411
local
row
=
rows
[
r
]
412
while
row
[
c
]
.
span
do
-- can also be previous row ones
413
c
=
c
+
1
414
end
415
data
.
currentcolumn
=
c
416
local
widths
=
data
.
widths
417
local
w
=
widths
[
c
]
418
local
drc
=
row
[
c
]
419
for
x
=
1
,
drc
.
nx
-1
do
420
w
=
w
+
widths
[
c
+
x
]
421
end
422
texsetdimen
(
"
d_tabl_x_width
"
,
w
)
423
local
dimensionstate
=
drc
.
dimensionstate
or
0
424
if
dimensionstate
=
=
1
or
dimensionstate
=
=
3
then
425
-- width was fixed so height is known
426
texsetcount
(
"
c_tabl_x_skip_mode
"
,
1
)
427
elseif
dimensionstate
=
=
2
then
428
-- height is enforced
429
texsetcount
(
"
c_tabl_x_skip_mode
"
,
1
)
430
elseif
data
.
autowidths
[
c
]
then
431
-- width has changed so we need to recalculate the height
432
texsetcount
(
"
c_tabl_x_skip_mode
"
,
0
)
433
elseif
data
.
fixedcolumns
[
c
]
then
434
texsetcount
(
"
c_tabl_x_skip_mode
"
,
0
)
-- new
435
else
436
texsetcount
(
"
c_tabl_x_skip_mode
"
,
1
)
437
end
438
end
439 440
function
xtables
.
set_reflow_height
(
)
441
local
r
=
data
.
currentrow
442
local
c
=
data
.
currentcolumn
443
local
rows
=
data
.
rows
444
local
row
=
rows
[
r
]
445
-- while row[c].span do -- we could adapt drc.nx instead
446
-- c = c + 1
447
-- end
448
local
tb
=
getbox
(
"
b_tabl_x
"
)
449
local
drc
=
row
[
c
]
450
--
451
local
width
,
height
,
depth
=
getwhd
(
tb
)
452
--
453
if
drc
.
ny
<
2
then
454
if
data
.
fixedrows
[
r
]
=
=
0
then
-- and drc.dimensionstate < 2
455
if
drc
.
ht
+
drc
.
dp
<
=
height
+
depth
then
-- new per 2017-12-15
456
local
heights
=
data
.
heights
457
local
depths
=
data
.
depths
458
-- report_xtable("set height, old: ht=%p, dp=%p",heights[r],depths[r])
459
-- report_xtable("set height, new: ht=%p, dp=%p",height,depth)
460
if
height
>
heights
[
r
]
then
461
heights
[
r
]
=
height
462
end
463
if
depth
>
depths
[
r
]
then
464
depths
[
r
]
=
depth
465
end
466
end
467
end
468
end
469
--
470
drc
.
wd
=
width
471
drc
.
ht
=
height
472
drc
.
dp
=
depth
473
--
474
-- c = c + drc.nx - 1
475
-- data.currentcolumn = c
476
end
477 478
function
xtables
.
initialize_construct
(
)
479
local
r
=
data
.
currentrow
480
local
c
=
data
.
currentcolumn
+
1
481
local
settings
=
data
.
settings
482
local
rows
=
data
.
rows
483
local
row
=
rows
[
r
]
484
while
row
[
c
]
.
span
do
-- can also be previous row ones
485
c
=
c
+
1
486
end
487
data
.
currentcolumn
=
c
488
local
widths
=
data
.
widths
489
local
heights
=
data
.
heights
490
local
depths
=
data
.
depths
491
local
distances
=
data
.
distances
492
--
493
local
drc
=
row
[
c
]
494
local
wd
=
drc
.
wd
495
local
ht
=
drc
.
ht
496
local
dp
=
drc
.
dp
497
local
nx
=
drc
.
nx
-
1
498
local
ny
=
drc
.
ny
-
1
499
--
500
local
width
=
widths
[
c
]
501
local
height
=
heights
[
r
]
502
local
depth
=
depths
[
r
]
-- problem: can be the depth of a one liner
503
--
504
local
total
=
height
+
depth
505
--
506
if
nx
>
0
then
507
for
x
=
1
,
nx
do
508
width
=
width
+
widths
[
c
+
x
]
+
distances
[
c
+
x
-1
]
509
end
510
local
distance
=
settings
.
columndistance
511
if
distance
~
=
0
then
512
width
=
width
+
nx
*
distance
513
end
514
end
515
--
516
if
ny
>
0
then
517
for
y
=
1
,
ny
do
518
local
nxt
=
r
+
y
519
total
=
total
+
heights
[
nxt
]
+
depths
[
nxt
]
520
end
521
local
distance
=
settings
.
rowdistance
522
if
distance
~
=
0
then
523
total
=
total
+
ny
*
distance
524
end
525
end
526
--
527
texsetdimen
(
"
d_tabl_x_width
"
,
width
)
528
texsetdimen
(
"
d_tabl_x_height
"
,
total
)
529
texsetdimen
(
"
d_tabl_x_depth
"
,
0
)
-- for now
530
end
531 532
function
xtables
.
set_construct
(
)
533
local
r
=
data
.
currentrow
534
local
c
=
data
.
currentcolumn
535
local
rows
=
data
.
rows
536
local
row
=
rows
[
r
]
537
-- while row[c].span do -- can also be previous row ones
538
-- c = c + 1
539
-- end
540
local
drc
=
row
[
c
]
541
-- this will change as soon as in luatex we can reset a box list without freeing
542
drc
.
list
=
takebox
(
"
b_tabl_x
"
)
543
-- c = c + drc.nx - 1
544
-- data.currentcolumn = c
545
end
546 547
local
function
showwidths
(
where
,
widths
,
autowidths
)
548
local
result
=
{
}
549
for
i
=
1
,
#
widths
do
550
result
[
#
result
+
1
]
=
format
(
"
%12s%s
"
,
points
(
widths
[
i
]
)
,
autowidths
[
i
]
and
"
*
"
or
"
"
)
551
end
552
return
report_xtable
(
"
%s widths: %s
"
,
where
,
concat
(
result
,
"
"
)
)
553
end
554 555
function
xtables
.
reflow_width
(
)
556
local
nofrows
=
data
.
nofrows
557
local
nofcolumns
=
data
.
nofcolumns
558
local
rows
=
data
.
rows
559
for
r
=
1
,
nofrows
do
560
local
row
=
rows
[
r
]
561
for
c
=
1
,
nofcolumns
do
562
local
drc
=
row
[
c
]
563
if
drc
.
list
then
564
-- flush_node_list(drc.list)
565
drc
.
list
=
false
566
end
567
end
568
end
569
-- spread
570
local
settings
=
data
.
settings
571
local
options
=
settings
.
options
572
local
maxwidth
=
settings
.
maxwidth
573
-- calculate width
574
local
widths
=
data
.
widths
575
local
heights
=
data
.
heights
576
local
depths
=
data
.
depths
577
local
distances
=
data
.
distances
578
local
autowidths
=
data
.
autowidths
579
local
fixedcolumns
=
data
.
fixedcolumns
580
local
frozencolumns
=
data
.
frozencolumns
581
local
width
=
0
582
local
distance
=
0
583
local
nofwide
=
0
584
local
widetotal
=
0
585
local
available
=
settings
.
textwidth
-
settings
.
leftmargindistance
-
settings
.
rightmargindistance
586
if
trace_xtable
then
587
showwidths
(
"
stage 1
"
,
widths
,
autowidths
)
588
end
589
local
noffrozen
=
0
590
-- here we can also check spans
591
if
options
[
v_max
]
then
592
for
c
=
1
,
nofcolumns
do
593
width
=
width
+
widths
[
c
]
594
if
width
>
maxwidth
then
595
autowidths
[
c
]
=
true
596
nofwide
=
nofwide
+
1
597
widetotal
=
widetotal
+
widths
[
c
]
598
end
599
if
c
<
nofcolumns
then
600
distance
=
distance
+
distances
[
c
]
601
end
602
if
frozencolumns
[
c
]
then
603
noffrozen
=
noffrozen
+
1
-- brr, should be nx or so
604
end
605
end
606
else
607
for
c
=
1
,
nofcolumns
do
-- also keep track of forced
608
local
fixedwidth
=
fixedcolumns
[
c
]
609
if
fixedwidth
>
0
then
610
widths
[
c
]
=
fixedwidth
611
width
=
width
+
fixedwidth
612
else
613
local
wc
=
widths
[
c
]
614
width
=
width
+
wc
615
-- if width > maxwidth then
616
if
wc
>
maxwidth
then
-- per 2015-08-09
617
autowidths
[
c
]
=
true
618
nofwide
=
nofwide
+
1
619
widetotal
=
widetotal
+
wc
620
end
621
end
622
if
c
<
nofcolumns
then
623
distance
=
distance
+
distances
[
c
]
624
end
625
if
frozencolumns
[
c
]
then
626
noffrozen
=
noffrozen
+
1
-- brr, should be nx or so
627
end
628
end
629
end
630
if
trace_xtable
then
631
showwidths
(
"
stage 2
"
,
widths
,
autowidths
)
632
end
633
local
delta
=
available
-
width
-
distance
-
(
nofcolumns
-1
)
*
settings
.
columndistance
634
if
delta
=
=
0
then
635
-- nothing to be done
636
if
trace_xtable
then
637
report_xtable
(
"
perfect fit
"
)
638
end
639
elseif
delta
>
0
then
640
-- we can distribute some
641
if
not
options
[
v_stretch
]
then
642
-- not needed
643
if
trace_xtable
then
644
report_xtable
(
"
too wide but no stretch, delta %p
"
,
delta
)
645
end
646
elseif
options
[
v_width
]
then
647
local
factor
=
delta
/
width
648
if
trace_xtable
then
649
report_xtable
(
"
proportional stretch, delta %p, width %p, factor %a
"
,
delta
,
width
,
factor
)
650
end
651
for
c
=
1
,
nofcolumns
do
652
widths
[
c
]
=
widths
[
c
]
+
factor
*
widths
[
c
]
653
end
654
else
655
-- frozen -> a column with option=fixed will not stretch
656
local
extra
=
delta
/
(
nofcolumns
-
noffrozen
)
657
if
trace_xtable
then
658
report_xtable
(
"
normal stretch, delta %p, extra %p
"
,
delta
,
extra
)
659
end
660
for
c
=
1
,
nofcolumns
do
661
if
not
frozencolumns
[
c
]
then
662
widths
[
c
]
=
widths
[
c
]
+
extra
663
end
664
end
665
end
666
elseif
nofwide
>
0
then
667
while
true
do
668
done
=
false
669
local
available
=
(
widetotal
+
delta
)
/
nofwide
670
if
trace_xtable
then
671
report_xtable
(
"
shrink check, total %p, delta %p, columns %s, fixed %p
"
,
widetotal
,
delta
,
nofwide
,
available
)
672
end
673
for
c
=
1
,
nofcolumns
do
674
if
autowidths
[
c
]
and
available
>
=
widths
[
c
]
then
675
autowidths
[
c
]
=
nil
676
nofwide
=
nofwide
-
1
677
widetotal
=
widetotal
-
widths
[
c
]
678
done
=
true
679
end
680
end
681
if
not
done
then
682
break
683
end
684
end
685
-- maybe also options[v_width] here but tricky as width does not say
686
-- much about amount
687
if
options
[
v_width
]
then
-- not that much (we could have a clever vpack loop balancing .. no fun)
688
local
factor
=
(
widetotal
+
delta
)
/
width
689
if
trace_xtable
then
690
report_xtable
(
"
proportional shrink used, total %p, delta %p, columns %s, factor %s
"
,
widetotal
,
delta
,
nofwide
,
factor
)
691
end
692
for
c
=
1
,
nofcolumns
do
693
if
autowidths
[
c
]
then
694
widths
[
c
]
=
factor
*
widths
[
c
]
695
end
696
end
697
else
698
local
available
=
(
widetotal
+
delta
)
/
nofwide
699
if
trace_xtable
then
700
report_xtable
(
"
normal shrink used, total %p, delta %p, columns %s, fixed %p
"
,
widetotal
,
delta
,
nofwide
,
available
)
701
end
702
for
c
=
1
,
nofcolumns
do
703
if
autowidths
[
c
]
then
704
widths
[
c
]
=
available
705
end
706
end
707
end
708
end
709
if
trace_xtable
then
710
showwidths
(
"
stage 3
"
,
widths
,
autowidths
)
711
end
712
--
713
data
.
currentrow
=
0
714
data
.
currentcolumn
=
0
715
end
716 717
function
xtables
.
reflow_height
(
)
718
data
.
currentrow
=
0
719
data
.
currentcolumn
=
0
720
local
settings
=
data
.
settings
721
--
722
-- analyze ny
723
--
724
local
nofrows
=
data
.
nofrows
725
local
nofcolumns
=
data
.
nofcolumns
726
local
widths
=
data
.
widths
727
local
heights
=
data
.
heights
728
local
depths
=
data
.
depths
729
--
730
for
r
=
1
,
nofrows
do
731
for
c
=
1
,
nofcolumns
do
732
local
drc
=
data
.
rows
[
r
]
[
c
]
733
if
drc
then
734
local
ny
=
drc
.
ny
735
if
ny
>
1
then
736
local
height
=
heights
[
r
]
737
local
depth
=
depths
[
r
]
738
local
total
=
height
+
depth
739
local
htdp
=
drc
.
ht
+
drc
.
dp
740
for
y
=
1
,
ny
-1
do
741
local
nxt
=
r
+
y
742
total
=
total
+
heights
[
nxt
]
+
depths
[
nxt
]
743
end
744
local
delta
=
htdp
-
total
745
if
delta
>
0
then
746
delta
=
delta
/
ny
747
for
y
=
0
,
ny
-1
do
748
local
nxt
=
r
+
y
749
heights
[
nxt
]
=
heights
[
nxt
]
+
delta
750
end
751
end
752
end
753
end
754
end
755
end
756
--
757
if
settings
.
options
[
v_height
]
then
758
local
totalheight
=
0
759
local
totaldepth
=
0
760
for
i
=
1
,
nofrows
do
761
totalheight
=
totalheight
+
heights
[
i
]
762
totalheight
=
totalheight
+
depths
[
i
]
763
end
764
local
total
=
totalheight
+
totaldepth
765
local
leftover
=
settings
.
textheight
-
total
766
if
leftover
>
0
then
767
local
leftheight
=
(
totalheight
/
total
)
*
leftover
/
#
heights
768
local
leftdepth
=
(
totaldepth
/
total
)
*
leftover
/
#
depths
769
for
i
=
1
,
nofrows
do
770
heights
[
i
]
=
heights
[
i
]
+
leftheight
771
depths
[
i
]
=
depths
[
i
]
+
leftdepth
772
end
773
end
774
end
775
end
776 777
local
function
showspans
(
data
)
778
local
rows
=
data
.
rows
779
local
modes
=
data
.
modes
780
local
nofcolumns
=
data
.
nofcolumns
781
local
nofrows
=
data
.
nofrows
782
for
r
=
1
,
nofrows
do
783
local
line
=
{
}
784
local
row
=
rows
[
r
]
785
for
c
=
1
,
nofcolumns
do
786
local
cell
=
row
[
c
]
787
if
cell
.
list
then
788
line
[
#
line
+
1
]
=
"
list
"
789
elseif
cell
.
span
then
790
line
[
#
line
+
1
]
=
"
span
"
791
else
792
line
[
#
line
+
1
]
=
"
none
"
793
end
794
end
795
report_xtable
(
"
%3d : %s : % t
"
,
r
,
namedmodes
[
modes
[
r
]
]
or
"
----
"
,
line
)
796
end
797
end
798 799
function
xtables
.
construct
(
)
800
local
rows
=
data
.
rows
801
local
heights
=
data
.
heights
802
local
depths
=
data
.
depths
803
local
widths
=
data
.
widths
804
-- local spans = data.spans
805
local
distances
=
data
.
distances
806
local
modes
=
data
.
modes
807
local
settings
=
data
.
settings
808
local
nofcolumns
=
data
.
nofcolumns
809
local
nofrows
=
data
.
nofrows
810
local
columndistance
=
settings
.
columndistance
811
local
rowdistance
=
settings
.
rowdistance
812
local
leftmargindistance
=
settings
.
leftmargindistance
813
local
rightmargindistance
=
settings
.
rightmargindistance
814
local
rowproperties
=
data
.
rowproperties
815
-- ranges can be mixes so we collect
816 817
if
trace_xtable
then
818
showspans
(
data
)
819
end
820 821
local
ranges
=
{
822
[
head_mode
]
=
{
}
,
823
[
foot_mode
]
=
{
}
,
824
[
more_mode
]
=
{
}
,
825
[
body_mode
]
=
{
}
,
826
}
827
for
r
=
1
,
nofrows
do
828
local
m
=
modes
[
r
]
829
if
m
=
=
0
then
830
m
=
body_mode
831
end
832
local
range
=
ranges
[
m
]
833
range
[
#
range
+
1
]
=
r
834
end
835
-- todo: hook in the splitter ... the splitter can ask for a chunk of
836
-- a certain size ... no longer a split memory issue then and header
837
-- footer then has to happen here too .. target height
838
local
function
packaged_column
(
r
)
839
local
row
=
rows
[
r
]
840
local
start
=
nil
841
local
stop
=
nil
842
if
leftmargindistance
>
0
then
843
start
=
new_kern
(
leftmargindistance
)
844
stop
=
start
845
end
846
local
hasspan
=
false
847
for
c
=
1
,
nofcolumns
do
848
local
drc
=
row
[
c
]
849
if
not
hasspan
then
850
hasspan
=
drc
.
span
851
end
852
local
list
=
drc
.
list
853
if
list
then
854
local
w
,
h
,
d
=
getwhd
(
list
)
855
setshift
(
list
,
h
+
d
)
856
-- list = hpack_node_list(list) -- is somehow needed
857
-- setwhd(list,0,0,0)
858
-- faster:
859
local
h
=
new_hlist
(
list
)
860
list
=
h
861
--
862
if
start
then
863
setlink
(
stop
,
list
)
864
else
865
start
=
list
866
end
867
stop
=
list
868
end
869
local
step
=
widths
[
c
]
870
if
c
<
nofcolumns
then
871
step
=
step
+
columndistance
+
distances
[
c
]
872
end
873
local
kern
=
new_kern
(
step
)
874
if
stop
then
875
setlink
(
stop
,
kern
)
876
else
-- can be first spanning next row (ny=...)
877
start
=
kern
878
end
879
stop
=
kern
880
end
881
if
start
then
882
if
rightmargindistance
>
0
then
883
local
kern
=
new_kern
(
rightmargindistance
)
884
setlink
(
stop
,
kern
)
885
-- stop = kern
886
end
887
return
start
,
heights
[
r
]
+
depths
[
r
]
,
hasspan
888
end
889
end
890
local
function
collect_range
(
range
)
891
local
result
,
nofr
=
{
}
,
0
892
local
nofrange
=
#
range
893
for
i
=
1
,
#
range
do
894
local
r
=
range
[
i
]
895
-- local row = rows[r]
896
local
list
,
size
,
hasspan
=
packaged_column
(
r
)
897
if
list
then
898
if
hasspan
and
nofr
>
0
then
899
result
[
nofr
]
[
4
]
=
true
900
end
901
nofr
=
nofr
+
1
902
local
rp
=
rowproperties
[
r
]
903
-- we have a direction issue here but hpack_node_list(list,0,"exactly","TLT") cannot be used
904
-- due to the fact that we need the width
905
local
hbox
=
hpack_node_list
(
list
)
906
setdirection
(
hbox
,
lefttoright_code
)
907
result
[
nofr
]
=
{
908
hbox
,
909
size
,
910
i
<
nofrange
and
rowdistance
>
0
and
rowdistance
or
false
,
-- might move
911
false
,
912
rp
or
false
,
913
}
914
end
915
end
916
if
nofr
>
0
then
917
-- the [5] slot gets the after break
918
result
[
1
]
[
5
]
=
false
919
result
[
nofr
]
[
5
]
=
false
920
for
i
=
2
,
nofr
-1
do
921
local
r
=
result
[
i
]
[
5
]
922
if
r
=
=
v_both
or
r
=
=
v_before
then
923
result
[
i
-1
]
[
5
]
=
true
924
elseif
r
=
=
v_after
then
925
result
[
i
]
[
5
]
=
true
926
end
927
end
928
end
929
return
result
930
end
931
local
body
=
collect_range
(
ranges
[
body_mode
]
)
932
data
.
results
=
{
933
[
head_mode
]
=
collect_range
(
ranges
[
head_mode
]
)
,
934
[
foot_mode
]
=
collect_range
(
ranges
[
foot_mode
]
)
,
935
[
more_mode
]
=
collect_range
(
ranges
[
more_mode
]
)
,
936
[
body_mode
]
=
body
,
937
}
938
if
#
body
=
=
0
then
939
texsetcount
(
"
global
"
,
"
c_tabl_x_state
"
,
0
)
940
texsetdimen
(
"
global
"
,
"
d_tabl_x_final_width
"
,
0
)
941
else
942
texsetcount
(
"
global
"
,
"
c_tabl_x_state
"
,
1
)
943
texsetdimen
(
"
global
"
,
"
d_tabl_x_final_width
"
,
getwidth
(
body
[
1
]
[
1
]
)
)
944
end
945
end
946 947
-- todo: join as that is as efficient as fushing multiple
948 949
local
function
inject
(
row
,
copy
,
package
)
950
local
list
=
row
[
1
]
951
if
copy
then
952
row
[
1
]
=
copy_node_list
(
list
)
953
end
954
if
package
then
955
ctx_beginvbox
(
)
956
ctxnode
(
tonode
(
list
)
)
957
ctxnode
(
tonode
(
new_kern
(
row
[
2
]
)
)
)
958
ctx_endvbox
(
)
959
ctx_nointerlineskip
(
)
-- figure out a better way
960
if
row
[
4
]
then
961
-- nothing as we have a span
962
elseif
row
[
5
]
then
963
if
row
[
3
]
then
964
ctx_blank
{
v_samepage
,
row
[
3
]
.
.
"
sp
"
}
965
else
966
ctx_blank
{
v_samepage
}
967
end
968
elseif
row
[
3
]
then
969
ctx_blank
{
row
[
3
]
.
.
"
sp
"
}
-- why blank ?
970
else
971
ctxnode
(
tonode
(
new_glue
(
0
)
)
)
972
end
973
else
974
ctxnode
(
tonode
(
list
)
)
975
ctxnode
(
tonode
(
new_kern
(
row
[
2
]
)
)
)
976
if
row
[
3
]
then
977
ctxnode
(
tonode
(
new_glue
(
row
[
3
]
)
)
)
978
end
979
end
980
end
981 982
local
function
total
(
row
,
distance
)
983
local
n
=
#
row
>
0
and
rowdistance
or
0
984
for
i
=
1
,
#
row
do
985
local
ri
=
row
[
i
]
986
n
=
n
+
ri
[
2
]
+
(
ri
[
3
]
or
0
)
987
end
988
return
n
989
end
990 991
-- local function append(list,what)
992
-- for i=1,#what do
993
-- local l = what[i]
994
-- list[#list+1] = l[1]
995
-- local k = l[2] + (l[3] or 0)
996
-- if k ~= 0 then
997
-- list[#list+1] = new_kern(k)
998
-- end
999
-- end
1000
-- end
1001 1002
local
function
spanheight
(
body
,
i
)
1003
local
height
,
n
=
0
,
1
1004
while
true
do
1005
local
bi
=
body
[
i
]
1006
if
bi
then
1007
height
=
height
+
bi
[
2
]
+
(
bi
[
3
]
or
0
)
1008
if
bi
[
4
]
then
1009
n
=
n
+
1
1010
i
=
i
+
1
1011
else
1012
break
1013
end
1014
else
1015
break
1016
end
1017
end
1018
return
height
,
n
1019
end
1020 1021
function
xtables
.
flush
(
directives
)
-- todo split by size / no inbetween then .. glue list kern blank
1022
local
height
=
directives
.
height
1023
local
method
=
directives
.
method
or
v_normal
1024
local
settings
=
data
.
settings
1025
local
results
=
data
.
results
1026
local
rowdistance
=
settings
.
rowdistance
1027
local
head
=
results
[
head_mode
]
1028
local
foot
=
results
[
foot_mode
]
1029
local
more
=
results
[
more_mode
]
1030
local
body
=
results
[
body_mode
]
1031
local
repeatheader
=
settings
.
header
=
=
v_repeat
1032
local
repeatfooter
=
settings
.
footer
=
=
v_repeat
1033
if
height
and
height
>
0
then
1034
ctx_beginvbox
(
)
1035
local
bodystart
=
data
.
bodystart
or
1
1036
local
bodystop
=
data
.
bodystop
or
#
body
1037
if
bodystart
>
0
and
bodystart
<
=
bodystop
then
1038
local
bodysize
=
height
1039
local
footsize
=
total
(
foot
,
rowdistance
)
1040
local
headsize
=
total
(
head
,
rowdistance
)
1041
local
moresize
=
total
(
more
,
rowdistance
)
1042
local
firstsize
,
firstspans
=
spanheight
(
body
,
bodystart
)
1043
if
bodystart
=
=
1
then
-- first chunk gets head
1044
bodysize
=
bodysize
-
headsize
-
footsize
1045
if
headsize
>
0
and
bodysize
>
=
firstsize
then
1046
for
i
=
1
,
#
head
do
1047
inject
(
head
[
i
]
,
repeatheader
)
1048
end
1049
if
rowdistance
>
0
then
1050
ctxnode
(
tonode
(
new_glue
(
rowdistance
)
)
)
1051
end
1052
if
not
repeatheader
then
1053
results
[
head_mode
]
=
{
}
1054
end
1055
end
1056
elseif
moresize
>
0
then
-- following chunk gets next
1057
bodysize
=
bodysize
-
footsize
-
moresize
1058
if
bodysize
>
=
firstsize
then
1059
for
i
=
1
,
#
more
do
1060
inject
(
more
[
i
]
,
true
)
1061
end
1062
if
rowdistance
>
0
then
1063
ctxnode
(
tonode
(
new_glue
(
rowdistance
)
)
)
1064
end
1065
end
1066
elseif
headsize
>
0
and
repeatheader
then
-- following chunk gets head
1067
bodysize
=
bodysize
-
footsize
-
headsize
1068
if
bodysize
>
=
firstsize
then
1069
for
i
=
1
,
#
head
do
1070
inject
(
head
[
i
]
,
true
)
1071
end
1072
if
rowdistance
>
0
then
1073
ctxnode
(
tonode
(
new_glue
(
rowdistance
)
)
)
1074
end
1075
end
1076
else
-- following chunk gets nothing
1077
bodysize
=
bodysize
-
footsize
1078
end
1079
if
bodysize
>
=
firstsize
then
1080
local
i
=
bodystart
1081
while
i
<
=
bodystop
do
-- room for improvement
1082
local
total
,
spans
=
spanheight
(
body
,
i
)
1083
local
bs
=
bodysize
-
total
1084
if
bs
>
0
then
1085
bodysize
=
bs
1086
for
s
=
1
,
spans
do
1087
inject
(
body
[
i
]
)
1088
body
[
i
]
=
nil
1089
i
=
i
+
1
1090
end
1091
bodystart
=
i
1092
else
1093
break
1094
end
1095
end
1096
if
bodystart
>
bodystop
then
1097
-- all is flushed and footer fits
1098
if
footsize
>
0
then
1099
if
rowdistance
>
0
then
1100
ctxnode
(
tonode
(
new_glue
(
rowdistance
)
)
)
1101
end
1102
for
i
=
1
,
#
foot
do
1103
inject
(
foot
[
i
]
)
1104
end
1105
results
[
foot_mode
]
=
{
}
1106
end
1107
results
[
body_mode
]
=
{
}
1108
texsetcount
(
"
global
"
,
"
c_tabl_x_state
"
,
0
)
1109
else
1110
-- some is left so footer is delayed
1111
-- todo: try to flush a few more lines
1112
if
repeatfooter
and
footsize
>
0
then
1113
if
rowdistance
>
0
then
1114
ctxnode
(
tonode
(
new_glue
(
rowdistance
)
)
)
1115
end
1116
for
i
=
1
,
#
foot
do
1117
inject
(
foot
[
i
]
,
true
)
1118
end
1119
else
1120
-- todo: try to fit more of body
1121
end
1122
texsetcount
(
"
global
"
,
"
c_tabl_x_state
"
,
2
)
1123
end
1124
else
1125
if
firstsize
>
height
then
1126
-- get rid of the too large cell
1127
for
s
=
1
,
firstspans
do
1128
inject
(
body
[
bodystart
]
)
1129
body
[
bodystart
]
=
nil
1130
bodystart
=
bodystart
+
1
1131
end
1132
end
1133
texsetcount
(
"
global
"
,
"
c_tabl_x_state
"
,
2
)
-- 1
1134
end
1135
else
1136
texsetcount
(
"
global
"
,
"
c_tabl_x_state
"
,
0
)
1137
end
1138
data
.
bodystart
=
bodystart
1139
data
.
bodystop
=
bodystop
1140
ctx_endvbox
(
)
1141
else
1142
if
method
=
=
variables
.
split
then
1143
-- maybe also a non float mode with header/footer repeat although
1144
-- we can also use a float without caption
1145
for
i
=
1
,
#
head
do
1146
inject
(
head
[
i
]
,
false
,
true
)
1147
end
1148
if
#
head
>
0
and
rowdistance
>
0
then
1149
ctx_blank
{
rowdistance
.
.
"
sp
"
}
1150
end
1151
for
i
=
1
,
#
body
do
1152
inject
(
body
[
i
]
,
false
,
true
)
1153
end
1154
if
#
foot
>
0
and
rowdistance
>
0
then
1155
ctx_blank
{
rowdistance
.
.
"
sp
"
}
1156
end
1157
for
i
=
1
,
#
foot
do
1158
inject
(
foot
[
i
]
,
false
,
true
)
1159
end
1160
else
-- normal
1161
ctx_beginvbox
(
)
1162
for
i
=
1
,
#
head
do
1163
inject
(
head
[
i
]
)
1164
end
1165
if
#
head
>
0
and
rowdistance
>
0
then
1166
ctxnode
(
tonode
(
new_glue
(
rowdistance
)
)
)
1167
end
1168
for
i
=
1
,
#
body
do
1169
inject
(
body
[
i
]
)
1170
end
1171
if
#
foot
>
0
and
rowdistance
>
0
then
1172
ctxnode
(
tonode
(
new_glue
(
rowdistance
)
)
)
1173
end
1174
for
i
=
1
,
#
foot
do
1175
inject
(
foot
[
i
]
)
1176
end
1177
ctx_endvbox
(
)
1178
end
1179
results
[
head_mode
]
=
{
}
1180
results
[
body_mode
]
=
{
}
1181
results
[
foot_mode
]
=
{
}
1182
texsetcount
(
"
global
"
,
"
c_tabl_x_state
"
,
0
)
1183
end
1184
end
1185 1186
function
xtables
.
cleanup
(
)
1187
for
mode
,
result
in
next
,
data
.
results
do
1188
for
_
,
r
in
next
,
result
do
1189
flush_node_list
(
r
[
1
]
)
1190
end
1191
end
1192 1193
-- local rows = data.rows
1194
-- for i=1,#rows do
1195
-- local row = rows[i]
1196
-- for i=1,#row do
1197
-- local cell = row[i]
1198
-- local list = cell.list
1199
-- if list then
1200
-- cell.width, cell.height, cell.depth = getwhd(list)
1201
-- cell.list = true
1202
-- end
1203
-- end
1204
-- end
1205
-- data.result = nil
1206 1207
data
=
table
.
remove
(
stack
)
1208
end
1209 1210
function
xtables
.
next_row
(
specification
)
1211
local
r
=
data
.
currentrow
+
1
1212
data
.
modes
[
r
]
=
texgetcount
(
"
c_tabl_x_mode
"
)
1213
data
.
currentrow
=
r
1214
data
.
currentcolumn
=
0
1215
data
.
rowproperties
[
r
]
=
specification
1216
end
1217 1218
function
xtables
.
finish_row
(
)
1219
local
c
=
data
.
currentcolumn
1220
local
r
=
data
.
currentrow
1221
local
d
=
data
.
rows
[
r
]
[
c
]
1222
local
n
=
data
.
nofcolumns
-
c
1223
if
d
then
1224
local
nx
=
d
.
nx
1225
if
nx
>
0
then
1226
n
=
n
-
nx
+
1
1227
end
1228
end
1229
if
n
>
0
then
1230
for
i
=
1
,
n
do
1231
ctx_dummyxcell
(
)
1232
end
1233
end
1234
end
1235 1236
-- eventually we might only have commands
1237 1238
implement
{
1239
name
=
"
x_table_create
"
,
1240
actions
=
xtables
.
create
,
1241
arguments
=
{
1242
{
1243
{
"
option
"
}
,
1244
{
"
textwidth
"
,
"
dimen
"
}
,
1245
{
"
textheight
"
,
"
dimen
"
}
,
1246
{
"
maxwidth
"
,
"
dimen
"
}
,
1247
{
"
lineheight
"
,
"
dimen
"
}
,
1248
{
"
columndistance
"
,
"
dimen
"
}
,
1249
{
"
leftmargindistance
"
,
"
dimen
"
}
,
1250
{
"
rightmargindistance
"
,
"
dimen
"
}
,
1251
{
"
rowdistance
"
,
"
dimen
"
}
,
1252
{
"
header
"
}
,
1253
{
"
footer
"
}
,
1254
}
1255
}
1256
}
1257 1258
implement
{
1259
name
=
"
x_table_flush
"
,
1260
actions
=
xtables
.
flush
,
1261
arguments
=
{
1262
{
1263
{
"
method
"
}
,
1264
{
"
height
"
,
"
dimen
"
}
1265
}
1266
}
1267
}
1268 1269
implement
{
name
=
"
x_table_reflow_width
"
,
actions
=
xtables
.
reflow_width
}
1270
implement
{
name
=
"
x_table_reflow_height
"
,
actions
=
xtables
.
reflow_height
}
1271
implement
{
name
=
"
x_table_construct
"
,
actions
=
xtables
.
construct
}
1272
implement
{
name
=
"
x_table_cleanup
"
,
actions
=
xtables
.
cleanup
}
1273
implement
{
name
=
"
x_table_next_row
"
,
actions
=
xtables
.
next_row
}
1274
implement
{
name
=
"
x_table_next_row_option
"
,
actions
=
xtables
.
next_row
,
arguments
=
"
string
"
}
1275
implement
{
name
=
"
x_table_finish_row
"
,
actions
=
xtables
.
finish_row
}
1276
implement
{
name
=
"
x_table_init_reflow_width
"
,
actions
=
xtables
.
initialize_reflow_width
}
1277
implement
{
name
=
"
x_table_init_reflow_height
"
,
actions
=
xtables
.
initialize_reflow_height
}
1278
implement
{
name
=
"
x_table_init_reflow_width_option
"
,
actions
=
xtables
.
initialize_reflow_width
,
arguments
=
"
string
"
}
1279
implement
{
name
=
"
x_table_init_reflow_height_option
"
,
actions
=
xtables
.
initialize_reflow_height
,
arguments
=
"
string
"
}
1280
implement
{
name
=
"
x_table_init_construct
"
,
actions
=
xtables
.
initialize_construct
}
1281
implement
{
name
=
"
x_table_set_reflow_width
"
,
actions
=
xtables
.
set_reflow_width
}
1282
implement
{
name
=
"
x_table_set_reflow_height
"
,
actions
=
xtables
.
set_reflow_height
}
1283
implement
{
name
=
"
x_table_set_construct
"
,
actions
=
xtables
.
set_construct
}
1284
implement
{
name
=
"
x_table_r
"
,
actions
=
function
(
)
context
(
data
.
currentrow
or
0
)
end
}
1285
implement
{
name
=
"
x_table_c
"
,
actions
=
function
(
)
context
(
data
.
currentcolumn
or
0
)
end
}
1286 1287
-- experiment:
1288 1289
do
1290 1291
local
context
=
context
1292
local
ctxcore
=
context
.
core
1293 1294
local
startxtable
=
ctxcore
.
startxtable
1295
local
stopxtable
=
ctxcore
.
stopxtable
1296 1297
local
startcollecting
=
context
.
startcollecting
1298
local
stopcollecting
=
context
.
stopcollecting
1299 1300
function
ctxcore
.
startxtable
(
...
)
1301
startcollecting
(
)
1302
startxtable
(
...
)
1303
end
1304 1305
function
ctxcore
.
stopxtable
(
)
1306
stopxtable
(
)
1307
stopcollecting
(
)
1308
end
1309 1310
end
1311