tabl-ltb.mkiv /size: 25 Kb    last modification: 2021-10-28 13:50
1%D \module
2%D   [       file=tabl-ltb,
3%D        version=2002.10.31, % updated 2016.01.08
4%D          title=\CONTEXT\ Table Macros,
5%D       subtitle=Line Tables,
6%D         author=Hans Hagen,
7%D           date=\currentdate,
8%D      copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
9%C
10%C This module is part of the \CONTEXT\ macro||package and is
11%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
12%C details.
13
14%D This module was made for some special project where we needed to typeset tables
15%D spanning spanning many pages horizontally and vertically, with repeated header
16%D lines and (entry) columns, tab tracking, color, etc. We do two passes over a
17%D table, which is why the table can go into a buffer or file. As said, tables can
18%D be real huge but performance is still quite okay (there is room for some speed
19%D up). The code has been adapted to \MKIV\ but the functionality is the same as in
20%D \MKII.
21
22% \BH \BC .. \EC \BC .. \EC \EH % append
23% \BR \BC .. \EC \BC .. \EC \ER
24%
25% or
26%
27% \NC .. \NC .. \NC \NR (todo: optional last \NC)
28
29% alternative:
30%
31% (1) direct run, save content in macro, but only if needed
32%
33% todo
34%
35% (2) buffered table content
36%
37% \startbuffer
38%   \startlinetablehead
39%   \stoplinetablehead
40%   \startlinetablebody
41%   \stoplinetablebody
42% \stopbuffer
43%
44% \processlinetablebuffer[buffer]
45%
46% in buffer : head and body
47%
48% (3) unbuffered run, multipass
49%
50% - run with starting width zero / prev run
51% - clip on prev run
52% - flush real widths
53
54\writestatus{loading}{ConTeXt Table Macros / Line Tables}
55
56\unprotect
57
58\installcorenamespace{linetable}
59\installcorenamespace{linetablepart}
60\installcorenamespace{linetablewidth}
61\installcorenamespace{linetableheight}
62\installcorenamespace{linetabledepth}
63
64\newconditional \c_tabl_lines_preroll
65\newconditional \c_tabl_lines_in_table
66
67\newdimen       \d_tabl_lines_width
68\newdimen       \d_tabl_lines_height
69%newdimen       \d_tabl_lines_depth
70
71\newbox         \b_tabl_lines_cell
72
73\newcount       \c_tabl_lines_n_of_columns
74\newcount       \c_tabl_lines_n_of_rows
75\newcount       \c_tabl_lines_n_of_lines
76\newcount       \c_tabl_lines_n_of_parts
77\newcount       \c_tabl_lines_part           \c_tabl_lines_part\plusone
78\newcount       \c_tabl_lines_step           \c_tabl_lines_step\plusone
79\newcount       \c_tabl_lines_line
80\newcount       \c_tabl_lines_row
81\newcount       \c_tabl_lines_rows
82\newcount       \c_tabl_lines_column
83\newcount       \c_tabl_lines_subcol
84
85\newconstant    \c_tabl_lines_hmode
86\newconstant    \c_tabl_lines_page
87\newconstant    \c_tabl_lines_repeat
88\newconstant    \c_tabl_lines_split_state
89\newconstant    \c_tabl_lines_head_state
90\newconstant    \c_tabl_lines_mode
91
92\newtoks        \t_tabl_lines_head
93
94\newconditional \linetableautoheight  \settrue\linetableautoheight
95
96\initializetablebox\zerocount % holds repeater
97
98\unexpanded\def\setuplinetable
99  {\dotripleempty\tabl_lines_setup}
100
101\def\tabl_lines_setup[#1][#2][#3]%
102  {\ifthirdargument
103     \getparameters[\??linetable#1:#2][#3]%
104   \else\ifsecondargument
105     \getparameters[\??linetable#1:][#2]%
106   \else
107     \getparameters[\??linetable][#1]%
108   \fi\fi}
109
110\setuplinetable
111  [\c!n=\maxcard,
112   \c!lines=\maxcard,
113   \c!nx=\plusone,
114   \c!nleft=\zerocount,
115   \c!repeat=\v!yes, % when nleft > 0, repeat on both pages
116   \c!before=,
117   \c!after=,
118   \c!inbetween=\page,
119   \c!distance=\zeropoint,
120   \c!stretch=\v!no,
121   \c!align=\c!right,
122   \c!leftoffset=.25\exheight,
123   \c!rightoffset=\linetableparameter\c!leftoffset,
124   \c!maxwidth=\zeropoint,
125   \c!width=5\emwidth,
126   \c!height=\v!fit, % \v!line = faster
127   \c!background=,
128   \c!backgroundcolor=,
129   \c!rulethickness=\linewidth]
130
131\def\linetableparameter#1%
132  {\begincsname\??linetable#1\endcsname}
133
134\unexpanded\def\doifelselinetablecparameter#1%
135  {\ifcsname\??linetable c:\number\c_tabl_lines_column#1\endcsname
136     \expandafter\firstoftwoarguments
137   \else\ifcsname\??linetable c:#1\endcsname
138     \doubleexpandafter\firstoftwoarguments
139   \else
140     \doubleexpandafter\secondoftwoarguments
141   \fi\fi}
142
143\let\doiflinetablecparameterelse\doifelselinetablecparameter
144
145\def\linetablecparameter#1%
146  {\begincsname
147     \??linetable
148     \ifcsname\??linetable c:\number\c_tabl_lines_column#1\endcsname
149       c:\number\c_tabl_lines_column
150     \else\ifcsname\??linetable c:#1\endcsname
151       c:%
152     \fi\fi
153     #1%
154   \endcsname}
155
156\def\linetablerparameter#1% faster, leaner and meaner
157  {\begincsname
158     \??linetable
159     \ifnum\c_tabl_lines_row=\zerocount % geen ifcase
160       \ifcsname\??linetable r:\v!header#1\endcsname
161         r:\v!header
162       \else\ifcsname\??linetable r:0#1\endcsname
163         r:0%
164       \fi\fi
165     \else
166       \ifcsname\??linetable r:\number\c_tabl_lines_row#1\endcsname
167         r:\number\c_tabl_lines_row
168       \else\ifcsname\??linetable r:\v!oddeven\c_tabl_lines_row#1\endcsname
169         r:\v!oddeven\c_tabl_lines_row
170       \fi\fi
171     \fi
172     #1%
173   \endcsname}
174
175\unexpanded\def\tabl_lines_set
176  {\edef\p_lines{\linetableparameter\c!lines}%
177   \ifx\p_lines\v!fit
178     \tabl_lines_set_indeed
179   \else
180     \global\c_tabl_lines_n_of_lines\p_lines
181   \fi}
182
183\unexpanded\def\tabl_lines_set_indeed
184  {% whitespace already added by vertical strut
185  %\triggerpagebuilder
186   \scratchdimen
187     \ifdim\pagegoal<\maxdimen
188       \dimexpr\pagegoal-\pagetotal\relax
189     \else
190       \textheight
191     \fi
192   \getrawnoflines\scratchdimen
193   \global\c_tabl_lines_n_of_lines\noflines
194   \ifconditional\c_tabl_lines_preroll \else \ifnum\c_tabl_lines_n_of_lines<\plustwo
195     \page
196     \tabl_lines_set
197   \fi \fi}
198
199\unexpanded\def\startlinetablecell
200  {\dosingleempty\tabl_lines_start_cell}
201
202\def\tabl_lines_step_cell
203  {\advance\scratchdimen\linetablecparameter\c!width
204   \global\advance      \c_tabl_lines_column\plusone
205   \advance\scratchskip \linetablecparameter\c!distance}
206
207\def\tabl_lines_start_cell[#1]%
208  {\global\setbox\b_tabl_lines_cell\hbox\bgroup
209   \iffirstargument
210     \getparameters[\??linetable c:\number\c_tabl_lines_column][#1]%
211   \fi
212   \global\c_tabl_lines_step\linetablecparameter\c!nx\relax
213   \ifcase\c_tabl_lines_step\or
214     \scratchdimen\linetablecparameter\c!width
215     \scratchskip \linetablecparameter\c!distance
216   \else
217     \scratchdimen  \zeropoint
218     \scratchskip   \zeropoint
219     \scratchcounter\c_tabl_lines_column
220     \dorecurse\c_tabl_lines_step\tabl_lines_step_cell
221     \global\c_tabl_lines_column\scratchcounter
222   \fi
223   \c_tabl_lines_mode
224     \ifconditional\c_tabl_lines_preroll
225       \ifdim\scratchdimen>\zeropoint \zerocount \else \plustwo \fi
226     \else
227       \zerocount
228     \fi
229   \ifcase\c_tabl_lines_mode
230     \ifcase\c_tabl_lines_hmode
231       % nothing
232     \or
233       % fit, keep it simple
234     \or
235       \c_tabl_lines_mode\plusone % line
236     \else
237       % some already calculated height
238     \fi
239   \fi
240   \setbox\scratchbox\hbox
241     \bgroup
242     \dontcomplain
243     \hskip\linetablecparameter\c!leftoffset\relax
244     % 0 = width, unknown height
245     % 1 = width, fixed height
246     % 2 = no width, auto hsize
247     \ifnum\c_tabl_lines_mode<\plustwo
248       \advance\scratchdimen-\linetablecparameter\c!leftoffset
249       \advance\scratchdimen-\linetablecparameter\c!rightoffset
250     \fi
251     \ifcase\c_tabl_lines_mode
252       \dosetraggedcommand{\linetablecparameter\c!align}%
253       \vtop \ifdim\d_tabl_lines_height>\zeropoint to\d_tabl_lines_height \fi \bgroup
254         \hsize\scratchdimen
255         \raggedcommand
256     \else
257       \setalignmentswitch{\linetablecparameter\c!align}%
258       \hbox \ifcase\c_tabl_lines_mode \or to\scratchdimen \fi \bgroup
259         \ifcase\alignmentswitch\hss\or\hss\fi
260     \fi
261     \dousestyleparameter{\linetablecparameter\c!style}%
262     \dousecolorparameter{\linetablecparameter\c!color}%
263     \begstrut \ignorespaces}
264
265\unexpanded\def\stoplinetablecell
266  {\unskip \endstrut
267   \ifcase\c_tabl_lines_mode
268     \endgraf
269   \else
270     \ifcase\alignmentswitch\else\hss\fi
271   \fi
272   \egroup
273   \hskip\linetablecparameter\c!rightoffset
274   \egroup
275   \ifconditional\c_tabl_lines_preroll
276     \box\scratchbox
277   \else
278     \tabl_lines_wrap_up
279   \fi
280   \egroup}
281
282\def\tabl_lines_wrap_up
283  {\edef\p_background{\linetablecparameter\c!background}%
284   \ifx\p_background\v!color
285     \ifconditional\linetableautoheight
286       \tabl_lines_wrap_up_auto
287     \else
288       \tabl_lines_wrap_up_line
289      \fi
290   \else
291     \box\scratchbox
292   \fi}
293
294% \startuseMPgraphic{one}
295%     path p, q ;
296%     numeric r ;
297%     r := RuleThickness ;
298%     p := unitsquare xysized(RuleWidth,RuleHeight+RuleDepth) ;
299%     q := p topenlarged -r bottomenlarged -r ;
300%     draw q ;
301%     setbounds currentpicture to p;
302% \stopuseMPgraphic
303%
304% \setuplinetable[r][odd] [type=mp,mp=one,backgroundcolor=gray,rulethickness=1pt]
305% \setuplinetable[r][even][type=mp,mp=one,backgroundcolor=green,rulethickness=1pt]
306%
307% \startlinetable
308%     \dorecurse{10}{\NC aaa \NC bb \NC c \NC ddddd \NC eeee \NC ff \NC \NR}
309% \stoplinetable
310
311\def\tabl_lines_wrap_up_auto
312  {\edef\p_height{\linetablerparameter{x\c!height}}%
313   \edef\p_depth {\linetablerparameter{x\c!depth }}%
314   \hpack
315     {\blackrule
316        [ \c!color=\linetablecparameter\c!backgroundcolor,
317           \c!type=\linetablecparameter\c!type,
318             \c!mp=\linetablecparameter\c!mp,
319  \c!rulethickness=\linetablecparameter\c!rulethickness,
320         \c!height=\ifx\p_height\empty\ht\scratchbox\else\p_height\fi,
321          \c!depth=\ifx\p_depth \empty\dp\scratchbox\else\p_depth \fi,
322          \c!width=\wd\scratchbox]%
323      \hskip-\wd\scratchbox\box\scratchbox}}
324
325\def\tabl_lines_wrap_up_auto_r
326  {\hpack
327     {\blackrule
328        [ \c!color=\linetablerparameter\c!backgroundcolor,
329           \c!type=\linetablerparameter\c!type,
330             \c!mp=\linetablerparameter\c!mp,
331  \c!rulethickness=\linetablerparameter\c!rulethickness,
332         \c!height=\ht\scratchbox,
333          \c!depth=\dp\scratchbox,
334          \c!width=\wd\scratchbox]%
335      \hskip-\wd\scratchbox\box\scratchbox}}
336
337\def\tabl_lines_wrap_up_line
338  {\backgroundline[\linetablecparameter\c!backgroundcolor]{\box\scratchbox}}
339
340\def\tabl_lines_save_part
341  {\global\setbox\tablebox\c_tabl_lines_part
342   \ifcase\c_tabl_lines_part\relax
343     \box\scratchbox % just storing
344   \else
345     \vbox
346       {\ifvoid\tablebox\c_tabl_lines_part\else\unvbox\tablebox\c_tabl_lines_part\fi
347        \edef\p_background{\linetablerparameter\c!background}%
348        \ifx\p_background\v!color
349          \backgroundline[\linetablerparameter\c!backgroundcolor]{\box\scratchbox}%
350        \else
351          \edef\p_type{\linetablerparameter\c!type}%
352          \ifx\p_type\empty
353            \box\scratchbox
354          \else
355            \tabl_lines_wrap_up_auto_r
356          \fi
357        \fi
358        \endgraf
359        \linetablerparameter\c!after}%
360   \fi}
361
362\def\tabl_lines_flush_parts
363  {\global\advance\c_tabl_lines_line\plusone
364   \ifnum\c_tabl_lines_line<\c_tabl_lines_n_of_lines
365     % keep collecting
366   \else
367     \ifconditional\c_tabl_lines_preroll
368       % forget about them
369     \else
370       \dorecurse\c_tabl_lines_n_of_parts
371         {\c_tabl_lines_part\recurselevel
372          \dp\tablebox\c_tabl_lines_part\strutdepth
373          % noindent en endgraf needed else whitespace mess-up!
374          \whitespace % here not after verticalstrut
375          \ifdim\topskipgap=\zeropoint\else
376            \verticalstrut
377            \nobreak
378            \kern-\struttotal
379            \kern-\parskip
380            \nobreak
381            \nointerlineskip % fix topskip
382          \fi
383          \noindent\strut
384          \hpack to \hsize{\box\tablebox\c_tabl_lines_part\hss}%
385          \endgraf
386          \ifnum\c_tabl_lines_part<\c_tabl_lines_n_of_parts\relax
387            \linetableparameter\c!inbetween
388          \fi}%
389       \ifnum\c_tabl_lines_rows<\c_tabl_lines_n_of_rows
390         \linetableparameter\c!inbetween
391       \else
392         % after, later
393       \fi
394       \c_tabl_lines_head_state\plusthree
395       \global\setbox\tablebox\zerocount\emptybox % here
396     \fi
397     % reset \c_tabl_lines_row will be an option, currently
398     % starts at zero after split
399     \global\c_tabl_lines_row\zerocount
400     \global\c_tabl_lines_line\zerocount
401     \global\c_tabl_lines_page\zerocount
402     \global\d_tabl_lines_width\zeropoint
403     \tabl_lines_set
404   \fi}
405
406\def\tabl_lines_start_part
407  {\global\c_tabl_lines_subcol\zerocount
408   \setbox\scratchbox\hbox\bgroup
409   \dousestyleparameter{\linetablerparameter\c!style}%
410   \dousecolorparameter{\linetablerparameter\c!color}%
411   \ignorespaces}
412
413\def\tabl_lines_stop_part
414  {\ifnum\c_tabl_lines_part>\zerocount
415     \unskip \unskip % remove last intercolumn skip (distance+fill)
416   \fi
417   \egroup
418   \ifconditional\c_tabl_lines_preroll \else
419     \ifcase\c_tabl_lines_part
420       % we're collecting the repeater
421     \else
422       \ifdim\dimexpr\hsize-\wd\scratchbox\relax>\linetableparameter\c!stretch\else
423         \setbox\scratchbox\hpack to \hsize{\unhbox\scratchbox}%
424       \fi
425     \fi
426   \fi}
427
428\def\tabl_lines_check_part
429  {\global\advance\d_tabl_lines_width\wd\b_tabl_lines_cell
430   \global\advance\c_tabl_lines_column\c_tabl_lines_step
431   \global\advance\c_tabl_lines_subcol\c_tabl_lines_step
432   \relax
433   %\message{\the\c_tabl_lines_column,\the\c_tabl_lines_subcol}\wait
434   % from now on the column counter is already incremented
435   \ifcase\c_tabl_lines_split_state
436     \ifconditional\c_tabl_lines_preroll \else
437       \box\b_tabl_lines_cell
438       % the columncounter is one ahead !
439       \hskip\scratchskip
440     \fi
441     %%%
442     \donefalse
443     \ifcase\c_tabl_lines_repeat\else
444       % calculate ahead
445       \ifnum\c_tabl_lines_repeat=\numexpr\c_tabl_lines_column-\plustwo\relax
446         \donetrue % collecting repeater
447       \fi
448     \fi
449     %%%%
450     \ifdone
451       % collecting repeater
452     \else
453       \ifnum\c_tabl_lines_column>\csname\??linetablepart\number\c_tabl_lines_part\endcsname\relax
454         \donetrue
455       \fi
456     \fi
457     \ifdone
458       \tabl_lines_stop_part
459       \ifconditional\c_tabl_lines_preroll \else
460         \tabl_lines_save_part
461       \fi
462       \ifcase\c_tabl_lines_page \or
463         \global\c_tabl_lines_page \plustwo
464       \else
465         \global\c_tabl_lines_page \plusone
466       \fi
467       \global\advance\c_tabl_lines_part\plusone
468       \global\d_tabl_lines_width\wd\tablebox\zerocount
469       \tabl_lines_start_part
470     \fi
471   \else
472     \donefalse
473     \!!doneafalse
474     \ifcase\c_tabl_lines_repeat\else
475       % calculate ahead
476       \ifnum\c_tabl_lines_repeat=\numexpr\c_tabl_lines_column-\plustwo\relax
477         \donetrue % collecting repeater
478       \fi
479     \fi
480     \ifdone
481       \!!doneatrue
482       % collecting repeater
483     \else\ifdim\d_tabl_lines_width>\hsize
484       \donetrue
485     \else
486       \global\advance\d_tabl_lines_width\scratchskip
487       \ifdim\d_tabl_lines_width>\hsize % ?
488         \donetrue
489       \fi
490     \fi\fi
491     \ifdone
492       \tabl_lines_stop_part
493       \tabl_lines_save_part
494       \ifcase\c_tabl_lines_page \or
495         \global\c_tabl_lines_page \plustwo
496       \else
497         \global\c_tabl_lines_page \plusone
498       \fi
499       \global\advance\c_tabl_lines_part\plusone
500       \ifnum\c_tabl_lines_part>\c_tabl_lines_n_of_parts
501         \global\c_tabl_lines_n_of_parts\c_tabl_lines_part
502         \initializetablebox\c_tabl_lines_part
503       \fi
504       \global\d_tabl_lines_width\wd\b_tabl_lines_cell
505       \tabl_lines_start_part
506       \if!!donea \else \ifcase\c_tabl_lines_repeat \else
507         % check for left/right page
508         \ifcase\c_tabl_lines_page\donetrue\or\donetrue\or\donefalse\fi\ifdone
509           % insert repeater
510           \global\advance\d_tabl_lines_width\wd\tablebox\zerocount
511           \ifconditional\c_tabl_lines_preroll\kern\wd\else\unhcopy\fi\tablebox\zerocount
512         \fi
513       \fi \fi
514     \fi
515     \ifconditional\c_tabl_lines_preroll \else
516       \box\b_tabl_lines_cell
517       % the columncounter is one ahead !
518%        \dorecurse\c_tabl_lines_step{\strut\hfil}%
519\strut
520       \hskip\scratchskip
521     \fi
522   \fi}
523
524\unexpanded\def\startlinetablerun % to do: quit when nested
525  {\bgroup
526   \settrue\c_tabl_lines_in_table
527   % autowidth
528   \doif{\linetableparameter\c!maxwidth}\v!fit
529     {\setuplinetable[\c!maxwidth=\zeropoint]}%
530   \processaction
531     [\linetableparameter\c!stretch]
532     [ \v!no=>{\setuplinetable[\c!stretch=\maxdimen]},% no stretch
533      \v!yes=>{\setuplinetable[\c!stretch=\zeropoint]}]% max stretch
534   \c_tabl_lines_repeat\linetableparameter\c!nleft
535   \c_tabl_lines_split_state % =
536     \ifdim\linetableparameter\c!maxwidth>\zeropoint
537       \zerocount \else \plusone
538     \fi
539   % optional prevdepth correction
540   \ifconditional\c_tabl_lines_preroll
541     \global\c_tabl_lines_n_of_rows\zerocount
542   \else
543     \linetableparameter\c!before
544   \fi
545   \global\c_tabl_lines_rows\zerocount
546   \global\c_tabl_lines_n_of_columns\zerocount
547   \global\c_tabl_lines_n_of_parts\zerocount
548   \scratchcounter\zerocount
549   \def\docommand##1%
550     {\global\advance\c_tabl_lines_n_of_parts\plusone
551      \advance\scratchcounter##1%
552      \setxvalue{\??linetablepart\number\c_tabl_lines_n_of_parts}{\the\scratchcounter}}%
553   \processcommacommand[\linetableparameter\c!n]\docommand
554   \initializetableboxes\c_tabl_lines_n_of_parts
555   \global\c_tabl_lines_part\ifcase\c_tabl_lines_repeat\plusone\else\zerocount\fi % repeater
556   \global\c_tabl_lines_step\plusone
557   \global\c_tabl_lines_line\zerocount
558   \global\c_tabl_lines_row \zerocount
559   \global\c_tabl_lines_column\zerocount
560   \global\c_tabl_lines_subcol\zerocount
561   \global\d_tabl_lines_width\zeropoint
562   \ifconditional\c_tabl_lines_preroll \else \ifdim\pagetotal>\zeropoint
563     \verticalstrut\kern-\struttotal
564   \fi \fi
565   \tabl_lines_set
566   \tabl_lines_check_page
567   \let\BR\tabl_lines_BR
568   \let\ER\tabl_lines_ER
569   \let\BH\tabl_lines_BR
570   \let\EH\tabl_lines_ER
571   \let\BC\tabl_lines_BC
572   \let\EC\tabl_lines_EC
573   \let\NC\tabl_lines_NC
574   \let\NR\tabl_lines_NR
575   \tabl_lines_flush_head}
576
577\unexpanded\def\stoplinetablerun
578  {\global\c_tabl_lines_line\maxcard
579   \c_tabl_lines_head_state\zerocount % blocked
580   \tabl_lines_flush_parts
581   \ifconditional\c_tabl_lines_preroll \else
582     \linetableparameter\c!after
583   \fi
584   \global\c_tabl_lines_part\zerocount
585   \global\c_tabl_lines_n_of_parts\zerocount
586   \egroup}
587
588\def\checklinecolumndimension#1#2#3%
589  {\expandafter\xdef\csname#1\number#3\endcsname
590     {\expandafter\ifx\csname#1\number#3\endcsname\relax
591        \the#2\b_tabl_lines_cell
592      \else\ifdim\csname#1\number#3\endcsname<#2\b_tabl_lines_cell
593        \the#2\b_tabl_lines_cell
594      \else
595        \csname#1\number#3\endcsname
596      \fi\fi}}
597
598\def\tabl_lines_check_width {\checklinecolumndimension\??linetablewidth \wd\c_tabl_lines_column}
599\def\tabl_lines_check_height{\checklinecolumndimension\??linetableheight\ht\c_tabl_lines_row}
600\def\tabl_lines_check_depth {\checklinecolumndimension\??linetabledepth \dp\c_tabl_lines_row}
601
602\unexpanded\def\tabl_lines_BR
603  {\dosingleempty\tabl_lines_BR_indeed}
604
605\def\tabl_lines_BR_indeed[#1]% #1 not yet implemented
606  {\ifnum\c_tabl_lines_head_state=1\else
607     \global\advance\c_tabl_lines_row\plusone
608     \global\advance\c_tabl_lines_rows\plusone
609   \fi
610   \global\c_tabl_lines_column\plusone
611   \global\c_tabl_lines_subcol\plusone
612   \d_tabl_lines_height\zeropoint
613   \edef\p_height{\linetablerparameter\c!height}%
614   \ifx\p_height\empty
615     \c_tabl_lines_hmode \zerocount
616   \else\ifx\p_height\v!fit
617     \c_tabl_lines_hmode \plusone
618   \else\ifx\p_height\v!line
619     \c_tabl_lines_hmode \plustwo
620   \else
621     \d_tabl_lines_height\dimexpr\p_height-\strutdepth\relax
622   \fi\fi\fi
623   \tabl_lines_start_part}
624
625\unexpanded\def\tabl_lines_BC
626  {\startlinetablecell}
627
628\unexpanded\def\tabl_lines_EC
629  {\stoplinetablecell
630   \ifconditional\c_tabl_lines_preroll
631     \tabl_lines_check_width
632     \tabl_lines_check_height
633     \tabl_lines_check_depth
634   \fi
635   \tabl_lines_check_part}
636
637\unexpanded\def\tabl_lines_ER
638  {% \stoplinetablecell
639   % no \box\b_tabl_lines_cell, i.e. dummy columnn, last \NC \NR
640   \tabl_lines_stop_part
641   \tabl_lines_save_part
642   \advance\c_tabl_lines_column \minusone
643   \ifnum\c_tabl_lines_column>\c_tabl_lines_n_of_columns
644     \global\c_tabl_lines_n_of_columns\c_tabl_lines_column
645   \fi
646   \tabl_lines_flush_parts
647   \global\c_tabl_lines_column\zerocount
648   \global\d_tabl_lines_width \zeropoint
649   \ifcase\c_tabl_lines_repeat
650     \global\c_tabl_lines_part\plusone
651   \else
652     \global\c_tabl_lines_part\zerocount % repeater
653   \fi
654   \tabl_lines_check_page
655   \tabl_lines_flush_head}
656
657\def\tabl_lines_check_page
658  {\global\c_tabl_lines_page\zerocount
659   \ifcase\c_tabl_lines_repeat \else \ifcase\c_tabl_lines_page
660     \doif{\linetableparameter\c!repeat}\v!no
661       {\global\c_tabl_lines_page\doifelseoddpage\plusone\plustwo}%
662   \fi \fi}
663
664\def\tabl_lines_flush_head
665  {\ifcase\c_tabl_lines_head_state
666     % 0 blocked
667   \or
668     % 1 doing head
669   \or
670     % 2 head done
671   \or
672     % 3 trigger flush
673     \c_tabl_lines_head_state\plusone
674     \the\t_tabl_lines_head\relax
675     \c_tabl_lines_head_state\plustwo
676   \fi}
677
678\unexpanded\def\tabl_lines_NC % first time special treatment
679  {\relax
680   \ifcase\c_tabl_lines_column
681     \tabl_lines_BR
682   \else
683     \tabl_lines_EC
684   \fi
685   \tabl_lines_BC} % beware, this will result in BR BC EC BC NR
686
687\unexpanded\def\tabl_lines_NR
688  {\stoplinetablecell % dummy
689   \tabl_lines_ER}
690
691\unexpanded\def\startlinetable
692  {\startlinetablerun}
693
694\unexpanded\def\stoplinetable
695  {\stoplinetablerun}
696
697\unexpanded\def\startlinetableanalysis
698  {\bgroup
699   \settrue\c_tabl_lines_preroll
700   \settrialtypesetting
701   \startlinetablerun}
702
703% \unexpanded\def\stoplinetableanalysis
704%   {\stoplinetablerun
705%    \egroup
706%    \global\c_tabl_lines_n_of_rows\c_tabl_lines_rows
707%    \dorecurse\c_tabl_lines_n_of_rows % global, from last run {\linetableparameter\c!n}
708%      {\setevalue{\??linetable r:\recurselevel x\c!height}{\getvalue{\??linetableheight\recurselevel}}%
709%       \setevalue{\??linetable r:\recurselevel x\c!depth }{\getvalue{\??linetabledepth \recurselevel}}%
710%       \letgvalue{\??linetableheight\recurselevel}\!!zeropoint
711%       \letgvalue{\??linetabledepth \recurselevel}\!!zeropoint}
712%    \dorecurse\c_tabl_lines_n_of_columns % global, from last run {\linetableparameter\c!n}
713%      {\setevalue{\??linetable c:\recurselevel\c!width}{\getvalue{\??linetablewidth\recurselevel}}%
714%       \letgvalue{\??linetablewidth\recurselevel}\!!zeropoint}} % init next table
715
716\unexpanded\def\stoplinetableanalysis
717  {\stoplinetablerun
718   \egroup
719   \global\c_tabl_lines_n_of_rows\c_tabl_lines_rows
720   \dorecurse\c_tabl_lines_n_of_rows % global, from last run {\linetableparameter\c!n}
721     {\setevalue{\??linetable r:##1x\c!height}{\csname\??linetableheight##1\endcsname}%
722      \setevalue{\??linetable r:##1x\c!depth }{\csname\??linetabledepth ##1\endcsname}%
723      \letgvalue{\??linetableheight##1}\zeropoint
724      \letgvalue{\??linetabledepth ##1}\zeropoint}
725   \dorecurse\c_tabl_lines_n_of_columns % global, from last run {\linetableparameter\c!n}
726     {\setevalue{\??linetable c:##1\c!width}{\csname\??linetablewidth##1\endcsname}%
727      \letgvalue{\??linetablewidth##1}\zeropoint}} % init next table
728
729% todo: store in box instead of macro
730
731\let\stoplinetablehead\relax
732
733\unexpanded\def\startlinetablehead#1\stoplinetablehead
734  {\ifconditional\c_tabl_lines_in_table
735     \t_tabl_lines_head\emptytoks
736   \fi
737   \c_tabl_lines_head_state\plusthree % full
738   \t_tabl_lines_head{#1}%
739   \ifconditional\c_tabl_lines_in_table
740     \tabl_lines_flush_head
741   \fi}
742
743\unexpanded\def\tabl_lines_BH
744  {\ifx\EC\relax
745     % signal, grabbing lines
746   \else
747     \t_tabl_lines_head\emptytoks
748   \fi
749   \push_macro_BC
750   \push_macro_EC
751   \def\BC##1\EC{\appendtoks##1\to\t_tabl_lines_head}%
752   \let\EC\relax} % signal
753
754\unexpanded\def\tabl_lines_EH
755  {\pop_macro_EC
756   \pop_macro_BC
757   \expandafter\startlinetablehead\the\t_tabl_lines_head\stoplinetablehead}
758
759\let\startlinetablebody\relax
760\let\stoplinetablebody \relax
761
762\unexpanded\def\processlinetablebuffer
763  {\dosingleempty\tabl_lines_process_buffer}
764
765\def\tabl_lines_process_buffer[#1]%
766  {\bgroup
767   \let\startlinetable\relax
768   \let\stoplinetable \relax
769   \startlinetableanalysis\getbuffer[#1]\stoplinetableanalysis
770   \startlinetablerun     \getbuffer[#1]\stoplinetablerun
771   \egroup}
772
773\unexpanded\def\processlinetablefile
774  {\dosingleempty\tabl_lines_process_file}
775
776\def\tabl_lines_process_file#1% maybe accept #1 as well as [#1]
777  {\bgroup
778   \let\startlinetable\relax
779   \let\stoplinetable \relax
780   \startlinetableanalysis\readfile{#1}\donothing\donothing\stoplinetableanalysis
781   \startlinetablerun     \readfile{#1}\donothing\donothing\stoplinetablerun
782   \egroup}
783
784\protect
785
786\continueifinputfile{tabl-ltb.mkiv}
787
788\setuplinetable[n=6,m={2,2,2},lines=25] % m ?
789
790\setuplinetable[c][1]   [width=2cm,background=color,backgroundcolor=red]
791\setuplinetable[c][4]   [width=3cm,background=color,backgroundcolor=yellow]
792\setuplinetable[c][6]   [width=3cm,background=color,backgroundcolor=magenta]
793\setuplinetable[r][odd] [background=color,backgroundcolor=gray]
794\setuplinetable[r][even][background=color,backgroundcolor=green]
795
796\starttext
797
798\showframe \showstruts
799
800\setuppagenumbering[alternative=doublesided]\page[left]
801
802\startlinetable
803\NC aaa\crlf aaa \NC bb \NC c \NC ddddd \NC eeee \NC ff \NC \NR
804\dorecurse{100}{\NC aaa \NC bb \NC c \NC ddddd \NC eeee \NC ff \NC \NR}
805\stoplinetable
806
807\startlinetable
808\NC[style=slanted,color=green,background=color,backgroundcolor=darkred,nx=2,uitlijnen=middle] xxx
809                 \NC yy \NC ddddd \NC eeee \NC ff \NC \NR
810\dorecurse{100}{\NC aaa \NC bb \NC c \NC ddddd \NC eeee \NC ff \NC \NR}
811\stoplinetable
812
813% \startbuffer[lt]
814% \NC aaa\crlf aaa \NC bb \NC c  \NC ddddd \NC ee   \NC ff \NC \NR
815% \NC aaa\crlf aaa \NC b  \NC cc \NC ddd   \NC eeee \NC f  \NC \NR
816% \stopbuffer
817%
818% \processlinetablebuffer[lt]
819
820\stoptext
821