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