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