tabl-tbl.mkxl /size: 125 Kb    last modification: 2025-02-21 11:03
1%D \module
2%D   [       file=core-tbl,
3%D        version=1998.11.03,
4%D          title=\CONTEXT\ Table Macros,
5%D       subtitle=Text Flow Tabulation,
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\writestatus{loading}{ConTeXt Table Macros / Tabulation}
15
16\unprotect
17
18% These are set at the lua end by parser:
19
20\newinteger\c_tabl_tabulate_nofcolumns
21\newinteger\c_tabl_tabulate_has_rule_spec_first
22\newinteger\c_tabl_tabulate_has_rule_spec_last
23
24\registerctxluafile{tabl-tbl}{autosuffix} % experiment
25
26%D I can probably reimplement this using a \LUATEX\ combination but it does not pay
27%D of in development time. If I need something else I will write it from scratch
28%D anyway. This module looks a bit complex which is a consequence of it dealing with
29%D paragraphs being split over pages and that there are several passes over the data
30%D set. We can probably do some cleanup (combine/split).
31%D
32%D Caching the preamble does not save much (compared to other bits and pieces of
33%D \CONTEXT). There are not that many ways to deal with preambles and this is just
34%D one of them. The keys are somewhat similar to those of the \TABLE\ package.
35
36% |p2|p3| 2:3 -> spanning (maybe)
37%
38% In-text tabbing environment
39%
40% \starttabulate[| separated template] % eg [|l|p|] or [|l|p|p|]
41%   \NC ... \NC ... \NC\NR
42% \stoptabulate
43%
44% with: two pass auto width calculation when no p-width
45% specified, even with multiple p's, see examples.
46%
47%  TaBlE compatible specifications:
48%
49%  l  align column/paragraph left
50%  r  align column/paragraph right
51%  c  align column/paragraph center
52%  p  p(dimen) of automatisch als alleen p
53%  w  column width
54%  f  font#1
55%  A  {alignmentoptions}
56%  B  bold
57%  I  italic
58%  S  slanted
59%  T  type
60%  R  roman
61%  m  math
62%  M  display math
63%  h  hook (inner level or par lines)
64%  b  before (may be command#1)
65%  a  after
66%  i  i<n> skip left of column
67%  j  i<n> skip right of column
68%  k  i<n> skip around column
69%  d  digits (~)
70%
71%  C  [LMRT] {color} % T is text color
72%
73%  |  {color,n}
74%
75%  s  setups
76%
77%  g  g{char} align at char
78%  .  align at .
79%  ,  align at ,
80%
81%  Still to be done
82%
83%  N      math numbers (best hook into existing digits mechanism)
84%  n      numbers (best hook into existing digits mechanism)
85%  Q      math numbers (best hook into existing digits mechanism)
86%  q      numbers (best hook into existing digits mechanism)
87%  ~      \hskip.5em
88%  |      check
89%
90%  nesting
91%
92%  10     evt auto stack; dan wel andere signal dan void nodig
93%
94%  present but not yet 100% ok
95%
96%  \TL [width,color]   bottom hrule
97%  \FL [width,color]   first hrule
98%  \ML [width,color]   mid hrule (with auto split)
99%  \LL [width,color]   bottom hrule
100%  \BL [width,color]   last hrule
101%
102%  \HL [width,color]   top rule
103%  \VL [width,color]
104%
105%  \CC \CL \CM \CR color
106%
107%  \EQ \RQ \HQ     equal  (raw, hook)
108%  \NC \RC \HC     normal (raw, hook)
109%
110%  \NR  checked break
111%  \NB  no break
112%
113%  \HR : rule with lineheight
114%
115%  \autotabulaterule : with lineheight, not first/last
116%  \autotabulateline : spaced, not first/last
117%  \tabulaterule     : with lineheight
118%  \tabulateline     : spaced
119%
120% tricky: align scans ahead, over # and expands ones before
121% while doing
122%
123% new:
124%
125% \starttabulate[|cg{.}|cg{,}|cg{,}|]
126% \NC period     \NC comma      \NC comma   \NC\NR
127% \NG 100.000,00 \NG 100.000,00 \NG 100,00  \NC\NR
128% \NG 10.000,00  \NG 10.000,00  \NG 1000,00 \NC\NR
129% \NG 100,00     \NG 100,00     \NG 10,00   \NC\NR
130% \NG 10         \NG 10         \NG 0,00    \NC\NR
131% \stoptabulate
132%
133% \starttabulate[|c.|c,|c,|]
134% \NC period     \NC comma      \NC comma   \NC\NR
135% \NG 100.000,00 \NG 100.000,00 \NG 100,00  \NC\NR
136% \NG 10.000,00  \NG 10.000,00  \NG 1000,00 \NC\NR
137% \NG 100,00     \NG 100,00     \NG 10,00   \NC\NR
138% \NG 10         \NG 10         \NG 0,00    \NC\NR
139% \stoptabulate
140
141% nice demo (for BG)
142%
143% \starttabulate[|r|b{$\star$}|ra{\percent}|b{=}|r|]
144% \NC 500 \NC \NC 60 \NC \NC 300 \NC \NR
145% \NC 500 \NC \NC 55 \NC \NC 275 \NC \NR
146% \NC 500 \NC \NC 50 \NC \NC 250 \NC \NR
147% \NC 500 \NC \NC 45 \NC \NC 225 \NC \NR
148% \NC 500 \NC \NC 40 \NC \NC 200 \NC \NR
149% \NC 500 \NC \NC 35 \NC \NC 175 \NC \NR
150% \NC 500 \NC \NC 30 \NC \NC 150 \NC \NR
151% \NC 500 \NC \NC 25 \NC \NC 125 \NC \NR
152% \NC 500 \NC \NC 20 \NC \NC 100 \NC \NR
153% \stoptabulate
154
155\newtoks         \t_tabl_tabulate_preamble
156\newtoks         \t_tabl_tabulate_before
157\newtoks         \t_tabl_tabulate_after
158\newtoks         \t_tabl_tabulate_bmath
159\newtoks         \t_tabl_tabulate_emath
160\newtoks         \t_tabl_tabulate_font
161\newtoks         \t_tabl_tabulate_settings
162\newtoks         \t_tabl_tabulate_dummy
163\newtoks         \t_tabl_tabulate_every_row
164\newtoks         \t_tabl_tabulate_every_after_row
165\newtoks         \t_tabl_tabulate_every_real_row
166
167\newtoks         \t_tabl_tabulate_initializers_first
168\newtoks         \t_tabl_tabulate_initializers_second
169
170\newinteger      \c_tabl_tabulate_nofauto
171\newinteger      \c_tabl_tabulate_columns
172\newinteger      \c_tabl_tabulate_column
173\newinteger      \c_tabl_tabulate_plines_min
174\newinteger      \c_tabl_tabulate_plines_max
175\newinteger      \c_tabl_tabulate_max_colorcolumn
176\newinteger      \c_tabl_tabulate_max_vrulecolumn
177\newinteger      \c_tabl_tabulate_repeathead
178\newinteger      \c_tabl_tabulate_noflines
179\newinteger      \c_tabl_tabulate_totalnoflines
180\newinteger      \c_tabl_tabulate_minusnoflines
181\newinteger      \c_tabl_tabulate_align
182\newinteger      \c_tabl_tabulate_nofrealrows
183\newinteger      \c_tabl_tabulate_autocolor
184
185\newconditional  \c_tabl_tabulate_nopbreak
186\newconditional  \c_tabl_tabulate_firstflushed
187\newconditional  \c_tabl_tabulate_equal
188\newconditional  \c_tabl_tabulate_split
189\newconditional  \c_tabl_tabulate_automode
190\newconditional  \c_tabl_tabulate_handlepbreak
191\newconditional  \c_tabl_tabulate_autorulespacing
192\newconditional  \c_tabl_tabulate_someamble
193\newconditional  \c_tabl_tabulate_tolerant_break
194\newconditional  \c_tabl_tabulate_splitoff_whitespace
195\newconditional  \c_tabl_tabulate_pwidth_set
196\newconditional  \c_tabl_tabulate_reshape
197\newconditional  \c_tabl_tabulate_no_blank_in_paragraphs % can become always on
198\newconditional  \c_tabl_tabulate_no_interline_space
199
200\c_tabl_tabulate_split                 \conditionaltrue
201\c_tabl_tabulate_handlepbreak          \conditionaltrue
202\c_tabl_tabulate_autorulespacing       \conditionaltrue
203\c_tabl_tabulate_no_blank_in_paragraphs\conditionaltrue
204
205\newdimension    \d_tabl_tabulate_width_p
206\newdimension    \d_tabl_tabulate_width_w
207\newdimension    \d_tabl_tabulate_width
208\newdimension    \d_tabl_tabulate_unit
209\newdimension    \d_tabl_tabulate_height_p_max
210\newdimension    \d_tabl_tabulate_vrulethickness_default
211\newdimension    \d_tabl_tabulate_hrulethickness_default
212\newdimension    \d_tabl_tabulate_hruledashsteps_default
213\newdimension    \d_tabl_tabulate_vrulethickness
214\newdimension    \d_tabl_tabulate_hrulethickness          % not used
215\newdimension    \d_tabl_tabulate_vrulethickness_local
216\newdimension    \d_tabl_tabulate_hrulethickness_local
217\newdimension    \d_tabl_tabulate_hruledashsteps_local
218\newdimension    \d_tabl_tabulate_indent
219\newdimension    \d_tabl_tabulate_splitoff_betweenskip
220\newdimension    \d_tabl_tabulate_margin
221\newcount        \c_tabl_tabulate_step
222
223\newgluespec     \s_tabl_tabulate_pre
224\newgluespec     \s_tabl_tabulate_post
225\newgluespec     \s_tabl_tabulate_first
226\newgluespec     \s_tabl_tabulate_last
227\newgluespec     \s_tabl_tabulate_separator
228
229\newbox          \b_tabl_tabulate
230
231\newconstant     \c_tabl_tabulate_pass
232\newconstant     \c_tabl_tabulate_type
233\newconstant     \c_tabl_tabulate_kind % 1=strong  2=equals
234\newconstant     \c_tabl_tabulate_splitlinemode    \c_tabl_tabulate_splitlinemode\plustwo % \plusone
235\newconstant     \c_tabl_tabulate_colorspan
236\newconstant     \c_tabl_tabulate_localcolorspan
237\newconstant     \c_tabl_tabulate_modus
238
239%newconditional  \c_tabl_pre_is_set
240\newconditional  \c_tabl_post_is_set
241
242\lettonothing    \m_tabl_tabulate_separator_factor  % fraction
243
244\aliasinteger\tabulatesplitlinemode\c_tabl_tabulate_splitlinemode % temp hack, we need an interface
245
246\newtoks         \everytabulatepar           % where used ?
247\newtoks         \everytabulate              % public ?
248
249\permanent\protected\def\tolerantTABLEbreaktrue{\c_tabl_tabulate_tolerant_break\conditionaltrue} % used in styles !
250
251\permanent\def\noftabulaterows{\the\c_tabl_tabulate_noflines} % handy for testing if a table is empty
252
253\installcorenamespace{tabulatebox}
254\installcorenamespace{tabulatesetup}
255\installcorenamespace{tabulatehook}
256\installcorenamespace{tabulatesplit}
257\installcorenamespace{tabulateseparator}
258\installcorenamespace{tabulatecolor}
259\installcorenamespace{tabulateheader}
260\installcorenamespace{tabulatealigning}
261\installcorenamespace{tabulatepreamble}
262\installcorenamespace{tabulatevrule}
263
264\installcorenamespace{tabulatehead}
265\installcorenamespace{tabulatefoot}
266\installcorenamespace{tabulatenext}
267
268\prependtoks
269    \global\c_tabl_tabulate_nofrealrows\zerocount
270\to \t_tabl_tabulate_initializers_first
271
272\prependtoks
273    \global\c_tabl_tabulate_nofrealrows\zerocount
274\to \t_tabl_tabulate_initializers_second
275
276\prependtoks
277    \global\advanceby\c_tabl_tabulate_nofrealrows\plusone
278\to \t_tabl_tabulate_every_real_row
279
280\permanent\def\b_tabl_tabulate_current#1%
281  {\csname\??tabulatebox\number#1\endcsname} % beware, a synonym
282
283\def\tabl_tabulate_initialize_boxes#1%
284  {\scratchcounter#1\relax
285   \tabl_tabulate_initialize_boxes_step}
286
287\def\tabl_tabulate_initialize_boxes_step
288  {\ifnum\scratchcounter>\zerocount
289     \tabl_tabulate_initialize_box\scratchcounter
290     \advanceby\scratchcounter\minusone
291     \expandafter\tabl_tabulate_initialize_boxes_step
292   \fi}
293
294\def\tabl_tabulate_initialize_box#1% also used elsewhere
295  {\ifcsname\??tabulatebox\number#1\endcsname
296     \tabl_tabulate_initialize_box_yes
297   \else
298     \tabl_tabulate_initialize_box_nop#1%
299   \fi}
300
301\def\tabl_tabulate_initialize_box_yes  {\global\setbox\lastnamedcs\emptybox}
302\def\tabl_tabulate_initialize_box_nop#1{\expandafter\newbox\csname\??tabulatebox\number#1\endcsname}
303
304\tabl_tabulate_initialize_boxes{16} % not really needed
305
306% 0 = NC column next   EQ equal column
307% 1 = RC column raw    RQ equal column raw
308% 2 = HC column hook   HQ equal column hook
309
310% [|lg{.}|] => \NG 12.34 \NC % old
311% [|lG{.}|] => \NG 12.34 \NC % new
312
313% The tracer is gone as if interfered and I never used it anyway. After all,
314% we can use \showmakleup[vpenalty].
315
316\def\tabl_tabulate_nobreak_inject
317  {\noalign{\tabl_tabulate_break_no}}
318
319\protected\def\tabl_tabulate_hook_check
320  {\ifnum\c_tabl_tabulate_type<\plustwo
321     \glet\tabl_tabulate_hook\tabl_tabulate_hook_nop
322   \else
323     \glet\tabl_tabulate_hook\tabl_tabulate_hook_yes
324   \fi}
325
326\protected\def\tabl_tabulate_setups_check
327  {\begincsname\??tabulatesetup\the\c_tabl_tabulate_column\endcsname}
328
329\let\tabl_tabulate_kooh\relax
330
331\protected\def\tabl_tabulate_entry_before{\ignorespaces\tabl_tabulate_hook}
332\protected\def\tabl_tabulate_entry_after {\unskip\unskip\ifmmode\else\endgraf\fi\tabl_tabulate_kooh}
333
334\protected\def\tabl_tabulate_shaped_par_begin
335  {\dowithnextboxcs\tabl_tabulate_shaped_par_finish\vbox\bgroup}
336
337\def\tabl_tabulate_shaped_par_finish
338  {\clf_doreshapeframedbox\nextbox\relax
339   \ifvmode\unvbox\else\box\fi\nextbox}
340
341\let\tabl_tabulate_shaped_par_end\egroup
342
343\ifdefined\dotagtabulatecell   \else \aliased\let\dotagtabulatecell  \relax \fi
344\ifdefined\dotagtabulatesignal \else \aliased\let\dotagtabulatesignal\relax \fi
345
346\protected\def\tabl_tabulate_check_local_color_first#1#2%
347  {\relax}
348
349\protected\def\tabl_tabulate_check_local_color_second#1#2%
350  {\relax
351   \ifempty\m_tabl_tabulate_color_local
352     \xdef\m_tabl_tabulate_color{#1}%
353   \else
354     \glet\m_tabl_tabulate_color\m_tabl_tabulate_color_local
355     \glettonothing\m_tabl_tabulate_color_local
356   \fi
357   \ifcase\c_tabl_tabulate_localcolorspan
358     \global\c_tabl_tabulate_colorspan#2\relax
359   \else
360     \global\c_tabl_tabulate_colorspan\c_tabl_tabulate_localcolorspan
361     \global\c_tabl_tabulate_localcolorspan\zerocount
362   \fi}
363
364\protected\def\tabl_tabulate_check_local_vrule_thickness#1%
365  {\relax
366   \ifcase\d_tabl_tabulate_vrulethickness_local
367     \global\d_tabl_tabulate_vrulethickness#1\relax
368   \else
369     \global\d_tabl_tabulate_vrulethickness\d_tabl_tabulate_vrulethickness_local
370     \global\d_tabl_tabulate_vrulethickness_local\zeropoint
371   \fi}
372
373\protected\def\tabl_tabulate_check_local_vrule_color_first#1%
374  {\relax}
375
376\protected\def\tabl_tabulate_check_local_vrule_color_second#1%
377  {\relax
378   \ifempty\m_tabl_tabulate_vrule_color_local
379     \xdef\m_tabl_tabulate_vrule_color{#1}%
380   \else
381     \glet\m_tabl_tabulate_vrule_color\m_tabl_tabulate_vrule_color_local
382     \glettonothing\m_tabl_tabulate_vrule_color_local
383   \fi}
384
385\let\tabl_tabulate_check_local_color      \gobbletwoarguments
386\let\tabl_tabulate_check_local_vrule_color\gobbleoneargument
387
388\appendtoks
389    \let\tabl_tabulate_check_local_color      \tabl_tabulate_check_local_color_first
390    \let\tabl_tabulate_check_local_vrule_color\tabl_tabulate_check_local_vrule_color_first
391\to \t_tabl_tabulate_initializers_first
392
393\appendtoks
394    \let\tabl_tabulate_check_local_color      \tabl_tabulate_check_local_color_second
395    \let\tabl_tabulate_check_local_vrule_color\tabl_tabulate_check_local_vrule_color_second
396\to \t_tabl_tabulate_initializers_second
397
398% \protected % we can expand this one
399\def\tabl_tabulate_inject_pre_skip#1%
400  {\ifdim#1>\zeropoint
401     \kern#1\relax % hskip
402   \orelse\ifzero\c_tabl_tabulate_column
403     \ifconditional\c_tabl_tabulate_autorulespacing
404       \ifcase\c_tabl_tabulate_has_rule_spec_first\else
405         \kern\s_tabl_tabulate_first\relax % hskip
406       \fi
407     \fi
408   \fi}
409
410% \protected % we can expand this one
411\def\tabl_tabulate_inject_post_skip#1#2%
412  {\ifdim#1>\zeropoint
413     \kern\ifnum\c_tabl_tabulate_columns=\c_tabl_tabulate_nofcolumns#2\else#1\fi\relax
414   \orelse\ifnum\c_tabl_tabulate_columns=\c_tabl_tabulate_nofcolumns
415     \ifconditional\c_tabl_tabulate_autorulespacing
416       \ifcase\c_tabl_tabulate_has_rule_spec_last\else
417         \kern\s_tabl_tabulate_last\relax % hskip
418       \fi
419     \fi
420   \fi}
421
422\let\tabl_tabulate_hook_b\donothing
423\let\tabl_tabulate_hook_e\donothing
424\let\tabl_tabulate_hook_g\donothing
425\let\tabl_tabulate_hook_G\donothing
426
427\newconditional\c_tabl_use_size
428\newconditional\c_tabl_sparse_skips
429
430\c_tabl_use_size    \conditionaltrue % default per 2022-08-25
431\c_tabl_sparse_skips\conditionaltrue % default per 2022-08-25
432
433% \installtexdirective {tabulateusesize}     {\c_tabl_use_size    \conditionaltrue} {\c_tabl_use_size    \conditionalfalse}
434% \installtexdirective {tabulatesparseskips} {\c_tabl_sparse_skips\conditionaltrue} {\c_tabl_sparse_skips\conditionalfalse}
435
436\def\tabl_tabulate_tag_start
437  {\dostarttaggedchained\t!tabulate\empty\empty\??tabulation}
438
439\def\tabl_tabulate_tag_start_row
440  {\dostarttaggednodetail\t!tabulaterow}
441
442\def\tabl_tabulate_tag_start_cell
443  {\dostarttaggednodetail\t!tabulatecell
444   \dotagtabulatecell}
445
446\def\tabl_tabulate_tag_stop
447  {\dostoptagged}
448
449\def\tabl_tabulate_tag_stop_row
450  {\dostoptagged}
451
452\def\tabl_tabulate_tag_stop_cell
453  {\dostoptagged}
454
455\noaligned\def\tabl_tabulate_disable_tagging
456  {\lettonothing\tabl_tabulate_tag_start
457   \lettonothing\tabl_tabulate_tag_start_row
458   \lettonothing\tabl_tabulate_tag_start_cell
459   \lettonothing\tabl_tabulate_tag_stop
460   \lettonothing\tabl_tabulate_tag_stop_row
461   \lettonothing\tabl_tabulate_tag_stop_cell}
462
463\def\tabl_tabulate_set_preamble_step#1#2% only makes sense for many tabulates
464  {\etoksapp\t_tabl_tabulate_preamble{%
465        % begin of between/initial part
466        \tabl_tabulate_check_local_vrule_thickness\constantdimenargument\d_tabl_tabulate_vrulethickness
467        \tabl_tabulate_check_local_vrule_color\constantemptyargument\m_tabl_tabulate_vrule_color
468        \tabl_tabulate_check_local_color\constantemptyargument\m_tabl_tabulate_color\constantnumberargument\c_tabl_tabulate_colorspan
469        \tabl_tabulate_color_side_right
470        % end of between/initial part
471        \aligntab
472        % begin of left part
473        \tabl_tabulate_column_vrule_inject
474        \tabl_tabulate_color_side_left
475        \tabl_tabulate_inject_pre_skip{\the\dimexpr\s_tabl_tabulate_pre}% get rid of plus
476        \aligncontent % \alignmark\alignmark
477        % end of left part
478        \ifconditional\c_tabl_use_size
479          \tabsize\zeropoint
480        \fi
481        \aligntab
482        % begin of main cell
483        \tabl_tabulate_color_side_both
484        \global\c_tabl_tabulate_colorspan\zerocount
485        \global\c_tabl_tabulate_column\constantnumber\c_tabl_tabulate_columns
486        \tabl_tabulate_hook_g
487        \tabl_tabulate_anchor % new
488        \tabl_tabulate_setups_check % unexpandable
489        \tabl_tabulate_hook_check   % unexpandable
490        \ifzeropt\d_tabl_tabulate_width
491            \ifcase\c_tabl_tabulate_modus\else
492               \c_tabl_tabulate_automode\conditionaltrue
493            \fi
494        \else
495            \ifcase\c_tabl_tabulate_modus
496                \ifconditional\c_tabl_use_size
497                    \tabsize % we could remove one level of grouping
498                \else
499                    \hbox to
500                \fi
501            \else
502                \hsize
503            \fi
504            \the\d_tabl_tabulate_width
505        \fi
506        \bgroup
507            \tabl_tabulate_bbskip
508            \bgroup % we cannot combine the if because a cell may have only one ##
509                \tabl_tabulate_hook_b
510                \c_tabl_tabulate_align\constantnumber\c_tabl_tabulate_align % needed in tag passing
511                \ifempty\m_tabl_tabulate_alignment \else
512                    \spac_align_use_now{\m_tabl_tabulate_alignment}%
513                \fi
514                \noexpand\tabl_tabulate_tag_start_cell
515                \noexpand#1%
516                \ifconditional\c_tabl_tabulate_reshape
517                    \tabl_tabulate_shaped_par_begin
518                \fi
519                \dotagtabulatesignal % empty cells
520                \noexpand\ifnum\noexpand\c_tabl_tabulate_type=\plusone\noexpand\else
521                    \the\t_tabl_tabulate_bmath % maybe later? can interfere with char 0
522                    \the\t_tabl_tabulate_font
523                    \the\t_tabl_tabulate_settings
524                    \the\t_tabl_tabulate_before
525                    \ifempty\m_tabl_tabulate_text_color
526                        \expandafter\gobbleoneargument
527                    \else
528                        \expandafter\colo_helpers_direct_activate
529                    \fi\m_tabl_tabulate_text_color
530                \noexpand\fi
531                % grouping needs to be outside macros (or expandable), nice test
532                % example \NC \string \aligntab \NC which will fail otherwise (mk)
533                \bgroup
534                \tabl_tabulate_hook_G
535                \tabl_tabulate_entry_before
536                \tabl_tabulate_hook_box_begin % might move
537                \aligncontent
538                \tabl_tabulate_hook_box_end   % might move
539                \tabl_tabulate_entry_after
540                \egroup
541                \noexpand\ifnum\noexpand\c_tabl_tabulate_type=\plusone\noexpand\else
542                    \the\t_tabl_tabulate_after
543                    \the\t_tabl_tabulate_emath
544                \noexpand\fi
545                \ifconditional\c_tabl_tabulate_reshape
546                    \tabl_tabulate_shaped_par_end
547                \else
548                \fi
549                \noexpand#2%
550                \tabl_tabulate_hook_e
551            \egroup
552        \egroup
553        % end of main cell
554        \aligntab
555        \ifconditional\c_tabl_use_size
556          \tabsize\zeropoint
557        \fi
558        % begin of right part
559        \noexpand\tabl_tabulate_tag_stop_cell
560        \tabl_tabulate_inject_post_skip
561          {\the\ifconditional\c_tabl_post_is_set\s_tabl_tabulate_post\else\s_tabl_tabulate_last\fi}%
562          {\the\s_tabl_tabulate_post}%
563        \aligncontent % \alignmark\alignmark
564        % end of right part
565   }%
566   \toksapp\t_tabl_tabulate_dummy{\NC}%
567   \s_tabl_tabulate_pre.5\d_tabl_tabulate_unit\relax
568   \ifnum\c_tabl_tabulate_columns<{\c_tabl_tabulate_nofcolumns-\plusone}%
569     \s_tabl_tabulate_post\s_tabl_tabulate_pre
570   \else
571     \s_tabl_tabulate_post\zeroskip
572   \fi
573  %\let\gettabulateexit\dogettabulateexit % still needed ?
574   \d_tabl_tabulate_width\zeropoint
575   %c_tabl_pre_is_set\conditionalfalse
576   \c_tabl_post_is_set\conditionalfalse}
577
578\permanent\protected\def\installtabulatepreambleoption#1#2%
579  {\defcsname\??tabulatepreamble\string#1\endcsname{#2}}%
580
581\installtabulatepreambleoption{x}{\c_tabl_tabulate_align\zerocount
582                                  \tabl_tabulate_set_preamble} % internal
583\installtabulatepreambleoption{l}{\c_tabl_tabulate_align\plusone
584                                  \tabl_tabulate_set_preamble}
585\installtabulatepreambleoption{r}{\c_tabl_tabulate_align\plustwo
586                                  \tabl_tabulate_set_preamble}
587\installtabulatepreambleoption{c}{\c_tabl_tabulate_align\plusthree
588                                  \tabl_tabulate_set_preamble}
589\installtabulatepreambleoption{p}{\tabl_tabulate_set_paragraph}
590\installtabulatepreambleoption{s}{\tabl_tabulate_set_setups}
591\installtabulatepreambleoption{w}{\tabl_tabulate_set_width}
592\installtabulatepreambleoption{f}{\tabl_tabulate_set_font}
593\installtabulatepreambleoption{B}{\t_tabl_tabulate_font{\bf}%
594                                  \tabl_tabulate_set_preamble}
595\installtabulatepreambleoption{I}{\t_tabl_tabulate_font{\it}%
596                                  \tabl_tabulate_set_preamble}
597\installtabulatepreambleoption{S}{\t_tabl_tabulate_font{\sl}%
598                                  \tabl_tabulate_set_preamble}
599\installtabulatepreambleoption{T}{\t_tabl_tabulate_font{\tt}%
600                                  \tabl_tabulate_set_preamble}
601\installtabulatepreambleoption{R}{\t_tabl_tabulate_font{\rm}%
602                                  \tabl_tabulate_set_preamble}
603\installtabulatepreambleoption{m}{\t_tabl_tabulate_bmath{\normalstartimath}%
604                                  \t_tabl_tabulate_emath{\normalstopimath}%
605                                  \tabl_tabulate_set_preamble}
606\installtabulatepreambleoption{M}{\t_tabl_tabulate_bmath{\normalstartimath\forcedisplaymath}%
607                                  \t_tabl_tabulate_emath{\normalstopimath}%
608                                  \tabl_tabulate_set_preamble}
609\installtabulatepreambleoption{h}{\tabl_tabulate_set_hook}
610\installtabulatepreambleoption{b}{\tabl_tabulate_set_before}
611\installtabulatepreambleoption{a}{\tabl_tabulate_set_after}
612\installtabulatepreambleoption{i}{\tabl_tabulate_set_preskip}
613\installtabulatepreambleoption{j}{\tabl_tabulate_set_posskip}
614\installtabulatepreambleoption{k}{\tabl_tabulate_set_preposskip}
615\installtabulatepreambleoption{e}{\toksapp\t_tabl_tabulate_settings{\global\c_tabl_tabulate_equal\conditionaltrue}%
616                                  \tabl_tabulate_set_preamble}
617\installtabulatepreambleoption{g}{\tabl_tabulate_set_align}
618\installtabulatepreambleoption{G}{\tabl_tabulate_set_align_new}
619\installtabulatepreambleoption{.}{\tabl_tabulate_set_align.}
620\installtabulatepreambleoption{,}{\tabl_tabulate_set_align,}
621\installtabulatepreambleoption{C}{\tabl_tabulate_set_color_span}
622\installtabulatepreambleoption{d}{\toksapp\t_tabl_tabulate_settings{\fixedspaces}%
623                                  \tabl_tabulate_set_preamble}
624\installtabulatepreambleoption{ }{\tabl_tabulate_set_preamble}
625\installtabulatepreambleoption{A}{\tabl_tabulate_set_alignment}
626
627%D We no longer deal with \type {~} here but map it onto \type {d} instead. Of
628%D course we could prefix a key with \type {\meaning} instead, which works ok (and
629%D is needed in order to pseudo expand \type {\next}, but is ugly at the same time.
630%D The type {d} stands for digitspace.
631
632%D \starttyping
633%D \installtabulatepreambleoption{~}{...} % see 'd'
634%D \stoptyping
635%D
636%D Also, as there is always a key, we no longer do some after assigment or future
637%D let but just pick up the key.
638
639\installtabulatepreambleoption\relax
640  {} % finished
641
642\def\tabl_tabulate_set_preamble#1%
643  {\ifcsname\??tabulatepreamble\string#1\endcsname
644     \expandafter\expandafter\expandafter\lastnamedcs\expandafter\gobbleoneargument
645   \else
646     \expandafter\tabl_tabulate_set_preamble_nop
647   \fi{#1}}
648
649\def\tabl_tabulate_set_preamble_yes#1%
650  {\csname\??tabulatepreamble\string#1\expandafter\endcsname}
651
652\def\tabl_tabulate_set_preamble_nop#1%
653  {\writestatus{tabulate}{unknown preamble key: #1}%
654   \tabl_tabulate_set_preamble}
655
656\def\tabl_tabulate_set_preskip#1%
657  {%\c_tabl_pre_is_set\conditionaltrue
658   \doifelsenumber{#1}%
659     {\s_tabl_tabulate_pre#1\d_tabl_tabulate_unit\tabl_tabulate_set_preamble  }%
660     {\s_tabl_tabulate_pre.5\d_tabl_tabulate_unit\tabl_tabulate_set_preamble#1}}
661
662\def\tabl_tabulate_set_posskip#1%
663  {\c_tabl_post_is_set\conditionaltrue
664   \doifelsenumber{#1}%
665     {\s_tabl_tabulate_post#1\d_tabl_tabulate_unit\tabl_tabulate_set_preamble  }%
666     {\s_tabl_tabulate_post.5\d_tabl_tabulate_unit\tabl_tabulate_set_preamble#1}}
667
668\def\tabl_tabulate_set_preposskip#1%
669  {%c_tabl_pre_is_set \conditionaltrue
670   \c_tabl_post_is_set\conditionaltrue
671   \doifelsenumber{#1}%
672     {\s_tabl_tabulate_pre#1\d_tabl_tabulate_unit\s_tabl_tabulate_post\s_tabl_tabulate_pre\tabl_tabulate_set_preamble  }%
673     {\s_tabl_tabulate_pre.5\d_tabl_tabulate_unit\s_tabl_tabulate_post\s_tabl_tabulate_pre\tabl_tabulate_set_preamble#1}}
674
675\def\tabl_tabulate_set_setups#1%
676  {\defcsname\??tabulatesetup\the\c_tabl_tabulate_columns\endcsname{\setups[#1]}%
677   \tabl_tabulate_set_preamble}
678
679\def\tabl_tabulate_set_hook#1%
680  {\defcsname\??tabulatehook\the\c_tabl_tabulate_columns\endcsname{#1}%
681   \tabl_tabulate_set_preamble}
682
683% begin of character align plugin
684
685\newconditional\c_tabl_auto_align_mode     % reset later
686\newconditional\c_tabl_auto_align_mode_new % reset later
687
688\def\tabl_tabulate_hook_g % partly expanded
689  {\ifconditional\c_tabl_auto_align_mode
690     \signalcharacteralign\c_tabl_tabulate_column{\c_tabl_tabulate_noflines+\plusone}%
691     \typo_charalign_adapt_font
692   \fi}
693
694\def\tabl_tabulate_hook_G % partly expanded
695  {\ifconditional\c_tabl_auto_align_mode_new
696     \typo_charalign_adapt_font
697     \attribute\aligncharacterattribute\the\attribute\aligncharacterattribute\relax
698   \else
699     \attribute\aligncharacterattribute\attributeunsetvalue
700   \fi}
701
702\def\tabl_tabulate_set_align#1%
703  {\global\c_tabl_auto_align_mode\conditionaltrue
704   \setcharacteralign\c_tabl_tabulate_columns{#1}%
705   \tabl_tabulate_set_preamble}
706
707\def\tabl_tabulate_set_align_new#1%
708  {\global\c_tabl_auto_align_mode_new\conditionaltrue
709   \ifempty{#1}\else\setalignmentcharacter{#1}\fi% todo: check for number or char or ... in lua
710   \tabl_tabulate_set_preamble}
711
712% end of character align plugin
713
714\def\tabl_tabulate_set_before#1%
715  {\t_tabl_tabulate_before{#1}%
716   \tabl_tabulate_set_preamble}
717
718\def\tabl_tabulate_set_after#1%
719  {\t_tabl_tabulate_after{#1}%
720   \tabl_tabulate_set_preamble}
721
722\def\tabl_tabulate_set_font#1%
723  {\t_tabl_tabulate_font{#1}%
724   \tabl_tabulate_set_preamble}
725
726\def\tabl_tabulate_pickup_width
727  {\doifelsenextparenthesis\tabl_tabulate_set_width_indeed\tabl_tabulate_set_preamble}
728
729\def\tabl_tabulate_set_width
730  {\c_tabl_tabulate_pwidth_set\conditionalfalse
731   \c_tabl_tabulate_modus\zerocount
732   \tabl_tabulate_pickup_width}
733
734\def\tabl_tabulate_set_alignment#1%
735  {\edef\m_tabl_tabulate_alignment{#1}%
736   \spac_align_use_later\m_tabl_tabulate_alignment
737   \tabl_tabulate_set_preamble}
738
739\def\tabl_tabulate_set_paragraph
740  {\doifelsenextparenthesis
741     {\c_tabl_tabulate_modus\plusone
742      \c_tabl_tabulate_pwidth_set\conditionaltrue
743      \tabl_tabulate_pickup_width}
744     {\c_tabl_tabulate_modus\plustwo
745      \c_tabl_tabulate_pwidth_set\conditionalfalse
746      \tabl_tabulate_set_preamble}}
747
748% \startbuffer
749%   \toplinebox{\framed[width=3cm,height=2cm]{tufte}}
750% \stopbuffer
751% \starttabulate[|p(fixed)|p|]
752%   \dorecurse{100}{\NC \getbuffer \NC test \par test \par \NC \NR}
753% \stoptabulate
754% \starttabulate[|p(fit)|p|]
755%   \dorecurse{100}{\NC \getbuffer \NC test \par test \par \NC \NR}
756% \stoptabulate
757
758% \starttabulate[|w(top,3cm)|w(top,3cm)|]
759% \NC test \NC test \par test \NC \NR
760% \NC test \NC test \par test \NC \NR
761% \stoptabulate
762%
763% \starttabulate[|w(top,packed,3cm)|w(top,packed,3cm)|]
764% \NC test \NC test \par test \NC \NR
765% \NC test \NC test \par test \NC \NR
766% \stoptabulate
767%
768% \starttabulate[interlinespace=no,format={|w(bottom,3cm)|w(bottom,3cm)|}]
769% \NC test \NC test \par test \NC \NR
770% \NC test \NC test \par test \NC \NR
771% \stoptabulate
772%
773% \starttabulate[format={|w(3cm)|w(3cm)|}]
774% \NC \vtop{\strut test} \NC \vtop{\strut test\par \strut test} \NC \NR
775% \NC \vtop{\strut test} \NC \vtop{\strut test\par \strut test} \NC \NR
776% \stoptabulate
777%
778% \starttabulate[interlinespace=no,format={|w(3cm)|w(3cm)|}]
779% \NC \vtop{\strut test} \NC \vtop{\strut test\par \strut test} \NC \NR
780% \NC \vtop{\strut test} \NC \vtop{\strut test\par \strut test} \NC \NR
781% \stoptabulate
782%
783% \starttabulate[interlinespace=no,format={|w(3cm)|w(3cm)|}]
784% \NC \vbox{\strut test} \NC \vbox{\strut test\par \strut test} \NC \NR
785% \NC \vbox{\strut test} \NC \vbox{\strut test\par \strut test} \NC \NR
786% \stoptabulate
787%
788% \starttabulate[interlinespace=no,format={|w(3cm)|w(3cm)|}]
789% \NC \vtop{\strut test} \NC \vbox{\strut test\par \strut test} \NC \NR
790% \NC \vbox{\strut test} \NC \vtop{\strut test\par \strut test} \NC \NR
791% \stoptabulate
792
793\installcorenamespace{tabulatewidth}
794
795\defcsname\??tabulatewidth\v!fit\endcsname
796  {\c_tabl_tabulate_modus\plusthree}
797
798\defcsname\??tabulatewidth\v!fixed\endcsname
799  {\c_tabl_tabulate_modus\plusthree
800   \c_tabl_tabulate_nopbreak\conditionaltrue}
801
802\defcsname\??tabulatewidth\v!packed\endcsname
803  {\c_tabl_tabulate_no_interline_space\conditionaltrue}
804
805\defcsname\??tabulatewidth\v!auto\endcsname
806  {\c_tabl_tabulate_modus\plusthree\c_tabl_tabulate_reshape\conditionaltrue}
807
808\lettonothing\tabl_tabulate_hook_box
809\lettonothing\tabl_tabulate_hook_box_begin
810\lettonothing\tabl_tabulate_hook_box_end
811
812\defcsname\??tabulatewidth\v!top\endcsname
813  {\def\tabl_tabulate_hook_box_begin{\vtop\bgroup\begstrut}%
814   \def\tabl_tabulate_hook_box_end  {\endstrut\egroup}}
815
816\defcsname\??tabulatewidth\v!bottom\endcsname
817  {\def\tabl_tabulate_hook_box_begin{\vbox\bgroup\begstrut}%
818   \def\tabl_tabulate_hook_box_end  {\endstrut\egroup}}
819
820\def\tabl_tabulate_set_width_step#1%
821  {\ifcsname\??tabulatewidth#1\endcsname
822     \lastnamedcs
823   \else
824     \d_tabl_tabulate_width#1\relax
825   \fi}
826
827\def\tabl_tabulate_set_width_indeed(#1)%
828  {\rawprocesscommacommand[#1]\tabl_tabulate_set_width_step
829   \ifconditional\c_tabl_tabulate_pwidth_set
830     \global\advanceby\d_tabl_tabulate_width_p\d_tabl_tabulate_width % accumulated parwidth
831   \fi
832   \tabl_tabulate_set_preamble}
833
834% done
835
836\def\tabl_tabulate_set_raggedright {\ifnum\c_tabl_tabulate_type=\plusone \else\raggedright \fi}
837\def\tabl_tabulate_set_raggedcenter{\ifnum\c_tabl_tabulate_type=\plusone \else\raggedcenter\fi}
838\def\tabl_tabulate_set_raggedleft  {\ifnum\c_tabl_tabulate_type=\plusone \else\raggedleft  \fi}
839\def\tabl_tabulate_set_notragged   {\ifnum\c_tabl_tabulate_type=\plusone \else\notragged   \fi}
840\def\tabl_tabulate_set_hss         {\ifnum\c_tabl_tabulate_type=\plusone \else\hss         \fi} % never change this to a fill
841
842\def\tabl_tabulate_bskip_raggedright {\tabl_tabulate_bskip\tabl_tabulate_set_raggedright }
843\def\tabl_tabulate_bskip_raggedleft  {\tabl_tabulate_bskip\tabl_tabulate_set_raggedleft  }
844\def\tabl_tabulate_bskip_raggedcenter{\tabl_tabulate_bskip\tabl_tabulate_set_raggedcenter}
845
846\def\tabl_tabulate_set_width_normal
847  {\ifcase\c_tabl_tabulate_align\relax
848     \tabl_tabulate_set_preamble_step\empty                \tabl_tabulate_set_hss \or
849     \tabl_tabulate_set_preamble_step\empty                \tabl_tabulate_set_hss \or
850     \tabl_tabulate_set_preamble_step\tabl_tabulate_set_hss\empty                 \or
851     \tabl_tabulate_set_preamble_step\tabl_tabulate_set_hss\tabl_tabulate_set_hss \fi}
852
853\def\tabl_tabulate_set_width_fixed
854  {\ifcase\c_tabl_tabulate_align\relax
855     \tabl_tabulate_set_preamble_step\tabl_tabulate_bskip             \tabl_tabulate_eskip \or
856     \tabl_tabulate_set_preamble_step\tabl_tabulate_bskip_raggedright \tabl_tabulate_eskip \or
857     \tabl_tabulate_set_preamble_step\tabl_tabulate_bskip_raggedleft  \tabl_tabulate_eskip \or
858     \tabl_tabulate_set_preamble_step\tabl_tabulate_bskip_raggedcenter\tabl_tabulate_eskip \fi}
859
860\def\tabl_tabulate_set_width_auto
861  {\global\advanceby\c_tabl_tabulate_nofauto\plusone
862   \ifcase\c_tabl_tabulate_align\relax
863     \tabl_tabulate_set_preamble_step\tabl_tabulate_bskip             \tabl_tabulate_eskip \or
864     \tabl_tabulate_set_preamble_step\tabl_tabulate_bskip_raggedright \tabl_tabulate_eskip \or
865     \tabl_tabulate_set_preamble_step\tabl_tabulate_bskip_raggedleft  \tabl_tabulate_eskip \or
866     \tabl_tabulate_set_preamble_step\tabl_tabulate_bskip_raggedcenter\tabl_tabulate_eskip \fi}
867
868\def\tabl_tabulate_set_width_simple
869  {\tabl_tabulate_set_preamble_step\tabl_tabulate_xbskip\tabl_tabulate_xeskip}
870
871% \def\tabl_tabulate_set_color_span#1#2%
872%   {\xdef\m_tabl_tabulate_color{#2}%
873%    \global\c_tabl_tabulate_colorspan\if#1L\plusone\orelse\if#1M\plustwo\orelse\if#1R\plusthree\else\zerocount\fi\relax
874%    \tabl_tabulate_set_preamble}
875
876\installcorenamespace{tabulatecolorspec}
877
878\defcsname\??tabulatecolorspec C\endcsname#1{\xdef\m_tabl_tabulate_color     {#1}\global\c_tabl_tabulate_colorspan\zerocount}
879\defcsname\??tabulatecolorspec L\endcsname#1{\xdef\m_tabl_tabulate_color     {#1}\global\c_tabl_tabulate_colorspan\plusone  }
880\defcsname\??tabulatecolorspec M\endcsname#1{\xdef\m_tabl_tabulate_color     {#1}\global\c_tabl_tabulate_colorspan\plustwo  }
881\defcsname\??tabulatecolorspec R\endcsname#1{\xdef\m_tabl_tabulate_color     {#1}\global\c_tabl_tabulate_colorspan\plusthree}
882\defcsname\??tabulatecolorspec T\endcsname#1{\xdef\m_tabl_tabulate_text_color{#1}}
883
884\def\tabl_tabulate_set_color_span#1#2%
885  {\csname\??tabulatecolorspec#1\endcsname{#2}%
886   \tabl_tabulate_set_preamble}
887
888\def\tabl_tabulate_set_vrule_command#1%
889  {\doifelsenumber{#1}
890     {\global\d_tabl_tabulate_vrulethickness#1\d_tabl_tabulate_vrulethickness_default}
891     {\xdef\m_tabl_tabulate_vrule_color{#1}}}
892
893\permanent\protected\def\tabl_tabulate_set_entry#1#2% rulespec template
894  {\c_tabl_tabulate_align\v_tabl_tabulate_align
895   \c_tabl_tabulate_modus\zerocount
896   \c_tabl_tabulate_pwidth_set\conditionalfalse
897   \c_tabl_tabulate_reshape\conditionalfalse
898   %c_tabl_pre_is_set\conditionalfalse
899   \c_tabl_post_is_set\conditionalfalse
900   \t_tabl_tabulate_before\emptytoks
901   \t_tabl_tabulate_after\emptytoks
902   \t_tabl_tabulate_bmath\emptytoks
903   \t_tabl_tabulate_emath\emptytoks
904   \t_tabl_tabulate_font\emptytoks
905   \t_tabl_tabulate_settings\emptytoks
906   \glettonothing\m_tabl_tabulate_alignment
907   \glettonothing\m_tabl_tabulate_color
908   \glettonothing\m_tabl_tabulate_text_color
909   \glettonothing\m_tabl_tabulate_vrule_color
910   \glettonothing\tabl_tabulate_hook_box
911   \global\c_tabl_tabulate_colorspan\zerocount
912   \global\c_tabl_auto_align_mode\conditionalfalse
913   \global\c_tabl_auto_align_mode_new\conditionalfalse
914   \resetalignmentcharacter
915 % \attribute\aligncharacterattribute\attributeunsetvalue
916   \global\advanceby\c_tabl_tabulate_columns\plusone
917   \letcsname\??tabulatesetup\the\c_tabl_tabulate_columns\endcsname\donothing % here ?
918   \ifempty{#1}%
919     \global\d_tabl_tabulate_vrulethickness\zeropoint
920   \else
921     \global\d_tabl_tabulate_vrulethickness\d_tabl_tabulate_vrulethickness_default
922     % the lmtx raw processor handles {} like the normal one so we need to prune
923     \rawprocesscommalist[#1]\tabl_tabulate_set_vrule_command
924   \fi
925   \tabl_tabulate_set_preamble#2\relax\relax % permits i without n
926   \ifcase\c_tabl_tabulate_modus\relax
927     \tabl_tabulate_set_width_normal
928   \or % fixed width
929     \tabl_tabulate_set_width_fixed
930   \or % auto width
931     \tabl_tabulate_set_width_auto
932   \or % simple
933     \tabl_tabulate_set_width_simple
934   \fi}
935
936\permanent\protected\def\tabl_tabulate_set_last_entry#1% rulespec
937  {\glettonothing\m_tabl_tabulate_color
938   \glettonothing\m_tabl_tabulate_vrule_color
939   \ifempty{#1}%
940     \global\d_tabl_tabulate_vrulethickness\zeropoint
941   \else
942     \global\d_tabl_tabulate_vrulethickness\d_tabl_tabulate_vrulethickness_default
943     \rawprocesscommalist[#1]\tabl_tabulate_set_vrule_command
944   \fi
945   \etoksapp\t_tabl_tabulate_preamble{%
946     \tabl_tabulate_check_local_vrule_thickness\constantdimenargument\d_tabl_tabulate_vrulethickness
947     \tabl_tabulate_check_local_vrule_color\constantemptyargument\m_tabl_tabulate_vrule_color
948     \tabl_tabulate_column_vrule_inject}}
949
950\aliased\let\settabulateentry    \tabl_tabulate_set_entry      % used at the lua end
951\aliased\let\settabulatelastentry\tabl_tabulate_set_last_entry % used at the lua end
952
953\newconditional\c_tabl_tabulate_balanced_split
954
955\def\tabl_tabulate_normalize_splitline
956  {\ifconditional\c_tabl_tabulate_balanced_split
957     \boxyoffset\b_tabl_tabulate-\strutdp
958     \ht\b_tabl_tabulate\strutht
959     \dp\b_tabl_tabulate\strutdp
960   \orelse\ifcase\c_tabl_tabulate_splitlinemode
961     % nothing
962   \or
963     \ht\b_tabl_tabulate\strutht
964     \dp\b_tabl_tabulate\strutdp
965   \or
966     \ifdim\ht\b_tabl_tabulate<\strutht
967       \ht\b_tabl_tabulate\strutht
968     \fi
969     \ifdim\dp\b_tabl_tabulate<\strutdp
970       \dp\b_tabl_tabulate\strutdp
971     \fi
972   \fi}
973
974\def\tabl_tabulate_whitespace
975  {\ifdim\d_tabl_tabulate_splitoff_betweenskip>\zeropoint
976     \ifconditional\c_tabl_tabulate_balanced_split
977       \enablealignskips
978       \noalign \s!attr \alignskipattribute\plusone{}% becomes a vskip via callback
979     \else
980       \vskip\d_tabl_tabulate_splitoff_betweenskip
981     \fi
982   \fi
983   \global\d_tabl_tabulate_splitoff_betweenskip\zeropoint}
984
985\def\tabl_tabulate_check_whitespace
986  {\setbox\scratchbox\vpack
987     {\splitdiscards
988      \unskip
989      \ifdim\lastskip>\d_tabl_tabulate_splitoff_betweenskip
990        \global\d_tabl_tabulate_splitoff_betweenskip\lastskip
991      \fi}}
992
993% see bruce's test file for variant that is template driven, could be an option
994% to a tabulate
995
996\installtexdirective
997  {tabulate.linenumbers}
998  {\def\tabl_tabulate_check_linenumbers{\page_postprocessors_linenumbers_deepbox\b_tabl_tabulate}}
999  {\let\tabl_tabulate_check_linenumbers\relax}
1000
1001\let\tabl_tabulate_check_linenumbers\relax
1002
1003\def\tabl_tabulate_splitoff_box
1004  {\dontcomplain
1005   \ifconditional\c_tabl_tabulate_balanced_split
1006     \setbox\b_tabl_tabulate\vbalancedbox\b_tabl_tabulate_current\c_tabl_tabulate_column
1007     \ifdim\d_tabl_tabulate_splitoff_betweenskip<\zeropoint
1008        % whitespace next to content
1009     \orelse\ifgluelineinbox\b_tabl_tabulate
1010        \global\d_tabl_tabulate_splitoff_betweenskip \lineheight % always the same
1011     \else
1012        \global\d_tabl_tabulate_splitoff_betweenskip-\lineheight % blocks
1013     \fi
1014   \else
1015     \setbox\b_tabl_tabulate\vsplit\b_tabl_tabulate_current\c_tabl_tabulate_column upto \lineheight % % % global ? % % %
1016     \ifconditional\c_tabl_tabulate_splitoff_whitespace
1017       \tabl_tabulate_check_whitespace
1018     \fi
1019   \fi
1020   \tabl_tabulate_color_repeat % needs to end up in a cell
1021   \setbox\b_tabl_tabulate\hpack to \wd\b_tabl_tabulate
1022     {\hss
1023      \tabl_tabulate_hook_yes{\box\b_tabl_tabulate}%
1024      \hss}%
1025   \tabl_tabulate_normalize_splitline
1026   \tabl_tabulate_check_linenumbers
1027   \box\b_tabl_tabulate}
1028
1029\protected\def\tabl_tabulate_hook_nop
1030  {}
1031
1032\let\tabl_tabulate_hook\tabl_tabulate_hook_nop
1033
1034\def\tabl_tabulate_hook_yes{\begincsname\??tabulatehook\the\c_tabl_tabulate_column\endcsname}
1035
1036\newinteger\c_tabl_tabulate_height_p_max_lines
1037
1038\def\tabl_tabulate_pheight_reset
1039  {\global\c_tabl_tabulate_plines_min\plusone
1040   \iftrue
1041     \global\c_tabl_tabulate_plines_max\c_tabl_tabulate_height_p_max_lines
1042   \orelse\ifdim\d_tabl_tabulate_height_p_max>\zeropoint
1043     \getnoflines\d_tabl_tabulate_height_p_max
1044     \global\c_tabl_tabulate_plines_max\noflines
1045   \else
1046     \global\c_tabl_tabulate_plines_max\zerocount
1047   \fi
1048   \global\d_tabl_tabulate_height_p_max\zeropoint
1049   \global\c_tabl_tabulate_height_p_max_lines\zerocount}
1050
1051% \def\tabl_tabulate_pheight_set
1052%   {\scratchdimen\ht\b_tabl_tabulate_current\c_tabl_tabulate_column\relax
1053%    \ifdim\scratchdimen>\d_tabl_tabulate_height_p_max
1054%      \global\d_tabl_tabulate_height_p_max\scratchdimen
1055%    \fi
1056%    \scratchcounter\noflinesinbox\b_tabl_tabulate_current\c_tabl_tabulate_column\relax
1057%    \ifnum\scratchcounter>\c_tabl_tabulate_height_p_max_lines
1058%      \global\c_tabl_tabulate_height_p_max_lines\scratchcounter
1059%    \fi}
1060
1061%D \starttyping
1062%D \starttabulate[|p|p|]
1063%D \NC \showboxes \samplefile{ward}\blank\samplefile{knuth}\blank\samplefile{tufte}
1064%D \NC \showboxes \samplefile{ward}\blank\samplefile{tufte}\blank\samplefile{knuth}
1065%D \NC \NR
1066%D \NC \showboxes \dorecurse{6}{\samplefile{ward}\par}
1067%D \NC \showboxes \dorecurse{4}{\samplefile{tufte}\par}
1068%D \NC \NR
1069%D \stoptabulate
1070%D \stoptyping
1071
1072\newdimension\d_tabl_tabulate_spacing_wd
1073
1074\installtextracker
1075  {tabulate.spacing}
1076  {\d_tabl_tabulate_spacing_wd\emwidth}
1077  {\d_tabl_tabulate_spacing_wd\zeropoint}
1078
1079\def\tabl_tabulate_pheight_set
1080  {\scratchdimen\ht\b_tabl_tabulate_current\c_tabl_tabulate_column\relax
1081   \ifdim\scratchdimen>\d_tabl_tabulate_height_p_max
1082     \global\d_tabl_tabulate_height_p_max\scratchdimen
1083   \fi
1084   \ifconditional\c_tabl_tabulate_balanced_split
1085     \gluetolinesinbox\b_tabl_tabulate_current\c_tabl_tabulate_column
1086        \d_tabl_tabulate_spacing_wd \strutht \strutdp
1087     \balancevsize     \lineheight
1088     \balancetolerance \plustenthousand
1089     \balancetopskip   \strutht
1090     \balancebottomskip\strutdp
1091     \global\setbox\b_tabl_tabulate_current\c_tabl_tabulate_column
1092       \vbalance\b_tabl_tabulate_current\c_tabl_tabulate_column
1093     \relax
1094   \fi
1095   \scratchcounter\noflinesinbox\b_tabl_tabulate_current\c_tabl_tabulate_column\relax
1096   \ifnum\scratchcounter>\c_tabl_tabulate_height_p_max_lines
1097     \global\c_tabl_tabulate_height_p_max_lines\scratchcounter
1098   \fi}
1099
1100% \def\tabl_tabulate_pbreak_inject
1101%   {\ifconditional\c_tabl_tabulate_handlepbreak
1102%      \ifconditional\c_tabl_tabulate_nopbreak
1103%        \tabl_tabulate_nobreak_inject
1104%      \orelse\ifnum\c_tabl_tabulate_plines_max>\plusone
1105%        \ifnum\c_tabl_tabulate_plines_min=\plusone
1106%          \tabl_tabulate_nobreak_inject
1107%        \fi
1108%        \global\advanceby\c_tabl_tabulate_plines_min\plusone
1109%        \ifnum\c_tabl_tabulate_plines_min=\c_tabl_tabulate_plines_max\relax
1110%          \tabl_tabulate_nobreak_inject
1111%        \fi
1112%      \fi
1113%    \fi}
1114
1115\def\tabl_tabulate_pbreak_inject
1116  {\ifconditional\c_tabl_tabulate_handlepbreak
1117     \ifconditional\c_tabl_tabulate_nopbreak
1118       \ifnum\c_tabl_tabulate_plines_max=\plusone
1119         \tabl_tabulate_break_no
1120       \else
1121         \tabl_tabulate_break_allow
1122       \fi
1123     \orelse\ifnum\c_tabl_tabulate_plines_max>\plusone
1124       \ifnum\c_tabl_tabulate_plines_min=\plusone
1125         \directvpenalty\c_tabl_club_penalty
1126       \fi
1127       \global\advanceby\c_tabl_tabulate_plines_min\plusone
1128       \ifnum\c_tabl_tabulate_plines_min=\c_tabl_tabulate_plines_max\relax
1129         \directvpenalty\c_tabl_widow_penalty
1130       \fi
1131     \fi
1132   \fi}
1133
1134\def\tabl_tabulate_pbreak_check
1135  {\noalign\bgroup
1136     \tabl_tabulate_pbreak_inject
1137     \ifconditional\c_tabl_tabulate_balanced_split
1138       \tabl_tabulate_whitespace
1139     \orelse\ifconditional\c_tabl_tabulate_splitoff_whitespace
1140       \tabl_tabulate_whitespace
1141     \fi
1142   \egroup}
1143
1144%D \startbuffer
1145%D \starttabulate[|c|p|p|]
1146%D \NC \bf Alpha \NC \bf Beta        \NC \bf Gamma          \NC\NR
1147%D \NC 1         \NC right indeed    \NC definitely wrong   \NC\NR
1148%D \NC 2         \NC \thinrules[n=3] \NC \thinrules[n=3]    \NC\NR
1149%D \NC 3         \NC oh yes          \NC simply no          \NC\NR
1150%D \NC 4         \NC very true       \NC as false as can be \NC\NR
1151%D \NC 5         \NC \thinrules[n=5] \NC \thinrules[n=5]    \NC\NR
1152%D \NC 6         \NC \thinrules[n=3] \NC \thinrules[n=4]    \NC\NR
1153%D \stoptabulate
1154%D \stopbuffer
1155%D
1156%D \typebuffer {\tracetabulatetrue\getbuffer}
1157%D
1158%D \startbuffer
1159%D \starttabulate[|c|p|p|]
1160%D \NC \bf Alpha \NC \bf Beta        \NC \bf Gamma          \NC\NR
1161%D \NC 1         \NC right indeed    \NC definitely wrong   \NC\NR
1162%D \NC 2         \NC oh yes          \NC simply no          \NC\NR
1163%D \NC 3         \NC very true       \NC as false as can be \NC\NR
1164%D \NC 4         \NC the whole truth \NC but the truth      \NC\NR
1165%D \stoptabulate
1166%D \stopbuffer
1167%D
1168%D \typebuffer {\tracetabulatetrue\getbuffer}
1169
1170%D Because we want to be compatible we use an indirect way to implement the
1171%D definers. The next examples demonstrate the difference:
1172%D
1173%D \starttyping
1174%D \definetabulate[test][|l|c|r|]
1175%D \definetabulate[test][two][|r|c|l|]
1176%D
1177%D \definetabulation[more][format={|l|c|r|}]
1178%D \definetabulation[more:two][format={|r|c|l|}]
1179%D
1180%D \starttest
1181%D \NC t \NC t \NC t \NC \NR
1182%D \NC te \NC te \NC te \NC \NR
1183%D \NC tes \NC tes \NC tes \NC \NR
1184%D \NC test \NC test \NC test \NC \NR
1185%D \stoptest
1186%D
1187%D \starttest[two]
1188%D \NC t \NC t \NC t \NC \NR
1189%D \NC te \NC te \NC te \NC \NR
1190%D \NC tes \NC tes \NC tes \NC \NR
1191%D \NC test \NC test \NC test \NC \NR
1192%D \stoptest
1193%D \startmore
1194%D \NC t \NC t \NC t \NC \NR
1195%D \NC te \NC te \NC te \NC \NR
1196%D \NC tes \NC tes \NC tes \NC \NR
1197%D \NC test \NC test \NC test \NC \NR
1198%D \stopmore
1199%D
1200%D \startmore[two]
1201%D \NC t \NC t \NC t \NC \NR
1202%D \NC te \NC te \NC te \NC \NR
1203%D \NC tes \NC tes \NC tes \NC \NR
1204%D \NC test \NC test \NC test \NC \NR
1205%D \stopmore
1206%D \stoptyping
1207
1208\installcorenamespace {tabulation}
1209
1210\installcommandhandler \??tabulation {tabulation} \??tabulation
1211
1212\setuptabulation
1213  [\c!unit=1em,
1214   EQ={:},
1215   \c!format={|l|p|},
1216   \c!frame=\v!off,
1217  %\c!bodyfont=,
1218   \c!rule=\v!normal,
1219  %\c!rulecolor=,
1220   \c!rulethickness=\linewidth,
1221  %\c!inner=,
1222   \c!before=\blank,
1223   \c!after=\blank,
1224   \c!distance={\v!depth,\v!medium},
1225   \c!align=\v!normal,
1226   \c!margin=\!!zeropoint,
1227   \c!split=\v!auto,
1228   \c!header=\v!yes,
1229   \c!dashstep=.1\emwidth,
1230  %\c!title=,
1231   \c!indenting=\v!no]
1232
1233\permanent\tolerant\protected\def\definetabulate[#1]#*[#S#2]#*[#S#3]%
1234  {\ifarguments
1235     % ignore
1236   \or
1237     % [tag]
1238     \definetabulation[#1][\c!format={|l|p|},\s!check=]%
1239   \or
1240     % [tag] [template]
1241     \definetabulation[#1][\c!format={#2},\s!check=]%
1242   \or
1243     % [tag] [sub] [template]
1244     \ifcsname\namedtabulationhash{#1}\s!check\endcsname \else
1245       \definetabulation[#1][\c!format={#3},\s!check=]%
1246     \fi
1247     \definetabulation[#1:#2][#1][\c!format={#3},\s!check=]%
1248   \fi}
1249
1250\permanent\tolerant\protected\def\setuptabulate[#S#1]#*[#S#2]#*[#S#3]%
1251  {\ifarguments
1252     % ignore
1253   \or
1254     % [tag]
1255     \setuptabulation[#1]%
1256   \or
1257     % [tag] [settings]
1258     \setuptabulation[#1][#2]%
1259   \or
1260     % [tag] [sub] [settings]
1261     \setuptabulation[#1:#2][#3]%
1262   \fi}
1263
1264\appendtoks
1265    \enforced\permanent\protected\edefcsname\e!start       \currenttabulation\endcsname{\tabl_start_defined[\currenttabulation]}%
1266    \enforced\aliased            \letcsname \e!stop        \currenttabulation\endcsname\relax
1267    \mutable                     \letcsname \??tabulatehead\currenttabulation\endcsname\empty
1268    \mutable                     \letcsname \??tabulatefoot\currenttabulation\endcsname\empty
1269\to \everydefinetabulation
1270
1271\aliased  \let\tabulateparameter\tabulationparameter % will stay for a while
1272\permanent\def\currenttabulate  {\currenttabulation} % will stay for a while
1273
1274% Here begins the implementation.
1275
1276\lettonothing\tabl_tabulate_insert_head
1277\lettonothing\tabl_tabulate_insert_body
1278\lettonothing\tabl_tabulate_insert_foot
1279
1280\def\tabl_tabulate_insert_head_content
1281  {\noalign{\global\c_tabl_tabulate_someamble\conditionaltrue}%
1282   \begincsname\??tabulatehead\currenttabulation\endcsname
1283   \noalign{\global\c_tabl_tabulate_someamble\conditionalfalse}}%
1284
1285\def\tabl_tabulate_insert_foot_content
1286  {\noalign{\global\c_tabl_tabulate_someamble\conditionaltrue}%
1287   \begincsname\??tabulatefoot\currenttabulation\endcsname
1288   \noalign{\global\c_tabl_tabulate_someamble\conditionalfalse}}%
1289
1290\def\tabl_tabulate_check_full_content % - needed, else confusion with \c!header
1291  {\ifcsname\??tabulatehead\currenttabulation\endcsname
1292     \ifempty{\lastnamedcs}%
1293       \lettonothing\tabl_tabulate_insert_head
1294     \else
1295       \let\tabl_tabulate_insert_head\tabl_tabulate_insert_head_content
1296     \fi
1297   \else
1298     \lettonothing\tabl_tabulate_insert_head
1299   \fi
1300   \ifcsname\??tabulatefoot\currenttabulation\endcsname
1301     \ifempty{\lastnamedcs}%
1302       \lettonothing\tabl_tabulate_insert_foot
1303     \else
1304       \let\tabl_tabulate_insert_foot\tabl_tabulate_insert_foot_content
1305     \fi
1306   \else
1307     \lettonothing\tabl_tabulate_insert_foot
1308   \fi}
1309
1310\def\tabl_tabulate_insert_content
1311  {\tabl_tabulate_insert_head
1312   \ifcase\c_tabl_tabulate_repeathead \else
1313     \noalign{\penalty\zerocount}% added 7/5/2014 WS mail
1314   \fi
1315   \tabl_tabulate_insert_body
1316   \tabl_tabulate_insert_foot
1317   \tabl_tabulate_remove_funny_line}
1318
1319\def\tabl_tabulate_remove_funny_line
1320  {\ifhmode
1321    %\ifinalignment % needs testing
1322       \strut\crcr
1323       \noalign{\kern-\lineheight}%
1324    %\fi
1325   \fi}
1326
1327% todo: make footer synonym to tail
1328
1329\permanent\protected\defcsname\e!start\v!tabulatehead\endcsname{\doifelsenextoptionalcs\tabl_tabulate_start_head_yes\tabl_tabulate_start_head_nop}
1330\permanent\protected\defcsname\e!start\v!tabulatetail\endcsname{\doifelsenextoptionalcs\tabl_tabulate_start_foot_yes\tabl_tabulate_start_foot_nop}
1331
1332\lettonothing\m_tabl_tabulate_data
1333
1334\def\tabl_tabulate_start_head_yes[#1]%
1335  {\processcontent{\e!stop\v!tabulatehead}\m_tabl_tabulate_data{\letcsname\??tabulatehead#1\endcsname\m_tabl_tabulate_data}}
1336
1337\def\tabl_tabulate_start_foot_yes[#1]%
1338  {\processcontent{\e!stop\v!tabulatetail}\m_tabl_tabulate_data{\letcsname\??tabulatefoot#1\endcsname\m_tabl_tabulate_data}}
1339
1340% \def\tabl_tabulate_start_head_nop{\tabl_tabulate_start_head_yes[\v!tabulate]}
1341% \def\tabl_tabulate_start_foot_nop{\tabl_tabulate_start_foot_yes[\v!tabulate]}
1342
1343\def\tabl_tabulate_start_head_nop{\tabl_tabulate_start_head_yes[]}
1344\def\tabl_tabulate_start_foot_nop{\tabl_tabulate_start_foot_yes[]}
1345
1346\protected\def\tabl_start_defined[#1]%
1347  {\bgroup
1348   \cdef\currenttabulationparent{#1}%
1349   \let\currenttabulation\currenttabulationparent
1350   \ifcstok{\tabulationparameter\c!format}\v!none
1351     % this is special case: we need to define the generic english
1352     % \starttabulate in other interfaces as well
1353     \lettabulationparameter\c!format\tabl_default_format
1354     \expandafter\tabl_start_regular
1355   \else
1356     \expandafter\tabl_start_defined_indeed
1357   \fi}
1358
1359\tolerant\def\tabl_start_defined_indeed[#S#1]#*[#S#2]%
1360  {\ifarguments\or
1361     \ifhastok={#1}%
1362       \setuptabulation[\currenttabulation][#1]%
1363     \else
1364       \cdef\currenttabulation{\currenttabulation:#1}%
1365     \fi
1366   \else
1367     \cdef\currenttabulation{\currenttabulation:#1}%
1368     \setuptabulation[\currenttabulation][#2]%
1369   \fi
1370   \tabl_tabulate_start_building}
1371
1372% \definetabulate[\v!tabulate][|l|p|] % we need to get rid of this one
1373
1374\def\tabl_default_format{|l|p|} % actually format is always set
1375
1376\permanent\protected\defcsname\e!start\v!tabulate\endcsname
1377  {\bgroup % whole thing
1378   \lettonothing\currenttabulationparent
1379   \tabl_start_regular}
1380
1381\tolerant\protected\def\tabl_start_regular[#S#1]#*[#S#2]% [format] | [settings] | [format] [settings] | [settings] [format]
1382  {\let\currenttabulation\currenttabulationparent
1383   \ifempty{#1}%
1384     \ifhaschar={#2}\relax
1385       \setupcurrenttabulation[#2]%
1386     \fi
1387   \orelse\ifhaschar={#1}\relax
1388     \ifempty{#2}\else
1389        \settabulationparameter\c!format{#2}%
1390     \fi
1391     \setupcurrenttabulation[#1]%
1392   \else
1393     \ifempty{#1}\else
1394       \settabulationparameter\c!format{#1}%
1395     \fi
1396     \ifhaschar={#2}\relax
1397       \setupcurrenttabulation[#2]%
1398     \fi
1399   \fi
1400   \tabl_tabulate_start_building}
1401
1402\permanent\letcsname\e!stop\v!tabulate    \endcsname\relax
1403\permanent\letcsname\e!stop\v!tabulatehead\endcsname\relax
1404\permanent\letcsname\e!stop\v!tabulatetail\endcsname\relax
1405
1406\permanent\protected\def\tabl_tabulate_start_ignore % todo when we go frozen
1407  {\em Nested tabulate is not (yet) supported.\relax
1408   \expandafter\ignoreupto\csname\ifconditional\c_tabl_generic stoptabulate\else\e!stop\v!tabulate\fi\endcsname}
1409
1410\appendtoks
1411    \enforced\letcsname\e!start\v!tabulate\endcsname\tabl_tabulate_start_ignore % only the main one
1412\to \everytabulate
1413
1414\defcsname\??tabulatesplit\v!yes   \endcsname{\c_tabl_tabulate_split\conditionaltrue}
1415\defcsname\??tabulatesplit\v!repeat\endcsname{\c_tabl_tabulate_split\conditionaltrue}
1416\defcsname\??tabulatesplit\v!no    \endcsname{\c_tabl_tabulate_split\conditionalfalse}
1417\defcsname\??tabulatesplit\v!auto  \endcsname{\ifinsidefloat\ifinsidesplitfloat\else\c_tabl_tabulate_split\conditionalfalse\fi\fi}
1418
1419% todo: spacing around tabulate when bodyfont is set
1420
1421% \let\tabl_tabulate_inside_before   \relax
1422% \let\tabl_tabulate_inside_after    \relax
1423% \let\tabl_tabulate_inside_inbetween\relax
1424%
1425% \def\tabl_tabulate_outside_before
1426%   {\whitespace
1427%    \tabulationparameter\c!before}
1428%
1429% \def\tabl_tabulate_outside_after
1430%   {\tabulationparameter\c!after}
1431
1432% \showboxes
1433%
1434% \startcombination
1435%     {\insidefloattrue \starttabulate[|||] \NC test \NC test \NC \NR \stoptabulate} {}
1436%     {\insidefloattrue \starttabulate[|||] \NC test \NC test \NC \NR \stoptabulate} {}
1437% \stopcombination
1438%
1439% \startcombination
1440%     {\vbox{\starttabulate[|||] \NC test \NC test \NC \NR \stoptabulate}} {}
1441%     {\vbox{\starttabulate[|||] \NC test \NC test \NC \NR \stoptabulate}} {}
1442% \stopcombination
1443%
1444% \startcombination
1445%     {\starttabulate[|||] \NC test \NC test \NC \NR \stoptabulate} {}
1446%     {\starttabulate[|||] \NC test \NC test \NC \NR \stoptabulate} {}
1447% \stopcombination
1448
1449\let\tabl_tabulate_inside_after     \relax
1450\let\tabl_tabulate_outside_after    \relax
1451\let\tabl_tabulate_inside_inbetween \relax
1452\let\tabl_tabulate_outside_inbetween\relax
1453
1454\protected\def\tabl_tabulate_inside_before
1455  {\ifhmode\par\fi
1456   \ifhmode
1457     \ifinsidesplitfloat
1458       \let\tabl_tabulate_inside_after\relax
1459     \else
1460       \vbox\bgroup
1461       \let\tabl_tabulate_inside_after\egroup
1462     \fi
1463   \else
1464     \let\tabl_tabulate_inside_after\relax
1465   \fi}
1466
1467% \protected\def\tabl_tabulate_outside_before
1468%   {\ifhmode\par\fi
1469%    \ifhmode
1470%      \vbox\bgroup
1471%      \let\tabl_tabulate_outside_after    \egroup
1472%      \let\tabl_tabulate_outside_inbetween\relax
1473%    \orelse\ifinner
1474%      \let\tabl_tabulate_outside_after    \relax
1475%      \let\tabl_tabulate_outside_inbetween\relax
1476%    \else
1477%      \whitespace
1478%      \tabulationparameter\c!before
1479%      \relax
1480%      \let\tabl_tabulate_outside_after    \tabl_tabulate_outside_after_indeed
1481%      \let\tabl_tabulate_outside_inbetween\tabl_tabulate_outside_inbetween_indeed
1482%    \fi}
1483
1484% \def\tabl_tabulate_outside_after_indeed
1485%   {\tabulationparameter\c!after}
1486
1487\def\tabl_tabulate_outside_inbetween_indeed
1488  {\ifempty{\tabulationparameter\c!after}%
1489     \vskip\strutdp
1490     \verticalstrut
1491     \vskip-\struttotal
1492   \fi}
1493
1494\def\tabl_tabulate_inside_inbetween % needs checking
1495  {\ifempty{\tabulationparameter\c!after}%
1496     \vskip\strutdp
1497     \verticalstrut
1498     \vskip-\struttotal
1499   \fi}
1500
1501% This supports \c!n where we have to handle before/after a bit differently:
1502
1503\definerows
1504  [\v!tabulate]
1505  [\c!n=\rowsparameter\c!n,
1506   \c!order=\v!vertical,
1507   \c!before=\tabulationparameter\c!before,
1508   \c!after=\tabulationparameter\c!after]
1509
1510\setuptabulate
1511  [\c!n=\zerocount]
1512
1513\let\tabl_tabulate_outside_stoprows \relax
1514
1515\protected\def\tabl_tabulate_outside_after_yes
1516  {\stoprows} % before/after handled in rows
1517
1518\protected\def\tabl_tabulate_outside_after_nop
1519  {\tabulationparameter\c!after}
1520
1521\protected\def\tabl_tabulate_outside_before
1522  {\ifhmode\par\fi
1523   \ifhmode
1524     \vbox\bgroup
1525     \let\tabl_tabulate_outside_after    \egroup
1526     \let\tabl_tabulate_outside_inbetween\relax
1527   \orelse\ifinner
1528     \let\tabl_tabulate_outside_after    \relax
1529     \let\tabl_tabulate_outside_inbetween\relax
1530   \else
1531     \whitespace
1532     \relax
1533     \ifcase\tabulateparameter\c!n\relax
1534       \tabulationparameter\c!before
1535       \let\tabl_tabulate_outside_after\tabl_tabulate_outside_after_nop % does \c!after
1536     \else
1537       \startrows
1538         [\v!tabulate]
1539         [\c!n=\tabulateparameter\c!n,%
1540          \c!before=\tabulateparameter\c!before,
1541          \c!after=\tabulateparameter\c!after]%
1542       \let\tabl_tabulate_outside_after\tabl_tabulate_outside_after_yes
1543     \fi
1544     \let\tabl_tabulate_outside_inbetween\tabl_tabulate_outside_inbetween_indeed
1545   \fi}
1546
1547\def\tabl_tabulate_outside_after_indeed
1548  {\tabl_tabulate_outside_stoprows_nop
1549   \tabulationparameter\c!after}
1550
1551% till here
1552
1553\newinteger\c_tabl_widow_penalty
1554\newinteger\c_tabl_club_penalty
1555
1556\protected\def\tabl_tabulate_start_building
1557  {\ifinsidefloat
1558     \tabl_tabulate_inside_before
1559   \else
1560     \tabl_tabulate_outside_before
1561   \fi
1562   \bgroup % settings
1563   %
1564   \t_tabl_tabulate_preamble\emptytoks
1565   \t_tabl_tabulate_dummy   \emptytoks
1566   %
1567   \resetcharacteralign
1568   %
1569   \edef\p_distance      {\tabulationparameter\c!distance}%
1570   \edef\p_align         {\tabulationparameter\c!align}%
1571   \edef\p_line          {\tabulationparameter\c!rule}%
1572   \edef\p_rulecolor     {\tabulationparameter\c!rulecolor}%
1573   \edef\p_rulethickness {\tabulationparameter\c!rulethickness}%
1574   \edef\p_bodyfont      {\tabulationparameter\c!bodyfont}%
1575   \edef\p_indenting     {\tabulationparameter\c!indenting}%
1576   \edef\p_blank         {\tabulationparameter\c!blank}%
1577   \edef\p_dashstep      {\tabulationparameter\c!dashstep}%
1578   %
1579   \ifcstok{\tabulationparameter\c!keeptogether}\v!no
1580     \c_tabl_tabulate_tolerant_break\conditionaltrue
1581    %\c_tabl_tabulate_handlepbreak\conditionalfalse
1582   \else
1583     \c_tabl_tabulate_tolerant_break\conditionalfalse
1584    %\c_tabl_tabulate_handlepbreak\conditionaltrue
1585   \fi
1586   %
1587   \ifcstok{\tabulationparameter\c!interlinespace}\v!no
1588     \c_tabl_tabulate_no_interline_space\conditionaltrue
1589   \else
1590     \c_tabl_tabulate_no_interline_space\conditionalfalse
1591   \fi
1592   %
1593   \c_tabl_tabulate_split\conditionaltrue
1594   \begincsname\??tabulatesplit\tabulationparameter\c!split\endcsname
1595   %
1596   \let\m_tabl_tabulate_blank_default\p_blank
1597   %
1598   \d_tabl_tabulate_unit{\tabulationparameter\c!unit}%
1599   \d_tabl_tabulate_margin{\tabulationparameter\c!margin}%
1600   \let\m_tabl_tabulate_vrule_color_default\p_rulecolor
1601   \let\m_tabl_tabulate_hrule_color_default\p_rulecolor
1602   \d_tabl_tabulate_vrulethickness_default\p_rulethickness
1603   \d_tabl_tabulate_hrulethickness_default\p_rulethickness
1604   \d_tabl_tabulate_hruledashsteps_default\p_dashstep
1605   \ifempty\p_bodyfont\else
1606     \switchtobodyfont[\p_bodyfont]%
1607   \fi
1608   \postponenotes % new, to be tested / will be configurable
1609   % otherwise lines are not broken but overlap in funny ways
1610   \c_tabl_widow_penalty\widowpenalty
1611   \c_tabl_club_penalty \clubpenalty
1612   \widowpenalty   \zerocount
1613   \clubpenalty    \zerocount
1614   \brokenpenalty  \zerocount
1615   \widowpenalties \zerocount
1616   \clubpenalties  \zerocount
1617   \brokenpenalties\zerocount
1618   \expand\everytabulate
1619   \usesetupsparameter\tabulationparameter
1620   \tabulationparameter\c!inner % use setups now
1621   \d_tabl_tabulate_indent{\leftskip+\hangindent\ifx\p_indenting\v!yes+\parindent\fi}%
1622   \global\c_tabl_tabulate_column\zerocount
1623   \begingroup
1624   \catcode\hashasciicode\othercatcode
1625   \ifconditional\c_tabl_generic
1626     \expandafter\tabl_tabulate_pickup_generic
1627   \orelse\ifempty\currenttabulationparent
1628     \expandafter\tabl_tabulate_pickup_interfaced
1629   \else
1630     \expandafter\tabl_tabulate_pickup_specific
1631   \fi}
1632
1633\protected\def\tabl_tabulate_pickup_generic
1634   #L\starttabulate
1635   #R\stoptabulate
1636   #1%
1637  {\endgroup
1638   \def\tabl_tabulate_insert_body{#1}%
1639   \tabl_tabulate_process}
1640
1641\protected\def\tabl_tabulate_pickup_indeed#1#2%
1642  {\protected\def\tabl_tabulate_pickup##L#1##R#2##1% indirect needed because otherwise ##L and ##R expand
1643     {\endgroup
1644      \def\tabl_tabulate_insert_body{##1}%
1645      \tabl_tabulate_process}%
1646   \tabl_tabulate_pickup}
1647
1648\protected\def\tabl_tabulate_pickup_interfaced
1649  {\normalexpanded{\tabl_tabulate_pickup_indeed
1650      \expandafter\noexpand\csname\e!start\v!tabulate\endcsname
1651      \expandafter\noexpand\csname\e!stop \v!tabulate\endcsname}}
1652
1653\protected\def\tabl_tabulate_pickup_specific
1654  {\normalexpanded{\tabl_tabulate_pickup_indeed
1655      \expandafter\noexpand\csname\e!start\currenttabulationparent\endcsname
1656      \expandafter\noexpand\csname\e!stop \currenttabulationparent\endcsname}}
1657
1658\permanent\protected\def\tabulateEQ
1659  {\ifconditional\c_tabl_tabulate_firstflushed\else
1660     \dostarttaggedchained\t!ignore\empty\empty\empty
1661     \dostarttaggednodetail\t!ignore
1662     \tabulationparameter{EQ}%
1663     \dostoptagged
1664     \dostoptagged
1665   \fi
1666   \global\c_tabl_tabulate_equal\conditionalfalse}
1667
1668% The next ones will be token registers
1669
1670\let\tabulatenormalpos\relax % hooks, todo
1671\let\tabulateequalpos \relax % hooks, todo
1672
1673% color columns
1674
1675\lettonothing\m_tabl_tabulate_color_previous
1676\lettonothing\m_tabl_tabulate_color
1677\lettonothing\m_tabl_tabulate_text_color
1678\lettonothing\m_tabl_tabulate_color_local
1679\lettonothing\m_tabl_tabulate_vrule_color
1680\lettonothing\m_tabl_tabulate_vrule_color_local
1681\lettonothing\m_tabl_tabulate_vrule_color_default % used local
1682\lettonothing\m_tabl_tabulate_hrule_color_default % used local
1683\lettonothing\m_tabl_tabulate_blank_default
1684
1685\appendtoks
1686    \glettonothing\m_tabl_tabulate_color_previous
1687    \glettonothing\m_tabl_tabulate_color
1688    \glettonothing\m_tabl_tabulate_text_color
1689    \glettonothing\m_tabl_tabulate_color_local
1690    \glettonothing\m_tabl_tabulate_vrule_color
1691    \glettonothing\m_tabl_tabulate_vrule_color_local
1692    \global\d_tabl_tabulate_vrulethickness_local\zeropoint
1693\to \t_tabl_tabulate_every_row
1694
1695\protected\def\tabl_tabulate_color_side_right_second
1696  {\ifempty\m_tabl_tabulate_color_previous \else
1697     \tabl_tabulate_color_set\m_tabl_tabulate_color_previous
1698     \glettonothing\m_tabl_tabulate_color_previous
1699   \fi}
1700
1701\protected\def\tabl_tabulate_color_side_left_second
1702  {\ifempty\m_tabl_tabulate_color \else
1703     \ifcase\c_tabl_tabulate_colorspan
1704     \or
1705       \tabl_tabulate_color_set\m_tabl_tabulate_color
1706     \or
1707       \tabl_tabulate_color_set\m_tabl_tabulate_color
1708     \fi
1709   \fi}
1710
1711\protected\def\tabl_tabulate_color_side_both_second
1712  {\ifempty\m_tabl_tabulate_color \else
1713     \tabl_tabulate_color_set\m_tabl_tabulate_color
1714     \ifcase\c_tabl_tabulate_colorspan
1715       %\glettonothing\m_tabl_tabulate_color_previous
1716     \or
1717       \glettonothing\m_tabl_tabulate_color_previous
1718     \or
1719       \glet\m_tabl_tabulate_color_previous\m_tabl_tabulate_color
1720     \or
1721       \glet\m_tabl_tabulate_color_previous\m_tabl_tabulate_color
1722     \fi
1723   \fi}
1724
1725\let\tabl_tabulate_color_side_right \relax
1726\let\tabl_tabulate_color_side_left  \relax
1727\let\tabl_tabulate_color_side_both  \relax
1728
1729\appendtoks
1730    \let\tabl_tabulate_color_side_right\tabl_tabulate_color_side_right_second
1731    \let\tabl_tabulate_color_side_left \tabl_tabulate_color_side_left_second
1732    \let\tabl_tabulate_color_side_both \tabl_tabulate_color_side_both_second
1733\to \t_tabl_tabulate_initializers_second
1734
1735\def\tabl_tabulate_set_color_column#1% overloaded / todo
1736  {\unskip
1737   \doifelsefastoptionalcheck{\tabl_tabulate_set_color_column_yes#1}{\tabl_tabulate_set_color_column_nop#1}}
1738
1739\def\tabl_tabulate_set_color_column_nop
1740  {\tabl_tabulate_column_normal\zerocount}
1741
1742\def\tabl_tabulate_set_color_column_yes#1[#2]%
1743  {\xdef\m_tabl_tabulate_color_local{#2}%
1744   \tabl_tabulate_column_normal\zerocount#1}
1745
1746% normal columns:
1747
1748\def\tabl_tabulate_column_normal#1#2%
1749  {\unskip
1750   \aligntab
1751   \ifconditional\c_tabl_tabulate_equal\tabulateequalpos\else\tabulatenormalpos\fi
1752   \ifnum\c_tabl_tabulate_column>\c_tabl_tabulate_max_vrulecolumn\else
1753     \tabl_tabulate_column_vrule_setup
1754   \fi
1755   \aligntab
1756   \global\c_tabl_tabulate_kind#1%
1757   \global\c_tabl_tabulate_type#2%
1758   \aligntab}
1759
1760% equal columns
1761
1762\def\tabl_tabulate_column_equal#1#2%
1763  {\unskip
1764   \aligntab
1765   \tabulateequalpos
1766   \aligntab
1767   \global\c_tabl_tabulate_kind#1%
1768   \global\c_tabl_tabulate_type#2%
1769   \aligntab}
1770
1771% ruled columns
1772
1773\def\tabl_tabulate_column_vruled_preset
1774  {\glet\m_tabl_tabulate_vrule_color_local\m_tabl_tabulate_vrule_color_default
1775   \global\d_tabl_tabulate_vrulethickness_local\d_tabl_tabulate_vrulethickness_default}
1776
1777\def\tabl_tabulate_column_vruled#1#2%
1778  {\unskip % 0-n
1779  %\ifnum\c_tabl_tabulate_column=\plusone
1780  %  \global\c_tabl_tabulate_has_rule_spec_first\plusone
1781  %\orelse\ifnum\c_tabl_tabulate_column=\c_tabl_tabulate_nofcolumns
1782  %  \global\c_tabl_tabulate_has_rule_spec_last\plusone
1783  %\fi
1784   \ifnum\c_tabl_tabulate_column>\c_tabl_tabulate_max_vrulecolumn
1785     \global\c_tabl_tabulate_max_vrulecolumn\c_tabl_tabulate_column
1786   \fi
1787   \doifelsefastoptionalcheck{\tabl_tabulate_column_vruled_yes#1#2}{\tabl_tabulate_column_vruled_nop#1#2}}
1788
1789\def\tabl_tabulate_column_vrule_setup
1790  {\begincsname\??tabulatevrule\the\c_tabl_tabulate_column\endcsname}
1791
1792\def\tabl_tabulate_column_vruled_nop
1793  {\gletcsname\??tabulatevrule\the\c_tabl_tabulate_column\endcsname\tabl_tabulate_column_vruled_preset
1794   \tabl_tabulate_column_normal}
1795
1796\def\tabl_tabulate_column_vruled_step#1%
1797  {\doifelsenumber{#1}%
1798     {\global\d_tabl_tabulate_vrulethickness_local#1\d_tabl_tabulate_vrulethickness_default}
1799     {\xdef\m_tabl_tabulate_vrule_color_local{#1}}}
1800
1801\def\tabl_tabulate_column_vruled_yes#1#2[#3]%
1802  {\gdefcsname\??tabulatevrule\the\c_tabl_tabulate_column\endcsname
1803     {\tabl_tabulate_column_vruled_preset
1804      \rawprocesscommalist[#3]\tabl_tabulate_column_vruled_step}%
1805   \tabl_tabulate_column_normal#1#2}
1806
1807\def\tabl_tabulate_vrule_reset
1808  {\ifcase\c_tabl_tabulate_max_vrulecolumn\else
1809     \tabl_tabulate_vrule_reset_indeed
1810   \fi}
1811
1812\def\tabl_tabulate_vrule_reset_indeed
1813  {\localcontrolledloop\zerocount\c_tabl_tabulate_max_vrulecolumn\plusone % start at 0
1814     {\gletcsname\??tabulatevrule\the\currentloopiterator\endcsname\undefined}%
1815   \global\c_tabl_tabulate_max_vrulecolumn\zerocount}
1816
1817\appendtoks
1818    \tabl_tabulate_vrule_reset
1819\to \t_tabl_tabulate_every_after_row
1820
1821\def\tabl_tabulate_column_vruled_normal
1822  {\vrule\s!width\d_tabl_tabulate_vrulethickness\relax}
1823
1824\def\tabl_tabulate_column_vruled_colored
1825  {\dousecolorparameter\m_tabl_tabulate_vrule_color
1826   \vrule\s!width\d_tabl_tabulate_vrulethickness\relax}
1827
1828\protected\def\tabl_tabulate_column_vrule_inject_first
1829  {\ifcase\d_tabl_tabulate_vrulethickness\else
1830     \tabl_tabulate_column_vruled_normal % could be a skip instead
1831   \fi
1832   \global\d_tabl_tabulate_vrulethickness\zeropoint} % nils second one
1833
1834\protected\def\tabl_tabulate_column_vrule_inject_second
1835  {\ifcase\d_tabl_tabulate_vrulethickness
1836   \orelse\ifempty\m_tabl_tabulate_vrule_color
1837     \tabl_tabulate_column_vruled_normal
1838   \else
1839     \tabl_tabulate_column_vruled_colored
1840   \fi
1841   \global\d_tabl_tabulate_vrulethickness\zeropoint} % nils second one
1842
1843\let\tabl_tabulate_column_vrule_inject\relax
1844
1845\appendtoks
1846    \let\tabl_tabulate_column_vrule_inject\tabl_tabulate_column_vrule_inject_first
1847\to \t_tabl_tabulate_initializers_first
1848
1849\appendtoks
1850    \let\tabl_tabulate_column_vrule_inject\tabl_tabulate_column_vrule_inject_second
1851\to \t_tabl_tabulate_initializers_second
1852
1853% auto columns
1854
1855\def\tabl_tabulate_column_inject_auto
1856  {\tabl_tabulate_column_normal\zerocount\zerocount
1857   \ifnum\c_tabl_tabulate_column>\c_tabl_tabulate_columns\relax
1858     \expandafter\NR
1859   \else
1860     \expandafter\ignorepars % \ignorespaces % interferes with the more tricky hooks
1861   \fi}
1862
1863\protected\def\tabl_tabulate_set_quick#1% see \startlegend \startgiven (for the moment still public)
1864  {\enforced\let#1\tabl_tabulate_column_inject_auto
1865   \enforced\let\\\tabl_tabulate_column_inject_auto} % brrr, will go
1866
1867\defcsname\??tabulateseparator\v!blank \endcsname{\s_tabl_tabulate_separator\bigskipamount}
1868\defcsname\??tabulateseparator\v!depth \endcsname{\s_tabl_tabulate_separator\strutdp}
1869\defcsname\??tabulateseparator\v!small \endcsname{\def\m_tabl_tabulate_separator_factor{.25}}
1870\defcsname\??tabulateseparator\v!medium\endcsname{\def\m_tabl_tabulate_separator_factor{.5}}
1871\defcsname\??tabulateseparator\v!big   \endcsname{}
1872\defcsname\??tabulateseparator\v!none  \endcsname{\s_tabl_tabulate_separator\zeroskip\let\m_tabl_tabulate_separator_factor\zerocount}
1873\defcsname\??tabulateseparator\v!grid  \endcsname{\s_tabl_tabulate_separator\zeroskip\let\m_tabl_tabulate_separator_factor\zerocount}
1874
1875\def\tabl_tabulate_column_rule_separator_step#1%
1876  {\ifcsname\??tabulateseparator#1\endcsname
1877     \lastnamedcs
1878   \else
1879     \s_tabl_tabulate_separator#1\relax
1880   \fi}
1881
1882\def\tabl_tabulate_column_rule_separator_inject % can be sped up (will do when used frequently)
1883  {\bgroup
1884   \s_tabl_tabulate_separator\strutdp
1885   \ifempty\p_distance\else
1886     \let\m_tabl_tabulate_separator_factor\plusone
1887     \processcommacommand[\p_distance]\tabl_tabulate_column_rule_separator_step
1888     \s_tabl_tabulate_separator\m_tabl_tabulate_separator_factor\s_tabl_tabulate_separator
1889   \fi
1890   % someamble: footer or header: unfortunately a skip can trigger a page break (weird
1891   % as we have lots of nobreaks)
1892 % \ifconditional\c_tabl_tabulate_someamble\kern\else\vskip\fi\s_tabl_tabulate_separator % new
1893 % \directvspacing{\the\s_tabl_tabulate_separator}% new
1894   \directvskip\s_tabl_tabulate_separator
1895   \egroup}
1896
1897% \starttabulate
1898% \FL[1,2] % linewidthfactor, dashstepfactor
1899% \NC test \NC test and test and test and done \NC \NR
1900% \ML[1,1]
1901% \NC test \NC test and test and test and done \NC \NR
1902% \NC test \NC test and test and test and done \NC \NR
1903% \NC test \NC test and test and test and done \NC \NR
1904% \LL[1,10]
1905% \stoptabulate
1906
1907\lettonothing\m_tabl_tabulate_hrule_color
1908
1909\def\tabl_tabulate_hrule_preset[#1]%
1910  {\glet\m_tabl_tabulate_hrule_color\m_tabl_tabulate_hrule_color_default
1911   \global\d_tabl_tabulate_hrulethickness_local\d_tabl_tabulate_hrulethickness_default
1912   \global\d_tabl_tabulate_hruledashsteps_local\zeropoint
1913   \c_tabl_tabulate_step\zerocount
1914   \ifempty{#1}\else\rawprocesscommalist[#1]\tabl_tabulate_hrule_preset_step\fi}
1915
1916\def\tabl_tabulate_hrule_preset_step#1%
1917  {\ifchknum#1\or
1918     \advanceby\c_tabl_tabulate_step\plusone
1919     \ifcase\c_tabl_tabulate_step\or
1920       \global\d_tabl_tabulate_hrulethickness_local#1\d_tabl_tabulate_hrulethickness_default
1921     \else
1922       \global\d_tabl_tabulate_hruledashsteps_local#1\d_tabl_tabulate_hruledashsteps_default
1923     \fi
1924   \else
1925     \xdef\m_tabl_tabulate_hrule_color{#1}%
1926   \fi}
1927
1928\def\tabl_tabulate_hrule_inject_normal
1929  {\autorule
1930     \s!height.5\d_tabl_tabulate_hrulethickness_local
1931     \s!depth .5\d_tabl_tabulate_hrulethickness_local
1932     \s!left    \d_tabl_tabulate_indent
1933     on         \d_tabl_tabulate_hruledashsteps_local
1934     off        \d_tabl_tabulate_hruledashsteps_local
1935   \relax}
1936
1937% \def\tabl_tabulate_hrule_inject_normal .. messes with prevdepth and needs mode
1938%   {\hrule % running
1939%      \s!height.5\d_tabl_tabulate_hrulethickness_local
1940%      \s!depth .5\d_tabl_tabulate_hrulethickness_local
1941%      \s!left    \d_tabl_tabulate_indent
1942%      on         \d_tabl_tabulate_hruledashsteps_local
1943%      off        \d_tabl_tabulate_hruledashsteps_local
1944%    \relax}
1945
1946\def\tabl_tabulate_hrule_inject_colored
1947  {\dousecolorparameter\m_tabl_tabulate_hrule_color
1948   \tabl_tabulate_hrule_inject_normal}
1949
1950\protected\def\tabl_tabulate_hrule_inject_first
1951  {\ifcase\d_tabl_tabulate_hrulethickness_local\else
1952     \tabl_tabulate_hrule_inject_normal
1953   \fi}
1954
1955\protected\def\tabl_tabulate_hrule_inject_second
1956  {\ifcase\d_tabl_tabulate_hrulethickness_local\else
1957     \ifempty\m_tabl_tabulate_hrule_color
1958       \tabl_tabulate_hrule_inject_normal
1959     \else
1960       \tabl_tabulate_hrule_inject_colored
1961     \fi
1962   \fi}
1963
1964\let\tabl_tabulate_hrule_inject\relax
1965
1966\appendtoks
1967    \let\tabl_tabulate_hrule_inject\tabl_tabulate_hrule_inject_first
1968\to \t_tabl_tabulate_initializers_first
1969
1970\appendtoks
1971    \let\tabl_tabulate_hrule_inject\tabl_tabulate_hrule_inject_second
1972\to \t_tabl_tabulate_initializers_second
1973
1974%D Color:
1975
1976% \starttabulate[||p||]
1977% \NC test \NC test \NC test \NC \NR
1978% \NC test \CC[green] \input tufte  \CC[yellow] test \NC \NR
1979% \NC test \NC test \NC test \NC \NR
1980% \NC test \NC test \NC test \NC \NR
1981% \NC test \NC test \NC test \NC \NR
1982% \NC test \NC test \NC test \NC \NR
1983% \CC[blue] test \CC[red] test \NC test \NC \NR
1984% \NC test \NC test \NC test \NC \NR
1985% \NC test \NC test \NC test \NC \NR
1986% \NC test \NC test \NC test \NC \NR
1987% \NC test \NC test \CC[gray] test \NC \NR
1988% \NC test \NC test \NC test \NC \NR
1989% \NC test \NC test \NC test \NC \NR
1990% \CC[blue] test \NC test \NC test \NC \NR
1991% \NC test \NC test \NC test \NC \NR
1992% \NC test \NC test \CC[magenta] test \NC \NR
1993% \NC test \NC test \NC test \NC \NR
1994% \NC test \CC[cyan] \dorecurse{10}{\input ward }\NC test \NC \NR
1995% \NC test \NC test \NC test \NC \NR
1996% \NC test \CC[yellow] test \NC test \NC \NR
1997% \stoptabulate
1998
1999\protected\def\tabl_tabulate_color_set#1% we could store the attributes at the cost of a lua call
2000  {\begingroup
2001   \clf_enablebackgroundalign % was \node_backgrounds_align_initialize
2002   \glet\tabl_tabulate_color_repeat\tabl_tabulate_color_repeat_second
2003   \ifnum\c_tabl_tabulate_column>\c_tabl_tabulate_max_colorcolumn
2004     \global\c_tabl_tabulate_max_colorcolumn\c_tabl_tabulate_column
2005   \fi
2006   \xdefcsname\??tabulatecolor\the\c_tabl_tabulate_column\endcsname{#1}%
2007   \hpack \thealignbackgroundcolorattr{#1}{}% pack ?
2008   \endgroup}
2009
2010\def\tabl_tabulate_color_repeat_second % for split off lines
2011  {\begingroup
2012   \scratchcounter{\c_tabl_tabulate_column-\plusone}% ugly !
2013   \ifcsname\??tabulatecolor\the\scratchcounter\endcsname
2014   % \hbox \thealignbackgroundcolorattr{\csname\??tabulatecolor\the\scratchcounter\endcsname}{}% pack ?
2015     \hpack \expandafter\thealignbackgroundcolorattr\expandafter{\lastnamedcs}{}% pack ?
2016   \fi
2017   \endgroup}
2018
2019\let\tabl_tabulate_color_repeat\relax
2020
2021\appendtoks
2022    \let\tabl_tabulate_color_repeat\relax
2023\to \everytabulate
2024
2025\def\tabl_tabulate_color_reset
2026  {\ifcase\c_tabl_tabulate_max_colorcolumn\else
2027     \tabl_tabulate_color_reset_indeed
2028   \fi}
2029
2030% \def\tabl_tabulate_color_reset_indeed
2031%   {\dofastloopcs\c_tabl_tabulate_max_colorcolumn\tabl_tabulate_color_reset_step}
2032%
2033% \def\tabl_tabulate_color_reset_step % undefined or empty?
2034%   {\gletcsname\??tabulatecolor\number\fastloopindex\endcsname\undefined}
2035
2036\def\tabl_tabulate_color_reset_indeed
2037  {\localcontrolledloop\zerocount\c_tabl_tabulate_max_colorcolumn\plusone % start at 1
2038     {\gletcsname\??tabulatecolor\the\currentloopiterator\endcsname\undefined}%
2039   \global\c_tabl_tabulate_max_colorcolumn\zerocount} % why not like vrule?
2040
2041\appendtoks
2042    \tabl_tabulate_color_reset
2043\to \t_tabl_tabulate_every_after_row
2044
2045% \def\tabl_tabulate_register_par_options_indeed
2046%   {\iftrialtypesetting \else
2047%      \registerparoptions
2048%      \ifinsidefloat
2049%        % that is, an unbreakable one
2050%        \glettonothing\tabl_tabulate_register_par_options
2051%      \else
2052%        % unsafe in crossing pages, at each b...
2053%        % \glettonothing\tabl_tabulate_register_par_options
2054%      \fi
2055%    \fi}
2056%
2057% \appendtoks
2058%     \glet\tabl_tabulate_register_par_options\tabl_tabulate_register_par_options_indeed
2059% \to \everytabulate
2060
2061\def\tabl_tabulate_register_par_options_first % maybe track here if needed
2062  {}
2063
2064\def\tabl_tabulate_register_par_options_second
2065  {\registerparoptions
2066   \ifinsidefloat
2067     % that is, an unbreakable one
2068     \glettonothing\tabl_tabulate_register_par_options
2069   \else
2070     % unsafe in crossing pages, at each b...
2071     % \glettonothing\tabl_tabulate_register_par_options
2072   \fi}
2073
2074\let\tabl_tabulate_register_par_options\relax
2075
2076\appendtoks
2077    \let\tabl_tabulate_register_par_options\tabl_tabulate_register_par_options_first
2078\to \t_tabl_tabulate_initializers_first
2079
2080\appendtoks
2081    \let\tabl_tabulate_register_par_options\tabl_tabulate_register_par_options_second
2082\to \t_tabl_tabulate_initializers_second
2083
2084\appendtoks
2085    \tabl_tabulate_register_par_options
2086\to \t_tabl_tabulate_every_row
2087
2088\def\tabl_tabulate_flush_indent_indeed
2089  {\hbox to \d_tabl_tabulate_indent % pack ?
2090     {% we now have a local hsize, and since we want to
2091      % register positional info (i.e. real hsizes) we
2092      % need to reconstitute the original hsize
2093      \advanceby\hsize\d_tabl_tabulate_indent
2094      % this is indeed rather messy and took a few hours
2095      % to dis/uncover
2096      \expand\t_tabl_tabulate_every_row
2097      \hss}}
2098
2099\def\tabl_tabulate_flush_indent
2100  {\ifzero\c_tabl_tabulate_column
2101     \tabl_tabulate_flush_indent_indeed
2102   \fi}
2103
2104\def\tabl_tabulate_digits{\digits}
2105
2106%D Beware, we cannot use \type {\protected} on \type {\HL} cum suis, since \TEX's
2107%D hard coded noalign lookahead fails on it! I mistakenly added this for a while.
2108%D Well, this is no longer true in \LMTX.
2109
2110\defcsname\??tabulatealigning\v!normal\endcsname{0}
2111\defcsname\??tabulatealigning\v!right \endcsname{1}
2112\defcsname\??tabulatealigning\v!left  \endcsname{2}
2113\defcsname\??tabulatealigning\v!middle\endcsname{3}
2114
2115\defcsname\??tabulateheader\v!repeat\endcsname{\plusone}
2116\defcsname\??tabulateheader\v!text  \endcsname{\plustwo}
2117
2118\protected\def\tabl_tabulate_bskip_first {\setbox\b_tabl_tabulate\vbox\bgroup\glet\tabl_tabulate_hook\tabl_tabulate_hook_nop}
2119\protected\def\tabl_tabulate_eskip_first {\par\egroup\glet\tabl_tabulate_hook\tabl_tabulate_hook_yes}
2120\protected\def\tabl_tabulate_xbskip_first{\hpack\bgroup\vbox\bgroup\glet\tabl_tabulate_hook\tabl_tabulate_hook_nop}
2121\protected\def\tabl_tabulate_xeskip_first{\par\egroup\egroup\glet\tabl_tabulate_hook\tabl_tabulate_hook_yes}
2122
2123\let\tabl_tabulate_bbskip\relax
2124\let\tabl_tabulate_eeskip\relax
2125\let\tabl_tabulate_bskip \relax
2126\let\tabl_tabulate_eskip \relax
2127\let\tabl_tabulate_xbskip\relax
2128\let\tabl_tabulate_xeskip\relax
2129
2130\appendtoks
2131   \let\tabl_tabulate_bbskip\relax
2132  %\let\tabl_tabulate_eeskip\relax % adapted by bskip
2133   \let\tabl_tabulate_bskip \tabl_tabulate_bskip_first
2134   \let\tabl_tabulate_eskip \tabl_tabulate_eskip_first
2135   \let\tabl_tabulate_xbskip\tabl_tabulate_xbskip_first
2136   \let\tabl_tabulate_xeskip\tabl_tabulate_xeskip_first
2137\to \t_tabl_tabulate_initializers_first
2138
2139\def\tabl_tabulate_baselinecorrection % keep an eye on this one
2140  {\def\dobaselinecorrection{\vskip{-\prevdepth+\strutdp+\strutdp}}% todo: mkiv
2141   \baselinecorrection}
2142
2143% some hack to prevent an allowbreak ... actually we could set up a system then
2144% that is dealt with atthe lua end in the skip handler: turn penalties with attributes
2145% values into other penalties that get removed
2146
2147\installcorenamespace{tabulatenobreak}
2148
2149\def\tabl_tabulate_break_allow{\directvpenalty\zerocount}
2150\def\tabl_tabulate_break_maybe{\directvpenalty\zerocount}
2151\def\tabl_tabulate_break_no   {\directvpenalty\plustenthousand} % ,order:2}}
2152
2153\let\tabl_tabulate_break_state_set       \relax
2154\let\tabl_tabulate_break_state_reset     \relax
2155\let\tabl_tabulate_break_state_allowbreak\tabl_tabulate_break_maybe
2156
2157% so far
2158
2159\permanent\protected\def\tabl_tabulate_VL_first{\tabl_tabulate_column_vruled\zerocount\zerocount}
2160\permanent\protected\def\tabl_tabulate_NC_first{\tabl_tabulate_column_normal\zerocount\zerocount}
2161\permanent\protected\def\tabl_tabulate_RC_first{\tabl_tabulate_column_normal\zerocount\plusone}
2162\permanent\protected\def\tabl_tabulate_HC_first{\tabl_tabulate_column_normal\zerocount\plustwo}
2163\permanent\protected\def\tabl_tabulate_EQ_first{\tabl_tabulate_column_equal \plustwo  \zerocount}
2164\permanent\protected\def\tabl_tabulate_RQ_first{\tabl_tabulate_column_equal \zerocount\plusone}
2165\permanent\protected\def\tabl_tabulate_HQ_first{\tabl_tabulate_column_equal \zerocount\plustwo}
2166
2167\permanent\protected\def\tabl_tabulate_NG_first{\tabl_tabulate_column_normal\zerocount\zerocount}
2168\permanent\protected\def\tabl_tabulate_NN_first{\tabl_tabulate_column_normal\zerocount\zerocount\tabl_tabulate_digits} % new, undocumented, test first
2169\permanent\protected\def\tabl_tabulate_ND_first{\tabl_tabulate_column_normal\zerocount\zerocount\tabl_tabulate_digits} % same, for old times sake
2170
2171\permanent\protected\def\tabl_tabulate_NR_first {\tabl_tabulate_NR_common\conditionaltrue \tabl_tabulate_check_penalties} % next row
2172\permanent\protected\def\tabl_tabulate_NB_first {\tabl_tabulate_NR_common\conditionaltrue \tabl_tabulate_nobreak_inject } % next row no break
2173
2174\permanent\protected\def\tabl_tabulate_NR_second{\tabl_tabulate_NR_common\conditionalfalse\tabl_tabulate_check_penalties} % next row
2175\permanent\protected\def\tabl_tabulate_NB_second{\tabl_tabulate_NR_common\conditionalfalse\tabl_tabulate_nobreak_inject } % next row no break
2176
2177\permanent\protected\def\tabl_tabulate_CC_first{\global\c_tabl_tabulate_localcolorspan\zerocount\tabl_tabulate_set_color_column\zerocount}
2178\permanent\protected\def\tabl_tabulate_CL_first{\global\c_tabl_tabulate_localcolorspan\plusone  \tabl_tabulate_set_color_column\zerocount}
2179\permanent\protected\def\tabl_tabulate_CM_first{\global\c_tabl_tabulate_localcolorspan\plustwo  \tabl_tabulate_set_color_column\zerocount}
2180\permanent\protected\def\tabl_tabulate_CR_first{\global\c_tabl_tabulate_localcolorspan\plusthree\tabl_tabulate_set_color_column\zerocount}
2181
2182%D New per 27/12/2022:
2183
2184% \defineorientation[test][orientation=down,vertical=top]
2185%
2186% \definetabulatemove[a][xoffset=40pt]
2187% \definetabulatemove[b][orientation=test,yoffset=depth]
2188%
2189% \startbuffer[b]
2190% \starttabulate[|c|c|]
2191% \TM[a] \NC \darkred   cell one   \NC \darkgray cell one   \NC \NR
2192% \TM[b] \NC \darkgreen cell one   \NC \darkblue cell one   \NC \NR
2193% \TM[a] \NC \darkred   cell two   \NC \darkgray cell two   \NC \NR
2194% \TM[b] \NC \darkgreen cell two   \NC \darkblue cell two   \NC \NR
2195% \TM[a] \NC \darkred   cell three \NC \darkgray cell three \NC \NR
2196% \TM[b] \NC \darkgreen cell three \NC \darkblue cell three \NC \NR
2197% \TM[a] \NC \darkred   cell four  \NC \darkgray cell four  \NC \NR
2198% \TM[b] \NC \darkgreen cell four  \NC \darkblue cell four  \NC \NR
2199% \stoptabulate
2200% \stopbuffer
2201%
2202% \start \showmakeup[line] \showstruts \ruledvbox{\getbuffer[b]} \stop
2203% \start                   \showstruts \ruledvbox{\getbuffer[b]} \stop
2204% \start                               \ruledvbox{\getbuffer[b]} \stop
2205%
2206% \startbuffer[b]
2207% \starttabulate[|p|p|]
2208% \TM[a] \NC \darkred   \samplefile{tufte} \NC \darkgray \samplefile{ward} \NC \NR
2209%        \NC \darkgreen \samplefile{tufte} \NC \darkblue \samplefile{ward} \NC \NR
2210% \TM[a] \NC \darkred   \samplefile{tufte} \NC \darkgray \samplefile{ward} \NC \NR
2211%        \NC \darkgreen \samplefile{tufte} \NC \darkblue \samplefile{ward} \NC \NR
2212% \stoptabulate
2213% \stopbuffer
2214%
2215% \start \showmakeup[line] \showstruts \getbuffer[b] \stop
2216
2217\installcorenamespace{tabulatemove}
2218
2219\installcommandhandler \??tabulatemove {tabulatemove} \??tabulatemove
2220
2221\setuptabulatemove
2222  [\c!xoffset=\zeropoint,
2223   \c!yoffset=\zeropoint,
2224   \c!orientation=]
2225
2226\noaligned\permanent\tolerant\protected\def\tabl_tabulate_TM_yes[#S#1]#*[#S#2]%
2227  {\beginlocalcontrol
2228   \ifhastok={#1}%
2229     \setupcurrenttabulatemove[#1]%
2230   \else
2231     \cdef\currenttabulatemove{#1}%
2232     \setupcurrenttabulatemove[#2]%
2233   \fi
2234   \edef\p_orientation{\theorientation{\tabulatemoveparameter\c!orientation}}%
2235   \edef\p_xoffset    {\tabulatemoveparameter\c!xoffset}%
2236   \edef\p_yoffset    {\tabulatemoveparameter\c!yoffset}%
2237   \scratchyoffset
2238     \ifx\p_yoffset\v!depth
2239       -\strutdp
2240     \orelse\ifx\p_yoffset\v!height
2241       -\strutht
2242     \else
2243       \p_yoffset
2244     \fi
2245   \relax
2246   \scratchxoffset\p_xoffset\relax
2247   \xdef\tabl_tabulate_tm
2248     {\ifzeropt\scratchxoffset\else\s!xmove  \the\scratchxoffset\fi % or move
2249      \ifzeropt\scratchyoffset\else\s!ymove  \the\scratchyoffset\fi % or move
2250      \ifzero  \p_orientation \else\s!orientation\p_orientation \fi
2251     }%
2252   \endlocalcontrol
2253   \noalign\tabl_tabulate_tm{}}
2254
2255\noaligned\permanent\tolerant\protected\def\tabl_tabulate_TM_nop[#S#1]#*[#S#2]%
2256  {}
2257
2258\lettonothing\tabl_tabulate_tm % new 27/12/2022
2259
2260%D Sort of special:
2261%D
2262%D \startbuffer
2263%D \startitemize[n]
2264%D \starttabulate[|||||]
2265%D \NC p \NC \itemtag \NC q \NC r \NC \NR
2266%D \NC p \NC \itemtag \NC q \NC r \NC \NR
2267%D \NC p \NC \itemtag \NC q \NC r \NC \NR
2268%D \NC p \NC \itemtag \NC q \NC r \NC \NR
2269%D \stoptabulate
2270%D \stopitemize
2271%D
2272%D \startitemize[n]
2273%D \starttabulate[|||||]
2274%D \NI b \NC c \NC d \NC \NR
2275%D \NC a \NI c \NC d \NC \NR
2276%D \NC a \NC b \NI d \NC \NR
2277%D \NC a \NC b \NC c \NI \NR
2278%D \stoptabulate
2279%D \stopitemize
2280%D \stopbuffer
2281%D
2282%D \typebuffer \getbuffer
2283
2284\permanent\tolerant\protected\def\tabl_tabulate_NI_first[#1]{\NC\itemtag[#1]\NC}
2285
2286%D The following shortcut is handy for tables where one needs bold headers:
2287
2288\permanent\protected\def\tabl_tabulate_BC_first
2289  {\tabl_tabulate_column_normal\plusone\zerocount
2290   \let\fontstyle\globalfontstyle
2291   \bf}
2292
2293\appendtoks
2294    \enforced\let\VL\tabl_tabulate_VL_first
2295    \enforced\let\NC\tabl_tabulate_NC_first
2296    \enforced\let\BC\tabl_tabulate_BC_first
2297    \enforced\let\RC\tabl_tabulate_RC_first
2298    \enforced\let\HC\tabl_tabulate_HC_first
2299    \enforced\let\EQ\tabl_tabulate_EQ_first
2300    \enforced\let\RQ\tabl_tabulate_RQ_first
2301    \enforced\let\HQ\tabl_tabulate_HQ_first
2302    \enforced\let\NG\tabl_tabulate_NG_first
2303    \enforced\let\NN\tabl_tabulate_NN_first
2304    \enforced\let\ND\tabl_tabulate_ND_first
2305    \enforced\let\NR\tabl_tabulate_NR_first
2306    \enforced\let\NB\tabl_tabulate_NB_first
2307    \enforced\let\CC\tabl_tabulate_CC_first
2308    \enforced\let\CL\tabl_tabulate_CL_first
2309    \enforced\let\CM\tabl_tabulate_CM_first
2310    \enforced\let\CR\tabl_tabulate_CR_first
2311    \enforced\let\NI\tabl_tabulate_NI_first
2312\to \t_tabl_tabulate_initializers_first
2313
2314\appendtoks
2315    \enforced\let\NR\tabl_tabulate_NR_second
2316    \enforced\let\NB\tabl_tabulate_NB_second
2317    \enforced\let\TM\tabl_tabulate_TM_yes
2318\to \t_tabl_tabulate_initializers_second
2319
2320\appendtoks
2321    \enforced\let\SR\NR
2322    \enforced\let\FR\NR
2323    \enforced\let\MR\NR
2324    \enforced\let\LR\NR
2325    \enforced\let\AR\NR
2326    \enforced\let\TM\tabl_tabulate_TM_nop
2327\to \t_tabl_tabulate_initializers_first
2328
2329% \permanent\protected\def\tabl_tabulate_NR_common#1#2%
2330%   {\global\advanceby\c_tabl_tabulate_noflines\plusone
2331%    \global\c_tabl_tabulate_firstflushed\conditionalfalse
2332%    \global\c_tabl_tabulate_equal\conditionalfalse
2333%    \global\c_tabl_tabulate_column\zerocount
2334%    \ifconditional#1\relax
2335%      \tabl_tabulate_break_state_reset
2336%    \fi
2337%    \tabl_tabulate_pheight_reset
2338%    \unskip\unskip\crcr\tabl_tabulate_flush_collected
2339%    % can we omit the next one in the first run? probably
2340%    \noalign{\expand\t_tabl_tabulate_every_after_row#2}}
2341
2342% test case for ignorepar error
2343%
2344% \starttabulatehead
2345%     \NC A \NC B \NC \NR
2346% \stoptabulatehead
2347% \starttabulate[|l|l|]
2348%     \NC 1 \NC 2 \NC \NR
2349% \stoptabulate
2350
2351\permanent\tolerant\protected\def\tabl_tabulate_NR_common#1#2% #. gobbles pars and spaces
2352  {\global\advanceby\c_tabl_tabulate_noflines\plusone
2353   \global\c_tabl_tabulate_firstflushed\conditionalfalse
2354   \global\c_tabl_tabulate_equal\conditionalfalse
2355   \global\c_tabl_tabulate_column\zerocount
2356   \ifconditional#1\relax
2357     \tabl_tabulate_break_state_reset
2358   \fi
2359   \tabl_tabulate_pheight_reset
2360   \unskip\unskip\crcr\tabl_tabulate_flush_collected
2361   % can we omit the next one in the first run? probably
2362   % todo: move \ignorepars ourside so no alignment error then
2363   \noalign{\expand\t_tabl_tabulate_every_after_row#2\ignorepars}}
2364
2365%D \starttyping
2366%D \showmakeup[vpenalty]
2367%D
2368%D \starttabulate
2369%D \NC one \NC \samplefile{ward} \NC \NR
2370%D \NC one \NC \samplefile{ward} \NC \NR
2371%D \NC one \NC \samplefile{ward} \NC \NR
2372%D \stoptabulate
2373%D
2374%D \starttabulate
2375%D \NC one \NC ward \NC \NR
2376%D \NC one \NC ward \NC \NR
2377%D \NC one \NC ward \NC \NR
2378%D \stoptabulate
2379%D \stoptyping
2380
2381% \def\tabl_tabulate_check_penalties
2382%   {\ifconditional\c_tabl_tabulate_tolerant_break\else
2383%      \ifnum\c_tabl_tabulate_totalnoflines=\plusone
2384%      %  \tabl_tabulate_break_allow
2385%      \else
2386%        \ifconditional\c_tabl_tabulate_someamble \ifcase\c_tabl_tabulate_repeathead \else
2387%          \tabl_tabulate_break_allow
2388%        \fi \fi
2389%        \ifnum\c_tabl_tabulate_noflines=\plusone
2390%          \tabl_tabulate_nobreak_inject
2391%        \orelse\ifnum\c_tabl_tabulate_noflines=\c_tabl_tabulate_minusnoflines
2392%          \ifnum\c_tabl_tabulate_plines_max<\plustwo
2393%            \tabl_tabulate_nobreak_inject
2394%          \else
2395%            \tabl_tabulate_break_allow % needed with pbreak prevention
2396%          \fi
2397%        \else
2398%          \tabl_tabulate_break_state_allowbreak
2399%        \fi
2400%      \fi
2401%    \fi
2402%    \global\c_tabl_tabulate_firstflushed\conditionalfalse
2403%    \ifconditional\c_tabl_tabulate_no_interline_space
2404%      \nointerlineskip
2405%      \injectzerobaselineskip
2406%    \fi}
2407
2408\def\tabl_tabulate_check_penalties
2409  {\ifconditional\c_tabl_tabulate_tolerant_break\else
2410     \ifnum\c_tabl_tabulate_totalnoflines=\plusone
2411     %  \tabl_tabulate_break_allow
2412     \else
2413       \ifconditional\c_tabl_tabulate_someamble \ifcase\c_tabl_tabulate_repeathead \else
2414         \tabl_tabulate_break_allow
2415       \fi \fi
2416       \ifnum\c_tabl_tabulate_noflines=\plusone
2417         \tabl_tabulate_nobreak_inject
2418       \orelse\ifnum\c_tabl_tabulate_noflines=\c_tabl_tabulate_minusnoflines
2419         \ifnum\c_tabl_tabulate_plines_max<\plustwo
2420           \tabl_tabulate_nobreak_inject
2421         \else
2422           \tabl_tabulate_break_allow % needed with pbreak prevention
2423         \fi
2424       \else
2425         \tabl_tabulate_break_state_allowbreak
2426       \fi
2427     \fi
2428   \fi
2429   \global\c_tabl_tabulate_firstflushed\conditionalfalse
2430   \ifconditional\c_tabl_tabulate_no_interline_space
2431     \nointerlineskip
2432     \injectzerobaselineskip
2433   \fi}
2434
2435\protected\def\tabl_tabulate_bbskip_second_split_yes
2436  {\ifvoid\b_tabl_tabulate_current\c_tabl_tabulate_column
2437     \ifempty\tabl_tabulate_flush_collected_indeed\else
2438       \tabl_tabulate_tag_start_cell\dotagtabulatesignal\tabl_tabulate_tag_stop_cell
2439       \setbox0\hbox
2440     \fi
2441  \fi}
2442
2443\protected\def\tabl_tabulate_eskip_second
2444  {\par
2445   \ifconditional\c_tabl_tabulate_no_blank_in_paragraphs
2446     \removelastskip
2447   \fi
2448   \egroup
2449   \tabl_tabulate_pheight_set
2450   \glet\tabl_tabulate_hook\tabl_tabulate_hook_yes
2451   \tabl_tabulate_splitoff_box}
2452
2453\protected\def\tabl_tabulate_bskip_second_split_yes
2454  {\ifvoid\b_tabl_tabulate_current\c_tabl_tabulate_column
2455     % first line
2456     \global\setbox\b_tabl_tabulate_current\c_tabl_tabulate_column\vbox
2457     \bgroup
2458     \ifconditional\c_tabl_tabulate_no_blank_in_paragraphs
2459       \inhibitblank
2460     \fi
2461     \glet\tabl_tabulate_hook\tabl_tabulate_hook_nop
2462     \ifconditional\c_tabl_tabulate_automode\hsize\d_tabl_tabulate_width\fi
2463     % \begstrut % interferes with pre-\pars
2464     % evt: \appendtoks\begstrut\to\everypar
2465     \let\tabl_tabulate_eskip\tabl_tabulate_eskip_second
2466     \expandafter\ignorepars % \ignorespaces
2467   \else
2468     % successive lines
2469     \lettonothing\tabl_tabulate_eskip
2470    %\dontcomplain
2471     \glet\tabl_tabulate_hook\tabl_tabulate_hook_yes
2472     \expandafter\tabl_tabulate_splitoff_box
2473   \fi}
2474
2475\protected\def\tabl_tabulate_xbskip_second{\tabl_tabulate_bskip}
2476\protected\def\tabl_tabulate_xeskip_second{\tabl_tabulate_eskip}
2477
2478% \protected\def\tabl_tabulate_flush_second_indeed
2479%   {\glettonothing\tabl_tabulate_flush_collected_indeed
2480%    \global\c_tabl_tabulate_column\zerocount
2481%    \tabl_tabulate_pbreak_check
2482%    \global\c_tabl_tabulate_split_done\conditionalfalse % new 27/12/2022
2483%    \dofastloopcs\c_tabl_tabulate_columns\tabl_tabulate_flush_second_step
2484%    \ifconditional\c_tabl_tabulate_split_done\else
2485%      \glet\tabl_tabulate_tm\s!reset % new 27/12/2022
2486%    \fi
2487%    \global\c_tabl_tabulate_firstflushed\conditionaltrue}
2488
2489% \protected\def\tabl_tabulate_flush_second_step
2490%   {\ifvoid\b_tabl_tabulate_current\fastloopindex
2491%    \else
2492%      \gdef\tabl_tabulate_flush_collected_indeed{\expand\t_tabl_tabulate_dummy}%
2493%      \ifvoid\b_tabl_tabulate_current\fastloopindex \else
2494%        \global\c_tabl_tabulate_split_done\conditionaltrue % new 27/12/2022
2495%      \fi
2496%    \fi}
2497
2498\newconditional\c_tabl_tabulate_split_done
2499
2500\protected\def\tabl_tabulate_flush_second_indeed
2501  {\glettonothing\tabl_tabulate_flush_collected_indeed
2502   \global\c_tabl_tabulate_column\zerocount
2503   \tabl_tabulate_pbreak_check
2504   \global\c_tabl_tabulate_split_done\conditionalfalse % new 27/12/2022
2505   \localcontrolledloop\plusone\c_tabl_tabulate_columns\plusone{\tabl_tabulate_flush_second_step}%
2506   \ifconditional\c_tabl_tabulate_split_done\else
2507     \glet\tabl_tabulate_tm\s!reset % new 27/12/2022
2508   \fi
2509   \global\c_tabl_tabulate_firstflushed\conditionaltrue}
2510
2511% \protected\def\tabl_tabulate_flush_second_step
2512%   {\ifvoid\b_tabl_tabulate_current\currentloopiterator
2513%    \else
2514%      \gdef\tabl_tabulate_flush_collected_indeed{\expand\t_tabl_tabulate_dummy}%
2515%      \ifvoid\b_tabl_tabulate_current\currentloopiterator \else
2516%        \global\c_tabl_tabulate_split_done\conditionaltrue % new 27/12/2022
2517%      \fi
2518%    \fi}
2519
2520\protected\def\tabl_tabulate_flush_second_step
2521  {\iflist\b_tabl_tabulate_current\currentloopiterator\relax % \ifvoid fails for balanced
2522     \gdef\tabl_tabulate_flush_collected_indeed{\expand\t_tabl_tabulate_dummy}%
2523     \global\c_tabl_tabulate_split_done\conditionaltrue % new 27/12/2022
2524   \fi}
2525
2526\def\tabl_tabulate_flush_second
2527  {\noalign{\tabl_tabulate_flush_second_indeed}%
2528   \noalign\tabl_tabulate_tm{\ifx\tabl_tabulate_tm\s!reset\glettonothing\tabl_tabulate_tm\fi}% new 27/12/2022
2529   \tabl_tabulate_flush_collected_indeed}
2530
2531\protected\def\tabl_tabulate_bskip_second_split_nop
2532% {\dbox\bgroup
2533  {\vtop\bgroup
2534     \ifconditional\c_tabl_tabulate_automode\hsize\d_tabl_tabulate_width\fi
2535\inhibitblank
2536     % \begstrut % interferes with pre-\pars
2537     % evt: \appendtoks\begstrut\to\everypar
2538     \ignorepars} % \ignorespaces
2539
2540\protected\def\tabl_tabulate_eskip_second_split_nop % vertical strut added august 2003
2541  {\par\verticalstrut
2542   \vskip-\struttotal
2543   \egroup}
2544
2545% \let\tabl_tabulate_eskip \relax % adapted by bskip
2546% \let\tabl_tabulate_eeskip\relax % adapted by bskip
2547
2548\appendtoks
2549   \let\tabl_tabulate_xbskip\tabl_tabulate_xbskip_second
2550   \let\tabl_tabulate_xeskip\tabl_tabulate_xeskip_second
2551   \ifconditional\c_tabl_tabulate_split
2552     \let\tabl_tabulate_bskip \tabl_tabulate_bskip_second_split_yes
2553     \let\tabl_tabulate_bbskip\tabl_tabulate_bbskip_second_split_yes
2554   \else
2555     \let\tabl_tabulate_bskip \tabl_tabulate_bskip_second_split_nop
2556     \let\tabl_tabulate_eskip \tabl_tabulate_eskip_second_split_nop
2557   \fi
2558\to \t_tabl_tabulate_initializers_second
2559
2560% see ***
2561%
2562% \enabletrackers[nodes.page_vspacing]
2563% \starttext
2564%     \starttabulate[||] \dorecurse{100}{\NC Eins \NC \NR \HL} \stoptabulate
2565% \stoptext
2566
2567\permanent\tolerant\noaligned\protected\def\tabl_tabulate_XX_none  [#1]{\noalign{\tabl_tabulate_break_state_set}}
2568
2569\permanent\tolerant\noaligned\protected\def\tabl_tabulate_FL_second[#1]{\noalign{\tabl_tabulate_hrule_preset[#1]\tabl_tabulate_FL_second_indeed}}
2570\permanent\tolerant\noaligned\protected\def\tabl_tabulate_ML_second[#1]{\noalign{\tabl_tabulate_hrule_preset[#1]\tabl_tabulate_ML_second_indeed}}
2571\permanent\tolerant\noaligned\protected\def\tabl_tabulate_SL_second[#1]{\noalign{\tabl_tabulate_hrule_preset[#1]\tabl_tabulate_SL_second_indeed}}
2572\permanent\tolerant\noaligned\protected\def\tabl_tabulate_LL_second[#1]{\noalign{\tabl_tabulate_hrule_preset[#1]\tabl_tabulate_LL_second_indeed}}
2573\permanent\tolerant\noaligned\protected\def\tabl_tabulate_TL_second[#1]{\noalign{\tabl_tabulate_hrule_preset[#1]\tabl_tabulate_TL_second_indeed}}
2574\permanent\tolerant\noaligned\protected\def\tabl_tabulate_BL_second[#1]{\noalign{\tabl_tabulate_hrule_preset[#1]\tabl_tabulate_BL_second_indeed}}
2575
2576\protected\def\tabl_tabulate_FL_second_indeed
2577  {\ifinsidefloat\orelse\ifempty{\tabulationparameter\c!before}%%
2578     \tabl_tabulate_baselinecorrection
2579   \fi
2580   \tabl_tabulate_hrule_inject
2581   \tabl_tabulate_break_no
2582   \tabl_tabulate_column_rule_separator_inject
2583   \prevdepth\strutdp
2584   \tabl_tabulate_break_no}
2585
2586\def\spac_vspacing_no_topskip % use grouped
2587  {\c_attr_skipcategory\plusten}
2588
2589\protected\def\tabl_tabulate_ML_second_indeed
2590  {\tabl_tabulate_break_no
2591   \tabl_tabulate_column_rule_separator_inject
2592   \tabl_tabulate_break_no
2593   \tabl_tabulate_hrule_inject
2594   \vskip-\p_rulethickness\relax
2595   \begingroup
2596   \spac_vspacing_no_topskip
2597   \tabl_tabulate_hrule_inject
2598   \endgroup
2599   \tabl_tabulate_break_no
2600   \tabl_tabulate_column_rule_separator_inject}
2601
2602\protected\def\tabl_tabulate_SL_second_indeed
2603  {\tabl_tabulate_break_no
2604   \tabl_tabulate_column_rule_separator_inject
2605   \tabl_tabulate_break_no
2606   \tabl_tabulate_hrule_inject
2607   \tabl_tabulate_break_no
2608   \tabl_tabulate_column_rule_separator_inject
2609   \tabl_tabulate_break_no}
2610
2611\protected\def\tabl_tabulate_LL_second_indeed
2612  {\tabl_tabulate_break_no
2613   \tabl_tabulate_column_rule_separator_inject
2614   \tabl_tabulate_break_no
2615   \tabl_tabulate_hrule_inject
2616   \ifinsidefloat
2617     \tabl_tabulate_inside_inbetween
2618   \else
2619     \tabl_tabulate_outside_inbetween
2620   \fi}
2621
2622\protected\def\tabl_tabulate_TL_second_indeed
2623  {\tabl_tabulate_break_no
2624   \tabl_tabulate_column_rule_separator_inject
2625   \tabl_tabulate_break_no
2626   \tabl_tabulate_hrule_inject
2627   \tabl_tabulate_break_no
2628   \tabl_tabulate_column_rule_separator_inject
2629  %\prevdepth\strutdp % todo, might differ between TL and BL
2630   \tabl_tabulate_break_no}
2631
2632\let\tabl_tabulate_BL_second_indeed\tabl_tabulate_TL_second_indeed
2633
2634\permanent\def\tabl_tabulate_HL_second
2635  {\csname
2636     \ifnum\c_tabl_tabulate_noflines=\zerocount                     F\orelse
2637   % \ifzeroc_tabl_tabulate_noflines                                F\orelse
2638     \ifnum\c_tabl_tabulate_noflines=\c_tabl_tabulate_totalnoflines L\else
2639                                                                    M\fi
2640   L\endcsname}
2641
2642\appendtoks
2643    \enforced\let\FL\tabl_tabulate_XX_none
2644    \enforced\let\ML\tabl_tabulate_XX_none
2645    \enforced\let\SL\tabl_tabulate_XX_none
2646    \enforced\let\LL\tabl_tabulate_XX_none
2647    \enforced\let\TL\tabl_tabulate_XX_none
2648    \enforced\let\BL\tabl_tabulate_XX_none
2649    \enforced\let\HL\tabl_tabulate_XX_none
2650    \enforced\let\HR\tabl_tabulate_XX_none
2651\to \t_tabl_tabulate_initializers_first
2652
2653\appendtoks
2654    \enforced\let\FL\tabl_tabulate_FL_second
2655    \enforced\let\ML\tabl_tabulate_ML_second
2656    \enforced\let\SL\tabl_tabulate_SL_second
2657    \enforced\let\LL\tabl_tabulate_LL_second
2658    \enforced\let\TL\tabl_tabulate_TL_second
2659    \enforced\let\BL\tabl_tabulate_BL_second
2660    \enforced\let\HL\tabl_tabulate_HL_second
2661    \enforced\let\HR\tabl_tabulate_HL_second
2662\to \t_tabl_tabulate_initializers_second
2663
2664% \dorecurse{10}{
2665%     \starttabulate[|l|]
2666%     \FL
2667%     \NC first line, bound to next rule    \NC \NR
2668%     \TL
2669%     \NC bound to previous rule            \NC \NR
2670%     \NC some line                         \NC \NR
2671%     \NC some line                         \NC \NR
2672%     \NC some line                         \NC \NR
2673%     \NC bound to next rule                \NC \NR
2674%     \ML
2675%     \NC bound to previous rule            \NC \NR
2676%     \NC bound to next rule                \NC \NR
2677%     \BL
2678%     \NC last line, bound to previous rule \NC \NR
2679%     \LL
2680%     \stoptabulate
2681% }
2682
2683% This needs checking:
2684
2685\permanent\def\tabulaterule    {\HR} % a rule with lineheight
2686\permanent\def\tabulateline    {\HL} % just a spaced rule
2687\permanent\def\tabulateautorule{\HR}%
2688\permanent\def\tabulateautoline{\HL} % no longer different (to be looked into)
2689
2690%D When support for vertical rules we needed a way to pick up the specification for
2691%D the final rule and a \type {|{}} interface was chosen. As a result parsing had to
2692%D become more complex and I was not in the mood for messing up the code too much.
2693%D Therefore from now on the preamble is split by \LUA. There are definitely more
2694%D places where we can use \LUA\ code (for instance in alignment of numbers. The
2695%D repeat parser is replace at the \LUA\ end as well.
2696
2697\lettonothing\tabl_tabulate_flush_collected
2698\lettonothing\tabl_tabulate_flush_collected_indeed
2699
2700\let\v_tabl_tabulate_align\!!zerocount
2701
2702\def\tabl_tabulate_check_side_float % new per 29-07-2016
2703  {\ifdefined\page_sides_check_floats_indeed
2704     \page_sides_check_floats_indeed
2705     \ifdim\hangindent>\zeropoint
2706       \advanceby\d_tabl_tabulate_indent\hangindent
2707     \fi
2708   \fi}
2709
2710\def\tabl_tabulate_set_local_hsize
2711  {\setlocalhsize
2712   \hsize\localhsize}
2713
2714% test case for pre/post spacing:
2715%
2716% \ruledvbox{\starttabulate[|l|]  \FL\NC xxx \NC         \NR\LL\stoptabulate}
2717% \ruledvbox{\starttabulate[|l|l|]\FL\NC xxx \NC xxx \NC \NR\LL\stoptabulate}
2718% \ruledvbox{\starttabulate[|l|]     \NC xxx \NC         \NR   \stoptabulate}
2719% \ruledvbox{\starttabulate[|lj8|]   \NC xxx \NC         \NR   \stoptabulate}
2720% \ruledvbox{\starttabulate[|k8|]    \NC xxx \NC         \NR   \stoptabulate}
2721% \ruledvbox{\starttabulate[|l|l|]   \NC xxx \NC xxx \NC \NR   \stoptabulate}
2722
2723% \enabletrackers[localanchor]
2724%
2725% \startoverlayMPgraphic{mp:whatever-6}
2726%     draw anchorcell (1,1)       withpen pencircle scaled 1pt withcolor "blue" ;
2727%     fill anchorspan (2,2) (3,5) withpen pencircle scaled 1pt withcolor "yellow" ;
2728%     draw anchorcell (2,2)       withpen pencircle scaled 1pt withcolor "green" ;
2729%     draw anchorcell (3,3)       withpen pencircle scaled 1pt withcolor "red" ;
2730% \stopoverlayMPgraphic
2731%
2732% \starttabulate[synchronize=background,background=mp:whatever-6,format={|l|c|r|}]
2733%     \NC test      \NC test      \NC test      \NC \NR
2734%     \NC test      \NC test test \NC test      \NC \NR
2735%     \NC test test \NC test      \NC test      \NC \NR
2736%     \NC test      \NC test      \NC test      \NC \NR
2737%     \NC test      \NC test      \NC test test \NC \NR
2738% \stoptabulate
2739
2740\protected\def\tabl_tabulate_anchor_indeed
2741  {\edef\xanchor{\the\c_tabl_tabulate_column}%
2742   \edef\yanchor{\the\c_tabl_tabulate_nofrealrows}%
2743   \markanchor{matrix}{\c_tabl_tabulate_column}{\c_tabl_tabulate_nofrealrows}}
2744
2745\def\tabl_tabulate_anchor_setup % a bit of a cheat but good enough for a lightweight experiment
2746  {\edef\p_synchronize{\tabulationparameter\c!synchronize}%
2747   \ifx\p_synchronize\v!background
2748     \cdef\currentframedcontent{\tabulationparameter\c!frame}%
2749     \ifx\currentframedcontent\v!off
2750       \resettabulationparameter\c!frame
2751       \lettonothing\currentframedcontent
2752       \letframedcontentparameter\c!frame\v!off
2753     \fi
2754     \letframedcontentparameter\c!synchronize\p_synchronize
2755     \setframedcontentparameter\c!background {\tabulationparameter\c!background}%
2756     \enforced\let\tabl_tabulate_anchor\tabl_tabulate_anchor_indeed
2757     \setlocalanchoring
2758   \fi}
2759
2760\permanent\protected\lettonothing\tabl_tabulate_anchor
2761
2762\definesystemattribute[alignskip][public]
2763
2764\def\tabl_tabulate_process
2765  {\c_tabl_tabulate_pass\plusone
2766   \tabl_tabulate_check_full_content
2767   \edef\v_tabl_tabulate_align{\ifcsname\??tabulatealigning\p_align\endcsname\lastnamedcs\else0\fi}%
2768   \s_tabl_tabulate_first.5\d_tabl_tabulate_unit
2769   \s_tabl_tabulate_last\s_tabl_tabulate_first
2770   \s_tabl_tabulate_pre\zeroskip
2771   \s_tabl_tabulate_post\zeroskip
2772   %c_tabl_pre_is_set\conditionalfalse
2773   \c_tabl_post_is_set\conditionalfalse
2774   \global\c_tabl_tabulate_columns\zerocount
2775   \global\c_tabl_tabulate_nofauto\zerocount
2776   \global\c_tabl_tabulate_noflines\zerocount
2777   \c_tabl_tabulate_totalnoflines\zerocount
2778   \c_tabl_tabulate_minusnoflines\zerocount
2779   \global\d_tabl_tabulate_width_p\zeropoint
2780   \global\d_tabl_tabulate_width_w\zeropoint
2781   \global\c_tabl_tabulate_equal\conditionalfalse
2782   \tabl_tabulate_pheight_reset
2783   \tabskip\zeroskip
2784   \ifinsidesplitfloat
2785     \donetrue
2786   \orelse\ifinsidefloat
2787     \donefalse
2788   \else
2789     \donetrue
2790   \fi
2791   \global\c_tabl_tabulate_repeathead
2792     \ifdone
2793       \ifcsname\??tabulateheader\tabulationparameter\c!header\endcsname
2794         \lastnamedcs
2795       \else
2796         \zerocount
2797       \fi
2798     \else
2799       \zerocount
2800     \fi
2801   %
2802   \expand\t_tabl_tabulate_initializers_first % collect more here
2803   %
2804   \glettonothing\tabl_tabulate_flush_collected
2805   \ifdim\d_tabl_tabulate_margin>\zeropoint
2806     \t_tabl_tabulate_preamble
2807       {\aligntab
2808        \tabl_tabulate_flush_indent
2809% \global\advanceby\c_tabl_tabulate_noflines\plusone
2810        \strut
2811        \aligncontent % \alignmark\alignmark
2812        \tabskip\d_tabl_tabulate_margin
2813        \strut
2814        \aligntab
2815        \aligncontent % \alignmark\alignmark
2816        \tabskip\zeropoint}%
2817   \else
2818     \t_tabl_tabulate_preamble
2819       {\aligntab
2820        \tabl_tabulate_flush_indent
2821% \global\advanceby\c_tabl_tabulate_noflines\plusone
2822        \strut
2823        \aligncontent % \alignmark\alignmark
2824        \aligntab
2825        \aligncontent % \alignmark\alignmark
2826        \tabskip\zeroskip}%
2827   \fi
2828   \d_tabl_tabulate_width\zeropoint
2829   % these counters are set at the lua end
2830   \c_tabl_tabulate_nofcolumns         \zerocount
2831   \c_tabl_tabulate_has_rule_spec_first\zerocount
2832   \c_tabl_tabulate_has_rule_spec_last \zerocount
2833   \clf_presettabulate{\detokenizedtabulationparameter\c!format}%
2834   %
2835   \d_tabl_tabulate_width\zeropoint
2836   \tabl_tabulate_initialize_boxes\c_tabl_tabulate_columns
2837   \toksapp\t_tabl_tabulate_preamble{%
2838     \aligntab
2839     \aligncontent % \alignmark\alignmark
2840     \global\advanceby\c_tabl_tabulate_column\plusone % maybe just set it already
2841   }%
2842   \toksapp\t_tabl_tabulate_dummy{%
2843     \NC\unskip\unskip\crcr\tabl_tabulate_flush_collected % no count
2844   }%
2845   \global\c_tabl_tabulate_column\zerocount
2846   \tabl_tabulate_pheight_reset
2847   \glet\tabl_tabulate_hook\tabl_tabulate_hook_yes
2848   \ifx\p_indenting\v!no
2849     \forgetparindent
2850   \fi
2851   \ifinsidefloat
2852     \d_tabl_tabulate_indent\zeropoint
2853   \else
2854     \tabl_tabulate_check_side_float
2855     \tabl_tabulate_set_local_hsize
2856   \fi
2857   \dontcomplain
2858   \forgetall % hm, interference with preceding \forgetparindent probably bug, to be solved
2859   \everypar\everytabulatepar
2860   \setbox\scratchbox\vbox % outside \if because of line counting
2861     {\notesenabledfalse
2862      \d_tabl_tabulate_indent\zeropoint
2863      \settrialtypesetting % very important
2864      \anch_backgrounds_text_level_start
2865      \halign
2866        \ifconditional\c_tabl_sparse_skips \s!noskips\fi
2867        \ifconditional\c_tabl_auto_align_mode_new \alignmentcharactertrigger\fi
2868        \expandafter{\the\t_tabl_tabulate_preamble\crcr\tabl_tabulate_insert_content\crcr}}%
2869      \anch_backgrounds_text_level_stop
2870      \ifcase\c_anch_backgrounds_text_state\else
2871        \global\tablehaspositions\conditionaltrue
2872      \fi
2873   \ifnum\c_tabl_tabulate_nofauto>\zerocount
2874     % so, even if the natural size is larger, in the final run, we force the calculated width
2875     \d_tabl_tabulate_width{\hsize-\wd\scratchbox-\d_tabl_tabulate_width_p-\d_tabl_tabulate_width_w}%
2876     \ifnum\c_tabl_tabulate_nofauto>\zerocount
2877       \divideby\d_tabl_tabulate_width \c_tabl_tabulate_nofauto\relax
2878     \fi
2879   \fi
2880   \setbox\scratchbox\emptybox % free memory
2881   \ifconditional\c_tabl_tabulate_split
2882     \splittopskip\strutht
2883     \glettonothing\tabl_tabulate_flush_collected_indeed
2884     \glet\tabl_tabulate_flush_collected\tabl_tabulate_flush_second
2885   \fi
2886   \c_tabl_tabulate_totalnoflines\c_tabl_tabulate_noflines
2887   \c_tabl_tabulate_minusnoflines{\c_tabl_tabulate_noflines+\minusone}%
2888   \global\c_tabl_tabulate_noflines\zerocount
2889   %
2890   \c_tabl_tabulate_pass\plustwo % final pass
2891   \expand\t_tabl_tabulate_initializers_second % collect more here
2892   %
2893   \ifx\p_line\v!line
2894     \enforced\let\HL\HR
2895     \enforced\let\tabulateautoline\tabulateautorule
2896     \enforced\let\tabulateline    \tabulaterule
2897   \fi
2898   %
2899   \ifcase\c_tabl_tabulate_repeathead
2900     \ifinsidesplitfloat
2901        \global\setbox\b_tabl_tabulate\vbox \bgroup
2902      \else
2903        \tabl_tabulate_anchor_setup
2904        \startframedcontent[\tabulationparameter\c!frame]%
2905      \fi
2906   \else
2907     \global\setbox\b_tabl_tabulate\vbox \bgroup
2908   \fi
2909   %
2910   \tabl_tabulate_tag_start
2911   \tabl_tabulate_tag_start_row
2912   \inhibitmargindata\conditionalfalse % new per 2012.06.13 ... really needed
2913   \toksapp\everycr{\noalign{\the\t_tabl_tabulate_every_real_row\tabl_tabulate_tag_stop_row\tabl_tabulate_tag_start_row\empty}}%
2914   \halign
2915     \s!callbacks \align_callback_alignskip % always
2916     \ifconditional\c_tabl_sparse_skips \s!noskips\fi
2917     \ifconditional\c_tabl_auto_align_mode_new \alignmentcharactertrigger\fi
2918     \expandafter{\the\t_tabl_tabulate_preamble\crcr\tabl_tabulate_insert_content\crcr}%
2919   \tabl_tabulate_tag_stop_row
2920   \tabl_tabulate_tag_stop
2921   \ifhmode\par\prevdepth\strutdp\fi % nog eens beter, temporary hack
2922   \ifx\p_distance\v!grid
2923     \vskip-\strutdp % experimental tm-prikkels
2924   \fi
2925   %
2926   \ifcase\c_tabl_tabulate_repeathead
2927     \ifinsidesplitfloat
2928       \egroup % box
2929       \egroup % settings
2930       \tabl_split_box\b_tabl_tabulate
2931     \else
2932       \stopframedcontent
2933       \egroup
2934     \fi
2935   \else
2936     \egroup % box
2937     \egroup % settings
2938     \tabl_split_box\b_tabl_tabulate
2939   \fi
2940   %
2941   \ifinsidefloat
2942     \tabl_tabulate_inside_after
2943   \else
2944     \tabl_tabulate_outside_after
2945   \fi
2946   \egroup} % whole thing
2947
2948% \egroup
2949
2950% \setuptabulate[split=yes,header=text,title=Vervolg van Tabel]
2951%
2952% % \starttabulatehead
2953% % \NC test \NC hans\NC \NR
2954% % \stoptabulatehead
2955%
2956% \starttabulate
2957% \NC test \NC \input tufte \relax \NC \NR
2958% \NC test \NC \input knuth \relax \NC \NR
2959% \NC test \NC \input knuth \relax \NC \NR
2960% \NC test \NC \input tufte \relax \NC \NR
2961% \NC test \NC \input tufte \relax \NC \NR
2962% \NC test \NC \input tufte \relax \NC \NR
2963% \stoptabulate
2964
2965% todo: use the more modern line getter
2966
2967\def\tabl_split_box#1% #1 <> 0/2 / derived from the one in core-ntb.tex
2968  {\ifinsidesplitfloat
2969     \tabl_split_box_indeed#1%
2970   \orelse\ifinsidefloat
2971     \unvbox#1%
2972   \else
2973     \tabl_split_box_indeed#1%
2974   \fi}
2975
2976\def\tabl_split_box_indeed#1%
2977  {\resettsplit
2978   \c_split_minimum_free_lines\plustwo
2979   \d_split_minimum_free_space\zeropoint
2980   \setbox\b_split_content\box#1%
2981   \ifcase\c_tabl_tabulate_repeathead\or
2982     \setbox\b_split_head\vsplit\b_split_content upto \lineheight
2983   \or
2984     \setbox\b_split_head\vbox{\hbox{\strut\tabulationparameter\c!title}}%
2985   \fi
2986   \handletsplit}
2987
2988%D \starttyping
2989%D \setuptabulate[split=no,rule=line]
2990%D
2991%D \starttabulate
2992%D \NC tufte \NC \input tufte \NC \NR \tabulateautorule
2993%D \NC tufte \NC \input tufte \NC \NR \tabulateautorule
2994%D \NC tufte \NC \input tufte \NC \NR \tabulateautorule
2995%D \NC tufte \NC \input tufte \NC \NR \tabulateautorule
2996%D \NC tufte \NC \input tufte \NC \NR \tabulateautorule
2997%D \NC tufte \NC \input tufte \NC \NR \tabulateautorule
2998%D \stoptabulate
2999%D \stoptyping
3000
3001%D Spacing:
3002%
3003% \starttabulate
3004% \NC text \NC text \NC \NR
3005% \TB[small]
3006% \NC text \NC text \NC \NR
3007% \TB[4*big]
3008% \NC text \NC text \NC \NR
3009% \stoptabulate
3010
3011\permanent\tolerant\noaligned\protected\def\tabl_tabulate_TB_yes[#1]%
3012  {\noalign\bgroup
3013     \unless\ifempty{#1}%
3014       \blank[#1]%
3015     \orelse\ifempty\m_tabl_tabulate_blank_default
3016       \blank
3017     \else
3018       \blank[\m_tabl_tabulate_blank_default]%
3019     \fi
3020   \egroup}
3021
3022\permanent\tolerant\noaligned\protected\def\tabl_tabulate_TB_nop[#1]%
3023  {}
3024
3025\appendtoks
3026    \enforced\let\TB\tabl_tabulate_TB_nop
3027\to \t_tabl_tabulate_initializers_first
3028
3029\appendtoks
3030    \enforced\let\TB\tabl_tabulate_TB_yes
3031\to \t_tabl_tabulate_initializers_second
3032
3033% %D Between alignment lines certain rules apply, and even a simple test can mess
3034% %D up a table, which is why we have a special test facilityL
3035% %D
3036% %D \startbuffer
3037% %D \starttabulate[|l|p|]
3038% %D \NC 1test \NC test \NC \NR
3039% %D \tableifelse{\doifelse{a}{a}}{\NC Xtest \NC test \NC \NR}{}%
3040% %D \stoptabulate
3041% %D \stopbuffer
3042% %D
3043% %D \typebuffer \getbuffer
3044%
3045% \def\tableifelse#1% should be tabulatenoalign then
3046%   {\tablenoalign
3047%      {#1%
3048%        {\aftergroup \firstoftwoarguments}%
3049%        {\aftergroup\secondoftwoarguments}}}
3050%
3051% \def\tableiftextelse#1{\tableifelse{\doiftextelse{#1}}}
3052
3053%D Some new trickery:
3054%D
3055%D \startbuffer
3056%D \c_tabl_tabulate_splitoff_whitespace\conditionaltrue
3057%D
3058%D \starttabulate[|p(2cm)|p(2cm)|p(2cm)|]
3059%D     \NC test 1a \NC test 2a \NC test 3a
3060%D                                 \par
3061%D                                 test 3b          \NC \NR
3062%D     \NC test 1a \NC test 2a \NC test 3a
3063%D                                 \blank[line]
3064%D                                 test 3b          \NC \NR
3065%D     \NC test 1a \NC test 2a \NC test 3a
3066%D                                 \blank[halfline]
3067%D                                 test 3b
3068%D                                 \blank[halfline]
3069%D                                 test 3c          \NC \NR
3070%D     \NC \blank  \NC \blank  \NC \blank           \NC \NR
3071%D     \NC test 1a \NC test 2a \NC test 3a
3072%D                                 \blank[halfline]
3073%D                                 test 3b
3074%D                                 \blank[halfline]
3075%D                                 test 3c          \NC \NR
3076%D     \NC \blank  \NC \blank  \NC                  \NC \NR
3077%D     \NC test 1a
3078%D         \par
3079%D         test 1b
3080%D         \par
3081%D         test 1b \NC test 2a
3082%D                     \par
3083%D                     test 2b
3084%D                     \par
3085%D                     test 2b \NC test 3a          \NC \NR
3086%D     \NC test 1a
3087%D         \blank
3088%D         test 1b
3089%D         \par
3090%D         test 1b \NC test 2a
3091%D                     \par
3092%D                     test 2b
3093%D                     \blank
3094%D                     test 2b \NC test 3a          \NC \NR
3095%D \stoptabulate
3096%D \stopbuffer
3097%D
3098%D \typebuffer \start \getbuffer \stop
3099
3100% \starttabulatie[|mc|]
3101% \NC \digits{100.000,00} \NC\NR
3102% \NC \digits{@10.000,00} \NC\NR
3103% \NC \digits{@@@.100,00} \NC\NR
3104% \NC \digits{@@@.@10,@@} \NC\NR
3105% \NC \digits{@@@.@@1,@@} \NC\NR
3106% \stoptabulatie
3107%
3108% \starttabulatie[|mc|]
3109% \ND 100.000,00 \NC\NR
3110% \ND @10.000,00 \NC\NR
3111% \ND @@@.100,00 \NC\NR
3112% \ND @@@.@10,@@ \NC\NR
3113% \ND @@@.@@1,@@ \NC\NR
3114% \stoptabulatie
3115%
3116% \starttabulatie[|c|]
3117% \ND $100.000,00$ \NC\NR
3118% \ND $@10.000,00$ \NC\NR
3119% \ND $@@@.100,00$ \NC\NR
3120% \ND $@@@.@10,@@$ \NC\NR
3121% \ND $@@@.@@1,@@$ \NC\NR
3122% \stoptabulatie
3123%
3124% \starttabulatie[|c|]
3125% \NC $\digits 100.000,00 $ \NC\NR
3126% \NC $\digits @10.000,00 $ \NC\NR
3127% \NC $\digits @@@.100,00 $ \NC\NR
3128% \NC $\digits @@@.@10,@@ $ \NC\NR
3129% \NC $\digits @@@.@@1,@@ $ \NC\NR
3130% \stoptabulatie
3131%
3132% \starttabulatie[|c|]
3133% \NC \digits $100.000,00$ \NC\NR
3134% \NC \digits $@10.000,00$ \NC\NR
3135% \NC \digits $@@@.100,00$ \NC\NR
3136% \NC \digits $@@@.@10,@@$ \NC\NR
3137% \NC \digits $@@@.@@1,@@$ \NC\NR
3138% \stoptabulatie
3139
3140%D Predefined categories (moved from core-mis):
3141
3142\mutable\let\leg \relax % column separators
3143\mutable\let\fact\relax % column separators
3144
3145\definetabulate
3146  [\v!legend]
3147  [|emj1|i1|mR|]
3148
3149\setuptabulate
3150  [\v!legend]
3151  [\c!unit=.75em,\c!inner=\tabl_tabulate_set_quick\leg,EQ={=}]
3152
3153\definetabulate
3154  [\v!legend][\v!two]
3155  [|emj1|emk1|i1|mR|]
3156
3157\definetabulate
3158  [\v!fact]
3159  [|R|ecmj1|i1mR|]
3160
3161\setuptabulate
3162  [\v!fact]
3163  [\c!unit=.75em,\c!inner=\tabl_tabulate_set_quick\fact,EQ={=}]
3164
3165%D Another example:
3166%D
3167%D \starttyping
3168%D \definetabulate
3169%D   [whatever]
3170%D   [|l|r|]
3171%D
3172%D \definetabulate
3173%D   [whatever][else]
3174%D   [|l|c|r|]
3175%D
3176%D \startwhatever
3177%D \NC l    \NC r     \NC \NR
3178%D \NC left \NC right \NC \NR
3179%D \stopwhatever
3180%D
3181%D \startwhatever[else]
3182%D \NC l    \NC m      \NC r     \NC \NR
3183%D \NC left \NC middle \NC right \NC \NR
3184%D \stopwhatever
3185%D
3186%D \startwhatever[else][format={|c|c|c|c|}]
3187%D \NC l    \NC m      \NC m      \NC r     \NC \NR
3188%D \NC left \NC middle \NC middle \NC right \NC \NR
3189%D \stopwhatever
3190%D \stoptyping
3191
3192%D This is needed because we sometimes use the english command in tracing macros. In
3193%D fact, most detailed tracing macros that are done with \LUA\ only work in the
3194%D english interface anyway.
3195
3196% \definetabulate[tabulate] \setuptabulate[tabulate][\c!format=\v!none] % so no \v! here
3197
3198\newconditional\c_tabl_generic
3199
3200\pushoverloadmode
3201
3202\permanent\protected\defcsname starttabulate\endcsname
3203  {\bgroup % whole thing
3204   \c_tabl_generic\conditionaltrue
3205   \lettonothing\currenttabulationparent
3206   \tabl_start_regular}
3207
3208\permanent\letcsname stoptabulate\endcsname\relax % testcase cvs-002.tex
3209
3210\popoverloadmode
3211
3212%D The following helpers are just there because we also have them at the \LUA\ end:
3213%D
3214%D \startbuffer
3215%D \starttabulate[|l|c|r|]
3216%D     \tabulaterow    {a,b,c}
3217%D     \tabulaterowbold{aa,bb,cc}
3218%D     \tabulaterowtype{aaa,bbb,ccc}
3219%D     \tabulaterowtyp {aaaa,bbbb,cccc}
3220%D \stoptabulate
3221%D \stopbuffer
3222%D
3223%D \typebuffer \getbuffer
3224
3225\def\tabl_tabulate_compact_row#1#2%
3226  {\NC\tabl_tabulate_compact_step#1#2,\end,}
3227
3228\def\tabl_tabulate_compact_step#1#2#3,%
3229  {\ifx#2\end
3230     \NR
3231     \expandafter\gobbleoneargument
3232   \else
3233     #1{#2#3}\NC
3234     \expandafter\tabl_tabulate_compact_step
3235   \fi#1}
3236
3237\permanent\protected\def\tabulaterow    {\tabl_tabulate_compact_row\relax}
3238\permanent\protected\def\tabulaterowbold{\tabl_tabulate_compact_row\bold}
3239\permanent\protected\def\tabulaterowtype{\tabl_tabulate_compact_row\type}
3240\permanent\protected\def\tabulaterowtyp {\tabl_tabulate_compact_row\typ}
3241
3242%D Here we plug in a row background feature. As we only have support for
3243%D \type {frame=name} we can use these variables.
3244%D
3245%D \starttyping
3246%D \startuseMPgraphic{foo}
3247%D     fill unitsquare
3248%D         xyscaled (RuleWidth,RuleHeight+RuleDepth) enlarged (ExHeight/4,ExHeight/8)
3249%D         randomized ExHeight
3250%D         shifted  (-ExHeight/8,ExHeight/16)
3251%D         withcolor RuleColor ;
3252%D \stopuseMPgraphic
3253%D
3254%D \setuptabulate % wel only have frame=name so we can use these:
3255%D   [background=foo,
3256%D    backgroundcolor=darkred,
3257%D    foregroundcolor=white]
3258%D
3259%D \definelinefiller[foo][mp=foo,color=darkgreen]
3260%D \definelinefiller[bar][mp=foo,color=darkred]
3261%D
3262%D \starttabulate[|||]
3263%D     \DB foo \BC bar \BC \NR
3264%D     \NC foo \NC bar \NC \NR
3265%D     \NC foo \NC bar \NC \NR
3266%D     \NC foo \NC bar \NC \NR
3267%D     \NC foo \NC bar \NC \NR
3268%D \stoptabulate
3269%D
3270%D \starttabulate[|||]
3271%D     \PB foo \BC bar \BC \NR
3272%D     \NC foo \NC bar \NC \NR
3273%D     \NC foo \NC bar \NC \NR
3274%D     \NC foo \NC bar \NC \NR
3275%D     \NC foo \NC bar \NC \NR
3276%D \stoptabulate
3277%D
3278%D \starttabulate[|||]
3279%D     \FB[bar] foo \BC bar \BC \NR
3280%D     \NC      foo \NC bar \NC \NR
3281%D     \NC      foo \NC bar \NC \NR
3282%D     \NC      foo \NC bar \NC \NR
3283%D     \NC      foo \NC bar \NC \NR
3284%D \stoptabulate
3285%D
3286%D \startnarrower
3287%D     \starttabulate[|||]
3288%D         \DB foo \DB bar \BC \NR
3289%D         \NC foo \NC bar \NC \NR
3290%D         \NC foo \NC bar \NC \NR
3291%D         \NC foo \NC bar \NC \NR
3292%D         \NC foo \NC bar \NC \NR
3293%D     \stoptabulate
3294%D \stopnarrower
3295%D
3296%D \starttabulate[|||]
3297%D     \BC          foo \BC bar \BC \NR
3298%D     \NL[magenta] foo \NC bar \NC \NR
3299%D     \NL[yellow]  foo \NC bar \NC \NR
3300%D     \NL[cyan]    foo \NC bar \NC \NR
3301%D     \NL[gray]    foo \NC bar \NC \NR
3302%D \stoptabulate
3303%D
3304%D \starttabulate
3305%D     \NL[red]     foo \NC bar \NC \NR
3306%D     \NL[green]   foo \NL[red] bar \NC \NR
3307%D     \NC          foo \NC bar \NC \NR
3308%D     \NL[blue]    foo \NC \input tufte  \NC \NR
3309%D     \NL[gray]    foo \NC bar \NC \NR
3310%D     \NL[yellow]  foo \NC bar \NC \NR
3311%D \stoptabulate
3312%D \stoptyping
3313
3314% \setuptabulate
3315%   [\c!background=,
3316%    \c!backgroundcolor=,
3317%    \c!foregroundcolor=,
3318%    \c!foregroundstyle=]
3319
3320\lettonothing\m_table_current_row_background
3321\lettonothing\m_table_current_row_background_default
3322\lettonothing\m_table_current_row_background_filler
3323\lettonothing\m_table_current_row_background_default_filler
3324\lettonothing\m_table_current_row_background_auto
3325
3326\protected\def\tabl_register_row_background#1%
3327  {\xdef\m_table_current_row_background{#1}}
3328
3329\protected\def\tabl_register_row_background_filler#1%
3330  {\xdef\m_table_current_row_background_filler{#1}}
3331
3332\protected\def\tabl_synchronize_row_background
3333  {\iftrialtypesetting\else
3334     \ifempty\m_table_current_row_background_filler
3335       \ifempty\m_table_current_row_background
3336         % nothing
3337         \tabl_synchronize_row_background_dummy
3338       \else
3339         \tabl_synchronize_row_background_indeed\m_table_current_row_background
3340       \fi
3341     \else
3342       \tabl_synchronize_row_background_filler_indeed\m_table_current_row_background_filler
3343     \fi
3344   \fi}
3345
3346\protected\def\tabl_synchronize_row_background_dummy
3347  {\iftrialtypesetting\else
3348     \begingroup
3349     \clf_setbackgroundrowdata\c_tabl_tabulate_nofrealrows\zerocount\zeropoint
3350     \endgroup
3351   \fi}
3352
3353\protected\def\tabl_synchronize_row_background_indeed#1%
3354  {\iftrialtypesetting\else
3355     \begingroup
3356     \clf_enablebackgroundalign % can be moved into \clf_setbackgroundrowdata
3357     \dousecolorparameter{#1}%
3358     \setbox\scratchbox\hpack{}%
3359     \clf_setbackgroundrowdata\c_tabl_tabulate_nofrealrows\scratchbox\d_tabl_tabulate_indent
3360     \endgroup
3361   \fi}
3362
3363\protected\def\tabl_synchronize_row_background_filler_indeed#1%
3364  {\iftrialtypesetting\else
3365     \begingroup
3366     \clf_enablebackgroundalign % can be moved into \clf_setbackgroundrowdata
3367     \node_linefiller_set{#1}%
3368     \setbox\scratchbox\hpack{}%
3369     \clf_setbackgroundrowdata\c_tabl_tabulate_nofrealrows\scratchbox\d_tabl_tabulate_indent
3370     \endgroup
3371   \fi}
3372
3373\appendtoks
3374    \glettonothing\m_table_current_row_background
3375    \glettonothing\m_table_current_row_background_filler
3376    \global\c_tabl_tabulate_nofrealrows\zerocount
3377    \global\c_tabl_tabulate_autocolor\zerocount
3378    \clf_resetbackgroundrowdata
3379\to \t_tabl_tabulate_initializers_first
3380
3381\appendtoks
3382    \glettonothing\m_table_current_row_background
3383    \glettonothing\m_table_current_row_background_filler
3384    \global\c_tabl_tabulate_nofrealrows\zerocount
3385    \global\c_tabl_tabulate_autocolor\zerocount
3386    \clf_resetbackgroundrowdata
3387\to \t_tabl_tabulate_initializers_second
3388
3389\appendtoks
3390    \tabl_synchronize_row_background
3391\to \t_tabl_tabulate_every_real_row
3392
3393\appendtoks
3394    \glettonothing\m_table_current_row_background
3395    \glettonothing\m_table_current_row_background_filler
3396\to \t_tabl_tabulate_every_after_row
3397
3398\permanent\protected\def\tabl_tabulate_NL_first[#1]%
3399  {\tabl_tabulate_column_normal\zerocount\zerocount\relax
3400   \ifcase\c_tabl_tabulate_column\or
3401     \tabl_register_row_background{#1}%
3402   \fi
3403   \ignorepars} % \ignorespaces
3404
3405\pushoverloadmode
3406
3407    % redefinition needs checking
3408
3409    \permanent\overloaded\protected\def\tabl_tabulate_ND_first
3410      {\tabl_tabulate_column_normal\zerocount\zerocount\relax
3411       \ifcase\c_tabl_tabulate_column\or
3412         \tabl_register_row_background\m_table_current_row_background_default
3413       \fi
3414       \ignorepars} % \ignorespaces
3415
3416\popoverloadmode
3417
3418\permanent\protected\def\tabl_tabulate_LB_first[#1]%
3419  {\tabl_tabulate_column_normal\plusone\zerocount\relax
3420   \ifcase\c_tabl_tabulate_column\or
3421     \tabl_register_row_background{#1}%
3422   \fi
3423   \usetabulationstyleandcolor\c!foregroundstyle\c!foregroundcolor
3424   \ignorepars} % \ignorespaces
3425
3426\permanent\protected\def\tabl_tabulate_DB_first
3427  {\tabl_tabulate_column_normal\plusone\zerocount\relax
3428   \ifcase\c_tabl_tabulate_column\or
3429     \tabl_register_row_background\m_table_current_row_background_default
3430   \fi
3431   \enforced\let\fontstyle\globalfontstyle
3432   \usetabulationstyleandcolor\c!foregroundstyle\c!foregroundcolor
3433   \ignorepars} % \ignorespaces
3434
3435\permanent\protected\def\tabl_tabulate_NF_first[#1]%
3436  {\tabl_tabulate_column_normal\zerocount\zerocount\relax
3437   \ifcase\c_tabl_tabulate_column\or
3438     \tabl_register_row_background_filler{#1}%
3439   \fi
3440   \ignorepars} % \ignorespaces
3441
3442\permanent\protected\def\tabl_tabulate_NP_first
3443  {\tabl_tabulate_column_normal\zerocount\zerocount\relax
3444   \ifcase\c_tabl_tabulate_column\or
3445     \tabl_register_row_background_filler\m_table_current_row_background_default_filler
3446   \fi
3447   \ignorepars} % \ignorespaces
3448
3449\permanent\protected\def\tabl_tabulate_FB_first[#1]%
3450  {\tabl_tabulate_column_normal\plusone\zerocount\relax
3451   \ifcase\c_tabl_tabulate_column\or
3452     \tabl_register_row_background_filler{#1}%
3453   \fi
3454   \usetabulationstyleandcolor\c!foregroundstyle\c!foregroundcolor
3455   \ignorepars} % \ignorespaces
3456
3457\permanent\protected\def\tabl_tabulate_PB_first
3458  {\tabl_tabulate_column_normal\plusone\zerocount\relax
3459   \ifcase\c_tabl_tabulate_column\or
3460     \tabl_register_row_background_filler\m_table_current_row_background_default_filler
3461   \fi
3462   \enforced\let\fontstyle\globalfontstyle
3463   \usetabulationstyleandcolor\c!foregroundstyle\c!foregroundcolor
3464   \ignorepars} % \ignorespaces
3465
3466\pushoverloadmode
3467
3468    \permanent\overloaded\protected\def\tabl_tabulate_BC_first
3469      {\tabl_tabulate_column_normal\plusone\zerocount
3470       \enforced\let\fontstyle\globalfontstyle
3471       \ifempty\m_table_current_row_background
3472         \ifempty\m_table_current_row_background_filler
3473           \usetabulationstyleandcolor\c!headstyle\c!headcolor
3474         \else
3475           \usetabulationstyleandcolor\c!foregroundstyle\c!foregroundcolor
3476         \fi
3477       \else
3478         \usetabulationstyleandcolor\c!foregroundstyle\c!foregroundcolor
3479       \fi}
3480
3481\popoverloadmode
3482
3483\permanent\protected\def\tabl_tabulate_A_first
3484  {\global\advanceby\c_tabl_tabulate_autocolor\plusone
3485   \edef\m_table_current_row_background_auto{\tabulateparameter{\c!backgroundcolor:\the\c_tabl_tabulate_autocolor}}%
3486   \ifempty\m_table_current_row_background_auto
3487     \global\c_tabl_tabulate_autocolor\plusone
3488     \edef\m_table_current_row_background_auto{\tabulateparameter{\c!backgroundcolor:\the\c_tabl_tabulate_autocolor}}%
3489   \fi
3490   \ifempty\m_table_current_row_background_auto
3491     \lettonothing\m_table_current_row_background_auto % \m_table_current_row_background_default
3492   \fi
3493   \tabl_register_row_background{\m_table_current_row_background_auto}}
3494
3495\permanent\protected\def\tabl_tabulate_NA_first
3496  {\tabl_tabulate_column_normal\zerocount\zerocount\relax
3497   \iftrialtypesetting\orelse\ifcase\c_tabl_tabulate_column\or
3498     \tabl_tabulate_A_first
3499   \fi
3500   \ignorepars} % \ignorespaces
3501
3502\permanent\protected\def\tabl_tabulate_BA_first
3503  {\tabl_tabulate_column_normal\plusone\zerocount\relax
3504   \iftrialtypesetting\orelse\ifcase\c_tabl_tabulate_column\or
3505     \tabl_tabulate_A_first
3506   \fi
3507   \usetabulationstyleandcolor\c!foregroundstyle\c!foregroundcolor
3508   \ignorepars} % \ignorespaces
3509
3510\appendtoks
3511    \enforced\let\NL\tabl_tabulate_NL_first % NC with Line
3512    \enforced\let\ND\tabl_tabulate_ND_first % NC with Default Line
3513    \enforced\let\LB\tabl_tabulate_LB_first % BC with Line
3514    \enforced\let\DB\tabl_tabulate_DB_first % BC with Default Line
3515    \enforced\let\NF\tabl_tabulate_NF_first % NC with Filler
3516    \enforced\let\NP\tabl_tabulate_NP_first % NC with Predefined Filler
3517    \enforced\let\FB\tabl_tabulate_FB_first % BC with Filler
3518    \enforced\let\PB\tabl_tabulate_PB_first % BC with Predefined Filler
3519    \enforced\let\NA\tabl_tabulate_NA_first % NC with Auto Line
3520    \enforced\let\BA\tabl_tabulate_BA_first % NC with Auto Line
3521\to \t_tabl_tabulate_initializers_first
3522
3523\appendtoks
3524   \edef\m_table_current_row_background_default{\tabulateparameter\c!backgroundcolor}%
3525   \edef\m_table_current_row_background_default_filler{\tabulateparameter\c!background}%
3526   \lettonothing\m_table_current_row_background_auto
3527\to \everytabulate
3528
3529\setuptabulate
3530  [\c!headcolor=,
3531   \c!headstyle=\bf,
3532   \c!backgroundcolor=\tabulationparameter\c!rulecolor,
3533   \c!foregroundcolor=,
3534   \c!foregroundstyle=\tabulationparameter\c!headstyle]
3535
3536%D Only for simple cases (read:myself):
3537%D
3538%D \starttyping
3539%D \starttabulate[|c|c|c|]
3540%D     \NC 1   \NC second column \NC third column \NC \NR
3541%D     \NC 2   \NC second        \NC third        \NC \NR
3542%D     \NC 3 r \NS[1][r]second & third \NC \NR
3543%D     \NC 3 c \NS[1][c]second & third \NC \NR
3544%D     \NC 3 l \NS[1][l]second & third \NC \NR
3545%D \stoptabulate
3546%D \stoptyping
3547
3548% Not okay yet as we loose alignment in later columns .. weird .. do
3549% we miss a tab?
3550
3551\installcorenamespace{tabulatespanb}
3552\installcorenamespace{tabulatespana}
3553
3554\noaligned\def\tabl_tabulate_span{\omit\span\omit\span\omit\span}
3555
3556%\letcsname\??tabulatespanb l\endcsname\relax
3557\letcsname\??tabulatespana l\endcsname\hfill
3558\letcsname\??tabulatespanb c\endcsname\hfill
3559\letcsname\??tabulatespana c\endcsname\hfill
3560\letcsname\??tabulatespanb m\endcsname\hfill
3561\letcsname\??tabulatespana m\endcsname\hfill
3562\letcsname\??tabulatespanb r\endcsname\hfill
3563%\letcsname\??tabulatespana r\endcsname\relax
3564
3565\noaligned\tolerant\def\tabl_tabulate_NS[#1]#*[#2]%
3566  {\NC\loopcs{#1}\tabl_tabulate_span % use localloop and quit
3567   \gdef\tabl_tabulate_kooh
3568     {\begincsname\??tabulatespana#2\endcsname
3569      \glet\tabl_tabulate_kooh\relax}%
3570   \begincsname\??tabulatespanb#2\endcsname
3571   \ignorepars} % \ignorespaces
3572
3573\appendtoks
3574    \enforced\let\NS\tabl_tabulate_NS
3575\to \t_tabl_tabulate_initializers_first
3576
3577% \appendtoks
3578%     \let\NS\tabl_tabulate_NS
3579% \to \t_tabl_tabulate_initializers_second
3580
3581\protect \endinput
3582