summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/context/base/mkxl/tabl-tbl.mkxl
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/tex/context/base/mkxl/tabl-tbl.mkxl')
-rw-r--r--Master/texmf-dist/tex/context/base/mkxl/tabl-tbl.mkxl2949
1 files changed, 2949 insertions, 0 deletions
diff --git a/Master/texmf-dist/tex/context/base/mkxl/tabl-tbl.mkxl b/Master/texmf-dist/tex/context/base/mkxl/tabl-tbl.mkxl
new file mode 100644
index 00000000000..88cd791e488
--- /dev/null
+++ b/Master/texmf-dist/tex/context/base/mkxl/tabl-tbl.mkxl
@@ -0,0 +1,2949 @@
+%D \module
+%D [ file=core-tbl,
+%D version=1998.11.03,
+%D title=\CONTEXT\ Table Macros,
+%D subtitle=Text Flow Tabulation,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\writestatus{loading}{ConTeXt Table Macros / Tabulation}
+
+\unprotect
+
+\registerctxluafile{tabl-tbl}{} % experiment
+
+%D I can probably reimplement this using a \LUATEX\ combination but it does not pay
+%D of in development time. If I need something else I will write it from scratch
+%D anyway. This module looks a bit complex which is a consequence of it dealing with
+%D paragraphs being split over pages and that there are several passes over the data
+%D set. We can probably do some cleanup (combine/split).
+%D
+%D Caching the preamble does not save much (compared to other bits and pieces of
+%D \CONTEXT). There are not that many ways to deal with preambles and this is just
+%D one of them. The keys are somewhat similar to those of the \TABLE\ package.
+
+% |p2|p3| 2:3 -> spanning (maybe)
+%
+% In-text tabbing environment
+%
+% \starttabulate[| separated template] % eg [|l|p|] or [|l|p|p|]
+% \NC ... \NC ... \NC\NR
+% \stoptabulate
+%
+% with: two pass auto width calculation when no p-width
+% specified, even with multiple p's, see examples.
+%
+% TaBlE compatible specifications:
+%
+% l align column/paragraph left
+% r align column/paragraph right
+% c align column/paragraph center
+% p p(dimen) of automatisch als alleen p
+% w column width
+% f font#1
+% A {alignmentoptions}
+% B bold
+% I italic
+% S slanted
+% T type
+% R roman
+% m math
+% M display math
+% h hook (inner level or par lines)
+% b before (may be command#1)
+% a after
+% i i<n> skip left of column
+% j i<n> skip right of column
+% k i<n> skip around column
+% d digits (~)
+%
+% C [LMRT] {color} % T is text color
+%
+% | {color,n}
+%
+% s setups
+%
+% g g{char} align at char
+% . align at .
+% , align at ,
+%
+% Still to be done
+%
+% N math numbers (best hook into existing digits mechanism)
+% n numbers (best hook into existing digits mechanism)
+% Q math numbers (best hook into existing digits mechanism)
+% q numbers (best hook into existing digits mechanism)
+% ~ \hskip.5em
+% | check
+%
+% nesting
+%
+% 10 evt auto stack; dan wel andere signal dan void nodig
+%
+% present but not yet 100% ok
+%
+% \TL [width,color] bottom hrule
+% \FL [width,color] first hrule
+% \ML [width,color] mid hrule (with auto split)
+% \LL [width,color] bottom hrule
+% \BL [width,color] last hrule
+%
+% \HL [width,color] top rule
+% \VL [width,color]
+%
+% \CC \CL \CM \CR color
+%
+% \EQ \RQ \HQ equal (raw, hook)
+% \NC \RC \HC normal (raw, hook)
+%
+% \NR checked break
+% \NB no break
+%
+% \HR : rule with lineheight
+%
+% \autotabulaterule : with lineheight, not first/last
+% \autotabulateline : spaced, not first/last
+% \tabulaterule : with lineheight
+% \tabulateline : spaced
+%
+% tricky: align scans ahead, over # and expands ones before
+% while doing
+%
+% new:
+%
+% \starttabulate[|cg{.}|cg{,}|cg{,}|]
+% \NC period \NC comma \NC comma \NC\NR
+% \NG 100.000,00 \NG 100.000,00 \NG 100,00 \NC\NR
+% \NG 10.000,00 \NG 10.000,00 \NG 1000,00 \NC\NR
+% \NG 100,00 \NG 100,00 \NG 10,00 \NC\NR
+% \NG 10 \NG 10 \NG 0,00 \NC\NR
+% \stoptabulate
+%
+% \starttabulate[|c.|c,|c,|]
+% \NC period \NC comma \NC comma \NC\NR
+% \NG 100.000,00 \NG 100.000,00 \NG 100,00 \NC\NR
+% \NG 10.000,00 \NG 10.000,00 \NG 1000,00 \NC\NR
+% \NG 100,00 \NG 100,00 \NG 10,00 \NC\NR
+% \NG 10 \NG 10 \NG 0,00 \NC\NR
+% \stoptabulate
+
+% nice demo (for BG)
+%
+% \starttabulate[|r|b{$\star$}|ra{\percent}|b{=}|r|]
+% \NC 500 \NC \NC 60 \NC \NC 300 \NC \NR
+% \NC 500 \NC \NC 55 \NC \NC 275 \NC \NR
+% \NC 500 \NC \NC 50 \NC \NC 250 \NC \NR
+% \NC 500 \NC \NC 45 \NC \NC 225 \NC \NR
+% \NC 500 \NC \NC 40 \NC \NC 200 \NC \NR
+% \NC 500 \NC \NC 35 \NC \NC 175 \NC \NR
+% \NC 500 \NC \NC 30 \NC \NC 150 \NC \NR
+% \NC 500 \NC \NC 25 \NC \NC 125 \NC \NR
+% \NC 500 \NC \NC 20 \NC \NC 100 \NC \NR
+% \stoptabulate
+
+\newtoks \t_tabl_tabulate_preamble
+\newtoks \t_tabl_tabulate_before
+\newtoks \t_tabl_tabulate_after
+\newtoks \t_tabl_tabulate_bmath
+\newtoks \t_tabl_tabulate_emath
+\newtoks \t_tabl_tabulate_font
+\newtoks \t_tabl_tabulate_settings
+\newtoks \t_tabl_tabulate_dummy
+\newtoks \t_tabl_tabulate_every_row
+\newtoks \t_tabl_tabulate_every_after_row
+\newtoks \t_tabl_tabulate_every_real_row
+
+\newtoks \t_tabl_tabulate_initializers_first
+\newtoks \t_tabl_tabulate_initializers_second
+
+\newcount \c_tabl_tabulate_nofauto
+\newcount \c_tabl_tabulate_columns
+\newcount \c_tabl_tabulate_column
+\newcount \c_tabl_tabulate_plines_min
+\newcount \c_tabl_tabulate_plines_max
+\newcount \c_tabl_tabulate_max_colorcolumn
+\newcount \c_tabl_tabulate_max_vrulecolumn
+\newcount \c_tabl_tabulate_repeathead
+\newcount \c_tabl_tabulate_noflines
+\newcount \c_tabl_tabulate_totalnoflines
+\newcount \c_tabl_tabulate_minusnoflines
+\newcount \c_tabl_tabulate_align
+\newcount \c_tabl_tabulate_nofrealrows
+\newcount \c_tabl_tabulate_autocolor
+
+\newcount \c_tabl_tabulate_nofcolumns % set at the lua end by parser
+\newcount \c_tabl_tabulate_has_rule_spec_first % set at the lua end by parser (for the moment a count)
+\newcount \c_tabl_tabulate_has_rule_spec_last % set at the lua end by parser (for the moment a count)
+
+\newconditional \c_tabl_tabulate_nopbreak
+\newconditional \c_tabl_tabulate_firstflushed
+\newconditional \c_tabl_tabulate_equal
+\newconditional \c_tabl_tabulate_split \settrue\c_tabl_tabulate_split
+\newconditional \c_tabl_tabulate_automode
+\newconditional \c_tabl_tabulate_handlepbreak \settrue\c_tabl_tabulate_handlepbreak
+\newconditional \c_tabl_tabulate_autorulespacing \settrue\c_tabl_tabulate_autorulespacing
+\newconditional \c_tabl_tabulate_someamble
+\newconditional \c_tabl_tabulate_tolerant_break
+\newconditional \c_tabl_tabulate_splitoff_whitespace
+\newconditional \c_tabl_tabulate_pwidth_set
+\newconditional \c_tabl_tabulate_reshape
+
+\newdimen \d_tabl_tabulate_width_p
+\newdimen \d_tabl_tabulate_width_w
+\newdimen \d_tabl_tabulate_width
+\newdimen \d_tabl_tabulate_unit
+\newdimen \d_tabl_tabulate_height_p_max
+\newdimen \d_tabl_tabulate_vrulethickness_default
+\newdimen \d_tabl_tabulate_hrulethickness_default
+\newdimen \d_tabl_tabulate_vrulethickness
+\newdimen \d_tabl_tabulate_hrulethickness % not used
+\newdimen \d_tabl_tabulate_vrulethickness_local
+\newdimen \d_tabl_tabulate_hrulethickness_local
+\newdimen \d_tabl_tabulate_indent
+\newdimen \d_tabl_tabulate_splitoff_betweenskip
+\newdimen \d_tabl_tabulate_margin
+
+\newskip \s_tabl_tabulate_pre
+\newskip \s_tabl_tabulate_post
+\newskip \s_tabl_tabulate_first
+\newskip \s_tabl_tabulate_last
+\newskip \s_tabl_tabulate_separator
+
+\newbox \b_tabl_tabulate
+
+\newconstant \c_tabl_tabulate_pass
+\newconstant \c_tabl_tabulate_type
+\newconstant \c_tabl_tabulate_kind % 1=strong 2=equals
+\newconstant \c_tabl_tabulate_splitlinemode \c_tabl_tabulate_splitlinemode\plusone
+\newconstant \c_tabl_tabulate_colorspan
+\newconstant \c_tabl_tabulate_localcolorspan
+\newconstant \c_tabl_tabulate_modus
+
+%newconditional \c_tabl_pre_is_set
+\newconditional \c_tabl_post_is_set
+
+\let \m_tabl_tabulate_separator_factor \empty % fraction
+
+\aliased\let\tabulatesplitlinemode\c_tabl_tabulate_splitlinemode % temp hack, we need an interface
+
+\newtoks \everytabulatepar % where used ?
+\newtoks \everytabulate % public ?
+
+\permanent\protected\def\tolerantTABLEbreaktrue{\settrue\c_tabl_tabulate_tolerant_break} % used in styles !
+
+\permanent\def\noftabulaterows{\number\c_tabl_tabulate_noflines} % handy for testing if a table is empty
+
+\installcorenamespace{tabulatebox}
+\installcorenamespace{tabulatesetup}
+\installcorenamespace{tabulatehook}
+\installcorenamespace{tabulatesplit}
+\installcorenamespace{tabulateseparator}
+\installcorenamespace{tabulatecolor}
+\installcorenamespace{tabulateheader}
+\installcorenamespace{tabulatealigning}
+\installcorenamespace{tabulatepreamble}
+\installcorenamespace{tabulatevrule}
+
+\installcorenamespace{tabulatehead}
+\installcorenamespace{tabulatefoot}
+\installcorenamespace{tabulatenext}
+
+\prependtoks
+ \global\c_tabl_tabulate_nofrealrows\zerocount
+\to \t_tabl_tabulate_initializers_first
+
+\prependtoks
+ \global\c_tabl_tabulate_nofrealrows\zerocount
+\to \t_tabl_tabulate_initializers_second
+
+\prependtoks
+ \global\advance\c_tabl_tabulate_nofrealrows\plusone
+\to \t_tabl_tabulate_every_real_row
+
+\permanent\def\b_tabl_tabulate_current#1%
+ {\csname\??tabulatebox\number#1\endcsname} % beware, a synonym
+
+\def\tabl_tabulate_initialize_boxes#1%
+ {\scratchcounter#1\relax
+ \tabl_tabulate_initialize_boxes_step}
+
+\def\tabl_tabulate_initialize_boxes_step
+ {\ifnum\scratchcounter>\zerocount
+ \tabl_tabulate_initialize_box\scratchcounter
+ \advance\scratchcounter\minusone
+ \expandafter\tabl_tabulate_initialize_boxes_step
+ \fi}
+
+\def\tabl_tabulate_initialize_box#1% also used elsewhere
+ {\ifcsname\??tabulatebox\number#1\endcsname
+ \tabl_tabulate_initialize_box_yes
+ \else
+ \tabl_tabulate_initialize_box_nop#1%
+ \fi}
+
+\def\tabl_tabulate_initialize_box_yes {\global \setbox\lastnamedcs\emptybox}
+\def\tabl_tabulate_initialize_box_nop#1{\expandafter\newbox\csname\??tabulatebox\number#1\endcsname}
+
+\tabl_tabulate_initialize_boxes{16} % not really needed
+
+% 0 = NC column next EQ equal column
+% 1 = RC column raw RQ equal column raw
+% 2 = HC column hook HQ equal column hook
+
+% [|lg{.}|] => \NG 12.34 \NC
+
+\def\tabl_tabulate_nobreak_inject_tracer
+ {\red % maybe use the fast color switcher here
+ \hrule\s!height.5\linewidth\s!depth.5\linewidth
+ \par
+ \kern-\linewidth
+ \tabl_tabulate_break_no}
+
+\installtextracker
+ {tables.tabulate.breaks}
+ {\let\tabl_tabulate_break_no_tracer\tabl_tabulate_nobreak_inject_tracer}
+ {\let\tabl_tabulate_break_no_tracer\donothing}
+
+\let\tabl_tabulate_break_no_tracer\donothing
+
+\def\tabl_tabulate_nobreak_inject_indeed
+ {\tabl_tabulate_break_no
+ \tabl_tabulate_break_no_tracer}
+
+\def\tabl_tabulate_nobreak_inject
+ {\noalign{\tabl_tabulate_nobreak_inject_indeed}}
+
+\protected\def\tabl_tabulate_hook_check
+ {\ifnum\c_tabl_tabulate_type<\plustwo
+ \glet\tabl_tabulate_hook\tabl_tabulate_hook_nop
+ \else
+ \glet\tabl_tabulate_hook\tabl_tabulate_hook_yes
+ \fi}
+
+\protected\def\tabl_tabulate_setups_check
+ {\begincsname\??tabulatesetup\the\c_tabl_tabulate_column\endcsname}
+
+\protected\def\tabl_tabulate_entry_before{\ignorespaces\tabl_tabulate_hook}
+\protected\def\tabl_tabulate_entry_after {\unskip\unskip\ifmmode\else\endgraf\fi}
+
+\protected\def\tabl_tabulate_shaped_par_begin
+ {\dowithnextboxcs\tabl_tabulate_shaped_par_finish\vbox\bgroup}
+
+\def\tabl_tabulate_shaped_par_finish
+ {\clf_doreshapeframedbox\nextbox\relax
+ \ifvmode\unvbox\else\box\fi\nextbox}
+
+\let\tabl_tabulate_shaped_par_end\egroup
+
+\ifdefined\dotagtabulatecell \else \aliased\let\dotagtabulatecell \relax \fi
+\ifdefined\dotagtabulatesignal \else \aliased\let\dotagtabulatesignal\relax \fi
+
+\protected\def\tabl_tabulate_check_local_color_first#1#2%
+ {\relax}
+
+\protected\def\tabl_tabulate_check_local_color_second#1#2%
+ {\relax
+ \ifempty\m_tabl_tabulate_color_local
+ \xdef\m_tabl_tabulate_color{#1}%
+ \else
+ \glet\m_tabl_tabulate_color\m_tabl_tabulate_color_local
+ \glet\m_tabl_tabulate_color_local\empty
+ \fi
+ \ifcase\c_tabl_tabulate_localcolorspan
+ \global\c_tabl_tabulate_colorspan#2\relax
+ \else
+ \global\c_tabl_tabulate_colorspan\c_tabl_tabulate_localcolorspan
+ \global\c_tabl_tabulate_localcolorspan\zerocount
+ \fi}
+
+\protected\def\tabl_tabulate_check_local_vrule_thickness#1%
+ {\relax
+ \ifcase\d_tabl_tabulate_vrulethickness_local
+ \global\d_tabl_tabulate_vrulethickness#1\relax
+ \else
+ \global\d_tabl_tabulate_vrulethickness\d_tabl_tabulate_vrulethickness_local
+ \global\d_tabl_tabulate_vrulethickness_local\zeropoint
+ \fi}
+
+\protected\def\tabl_tabulate_check_local_vrule_color_first#1%
+ {\relax}
+
+\protected\def\tabl_tabulate_check_local_vrule_color_second#1%
+ {\relax
+ \ifempty\m_tabl_tabulate_vrule_color_local
+ \xdef\m_tabl_tabulate_vrule_color{#1}%
+ \else
+ \glet\m_tabl_tabulate_vrule_color\m_tabl_tabulate_vrule_color_local
+ \glet\m_tabl_tabulate_vrule_color_local\empty
+ \fi}
+
+\let\tabl_tabulate_check_local_color \gobbletwoarguments
+\let\tabl_tabulate_check_local_vrule_color\gobbleoneargument
+
+\appendtoks
+ \let\tabl_tabulate_check_local_color \tabl_tabulate_check_local_color_first
+ \let\tabl_tabulate_check_local_vrule_color\tabl_tabulate_check_local_vrule_color_first
+\to \t_tabl_tabulate_initializers_first
+
+\appendtoks
+ \let\tabl_tabulate_check_local_color \tabl_tabulate_check_local_color_second
+ \let\tabl_tabulate_check_local_vrule_color\tabl_tabulate_check_local_vrule_color_second
+\to \t_tabl_tabulate_initializers_second
+
+% \protected % we can expand this one
+\def\tabl_tabulate_inject_pre_skip#1%
+ {\ifdim#1>\zeropoint
+ \kern#1\relax % was \hskip
+ \orelse\ifnum\c_tabl_tabulate_column=\zerocount
+ \ifconditional\c_tabl_tabulate_autorulespacing
+ \ifcase\c_tabl_tabulate_has_rule_spec_first\else
+ \kern\s_tabl_tabulate_first\relax % was \hskip
+ \fi
+ \fi
+ \fi}
+
+% \protected % we can expand this one
+\def\tabl_tabulate_inject_post_skip#1#2%
+ {\ifdim#1>\zeropoint
+ \kern\ifnum\c_tabl_tabulate_columns=\c_tabl_tabulate_nofcolumns#2\else#1\fi\relax
+ \orelse\ifnum\c_tabl_tabulate_columns=\c_tabl_tabulate_nofcolumns
+ \ifconditional\c_tabl_tabulate_autorulespacing
+ \ifcase\c_tabl_tabulate_has_rule_spec_last\else
+ \kern\s_tabl_tabulate_last\relax % was \hskip
+ \fi
+ \fi
+ \fi}
+
+\let\tabl_tabulate_hook_b\donothing
+\let\tabl_tabulate_hook_e\donothing
+
+\let\tabl_tabulate_hook_g\donothing
+
+\def\tabl_tabulate_set_preamble_step#1#2% only makes sense for many tabulates
+ {\etoksapp\t_tabl_tabulate_preamble{%
+ \tabl_tabulate_check_local_vrule_thickness\constantdimenargument\d_tabl_tabulate_vrulethickness
+ \tabl_tabulate_check_local_vrule_color\constantemptyargument\m_tabl_tabulate_vrule_color
+ \tabl_tabulate_check_local_color\constantemptyargument\m_tabl_tabulate_color\constantnumberargument\c_tabl_tabulate_colorspan
+ \tabl_tabulate_color_side_right
+ \aligntab
+ \tabl_tabulate_column_vrule_inject
+ \tabl_tabulate_color_side_left
+ \tabl_tabulate_inject_pre_skip{\the\dimexpr\s_tabl_tabulate_pre}% get rid of plus
+ \alignmark\alignmark
+ \aligntab
+ \tabl_tabulate_color_side_both
+ \global\c_tabl_tabulate_colorspan\zerocount
+ \global\c_tabl_tabulate_column\constantnumber\c_tabl_tabulate_columns
+ \tabl_tabulate_hook_g
+ \tabl_tabulate_setups_check % unexpandable
+ \tabl_tabulate_hook_check % unexpandable
+ \ifzeropt\d_tabl_tabulate_width
+ \ifcase\c_tabl_tabulate_modus\else
+ \settrue\c_tabl_tabulate_automode
+ \fi
+ \else
+ \ifcase\c_tabl_tabulate_modus
+ \hbox to
+ \else
+ \hsize
+ \fi
+ \the\d_tabl_tabulate_width
+ \fi
+ \bgroup
+ \tabl_tabulate_bbskip
+ \bgroup % we cannot combine the if because a cell may have only one ##
+ \tabl_tabulate_hook_b
+ \c_tabl_tabulate_align\constantnumber\c_tabl_tabulate_align % needed in tag passing
+ \ifempty\m_tabl_tabulate_alignment \else
+ \spac_align_use_now{\m_tabl_tabulate_alignment}%
+ \fi
+ \noexpand\dostarttagged\noexpand\t!tabulatecell\noexpand\empty
+ \noexpand\dotagtabulatecell
+ \noexpand#1%
+ \ifconditional\c_tabl_tabulate_reshape
+ \tabl_tabulate_shaped_par_begin
+ \fi
+ \dotagtabulatesignal % empty cells .. todo (can be removed as soon as build)
+ \noexpand\ifnum\noexpand\c_tabl_tabulate_type=\plusone\noexpand\else
+ \the\t_tabl_tabulate_bmath % maybe later? can interfere with char 0
+ \the\t_tabl_tabulate_font
+ \the\t_tabl_tabulate_settings
+ \the\t_tabl_tabulate_before
+ \ifempty\m_tabl_tabulate_text_color
+ \expandafter\gobbleoneargument
+ \else
+ \expandafter\colo_helpers_direct_activate
+ \fi\m_tabl_tabulate_text_color
+ \noexpand\fi
+ % grouping needs to be outside macros (or expandable), nice test
+ % example \NC \string \aligntab \NC which will fail otherwise (mk)
+ \bgroup
+ \tabl_tabulate_entry_before
+ \alignmark\alignmark
+ \tabl_tabulate_entry_after
+ \egroup
+ \noexpand\ifnum\noexpand\c_tabl_tabulate_type=\plusone\noexpand\else
+ \the\t_tabl_tabulate_after
+ \the\t_tabl_tabulate_emath
+ \noexpand\fi
+ \ifconditional\c_tabl_tabulate_reshape
+ \tabl_tabulate_shaped_par_end
+ \fi
+ \noexpand#2%
+ \tabl_tabulate_hook_e
+ \egroup
+ \egroup
+ \aligntab
+ \noexpand\dostoptagged
+ \tabl_tabulate_inject_post_skip
+ {\the\ifconditional\c_tabl_post_is_set\s_tabl_tabulate_post\else\s_tabl_tabulate_last\fi}%
+ {\the\s_tabl_tabulate_post}%
+ \alignmark\alignmark
+ }%
+ \toksapp\t_tabl_tabulate_dummy{\NC}%
+ \s_tabl_tabulate_pre.5\d_tabl_tabulate_unit\relax
+ \ifnum\c_tabl_tabulate_columns<\numexpr\c_tabl_tabulate_nofcolumns-\plusone\relax
+ \s_tabl_tabulate_post\s_tabl_tabulate_pre
+ \else
+ \s_tabl_tabulate_post\zeropoint
+ \fi
+ %\let\gettabulateexit\dogettabulateexit % still needed ?
+ \d_tabl_tabulate_width\zeropoint
+ %setfalse\c_tabl_pre_is_set
+ \setfalse\c_tabl_post_is_set}
+
+\permanent\protected\def\installtabulatepreambleoption#1#2%
+ {\defcsname\??tabulatepreamble\string#1\endcsname{#2}}%
+
+\installtabulatepreambleoption{x}{\c_tabl_tabulate_align\zerocount
+ \tabl_tabulate_set_preamble} % internal
+\installtabulatepreambleoption{l}{\c_tabl_tabulate_align\plusone
+ \tabl_tabulate_set_preamble}
+\installtabulatepreambleoption{r}{\c_tabl_tabulate_align\plustwo
+ \tabl_tabulate_set_preamble}
+\installtabulatepreambleoption{c}{\c_tabl_tabulate_align\plusthree
+ \tabl_tabulate_set_preamble}
+\installtabulatepreambleoption{p}{\tabl_tabulate_set_paragraph}
+\installtabulatepreambleoption{s}{\tabl_tabulate_set_setups}
+\installtabulatepreambleoption{w}{\tabl_tabulate_set_width}
+\installtabulatepreambleoption{f}{\tabl_tabulate_set_font}
+\installtabulatepreambleoption{B}{\t_tabl_tabulate_font{\bf}%
+ \tabl_tabulate_set_preamble}
+\installtabulatepreambleoption{I}{\t_tabl_tabulate_font{\it}%
+ \tabl_tabulate_set_preamble}
+\installtabulatepreambleoption{S}{\t_tabl_tabulate_font{\sl}%
+ \tabl_tabulate_set_preamble}
+\installtabulatepreambleoption{T}{\t_tabl_tabulate_font{\tt}%
+ \tabl_tabulate_set_preamble}
+\installtabulatepreambleoption{R}{\t_tabl_tabulate_font{\rm}%
+ \tabl_tabulate_set_preamble}
+\installtabulatepreambleoption{m}{\t_tabl_tabulate_bmath{\normalstartimath}%
+ \t_tabl_tabulate_emath{\normalstopimath}%
+ \tabl_tabulate_set_preamble}
+\installtabulatepreambleoption{M}{\t_tabl_tabulate_bmath{\normalstartimath\displaystyle}%
+ \t_tabl_tabulate_emath{\normalstopimath}%
+ \tabl_tabulate_set_preamble}
+\installtabulatepreambleoption{h}{\tabl_tabulate_set_hook}
+\installtabulatepreambleoption{b}{\tabl_tabulate_set_before}
+\installtabulatepreambleoption{a}{\tabl_tabulate_set_after}
+\installtabulatepreambleoption{i}{\tabl_tabulate_set_preskip}
+\installtabulatepreambleoption{j}{\tabl_tabulate_set_posskip}
+\installtabulatepreambleoption{k}{\tabl_tabulate_set_preposskip}
+\installtabulatepreambleoption{e}{\toksapp\t_tabl_tabulate_settings{\global\settrue\c_tabl_tabulate_equal}%
+ \tabl_tabulate_set_preamble}
+\installtabulatepreambleoption{g}{\tabl_tabulate_set_align}
+\installtabulatepreambleoption{.}{\tabl_tabulate_set_align.}
+\installtabulatepreambleoption{,}{\tabl_tabulate_set_align,}
+\installtabulatepreambleoption{C}{\tabl_tabulate_set_color_span}
+\installtabulatepreambleoption{d}{\toksapp\t_tabl_tabulate_settings{\fixedspaces}%
+ \tabl_tabulate_set_preamble}
+\installtabulatepreambleoption{ }{\tabl_tabulate_set_preamble}
+\installtabulatepreambleoption{A}{\tabl_tabulate_set_alignment}
+
+%D We no longer deal with \type {~} here but map it onto \type {d} instead. Of
+%D course we could prefix a key with \type {\meaning} instead, which works ok (and
+%D is needed in order to pseudo expand \type {\next}, but is ugly at the same time.
+%D The type {d} stands for digitspace.
+
+%D \starttyping
+%D \installtabulatepreambleoption{~}{...} % see 'd'
+%D \stoptyping
+%D
+%D Also, as there is always a key, we no longer do some after assigment or future
+%D let but just pick up the key.
+
+\installtabulatepreambleoption\relax
+ {} % finished
+
+\def\tabl_tabulate_set_preamble#1%
+ {\ifcsname\??tabulatepreamble\string#1\endcsname
+ \expandafter\expandafter\expandafter\lastnamedcs\expandafter\gobbleoneargument
+ \else
+ \expandafter\tabl_tabulate_set_preamble_nop
+ \fi{#1}}
+
+\def\tabl_tabulate_set_preamble_yes#1%
+ {\csname\??tabulatepreamble\string#1\expandafter\endcsname}
+
+\def\tabl_tabulate_set_preamble_nop#1%
+ {\writestatus{tabulate}{unknown preamble key: #1}%
+ \tabl_tabulate_set_preamble}
+
+\def\tabl_tabulate_set_preskip#1%
+ {%settrue\c_tabl_pre_is_set
+ \doifelsenumber{#1}%
+ {\s_tabl_tabulate_pre#1\d_tabl_tabulate_unit\tabl_tabulate_set_preamble }%
+ {\s_tabl_tabulate_pre.5\d_tabl_tabulate_unit\tabl_tabulate_set_preamble#1}}
+
+\def\tabl_tabulate_set_posskip#1%
+ {\settrue\c_tabl_post_is_set
+ \doifelsenumber{#1}%
+ {\s_tabl_tabulate_post#1\d_tabl_tabulate_unit\tabl_tabulate_set_preamble }%
+ {\s_tabl_tabulate_post.5\d_tabl_tabulate_unit\tabl_tabulate_set_preamble#1}}
+
+\def\tabl_tabulate_set_preposskip#1%
+ {%settrue\c_tabl_pre_is_set
+ \settrue\c_tabl_post_is_set
+ \doifelsenumber{#1}%
+ {\s_tabl_tabulate_pre#1\d_tabl_tabulate_unit\s_tabl_tabulate_post\s_tabl_tabulate_pre\tabl_tabulate_set_preamble }%
+ {\s_tabl_tabulate_pre.5\d_tabl_tabulate_unit\s_tabl_tabulate_post\s_tabl_tabulate_pre\tabl_tabulate_set_preamble#1}}
+
+\def\tabl_tabulate_set_setups#1%
+ {\defcsname\??tabulatesetup\the\c_tabl_tabulate_columns\endcsname{\setups[#1]}%
+ \tabl_tabulate_set_preamble}
+
+\def\tabl_tabulate_set_hook#1%
+ {\defcsname\??tabulatehook\the\c_tabl_tabulate_columns\endcsname{#1}%
+ \tabl_tabulate_set_preamble}
+
+% begin of character align plugin
+
+\newconditional\c_tabl_auto_align_mode % reset later
+
+\def\tabl_tabulate_hook_g % partly expanded
+ {\ifconditional\c_tabl_auto_align_mode
+ \signalcharacteralign\c_tabl_tabulate_column{\c_tabl_tabulate_noflines+\plusone}%
+ \typo_charalign_adapt_font
+ \fi}
+
+\def\tabl_tabulate_set_align#1%
+ {\global\settrue\c_tabl_auto_align_mode
+ \setcharacteralign\c_tabl_tabulate_columns{#1}%
+ \tabl_tabulate_set_preamble}
+
+% end of character align plugin
+
+\def\tabl_tabulate_set_before#1%
+ {\t_tabl_tabulate_before{#1}%
+ \tabl_tabulate_set_preamble}
+
+\def\tabl_tabulate_set_after#1%
+ {\t_tabl_tabulate_after{#1}%
+ \tabl_tabulate_set_preamble}
+
+\def\tabl_tabulate_set_font#1%
+ {\t_tabl_tabulate_font{#1}%
+ \tabl_tabulate_set_preamble}
+
+\def\tabl_tabulate_pickup_width
+ {\doifelsenextparenthesis\tabl_tabulate_set_width_indeed\tabl_tabulate_set_preamble}
+
+\def\tabl_tabulate_set_width
+ {\setfalse\c_tabl_tabulate_pwidth_set
+ \c_tabl_tabulate_modus\zerocount
+ \tabl_tabulate_pickup_width}
+
+\def\tabl_tabulate_set_alignment#1%
+ {\edef\m_tabl_tabulate_alignment{#1}%
+ \spac_align_use_later\m_tabl_tabulate_alignment
+ \tabl_tabulate_set_preamble}
+
+\def\tabl_tabulate_set_paragraph
+ {\doifelsenextparenthesis
+ {\c_tabl_tabulate_modus\plusone
+ \settrue\c_tabl_tabulate_pwidth_set
+ \tabl_tabulate_pickup_width}
+ {\c_tabl_tabulate_modus\plustwo
+ \setfalse\c_tabl_tabulate_pwidth_set
+ \tabl_tabulate_set_preamble}}
+
+% \startbuffer
+% \toplinebox{\framed[width=3cm,height=2cm]{tufte}}
+% \stopbuffer
+% \starttabulate[|p(fixed)|p|]
+% \dorecurse{100}{\NC \getbuffer \NC test \par test \par \NC \NR}
+% \stoptabulate
+% \starttabulate[|p(fit)|p|]
+% \dorecurse{100}{\NC \getbuffer \NC test \par test \par \NC \NR}
+% \stoptabulate
+
+\def\tabl_tabulate_set_width_indeed(#1)%
+ {\processallactionsinset % can be made faster
+ [#1]%
+ [ \v!fit=>\c_tabl_tabulate_modus\plusthree,
+ \v!fixed=>\c_tabl_tabulate_modus\plusthree
+ \settrue\c_tabl_tabulate_nopbreak,
+ \v!auto=>\c_tabl_tabulate_modus\plusthree
+ \settrue\c_tabl_tabulate_reshape,
+ \s!unknown=>\d_tabl_tabulate_width#1\relax]%
+ \ifconditional\c_tabl_tabulate_pwidth_set
+ \global\advance\d_tabl_tabulate_width_p\d_tabl_tabulate_width % accumulated parwidth
+ \fi
+ \tabl_tabulate_set_preamble}
+
+% faster but seldom used
+%
+% \installcorenamespace{tabulatewidth}
+%
+% \setvalue{\??tabulatewidth\v!fit }{\c_tabl_tabulate_modus\plusthree}
+% \setvalue{\??tabulatewidth\v!fixed}{\c_tabl_tabulate_modus\plusthree\settrue\c_tabl_tabulate_nopbreak}
+% \setvalue{\??tabulatewidth\v!auto }{\c_tabl_tabulate_modus\plusthree\settrue\c_tabl_tabulate_reshape}
+%
+% \def\tabl_tabulate_set_width_step#1%
+% {\ifcsname\??tabulatewidth#1\endcsname
+% \lastnamedcs
+% \else
+% \d_tabl_tabulate_width#1\relax
+% \fi}
+%
+% \def\tabl_tabulate_set_width_indeed(#1)%
+% {\rawprocesscommacommand[#1]\tabl_tabulate_set_width_step
+% \ifconditional\c_tabl_tabulate_pwidth_set
+% \global\advance\d_tabl_tabulate_width_p\d_tabl_tabulate_width % accumulated parwidth
+% \fi
+% \tabl_tabulate_set_preamble}
+
+\def\tabl_tabulate_set_raggedright {\ifnum\c_tabl_tabulate_type=\plusone \else\raggedright \fi}
+\def\tabl_tabulate_set_raggedcenter{\ifnum\c_tabl_tabulate_type=\plusone \else\raggedcenter\fi}
+\def\tabl_tabulate_set_raggedleft {\ifnum\c_tabl_tabulate_type=\plusone \else\raggedleft \fi}
+\def\tabl_tabulate_set_notragged {\ifnum\c_tabl_tabulate_type=\plusone \else\notragged \fi}
+\def\tabl_tabulate_set_hss {\ifnum\c_tabl_tabulate_type=\plusone \else\hss \fi} % never change this to a fill
+
+\def\tabl_tabulate_bskip_raggedright {\tabl_tabulate_bskip\tabl_tabulate_set_raggedright }
+\def\tabl_tabulate_bskip_raggedleft {\tabl_tabulate_bskip\tabl_tabulate_set_raggedleft }
+\def\tabl_tabulate_bskip_raggedcenter{\tabl_tabulate_bskip\tabl_tabulate_set_raggedcenter}
+
+\def\tabl_tabulate_set_width_normal
+ {\ifcase\c_tabl_tabulate_align\relax
+ \tabl_tabulate_set_preamble_step\empty \tabl_tabulate_set_hss \or
+ \tabl_tabulate_set_preamble_step\empty \tabl_tabulate_set_hss \or
+ \tabl_tabulate_set_preamble_step\tabl_tabulate_set_hss\empty \or
+ \tabl_tabulate_set_preamble_step\tabl_tabulate_set_hss\tabl_tabulate_set_hss \fi}
+
+\def\tabl_tabulate_set_width_fixed
+ {\ifcase\c_tabl_tabulate_align\relax
+ \tabl_tabulate_set_preamble_step\tabl_tabulate_bskip \tabl_tabulate_eskip \or
+ \tabl_tabulate_set_preamble_step\tabl_tabulate_bskip_raggedright \tabl_tabulate_eskip \or
+ \tabl_tabulate_set_preamble_step\tabl_tabulate_bskip_raggedleft \tabl_tabulate_eskip \or
+ \tabl_tabulate_set_preamble_step\tabl_tabulate_bskip_raggedcenter\tabl_tabulate_eskip \fi}
+
+\def\tabl_tabulate_set_width_auto
+ {\global\advance\c_tabl_tabulate_nofauto\plusone
+ \ifcase\c_tabl_tabulate_align\relax
+ \tabl_tabulate_set_preamble_step\tabl_tabulate_bskip \tabl_tabulate_eskip \or
+ \tabl_tabulate_set_preamble_step\tabl_tabulate_bskip_raggedright \tabl_tabulate_eskip \or
+ \tabl_tabulate_set_preamble_step\tabl_tabulate_bskip_raggedleft \tabl_tabulate_eskip \or
+ \tabl_tabulate_set_preamble_step\tabl_tabulate_bskip_raggedcenter\tabl_tabulate_eskip \fi}
+
+\def\tabl_tabulate_set_width_simple
+ {\tabl_tabulate_set_preamble_step\tabl_tabulate_xbskip\tabl_tabulate_xeskip}
+
+% \def\tabl_tabulate_set_color_span#1#2%
+% {\xdef\m_tabl_tabulate_color{#2}%
+% \global\c_tabl_tabulate_colorspan\if#1L\plusone\orelse\if#1M\plustwo\orelse\if#1R\plusthree\else\zerocount\fi\relax
+% \tabl_tabulate_set_preamble}
+
+\installcorenamespace{tabulatecolorspec}
+
+\defcsname\??tabulatecolorspec C\endcsname#1{\xdef\m_tabl_tabulate_color {#1}\global\c_tabl_tabulate_colorspan\zerocount}
+\defcsname\??tabulatecolorspec L\endcsname#1{\xdef\m_tabl_tabulate_color {#1}\global\c_tabl_tabulate_colorspan\plusone }
+\defcsname\??tabulatecolorspec M\endcsname#1{\xdef\m_tabl_tabulate_color {#1}\global\c_tabl_tabulate_colorspan\plustwo }
+\defcsname\??tabulatecolorspec R\endcsname#1{\xdef\m_tabl_tabulate_color {#1}\global\c_tabl_tabulate_colorspan\plusthree}
+\defcsname\??tabulatecolorspec T\endcsname#1{\xdef\m_tabl_tabulate_text_color{#1}}
+
+\def\tabl_tabulate_set_color_span#1#2%
+ {\csname\??tabulatecolorspec#1\endcsname{#2}%
+ \tabl_tabulate_set_preamble}
+
+\def\tabl_tabulate_set_vrule_command#1%
+ {\doifelsenumber{#1}
+ {\global\d_tabl_tabulate_vrulethickness#1\d_tabl_tabulate_vrulethickness_default}
+ {\xdef\m_tabl_tabulate_vrule_color{#1}}}
+
+\permanent\protected\def\tabl_tabulate_set_entry#1#2% rulespec template
+ {\c_tabl_tabulate_align\v_tabl_tabulate_align
+ \c_tabl_tabulate_modus\zerocount
+ \setfalse\c_tabl_tabulate_pwidth_set
+ \setfalse\c_tabl_tabulate_reshape
+ %setfalse\c_tabl_pre_is_set
+ \setfalse\c_tabl_post_is_set
+ \t_tabl_tabulate_before\emptytoks
+ \t_tabl_tabulate_after\emptytoks
+ \t_tabl_tabulate_bmath\emptytoks
+ \t_tabl_tabulate_emath\emptytoks
+ \t_tabl_tabulate_font\emptytoks
+ \t_tabl_tabulate_settings\emptytoks
+ \glet\m_tabl_tabulate_alignment\empty
+ \glet\m_tabl_tabulate_color\empty
+ \glet\m_tabl_tabulate_text_color\empty
+ \glet\m_tabl_tabulate_vrule_color\empty
+ \global\c_tabl_tabulate_colorspan\zerocount
+ \global\setfalse\c_tabl_auto_align_mode
+ \global\advance\c_tabl_tabulate_columns\plusone
+ \letcsname\??tabulatesetup\the\c_tabl_tabulate_columns\endcsname\donothing % here ?
+ \iftok{#1}\emptytoks
+ \global\d_tabl_tabulate_vrulethickness\zeropoint
+ \else
+ \global\d_tabl_tabulate_vrulethickness\d_tabl_tabulate_vrulethickness_default
+ % the lmtx raw processor handles {} like the normal one so we need to prune
+ \rawprocesscommalist[#1]\tabl_tabulate_set_vrule_command
+ \fi
+ \tabl_tabulate_set_preamble#2\relax\relax % permits i without n
+ \ifcase\c_tabl_tabulate_modus\relax
+ \tabl_tabulate_set_width_normal
+ \or % fixed width
+ \tabl_tabulate_set_width_fixed
+ \or % auto width
+ \tabl_tabulate_set_width_auto
+ \or % simple
+ \tabl_tabulate_set_width_simple
+ \fi}
+
+\permanent\protected\def\tabl_tabulate_set_last_entry#1% rulespec
+ {\glet\m_tabl_tabulate_color\empty
+ \glet\m_tabl_tabulate_vrule_color\empty
+ \iftok{#1}\emptytoks
+ \global\d_tabl_tabulate_vrulethickness\zeropoint
+ \else
+ \global\d_tabl_tabulate_vrulethickness\d_tabl_tabulate_vrulethickness_default
+ \rawprocesscommalist[#1]\tabl_tabulate_set_vrule_command
+ \fi
+ \etoksapp\t_tabl_tabulate_preamble{%
+ \tabl_tabulate_check_local_vrule_thickness\constantdimenargument\d_tabl_tabulate_vrulethickness
+ \tabl_tabulate_check_local_vrule_color\constantemptyargument\m_tabl_tabulate_vrule_color
+ \tabl_tabulate_column_vrule_inject}}
+
+\aliased\let\settabulateentry \tabl_tabulate_set_entry % used at the lua end
+\aliased\let\settabulatelastentry\tabl_tabulate_set_last_entry % used at the lua end
+
+\def\tabl_tabulate_normalize_splitline
+ {\ifcase\c_tabl_tabulate_splitlinemode
+ % nothing
+ \or
+ \ht\b_tabl_tabulate\strutht
+ \dp\b_tabl_tabulate\strutdp
+ \or
+ \ifdim\ht\b_tabl_tabulate<\strutht
+ \ht\b_tabl_tabulate\strutht
+ \fi
+ \ifdim\dp\b_tabl_tabulate<\strutdp
+ \dp\b_tabl_tabulate\strutdp
+ \fi
+ \fi}
+
+\def\tabl_tabulate_whitespace
+ {\ifdim\d_tabl_tabulate_splitoff_betweenskip>\zeropoint
+ \vskip\d_tabl_tabulate_splitoff_betweenskip
+ \global\d_tabl_tabulate_splitoff_betweenskip\zeropoint
+ \fi}
+
+\def\tabl_tabulate_check_whitespace
+ {\setbox\scratchbox\vpack
+ {\splitdiscards
+ \unskip
+ \ifdim\lastskip>\d_tabl_tabulate_splitoff_betweenskip
+ \global\d_tabl_tabulate_splitoff_betweenskip\lastskip
+ \fi}}
+
+\installtexdirective
+ {tabulate.linenumbers}
+ {\def\tabl_tabulate_check_linenumbers{\page_postprocessors_linenumbers_deepbox\b_tabl_tabulate}}
+ {\let\tabl_tabulate_check_linenumbers\relax}
+
+\let\tabl_tabulate_check_linenumbers\relax
+
+\def\tabl_tabulate_splitoff_box
+ {\dontcomplain
+ \global\setbox\b_tabl_tabulate\vsplit\b_tabl_tabulate_current\c_tabl_tabulate_column to \lineheight % % % global ? % % %
+ \setbox\b_tabl_tabulate\vbox
+ {\unvbox\b_tabl_tabulate}%
+ \ifconditional\c_tabl_tabulate_splitoff_whitespace
+ \tabl_tabulate_check_whitespace
+ \fi
+ \tabl_tabulate_color_repeat % needs to end up in a cell
+ \setbox\b_tabl_tabulate\hpack to \wd\b_tabl_tabulate
+ {\hss\tabl_tabulate_hook_yes{\box\b_tabl_tabulate}\hss}%
+ \tabl_tabulate_normalize_splitline
+ \tabl_tabulate_check_linenumbers
+ \box\b_tabl_tabulate}
+
+\protected\def\tabl_tabulate_hook_nop
+ {}
+
+\let\tabl_tabulate_hook\tabl_tabulate_hook_nop
+
+\def\tabl_tabulate_hook_yes{\begincsname\??tabulatehook\the\c_tabl_tabulate_column\endcsname}
+
+\def\tabl_tabulate_pheight_reset
+ {\global\c_tabl_tabulate_plines_min\plusone
+ \ifdim\d_tabl_tabulate_height_p_max>\zeropoint
+ \getnoflines\d_tabl_tabulate_height_p_max
+ \global\c_tabl_tabulate_plines_max\noflines
+ \else
+ \global\c_tabl_tabulate_plines_max\zerocount
+ \fi
+ \global\d_tabl_tabulate_height_p_max\zeropoint}
+
+\def\tabl_tabulate_pheight_set
+ {\scratchdimen\ht\b_tabl_tabulate_current\c_tabl_tabulate_column\relax
+ \ifdim\scratchdimen>\d_tabl_tabulate_height_p_max
+ \global\d_tabl_tabulate_height_p_max\scratchdimen
+ \fi}
+
+\def\tabl_tabulate_pbreak_inject
+ {\ifconditional\c_tabl_tabulate_handlepbreak
+ \ifconditional\c_tabl_tabulate_nopbreak
+ \tabl_tabulate_nobreak_inject
+ \orelse\ifnum\c_tabl_tabulate_plines_max>\plusone
+ \ifnum\c_tabl_tabulate_plines_min=\plusone
+ \tabl_tabulate_nobreak_inject
+ \fi
+ \global\advance\c_tabl_tabulate_plines_min\plusone
+ \ifnum\c_tabl_tabulate_plines_min=\c_tabl_tabulate_plines_max\relax
+ \tabl_tabulate_nobreak_inject
+ \fi
+ \fi
+ \fi}
+
+\def\tabl_tabulate_pbreak_check
+ {\noalign\bgroup
+ \tabl_tabulate_pbreak_inject
+ \ifconditional\c_tabl_tabulate_splitoff_whitespace
+ \tabl_tabulate_whitespace
+ \fi
+ \egroup}
+
+%D \startbuffer
+%D \starttabulate[|c|p|p|]
+%D \NC \bf Alpha \NC \bf Beta \NC \bf Gamma \NC\NR
+%D \NC 1 \NC right indeed \NC definitely wrong \NC\NR
+%D \NC 2 \NC \thinrules[n=3] \NC \thinrules[n=3] \NC\NR
+%D \NC 3 \NC oh yes \NC simply no \NC\NR
+%D \NC 4 \NC very true \NC as false as can be \NC\NR
+%D \NC 5 \NC \thinrules[n=5] \NC \thinrules[n=5] \NC\NR
+%D \NC 6 \NC \thinrules[n=3] \NC \thinrules[n=4] \NC\NR
+%D \stoptabulate
+%D \stopbuffer
+%D
+%D \typebuffer {\tracetabulatetrue\getbuffer}
+%D
+%D \startbuffer
+%D \starttabulate[|c|p|p|]
+%D \NC \bf Alpha \NC \bf Beta \NC \bf Gamma \NC\NR
+%D \NC 1 \NC right indeed \NC definitely wrong \NC\NR
+%D \NC 2 \NC oh yes \NC simply no \NC\NR
+%D \NC 3 \NC very true \NC as false as can be \NC\NR
+%D \NC 4 \NC the whole truth \NC but the truth \NC\NR
+%D \stoptabulate
+%D \stopbuffer
+%D
+%D \typebuffer {\tracetabulatetrue\getbuffer}
+
+%D Because we want to be compatible we use an indirect way to implement the
+%D definers. The next examples demonstrate the difference:
+%D
+%D \starttyping
+%D \definetabulate[test][|l|c|r|]
+%D \definetabulate[test][two][|r|c|l|]
+%D
+%D \definetabulation[more][format={|l|c|r|}]
+%D \definetabulation[more:two][format={|r|c|l|}]
+%D
+%D \starttest
+%D \NC t \NC t \NC t \NC \NR
+%D \NC te \NC te \NC te \NC \NR
+%D \NC tes \NC tes \NC tes \NC \NR
+%D \NC test \NC test \NC test \NC \NR
+%D \stoptest
+%D
+%D \starttest[two]
+%D \NC t \NC t \NC t \NC \NR
+%D \NC te \NC te \NC te \NC \NR
+%D \NC tes \NC tes \NC tes \NC \NR
+%D \NC test \NC test \NC test \NC \NR
+%D \stoptest
+%D \startmore
+%D \NC t \NC t \NC t \NC \NR
+%D \NC te \NC te \NC te \NC \NR
+%D \NC tes \NC tes \NC tes \NC \NR
+%D \NC test \NC test \NC test \NC \NR
+%D \stopmore
+%D
+%D \startmore[two]
+%D \NC t \NC t \NC t \NC \NR
+%D \NC te \NC te \NC te \NC \NR
+%D \NC tes \NC tes \NC tes \NC \NR
+%D \NC test \NC test \NC test \NC \NR
+%D \stopmore
+%D \stoptyping
+
+\installcorenamespace {tabulation}
+
+\installcommandhandler \??tabulation {tabulation} \??tabulation
+
+\setuptabulation
+ [\c!unit=1em,
+ EQ={:},
+ \c!format={|l|p|},
+ \c!frame=\v!off,
+ %\c!bodyfont=,
+ \c!rule=\v!normal,
+ %\c!rulecolor=,
+ \c!rulethickness=\linewidth,
+ %\c!inner=,
+ \c!before=\blank,
+ \c!after=\blank,
+ \c!distance={\v!depth,\v!medium},
+ \c!align=\v!normal,
+ \c!margin=\!!zeropoint,
+ \c!split=\v!auto,
+ \c!header=\v!yes,
+ %\c!title=,
+ \c!indenting=\v!no]
+
+\permanent\tolerant\protected\def\definetabulate[#1]#*[#2]#*[#3]%
+ {\ifarguments
+ % ignore
+ \or
+ % [tag]
+ \definetabulation[#1][\c!format={|l|p|},\s!check=]%
+ \or
+ % [tag] [template]
+ \definetabulation[#1][\c!format={#2},\s!check=]%
+ \or
+ % [tag] [sub] [template]
+ \ifcsname\namedtabulationhash{#1}\s!check\endcsname \else
+ \definetabulation[#1][\c!format={#3},\s!check=]%
+ \fi
+ \definetabulation[#1:#2][#1][\c!format={#3},\s!check=]%
+ \fi}
+
+\permanent\tolerant\protected\def\setuptabulate[#1]#*[#2]#*[#3]%
+ {\ifarguments
+ % ignore
+ \or
+ % [tag]
+ \setuptabulation[#1]%
+ \or
+ % [tag] [settings]
+ \setuptabulation[#1][#2]%
+ \or
+ % [tag] [sub] [settings]
+ \setuptabulation[#1:#2][#3]%
+ \fi}
+
+\appendtoks
+ \enforced\permanent\protected\edefcsname\e!start \currenttabulation\endcsname{\tabl_start_defined[\currenttabulation]}%
+ \enforced\aliased \letcsname \e!stop \currenttabulation\endcsname\relax
+ \enforced\aliased \letcsname \??tabulatehead\currenttabulation\endcsname\empty
+ \enforced\aliased \letcsname \??tabulatefoot\currenttabulation\endcsname\empty
+\to \everydefinetabulation
+
+\aliased \let\tabulateparameter\tabulationparameter % will stay for a while
+\permanent\def\currenttabulate {\currenttabulation} % will stay for a while
+
+% Here begins the implementation.
+
+\let\tabl_tabulate_insert_head\empty
+\let\tabl_tabulate_insert_body\empty
+\let\tabl_tabulate_insert_foot\empty
+
+\def\tabl_tabulate_insert_head_content
+ {\noalign{\global\settrue\c_tabl_tabulate_someamble}%
+ \begincsname\??tabulatehead\currenttabulation\endcsname
+ \noalign{\global\setfalse\c_tabl_tabulate_someamble}}%
+
+\def\tabl_tabulate_insert_foot_content
+ {\noalign{\global\settrue\c_tabl_tabulate_someamble}%
+ \begincsname\??tabulatefoot\currenttabulation\endcsname
+ \noalign{\global\setfalse\c_tabl_tabulate_someamble}}%
+
+\def\tabl_tabulate_check_full_content % - needed, else confusion with \c!header
+ {\ifcsname\??tabulatehead\currenttabulation\endcsname
+ %\expandafter\ifempty\csname\??tabulatehead\currenttabulation\endcsname
+ %\expandafter\ifempty\lastnamedcs
+ \ifempty\lastnamedcs
+ \let\tabl_tabulate_insert_head\empty
+ \else
+ \let\tabl_tabulate_insert_head\tabl_tabulate_insert_head_content
+ \fi
+ \else
+ \let\tabl_tabulate_insert_head\empty
+ \fi
+ \ifcsname\??tabulatefoot\currenttabulation\endcsname
+ %\expandafter\ifempty\csname\??tabulatefoot\currenttabulation\endcsname
+ %\expandafter\ifempty\lastnamedcs
+ \ifempty\lastnamedcs
+ \let\tabl_tabulate_insert_foot\empty
+ \else
+ \let\tabl_tabulate_insert_foot\tabl_tabulate_insert_foot_content
+ \fi
+ \else
+ \let\tabl_tabulate_insert_foot\empty
+ \fi}
+
+\def\tabl_tabulate_insert_content
+ {\tabl_tabulate_insert_head
+ \ifcase\c_tabl_tabulate_repeathead \else
+ \noalign{\penalty\zerocount}% added 7/5/2014 WS mail
+ \fi
+ \tabl_tabulate_insert_body
+ \tabl_tabulate_insert_foot
+ \tabl_tabulate_remove_funny_line}
+
+\def\tabl_tabulate_remove_funny_line
+ {\ifhmode
+ \strut\crcr
+ \noalign{\kern-\lineheight}%
+ \fi}
+
+% todo: make footer synonym to tail
+
+\permanent\protected\defcsname\e!start\v!tabulatehead\endcsname{\doifelsenextoptionalcs\tabl_tabulate_start_head_yes\tabl_tabulate_start_head_nop}
+\permanent\protected\defcsname\e!start\v!tabulatetail\endcsname{\doifelsenextoptionalcs\tabl_tabulate_start_foot_yes\tabl_tabulate_start_foot_nop}
+
+\let\m_tabl_tabulate_data\empty
+
+\def\tabl_tabulate_start_head_yes[#1]%
+ {\processcontent{\e!stop\v!tabulatehead}\m_tabl_tabulate_data{\letvalue{\??tabulatehead#1}\m_tabl_tabulate_data}}
+
+\def\tabl_tabulate_start_foot_yes[#1]%
+ {\processcontent{\e!stop\v!tabulatetail}\m_tabl_tabulate_data{\letvalue{\??tabulatefoot#1}\m_tabl_tabulate_data}}
+
+\def\tabl_tabulate_start_head_nop{\tabl_tabulate_start_head_yes[\v!tabulate]}
+\def\tabl_tabulate_start_foot_nop{\tabl_tabulate_start_foot_yes[\v!tabulate]}
+
+\protected\def\tabl_start_defined[#1]%
+ {\bgroup
+ \edef\currenttabulationparent{#1}%
+ \let\currenttabulation\currenttabulationparent
+ \iftok{\tabulationparameter\c!format}{\v!none}%
+ % this is special case: we need to define the generic english
+ % \starttabulate in other interfaces as well
+ \lettabulationparameter\c!format\tabl_default_format
+ \expandafter\tabl_start_regular
+ \else
+ \expandafter\tabl_start_defined_indeed
+ \fi}
+
+\tolerant\def\tabl_start_defined_indeed[#1]#*[#2]%
+ {\ifarguments\or
+ \ifhastok={#1}%
+ \setuptabulation[\currenttabulation][#1]%
+ \else
+ \edef\currenttabulation{\currenttabulation:#1}%
+ \fi
+ \else
+ \edef\currenttabulation{\currenttabulation:#1}%
+ \setuptabulation[\currenttabulation][#2]%
+ \fi
+ \tabl_tabulate_start_building}
+
+% \definetabulate[\v!tabulate][|l|p|] % we need to get rid of this one
+
+\def\tabl_default_format{|l|p|} % actually format is always set
+
+\permanent\protected\setuvalue{\e!start\v!tabulate}%
+ {\bgroup % whole thing
+ \let\currenttabulationparent\empty
+ \tabl_start_regular}
+
+% \tolerant\protected\def\tabl_start_regular[#1]#*[#2]% [format] | [settings] | [format] [settings] | [settings] [format]
+% {\let\currenttabulation\currenttabulationparent
+% \iftok{#1}\emptytoks
+% \ifhastok={#2}\relax
+% \setupcurrenttabulation[#2]%
+% \fi
+% \orelse\ifhastok={#1}\relax
+% \iftok{#2}\emptytoks\else
+% \settabulationparameter\c!format{#2}%
+% \fi
+% \setupcurrenttabulation[#1]%
+% \else
+% \settabulationparameter\c!format{#1}%
+% \ifhastok={#2}\relax
+% \setupcurrenttabulation[#2]%
+% \fi
+% \fi
+% \tabl_tabulate_start_building}
+
+\tolerant\protected\def\tabl_start_regular[#1]#*[#2]% [format] | [settings] | [format] [settings] | [settings] [format]
+ {\let\currenttabulation\currenttabulationparent
+ \iftok{#1}\emptytoks
+ \ifhastok={#2}\relax
+ \setupcurrenttabulation[#2]%
+ \fi
+ \orelse\ifhastok={#1}\relax
+ \iftok{#2}\emptytoks\else
+ \settabulationparameter\c!format{#2}%
+ \fi
+ \setupcurrenttabulation[#1]%
+ \else
+ \iftok{#1}\emptytoks\else
+ \settabulationparameter\c!format{#1}%
+ \fi
+ \ifhastok={#2}\relax
+ \setupcurrenttabulation[#2]%
+ \fi
+ \fi
+ \tabl_tabulate_start_building}
+
+\permanent\letcsname\e!stop\v!tabulate \endcsname\relax
+\permanent\letcsname\e!stop\v!tabulatehead\endcsname\relax
+\permanent\letcsname\e!stop\v!tabulatetail\endcsname\relax
+
+\permanent\protected\def\tabl_tabulate_start_ignore % todo when we go frozen
+ {\em Nested tabulate is not (yet) supported.\relax
+ \expandafter\gobbleuntil\csname\ifconditional\c_tabl_generic stoptabulate\else\e!stop\v!tabulate\fi\endcsname}
+
+\appendtoks
+ \enforced\letvalue{\e!start\v!tabulate}\tabl_tabulate_start_ignore % only the main one
+\to \everytabulate
+
+\defcsname\??tabulatesplit\v!yes \endcsname{\settrue\c_tabl_tabulate_split}
+\defcsname\??tabulatesplit\v!repeat\endcsname{\settrue\c_tabl_tabulate_split}
+\defcsname\??tabulatesplit\v!no \endcsname{\setfalse\c_tabl_tabulate_split}
+\defcsname\??tabulatesplit\v!auto \endcsname{\ifinsidefloat\ifinsidesplitfloat\else\setfalse\c_tabl_tabulate_split\fi\fi}
+
+% todo: spacing around tabulate when bodyfont is set
+
+% \let\tabl_tabulate_inside_before \relax
+% \let\tabl_tabulate_inside_after \relax
+% \let\tabl_tabulate_inside_inbetween\relax
+%
+% \def\tabl_tabulate_outside_before
+% {\whitespace
+% \tabulationparameter\c!before}
+%
+% \def\tabl_tabulate_outside_after
+% {\tabulationparameter\c!after}
+
+% \showboxes
+%
+% \startcombination
+% {\insidefloattrue \starttabulate[|||] \NC test \NC test \NC \NR \stoptabulate} {}
+% {\insidefloattrue \starttabulate[|||] \NC test \NC test \NC \NR \stoptabulate} {}
+% \stopcombination
+%
+% \startcombination
+% {\vbox{\starttabulate[|||] \NC test \NC test \NC \NR \stoptabulate}} {}
+% {\vbox{\starttabulate[|||] \NC test \NC test \NC \NR \stoptabulate}} {}
+% \stopcombination
+%
+% \startcombination
+% {\starttabulate[|||] \NC test \NC test \NC \NR \stoptabulate} {}
+% {\starttabulate[|||] \NC test \NC test \NC \NR \stoptabulate} {}
+% \stopcombination
+
+\let\tabl_tabulate_inside_after \relax
+\let\tabl_tabulate_outside_after \relax
+\let\tabl_tabulate_inside_inbetween \relax
+\let\tabl_tabulate_outside_inbetween\relax
+
+\protected\def\tabl_tabulate_inside_before
+ {\ifhmode\par\fi
+ \ifhmode
+ \ifinsidesplitfloat
+ \let\tabl_tabulate_inside_after\relax
+ \else
+ \vbox\bgroup
+ \let\tabl_tabulate_inside_after\egroup
+ \fi
+ \else
+ \let\tabl_tabulate_inside_after\relax
+ \fi}
+
+\protected\def\tabl_tabulate_outside_before
+ {\ifhmode\par\fi
+ \ifhmode
+ \vbox\bgroup
+ \let\tabl_tabulate_outside_after \egroup
+ \let\tabl_tabulate_outside_inbetween\relax
+ \orelse\ifinner
+ \let\tabl_tabulate_outside_after \relax
+ \let\tabl_tabulate_outside_inbetween\relax
+ \else
+ \whitespace
+ \tabulationparameter\c!before
+ \relax
+ \let\tabl_tabulate_outside_after \tabl_tabulate_outside_after_indeed
+ \let\tabl_tabulate_outside_inbetween\tabl_tabulate_outside_inbetween_indeed
+ \fi}
+
+\def\tabl_tabulate_outside_after_indeed
+ {\tabulationparameter\c!after}
+
+\def\tabl_tabulate_outside_inbetween_indeed
+ {\doifempty{\tabulationparameter\c!after}
+ {\vskip\strutdp
+ \verticalstrut
+ \vskip-\struttotal}}
+
+\def\tabl_tabulate_inside_inbetween % needs checking
+ {\doifempty{\tabulationparameter\c!after}
+ {\vskip\strutdp
+ \verticalstrut
+ \vskip-\struttotal}}
+
+\protected\def\tabl_tabulate_start_building
+ {\ifinsidefloat
+ \tabl_tabulate_inside_before
+ \else
+ \tabl_tabulate_outside_before
+ \fi
+ \bgroup % settings
+ %
+ \t_tabl_tabulate_preamble\emptytoks
+ \t_tabl_tabulate_dummy \emptytoks
+ %
+ \resetcharacteralign
+ %
+ \edef\p_distance {\tabulationparameter\c!distance}%
+ \edef\p_align {\tabulationparameter\c!align}%
+ \edef\p_line {\tabulationparameter\c!rule}%
+ \edef\p_rulecolor {\tabulationparameter\c!rulecolor}%
+ \edef\p_rulethickness{\tabulationparameter\c!rulethickness}%
+ \edef\p_bodyfont {\tabulationparameter\c!bodyfont}%
+ \edef\p_indenting {\tabulationparameter\c!indenting}%
+ \edef\p_keeptogether {\tabulationparameter\c!keeptogether}%
+ \edef\p_blank {\tabulationparameter\c!blank}%
+ %
+ \ifx\p_keeptogether\v!no
+ \settrue \c_tabl_tabulate_tolerant_break
+ %\setfalse\c_tabl_tabulate_handlepbreak
+ \else
+ \setfalse\c_tabl_tabulate_tolerant_break
+ %\settrue \c_tabl_tabulate_handlepbreak
+ \fi
+ %
+ \settrue\c_tabl_tabulate_split
+ \begincsname\??tabulatesplit\tabulationparameter\c!split\endcsname
+ %
+ \let\m_tabl_tabulate_blank_default\p_blank
+ %
+ \d_tabl_tabulate_unit\tabulationparameter\c!unit
+ \d_tabl_tabulate_margin\tabulationparameter\c!margin
+ \let\m_tabl_tabulate_vrule_color_default\p_rulecolor
+ \let\m_tabl_tabulate_hrule_color_default\p_rulecolor
+ \d_tabl_tabulate_vrulethickness_default\p_rulethickness
+ \d_tabl_tabulate_hrulethickness_default\p_rulethickness
+ \ifempty\p_bodyfont\else
+ \switchtobodyfont[\p_bodyfont]%
+ \fi
+ \postponenotes % new, to be tested / will be configurable
+ \widowpenalty\zerocount % otherwise lines are not broken
+ \clubpenalty \zerocount % but overlap in funny ways
+ \the\everytabulate
+ \tabulationparameter\c!inner
+ \d_tabl_tabulate_indent\dimexpr\leftskip+\hangindent\ifx\p_indenting\v!yes+\parindent\fi\relax
+ \global\c_tabl_tabulate_column\zerocount
+ \processcontent % stoptabulate needs to match the frozen one
+ {\ifconditional\c_tabl_generic stoptabulate\else\e!stop\ifempty\currenttabulationparent\v!tabulate\else\currenttabulationparent\fi\fi}
+ \tabl_tabulate_insert_body
+ \tabl_tabulate_process}
+
+\permanent\protected\def\tabulateEQ
+ {\ifconditional\c_tabl_tabulate_firstflushed\else
+ \dostarttaggedchained\t!ignore\empty\empty
+ \dostarttagged\t!ignore\empty
+ \tabulationparameter{EQ}%
+ \dostoptagged
+ \dostoptagged
+ \fi
+ \global\setfalse\c_tabl_tabulate_equal}
+
+% The next ones will be token registers
+
+\let\tabulatenormalpos\relax % hooks, todo
+\let\tabulateequalpos \relax % hooks, todo
+
+% color columns
+
+\let\m_tabl_tabulate_color_previous \empty
+\let\m_tabl_tabulate_color \empty
+\let\m_tabl_tabulate_text_color \empty
+\let\m_tabl_tabulate_color_local \empty
+\let\m_tabl_tabulate_vrule_color \empty
+\let\m_tabl_tabulate_vrule_color_local \empty
+\let\m_tabl_tabulate_vrule_color_default\empty % used local
+\let\m_tabl_tabulate_hrule_color_default\empty % used local
+\let\m_tabl_tabulate_blank_default \empty
+
+\appendtoks
+ \glet \m_tabl_tabulate_color_previous \empty
+ \glet \m_tabl_tabulate_color \empty
+ \glet \m_tabl_tabulate_text_color \empty
+ \glet \m_tabl_tabulate_color_local \empty
+ \glet \m_tabl_tabulate_vrule_color \empty
+ \glet \m_tabl_tabulate_vrule_color_local \empty
+ \global\d_tabl_tabulate_vrulethickness_local\zeropoint
+\to \t_tabl_tabulate_every_row
+
+\protected\def\tabl_tabulate_color_side_right_second
+ {\ifempty\m_tabl_tabulate_color_previous \else
+ \tabl_tabulate_color_set\m_tabl_tabulate_color_previous
+ \glet\m_tabl_tabulate_color_previous\empty
+ \fi}
+
+\protected\def\tabl_tabulate_color_side_left_second
+ {\ifempty\m_tabl_tabulate_color \else
+ \ifcase\c_tabl_tabulate_colorspan
+ \or
+ \tabl_tabulate_color_set\m_tabl_tabulate_color
+ \or
+ \tabl_tabulate_color_set\m_tabl_tabulate_color
+ \fi
+ \fi}
+
+\protected\def\tabl_tabulate_color_side_both_second
+ {\ifempty\m_tabl_tabulate_color \else
+ \tabl_tabulate_color_set\m_tabl_tabulate_color
+ \ifcase\c_tabl_tabulate_colorspan
+ %\glet\m_tabl_tabulate_color_previous\empty
+ \or
+ \glet\m_tabl_tabulate_color_previous\empty
+ \or
+ \glet\m_tabl_tabulate_color_previous\m_tabl_tabulate_color
+ \or
+ \glet\m_tabl_tabulate_color_previous\m_tabl_tabulate_color
+ \fi
+ \fi}
+
+\let\tabl_tabulate_color_side_right \relax
+\let\tabl_tabulate_color_side_left \relax
+\let\tabl_tabulate_color_side_both \relax
+
+\appendtoks
+ \let\tabl_tabulate_color_side_right\tabl_tabulate_color_side_right_second
+ \let\tabl_tabulate_color_side_left \tabl_tabulate_color_side_left_second
+ \let\tabl_tabulate_color_side_both \tabl_tabulate_color_side_both_second
+\to \t_tabl_tabulate_initializers_second
+
+\def\tabl_tabulate_set_color_column#1% overloaded / todo
+ {\unskip
+ \doifelsefastoptionalcheck{\tabl_tabulate_set_color_column_yes#1}{\tabl_tabulate_set_color_column_nop#1}}
+
+\def\tabl_tabulate_set_color_column_nop
+ {\tabl_tabulate_column_normal\zerocount}
+
+\def\tabl_tabulate_set_color_column_yes#1[#2]%
+ {\xdef\m_tabl_tabulate_color_local{#2}%
+ \tabl_tabulate_column_normal\zerocount#1}
+
+% normal columns:
+
+\def\tabl_tabulate_column_normal#1#2%
+ {\unskip
+ \aligntab
+ \ifconditional\c_tabl_tabulate_equal\tabulateequalpos\else\tabulatenormalpos\fi
+ \ifnum\c_tabl_tabulate_column>\c_tabl_tabulate_max_vrulecolumn\else
+ \tabl_tabulate_column_vrule_setup
+ \fi
+ \aligntab
+ \global\c_tabl_tabulate_kind#1%
+ \global\c_tabl_tabulate_type#2%
+ \aligntab}
+
+% equal columns
+
+\def\tabl_tabulate_column_equal#1#2%
+ {\unskip
+ \aligntab
+ \tabulateequalpos
+ \aligntab
+ \global\c_tabl_tabulate_kind#1%
+ \global\c_tabl_tabulate_type#2%
+ \aligntab}
+
+% ruled columns
+
+\def\tabl_tabulate_column_vruled_preset
+ {\glet\m_tabl_tabulate_vrule_color_local\m_tabl_tabulate_vrule_color_default
+ \global\d_tabl_tabulate_vrulethickness_local\d_tabl_tabulate_vrulethickness_default}
+
+\def\tabl_tabulate_column_vruled#1#2%
+ {\unskip % 0-n
+ %\ifnum\c_tabl_tabulate_column=\plusone
+ % \global\c_tabl_tabulate_has_rule_spec_first\plusone
+ %\orelse\ifnum\c_tabl_tabulate_column=\c_tabl_tabulate_nofcolumns
+ % \global\c_tabl_tabulate_has_rule_spec_last\plusone
+ %\fi
+ \ifnum\c_tabl_tabulate_column>\c_tabl_tabulate_max_vrulecolumn
+ \global\c_tabl_tabulate_max_vrulecolumn\c_tabl_tabulate_column
+ \fi
+ \doifelsefastoptionalcheck{\tabl_tabulate_column_vruled_yes#1#2}{\tabl_tabulate_column_vruled_nop#1#2}}
+
+\def\tabl_tabulate_column_vrule_setup
+ {\begincsname\??tabulatevrule\the\c_tabl_tabulate_column\endcsname}
+
+\def\tabl_tabulate_column_vruled_nop
+ {\gletcsname\??tabulatevrule\the\c_tabl_tabulate_column\endcsname\tabl_tabulate_column_vruled_preset
+ \tabl_tabulate_column_normal}
+
+\def\tabl_tabulate_column_vruled_step#1%
+ {\doifelsenumber{#1}%
+ {\global\d_tabl_tabulate_vrulethickness_local#1\d_tabl_tabulate_vrulethickness_default}
+ {\xdef\m_tabl_tabulate_vrule_color_local{#1}}}
+
+\def\tabl_tabulate_column_vruled_yes#1#2[#3]%
+ {\gdefcsname\??tabulatevrule\the\c_tabl_tabulate_column\endcsname
+ {\tabl_tabulate_column_vruled_preset
+ \rawprocesscommalist[#3]\tabl_tabulate_column_vruled_step}%
+ \tabl_tabulate_column_normal#1#2}
+
+\def\tabl_tabulate_vrule_reset
+ {\ifcase\c_tabl_tabulate_max_vrulecolumn\else
+ \tabl_tabulate_vrule_reset_indeed
+ \fi}
+
+\def\tabl_tabulate_vrule_reset_indeed
+ {\dofastloopcs\c_tabl_tabulate_max_vrulecolumn\tabl_tabulate_vrule_reset_step
+ \global\c_tabl_tabulate_max_vrulecolumn\zerocount}
+
+\def\tabl_tabulate_vrule_reset_step % undefined or relax
+ {\gletcsname\??tabulatevrule\the\fastloopindex\endcsname\undefined}
+
+\appendtoks
+ \tabl_tabulate_vrule_reset
+\to \t_tabl_tabulate_every_after_row
+
+\def\tabl_tabulate_column_vruled_normal
+ {\vrule\s!width\d_tabl_tabulate_vrulethickness\relax}
+
+\def\tabl_tabulate_column_vruled_colored
+ {\dousecolorparameter\m_tabl_tabulate_vrule_color
+ \vrule\s!width\d_tabl_tabulate_vrulethickness\relax}
+
+\protected\def\tabl_tabulate_column_vrule_inject_first
+ {\ifcase\d_tabl_tabulate_vrulethickness\else
+ \tabl_tabulate_column_vruled_normal % could be a skip instead
+ \fi
+ \global\d_tabl_tabulate_vrulethickness\zeropoint} % nils second one
+
+\protected\def\tabl_tabulate_column_vrule_inject_second
+ {\ifcase\d_tabl_tabulate_vrulethickness\else
+ \ifempty\m_tabl_tabulate_vrule_color
+ \tabl_tabulate_column_vruled_normal
+ \else
+ \tabl_tabulate_column_vruled_colored
+ \fi
+ \fi
+ \global\d_tabl_tabulate_vrulethickness\zeropoint} % nils second one
+
+\let\tabl_tabulate_column_vrule_inject\relax
+
+\appendtoks
+ \let\tabl_tabulate_column_vrule_inject\tabl_tabulate_column_vrule_inject_first
+\to \t_tabl_tabulate_initializers_first
+
+\appendtoks
+ \let\tabl_tabulate_column_vrule_inject\tabl_tabulate_column_vrule_inject_second
+\to \t_tabl_tabulate_initializers_second
+
+% auto columns
+
+\def\tabl_tabulate_column_inject_auto
+ {\tabl_tabulate_column_normal\zerocount\zerocount
+ \ifnum\c_tabl_tabulate_column>\c_tabl_tabulate_columns\relax
+ \expandafter\NR
+ \else
+ \expandafter\ignorespaces % interferes with the more tricky hooks
+ \fi}
+
+\protected\def\tabl_tabulate_set_quick#1% see \startlegend \startgiven (for the moment still public)
+ {\enforced\let#1\tabl_tabulate_column_inject_auto
+ \enforced\let\\\tabl_tabulate_column_inject_auto} % brrr, will go
+
+\defcsname\??tabulateseparator\v!blank \endcsname{\s_tabl_tabulate_separator\bigskipamount}
+\defcsname\??tabulateseparator\v!depth \endcsname{\s_tabl_tabulate_separator\strutdp}
+\defcsname\??tabulateseparator\v!small \endcsname{\def\m_tabl_tabulate_separator_factor{.25}}
+\defcsname\??tabulateseparator\v!medium\endcsname{\def\m_tabl_tabulate_separator_factor{.5}}
+\defcsname\??tabulateseparator\v!big \endcsname{}
+\defcsname\??tabulateseparator\v!none \endcsname{\s_tabl_tabulate_separator\zeropoint\let\m_tabl_tabulate_separator_factor\zerocount}
+\defcsname\??tabulateseparator\v!grid \endcsname{\s_tabl_tabulate_separator\zeropoint\let\m_tabl_tabulate_separator_factor\zerocount}
+
+\def\tabl_tabulate_column_rule_separator_step#1%
+ {\ifcsname\??tabulateseparator#1\endcsname
+ \lastnamedcs
+ \else
+ \s_tabl_tabulate_separator#1\relax
+ \fi}
+
+\def\tabl_tabulate_column_rule_separator_inject % can be sped up (will do when used frequently)
+ {\bgroup
+ \s_tabl_tabulate_separator\strutdp
+ \ifempty\p_distance\else
+ \let\m_tabl_tabulate_separator_factor\plusone
+ \processcommacommand[\p_distance]\tabl_tabulate_column_rule_separator_step
+ \s_tabl_tabulate_separator\m_tabl_tabulate_separator_factor\s_tabl_tabulate_separator
+ \fi
+ % someamble: footer or header: unfortunately a skip can trigger a page break (weird
+ % as we have lots of nobreaks)
+ % \ifconditional\c_tabl_tabulate_someamble\kern\else\vskip\fi\s_tabl_tabulate_separator % new
+ % \directvspacing{\the\s_tabl_tabulate_separator}% new
+ \directvskip\s_tabl_tabulate_separator
+ \egroup}
+
+\let\m_tabl_tabulate_hrule_color\empty
+
+\def\tabl_tabulate_hrule_preset_step#1%
+ {\doifelsenumber{#1}%
+ {\global\d_tabl_tabulate_hrulethickness_local#1\d_tabl_tabulate_hrulethickness_default}
+ {\xdef\m_tabl_tabulate_hrule_color{#1}}}
+
+\def\tabl_tabulate_hrule_preset[#1]%
+ {\glet\m_tabl_tabulate_hrule_color\m_tabl_tabulate_hrule_color_default
+ \global\d_tabl_tabulate_hrulethickness_local\d_tabl_tabulate_hrulethickness_default
+ \iftok{#1}\emptytoks\else\rawprocesscommalist[#1]\tabl_tabulate_hrule_preset_step\fi}
+
+\def\tabl_tabulate_hrule_inject_normal
+ {\autorule
+ \s!height.5\d_tabl_tabulate_hrulethickness_local
+ \s!depth .5\d_tabl_tabulate_hrulethickness_local
+ \s!left \d_tabl_tabulate_indent
+ \relax}
+
+\def\tabl_tabulate_hrule_inject_colored
+ {\dousecolorparameter\m_tabl_tabulate_hrule_color
+ \tabl_tabulate_hrule_inject_normal}
+
+\protected\def\tabl_tabulate_hrule_inject_first
+ {\ifcase\d_tabl_tabulate_hrulethickness_local\else
+ \tabl_tabulate_hrule_inject_normal
+ \fi}
+
+\protected\def\tabl_tabulate_hrule_inject_second
+ {\ifcase\d_tabl_tabulate_hrulethickness_local\else
+ \ifempty\m_tabl_tabulate_hrule_color
+ \tabl_tabulate_hrule_inject_normal
+ \else
+ \tabl_tabulate_hrule_inject_colored
+ \fi
+ \fi}
+
+\let\tabl_tabulate_hrule_inject\relax
+
+\appendtoks
+ \let\tabl_tabulate_hrule_inject\tabl_tabulate_hrule_inject_first
+\to \t_tabl_tabulate_initializers_first
+
+\appendtoks
+ \let\tabl_tabulate_hrule_inject\tabl_tabulate_hrule_inject_second
+\to \t_tabl_tabulate_initializers_second
+
+%D Color:
+
+% \starttabulate[||p||]
+% \NC test \NC test \NC test \NC \NR
+% \NC test \CC[green] \input tufte \CC[yellow] test \NC \NR
+% \NC test \NC test \NC test \NC \NR
+% \NC test \NC test \NC test \NC \NR
+% \NC test \NC test \NC test \NC \NR
+% \NC test \NC test \NC test \NC \NR
+% \CC[blue] test \CC[red] test \NC test \NC \NR
+% \NC test \NC test \NC test \NC \NR
+% \NC test \NC test \NC test \NC \NR
+% \NC test \NC test \NC test \NC \NR
+% \NC test \NC test \CC[gray] test \NC \NR
+% \NC test \NC test \NC test \NC \NR
+% \NC test \NC test \NC test \NC \NR
+% \CC[blue] test \NC test \NC test \NC \NR
+% \NC test \NC test \NC test \NC \NR
+% \NC test \NC test \CC[magenta] test \NC \NR
+% \NC test \NC test \NC test \NC \NR
+% \NC test \CC[cyan] \dorecurse{10}{\input ward }\NC test \NC \NR
+% \NC test \NC test \NC test \NC \NR
+% \NC test \CC[yellow] test \NC test \NC \NR
+% \stoptabulate
+
+\protected\def\tabl_tabulate_color_set#1% we could store the attributes at the cost of a lua call
+ {\begingroup
+ \clf_enablebackgroundalign % was \node_backgrounds_align_initialize
+ \glet\tabl_tabulate_color_repeat\tabl_tabulate_color_repeat_second
+ \ifnum\c_tabl_tabulate_column>\c_tabl_tabulate_max_colorcolumn
+ \global\c_tabl_tabulate_max_colorcolumn\c_tabl_tabulate_column
+ \fi
+ \xdefcsname\??tabulatecolor\the\c_tabl_tabulate_column\endcsname{#1}%
+ \hpack \thealignbackgroundcolorattr{#1}{}% pack ?
+ \endgroup}
+
+\def\tabl_tabulate_color_repeat_second % for split off lines
+ {\begingroup
+ \scratchcounter\numexpr\c_tabl_tabulate_column-\plusone\relax % ugly !
+ \ifcsname\??tabulatecolor\the\scratchcounter\endcsname
+ % \hbox \thealignbackgroundcolorattr{\csname\??tabulatecolor\the\scratchcounter\endcsname}{}% pack ?
+ \hpack \expandafter\thealignbackgroundcolorattr\expandafter{\lastnamedcs}{}% pack ?
+ \fi
+ \endgroup}
+
+\let\tabl_tabulate_color_repeat\relax
+
+\appendtoks
+ \let\tabl_tabulate_color_repeat\relax
+\to \everytabulate
+
+\def\tabl_tabulate_color_reset
+ {\ifcase\c_tabl_tabulate_max_colorcolumn\else
+ \tabl_tabulate_color_reset_indeed
+ \fi}
+
+% \def\tabl_tabulate_color_reset_indeed
+% {\dorecurse\c_tabl_tabulate_max_colorcolumn{\letgvalue{\??tabulatecolor\recurselevel}\undefined}} % slow
+
+\def\tabl_tabulate_color_reset_indeed
+ {\dofastloopcs\c_tabl_tabulate_max_colorcolumn\tabl_tabulate_color_reset_step}
+
+\def\tabl_tabulate_color_reset_step % undefined or empty?
+ {\gletcsname\??tabulatecolor\number\fastloopindex\endcsname\undefined}
+
+\appendtoks
+ \tabl_tabulate_color_reset
+\to \t_tabl_tabulate_every_after_row
+
+% \def\tabl_tabulate_register_par_options_indeed
+% {\iftrialtypesetting \else
+% \registerparoptions
+% \ifinsidefloat
+% % that is, an unbreakable one
+% \glet\tabl_tabulate_register_par_options\empty
+% \else
+% % unsafe in crossing pages, at each b...
+% % \glet\tabl_tabulate_register_par_options\empty
+% \fi
+% \fi}
+%
+% \appendtoks
+% \glet\tabl_tabulate_register_par_options\tabl_tabulate_register_par_options_indeed
+% \to \everytabulate
+
+\def\tabl_tabulate_register_par_options_first % maybe track here if needed
+ {}
+
+\def\tabl_tabulate_register_par_options_second
+ {\registerparoptions
+ \ifinsidefloat
+ % that is, an unbreakable one
+ \glet\tabl_tabulate_register_par_options\empty
+ \else
+ % unsafe in crossing pages, at each b...
+ % \glet\tabl_tabulate_register_par_options\empty
+ \fi}
+
+\let\tabl_tabulate_register_par_options\relax
+
+\appendtoks
+ \let\tabl_tabulate_register_par_options\tabl_tabulate_register_par_options_first
+\to \t_tabl_tabulate_initializers_first
+
+\appendtoks
+ \let\tabl_tabulate_register_par_options\tabl_tabulate_register_par_options_second
+\to \t_tabl_tabulate_initializers_second
+
+\appendtoks
+ \tabl_tabulate_register_par_options
+\to \t_tabl_tabulate_every_row
+
+\def\tabl_tabulate_flush_indent_indeed
+ {\hbox to \d_tabl_tabulate_indent % pack ?
+ {% we now have a local hsize, and since we want to
+ % register positional info (i.e. real hsizes) we
+ % need to reconstitute the original hsize
+ \advance\hsize\d_tabl_tabulate_indent
+ % this is indeed rather messy and took a few hours
+ % to dis/uncover
+ \the\t_tabl_tabulate_every_row
+ \hss}}
+
+\def\tabl_tabulate_flush_indent
+ {\ifnum\c_tabl_tabulate_column=\zerocount
+ \tabl_tabulate_flush_indent_indeed
+ \fi}
+
+\def\tabl_tabulate_digits{\digits}
+
+%D Beware, we cannot use \type {\protected} on \type {\HL} cum suis, since \TEX's
+%D hard coded noalign lookahead fails on it! I mistakenly added this for a while.
+
+\defcsname\??tabulatealigning\v!normal\endcsname{0}
+\defcsname\??tabulatealigning\v!right \endcsname{1}
+\defcsname\??tabulatealigning\v!left \endcsname{2}
+\defcsname\??tabulatealigning\v!middle\endcsname{3}
+
+\defcsname\??tabulateheader\v!repeat\endcsname{\plusone}
+\defcsname\??tabulateheader\v!text \endcsname{\plustwo}
+
+\protected\def\tabl_tabulate_bskip_first {\setbox\b_tabl_tabulate\vbox\bgroup\glet\tabl_tabulate_hook\tabl_tabulate_hook_nop}
+\protected\def\tabl_tabulate_eskip_first {\par\egroup\glet\tabl_tabulate_hook\tabl_tabulate_hook_yes}
+\protected\def\tabl_tabulate_xbskip_first{\hpack\bgroup\vbox\bgroup\glet\tabl_tabulate_hook\tabl_tabulate_hook_nop}
+\protected\def\tabl_tabulate_xeskip_first{\par\egroup\egroup\glet\tabl_tabulate_hook\tabl_tabulate_hook_yes}
+
+\let\tabl_tabulate_bbskip\relax
+\let\tabl_tabulate_eeskip\relax
+\let\tabl_tabulate_bskip \relax
+\let\tabl_tabulate_eskip \relax
+\let\tabl_tabulate_xbskip\relax
+\let\tabl_tabulate_xeskip\relax
+
+\appendtoks
+ \let\tabl_tabulate_bbskip\relax
+ %\let\tabl_tabulate_eeskip\relax % adapted by bskip
+ \let\tabl_tabulate_bskip \tabl_tabulate_bskip_first
+ \let\tabl_tabulate_eskip \tabl_tabulate_eskip_first
+ \let\tabl_tabulate_xbskip\tabl_tabulate_xbskip_first
+ \let\tabl_tabulate_xeskip\tabl_tabulate_xeskip_first
+\to \t_tabl_tabulate_initializers_first
+
+\def\tabl_tabulate_baselinecorrection % keep an eye on this one
+ {\def\dobaselinecorrection{\vskip\dimexpr-\prevdepth+\strutdp+\strutdp\relax}% todo: mkiv
+ \baselinecorrection}
+
+% some hack to prevent an allowbreak ... actually we could set up a system then
+% that is dealt with atthe lua end in the skip handler: turn penalties with attributes
+% values into other penalties that get removed
+
+\installcorenamespace{tabulatenobreak}
+
+\def\tabl_tabulate_break_allow{\directvpenalty\zerocount}
+\def\tabl_tabulate_break_maybe{\directvpenalty\zerocount}
+\def\tabl_tabulate_break_no {\directvpenalty\plustenthousand} % ,order:2}}
+
+\let\tabl_tabulate_break_state_set \relax
+\let\tabl_tabulate_break_state_reset \relax
+\let\tabl_tabulate_break_state_allowbreak\tabl_tabulate_break_maybe
+
+% so far
+
+\permanent\protected\def\tabl_tabulate_VL_first{\tabl_tabulate_column_vruled\zerocount\zerocount}
+\permanent\protected\def\tabl_tabulate_NC_first{\tabl_tabulate_column_normal\zerocount\zerocount}
+\permanent\protected\def\tabl_tabulate_RC_first{\tabl_tabulate_column_normal\zerocount\plusone}
+\permanent\protected\def\tabl_tabulate_HC_first{\tabl_tabulate_column_normal\zerocount\plustwo}
+\permanent\protected\def\tabl_tabulate_EQ_first{\tabl_tabulate_column_equal \plustwo \zerocount}
+\permanent\protected\def\tabl_tabulate_RQ_first{\tabl_tabulate_column_equal \zerocount\plusone}
+\permanent\protected\def\tabl_tabulate_HQ_first{\tabl_tabulate_column_equal \zerocount\plustwo}
+
+\permanent\protected\def\tabl_tabulate_NG_first{\tabl_tabulate_column_normal\zerocount\zerocount}
+\permanent\protected\def\tabl_tabulate_NN_first{\tabl_tabulate_column_normal\zerocount\zerocount\tabl_tabulate_digits} % new, undocumented, test first
+\permanent\protected\def\tabl_tabulate_ND_first{\tabl_tabulate_column_normal\zerocount\zerocount\tabl_tabulate_digits} % same, for old times sake
+
+\permanent\protected\def\tabl_tabulate_NR_first {\tabl_tabulate_NR_common\conditionaltrue \tabl_tabulate_check_penalties} % next row
+\permanent\protected\def\tabl_tabulate_NB_first {\tabl_tabulate_NR_common\conditionaltrue \tabl_tabulate_nobreak_inject } % next row no break
+
+\permanent\protected\def\tabl_tabulate_NR_second{\tabl_tabulate_NR_common\conditionalfalse\tabl_tabulate_check_penalties} % next row
+\permanent\protected\def\tabl_tabulate_NB_second{\tabl_tabulate_NR_common\conditionalfalse\tabl_tabulate_nobreak_inject } % next row no break
+
+\permanent\protected\def\tabl_tabulate_CC_first{\global\c_tabl_tabulate_localcolorspan\zerocount\tabl_tabulate_set_color_column\zerocount}
+\permanent\protected\def\tabl_tabulate_CL_first{\global\c_tabl_tabulate_localcolorspan\plusone \tabl_tabulate_set_color_column\zerocount}
+\permanent\protected\def\tabl_tabulate_CM_first{\global\c_tabl_tabulate_localcolorspan\plustwo \tabl_tabulate_set_color_column\zerocount}
+\permanent\protected\def\tabl_tabulate_CR_first{\global\c_tabl_tabulate_localcolorspan\plusthree\tabl_tabulate_set_color_column\zerocount}
+
+%D Sort of special:
+%D
+%D \startbuffer
+%D \startitemize[n]
+%D \starttabulate[|||||]
+%D \NC p \NC \itemtag \NC q \NC r \NC \NR
+%D \NC p \NC \itemtag \NC q \NC r \NC \NR
+%D \NC p \NC \itemtag \NC q \NC r \NC \NR
+%D \NC p \NC \itemtag \NC q \NC r \NC \NR
+%D \stoptabulate
+%D \stopitemize
+%D
+%D \startitemize[n]
+%D \starttabulate[|||||]
+%D \NI b \NC c \NC d \NC \NR
+%D \NC a \NI c \NC d \NC \NR
+%D \NC a \NC b \NI d \NC \NR
+%D \NC a \NC b \NC c \NI \NR
+%D \stoptabulate
+%D \stopitemize
+%D \stopbuffer
+%D
+%D \typebuffer \getbuffer
+
+\permanent\tolerant\protected\def\tabl_tabulate_NI_first[#1]{\NC\itemtag[#1]\NC}
+
+%D The following shortcut is handy for tables where one needs bold headers:
+
+\permanent\protected\def\tabl_tabulate_BC_first
+ {\tabl_tabulate_column_normal\plusone\zerocount
+ \let\fontstyle\globalfontstyle
+ \bf}
+
+\appendtoks
+ \enforced\let\VL\tabl_tabulate_VL_first
+ \enforced\let\NC\tabl_tabulate_NC_first
+ \enforced\let\BC\tabl_tabulate_BC_first
+ \enforced\let\RC\tabl_tabulate_RC_first
+ \enforced\let\HC\tabl_tabulate_HC_first
+ \enforced\let\EQ\tabl_tabulate_EQ_first
+ \enforced\let\RQ\tabl_tabulate_RQ_first
+ \enforced\let\HQ\tabl_tabulate_HQ_first
+ \enforced\let\NG\tabl_tabulate_NG_first
+ \enforced\let\NN\tabl_tabulate_NN_first
+ \enforced\let\ND\tabl_tabulate_ND_first
+ \enforced\let\NR\tabl_tabulate_NR_first
+ \enforced\let\NB\tabl_tabulate_NB_first
+ \enforced\let\CC\tabl_tabulate_CC_first
+ \enforced\let\CL\tabl_tabulate_CL_first
+ \enforced\let\CM\tabl_tabulate_CM_first
+ \enforced\let\CR\tabl_tabulate_CR_first
+ \enforced\let\NI\tabl_tabulate_NI_first
+\to \t_tabl_tabulate_initializers_first
+
+\appendtoks
+ \enforced\let\NR\tabl_tabulate_NR_second
+ \enforced\let\NB\tabl_tabulate_NB_second
+\to \t_tabl_tabulate_initializers_second
+
+\appendtoks
+ \enforced\let\SR\NR
+ \enforced\let\FR\NR
+ \enforced\let\MR\NR
+ \enforced\let\LR\NR
+ \enforced\let\AR\NR
+\to \t_tabl_tabulate_initializers_first
+
+\permanent\protected\def\tabl_tabulate_NR_common#1#2%
+ {\global\advance\c_tabl_tabulate_noflines\plusone
+ \global\setfalse\c_tabl_tabulate_firstflushed
+ \global\setfalse\c_tabl_tabulate_equal
+ \global\c_tabl_tabulate_column\zerocount
+ \ifconditional#1\relax
+ \tabl_tabulate_break_state_reset
+ \fi
+ \tabl_tabulate_pheight_reset
+ \unskip\unskip\crcr\tabl_tabulate_flush_collected
+ % can we omit the next one in the first run? probably
+ \noalign{\the\t_tabl_tabulate_every_after_row#2}}
+
+\def\tabl_tabulate_check_penalties
+ {\ifconditional\c_tabl_tabulate_tolerant_break\else
+ \ifnum\c_tabl_tabulate_totalnoflines=\plusone
+ % \tabl_tabulate_break_allow
+ \else
+ \ifconditional\c_tabl_tabulate_someamble \ifcase\c_tabl_tabulate_repeathead \else
+ \tabl_tabulate_break_allow
+ \fi \fi
+ \ifnum\c_tabl_tabulate_noflines=\plusone
+ \tabl_tabulate_nobreak_inject
+ \orelse\ifnum\c_tabl_tabulate_noflines=\c_tabl_tabulate_minusnoflines
+ \ifnum\c_tabl_tabulate_plines_max<\plustwo
+ \tabl_tabulate_nobreak_inject
+ \else
+ \tabl_tabulate_break_allow % needed with pbreak prevention
+ \fi
+ \else
+ \tabl_tabulate_break_state_allowbreak
+ \fi
+ \fi
+ \fi
+ \global\setfalse\c_tabl_tabulate_firstflushed}
+
+\protected\def\tabl_tabulate_bbskip_second_split_yes
+ {\ifvoid\b_tabl_tabulate_current\c_tabl_tabulate_column
+ \ifempty\tabl_tabulate_flush_collected_indeed\else
+ \setbox0\hbox
+ \fi
+ \fi}
+
+\protected\def\tabl_tabulate_eskip_second
+ {\par\egroup
+ \tabl_tabulate_pheight_set
+ \glet\tabl_tabulate_hook\tabl_tabulate_hook_yes
+ \tabl_tabulate_splitoff_box}
+
+\protected\def\tabl_tabulate_bskip_second_split_yes
+ {\ifvoid\b_tabl_tabulate_current\c_tabl_tabulate_column
+ % first line
+ \global\setbox\b_tabl_tabulate_current\c_tabl_tabulate_column\vbox
+ \bgroup
+ \glet\tabl_tabulate_hook\tabl_tabulate_hook_nop
+ \ifconditional\c_tabl_tabulate_automode\hsize\d_tabl_tabulate_width\fi
+ % \begstrut % interferes with pre-\pars
+ % evt: \appendtoks\begstrut\to\everypar
+ \ignorespaces
+ \let\tabl_tabulate_eskip\tabl_tabulate_eskip_second
+ \else
+ % successive lines
+ \let\tabl_tabulate_eskip\empty
+ \dontcomplain
+ \glet\tabl_tabulate_hook\tabl_tabulate_hook_yes
+ \expandafter\tabl_tabulate_splitoff_box
+ \fi}
+
+\protected\def\tabl_tabulate_xbskip_second{\tabl_tabulate_bskip}
+\protected\def\tabl_tabulate_xeskip_second{\tabl_tabulate_eskip}
+
+\protected\def\tabl_tabulate_flush_second_indeed
+ {\glet\tabl_tabulate_flush_collected_indeed\empty
+ \global\c_tabl_tabulate_column\zerocount
+ \tabl_tabulate_pbreak_check
+ \dofastloopcs\c_tabl_tabulate_columns\tabl_tabulate_flush_second_step
+ \global\settrue\c_tabl_tabulate_firstflushed}
+
+\protected\def\tabl_tabulate_flush_second_step
+ {\ifvoid\b_tabl_tabulate_current\fastloopindex\else
+ \gdef\tabl_tabulate_flush_collected_indeed{\the\t_tabl_tabulate_dummy}%
+ \fi}
+
+\def\tabl_tabulate_flush_second
+ {\noalign{\tabl_tabulate_flush_second_indeed}%
+ \tabl_tabulate_flush_collected_indeed}
+
+\protected\def\tabl_tabulate_bskip_second_split_nop
+ {\vtop\bgroup
+ \ifconditional\c_tabl_tabulate_automode\hsize\d_tabl_tabulate_width\fi
+ % \begstrut % interferes with pre-\pars
+ % evt: \appendtoks\begstrut\to\everypar
+ \ignorespaces}
+
+\protected\def\tabl_tabulate_eskip_second_split_nop % vertical strut added august 2003
+ {\par\verticalstrut
+ \vskip-\struttotal
+ \egroup}
+
+% \let\tabl_tabulate_eskip \relax % adapted by bskip
+% \let\tabl_tabulate_eeskip\relax % adapted by bskip
+
+\appendtoks
+ \let\tabl_tabulate_xbskip\tabl_tabulate_xbskip_second
+ \let\tabl_tabulate_xeskip\tabl_tabulate_xeskip_second
+ \ifconditional\c_tabl_tabulate_split
+ \let\tabl_tabulate_bskip \tabl_tabulate_bskip_second_split_yes
+ \let\tabl_tabulate_bbskip\tabl_tabulate_bbskip_second_split_yes
+ \else
+ \let\tabl_tabulate_bskip \tabl_tabulate_bskip_second_split_nop
+ \let\tabl_tabulate_eskip \tabl_tabulate_eskip_second_split_nop
+ \fi
+\to \t_tabl_tabulate_initializers_second
+
+% see ***
+%
+% \enabletrackers[nodes.page_vspacing]
+% \starttext
+% \starttabulate[||] \dorecurse{100}{\NC Eins \NC \NR \HL} \stoptabulate
+% \stoptext
+
+\permanent\tolerant\noaligned\protected\def\tabl_tabulate_XX_none [#1]{\noalign{\tabl_tabulate_break_state_set}}
+
+\permanent\tolerant\noaligned\protected\def\tabl_tabulate_FL_second[#1]{\noalign{\tabl_tabulate_hrule_preset[#1]\tabl_tabulate_FL_second_indeed}}
+\permanent\tolerant\noaligned\protected\def\tabl_tabulate_ML_second[#1]{\noalign{\tabl_tabulate_hrule_preset[#1]\tabl_tabulate_ML_second_indeed}}
+\permanent\tolerant\noaligned\protected\def\tabl_tabulate_LL_second[#1]{\noalign{\tabl_tabulate_hrule_preset[#1]\tabl_tabulate_LL_second_indeed}}
+\permanent\tolerant\noaligned\protected\def\tabl_tabulate_TL_second[#1]{\noalign{\tabl_tabulate_hrule_preset[#1]\tabl_tabulate_TL_second_indeed}}
+\permanent\tolerant\noaligned\protected\def\tabl_tabulate_BL_second[#1]{\noalign{\tabl_tabulate_hrule_preset[#1]\tabl_tabulate_BL_second_indeed}}
+
+\protected\def\tabl_tabulate_FL_second_indeed
+ {\ifinsidefloat\else
+ \doifempty{\tabulationparameter\c!before}\tabl_tabulate_baselinecorrection % no expansion
+ \fi
+ \tabl_tabulate_hrule_inject
+ \tabl_tabulate_nobreak_inject
+ \tabl_tabulate_column_rule_separator_inject
+ \prevdepth\strutdp
+ \tabl_tabulate_nobreak_inject}
+
+\def\spac_vspacing_no_topskip % use grouped
+ {\c_attr_skipcategory\plusten}
+
+\protected\def\tabl_tabulate_ML_second_indeed
+ {\tabl_tabulate_break_no
+ \tabl_tabulate_column_rule_separator_inject
+ \tabl_tabulate_break_no
+ \tabl_tabulate_hrule_inject
+ \vskip-\p_rulethickness\relax
+ \begingroup
+ \spac_vspacing_no_topskip
+ \tabl_tabulate_hrule_inject
+ \endgroup
+ \tabl_tabulate_break_no
+ \tabl_tabulate_column_rule_separator_inject}
+
+\protected\def\tabl_tabulate_LL_second_indeed
+ {\tabl_tabulate_nobreak_inject
+ \tabl_tabulate_column_rule_separator_inject
+ \tabl_tabulate_nobreak_inject
+ \tabl_tabulate_hrule_inject
+ \ifinsidefloat
+ \tabl_tabulate_inside_inbetween
+ \else
+ \tabl_tabulate_outside_inbetween
+ \fi}
+
+\protected\def\tabl_tabulate_TL_second_indeed
+ {\tabl_tabulate_nobreak_inject
+ \tabl_tabulate_column_rule_separator_inject
+ \tabl_tabulate_nobreak_inject
+ \tabl_tabulate_hrule_inject
+ \tabl_tabulate_nobreak_inject
+ \tabl_tabulate_column_rule_separator_inject
+ %\prevdepth\strutdp % todo, might differ between TL and BL
+ \tabl_tabulate_nobreak_inject}
+
+\let\tabl_tabulate_BL_second_indeed\tabl_tabulate_TL_second_indeed
+
+\permanent\def\tabl_tabulate_HL_second
+ {\csname
+ \ifnum\c_tabl_tabulate_noflines=\zerocount F\orelse
+ \ifnum\c_tabl_tabulate_noflines=\c_tabl_tabulate_totalnoflines L\else
+ M\fi
+ L\endcsname}
+
+\appendtoks
+ \enforced\let\FL\tabl_tabulate_XX_none
+ \enforced\let\ML\tabl_tabulate_XX_none
+ \enforced\let\LL\tabl_tabulate_XX_none
+ \enforced\let\TL\tabl_tabulate_XX_none
+ \enforced\let\BL\tabl_tabulate_XX_none
+ \enforced\let\HL\tabl_tabulate_XX_none
+ \enforced\let\HR\tabl_tabulate_XX_none
+\to \t_tabl_tabulate_initializers_first
+
+\appendtoks
+ \enforced\let\FL\tabl_tabulate_FL_second
+ \enforced\let\ML\tabl_tabulate_ML_second
+ \enforced\let\LL\tabl_tabulate_LL_second
+ \enforced\let\TL\tabl_tabulate_TL_second
+ \enforced\let\BL\tabl_tabulate_BL_second
+ \enforced\let\HL\tabl_tabulate_HL_second
+ \enforced\let\HR\tabl_tabulate_HL_second
+\to \t_tabl_tabulate_initializers_second
+
+% \dorecurse{10}{
+% \starttabulate[|l|]
+% \FL
+% \NC first line, bound to next rule \NC \NR
+% \TL
+% \NC bound to previous rule \NC \NR
+% \NC some line \NC \NR
+% \NC some line \NC \NR
+% \NC some line \NC \NR
+% \NC bound to next rule \NC \NR
+% \ML
+% \NC bound to previous rule \NC \NR
+% \NC bound to next rule \NC \NR
+% \BL
+% \NC last line, bound to previous rule \NC \NR
+% \LL
+% \stoptabulate
+% }
+
+% This needs checking:
+
+\permanent\def\tabulaterule {\HR} % a rule with lineheight
+\permanent\def\tabulateline {\HL} % just a spaced rule
+\permanent\def\tabulateautorule{\HR}%
+\permanent\def\tabulateautoline{\HL} % no longer different (to be looked into)
+
+%D When support for vertical rules we needed a way to pick up the specification for
+%D the final rule and a \type {|{}} interface was chosen. As a result parsing had to
+%D become more complex and I was not in the mood for messing up the code too much.
+%D Therefore from now on the preamble is split by \LUA. There are definitely more
+%D places where we can use \LUA\ code (for instance in alignment of numbers. The
+%D repeat parser is replace at the \LUA\ end as well.
+
+\let\tabl_tabulate_flush_collected \empty
+\let\tabl_tabulate_flush_collected_indeed\empty
+
+\let\v_tabl_tabulate_align\!!zerocount
+
+\def\tabl_tabulate_check_side_float % new per 29-07-2016
+ {\ifdefined\page_sides_check_floats_indeed
+ \page_sides_check_floats_indeed
+ \ifdim\hangindent>\zeropoint
+ \advance\d_tabl_tabulate_indent\hangindent
+ \fi
+ \fi}
+
+\def\tabl_tabulate_set_local_hsize
+ {\setlocalhsize
+ \hsize\localhsize}
+
+% test case for pre/post spacing:
+%
+% \ruledvbox{\starttabulate[|l|] \FL\NC xxx \NC \NR\LL\stoptabulate}
+% \ruledvbox{\starttabulate[|l|l|]\FL\NC xxx \NC xxx \NC \NR\LL\stoptabulate}
+% \ruledvbox{\starttabulate[|l|] \NC xxx \NC \NR \stoptabulate}
+% \ruledvbox{\starttabulate[|lj8|] \NC xxx \NC \NR \stoptabulate}
+% \ruledvbox{\starttabulate[|k8|] \NC xxx \NC \NR \stoptabulate}
+% \ruledvbox{\starttabulate[|l|l|] \NC xxx \NC xxx \NC \NR \stoptabulate}
+
+\def\tabl_tabulate_process
+ {\c_tabl_tabulate_pass\plusone
+ \tabl_tabulate_check_full_content
+ \edef\v_tabl_tabulate_align{\ifcsname\??tabulatealigning\p_align\endcsname\lastnamedcs\else0\fi}%
+ \s_tabl_tabulate_first.5\d_tabl_tabulate_unit
+ \s_tabl_tabulate_last\s_tabl_tabulate_first
+ \s_tabl_tabulate_pre\zeropoint
+ \s_tabl_tabulate_post\zeropoint
+ %setfalse\c_tabl_pre_is_set
+ \setfalse\c_tabl_post_is_set
+ \global\c_tabl_tabulate_columns\zerocount
+ \global\c_tabl_tabulate_nofauto\zerocount
+ \global\c_tabl_tabulate_noflines\zerocount
+ \c_tabl_tabulate_totalnoflines\zerocount
+ \c_tabl_tabulate_minusnoflines\zerocount
+ \global\d_tabl_tabulate_width_p\zeropoint
+ \global\d_tabl_tabulate_width_w\zeropoint
+ \global\setfalse\c_tabl_tabulate_equal
+ \tabl_tabulate_pheight_reset
+ \tabskip\zeropoint
+ \ifinsidesplitfloat
+ \donetrue
+ \orelse\ifinsidefloat
+ \donefalse
+ \else
+ \donetrue
+ \fi
+ \global\c_tabl_tabulate_repeathead
+ \ifdone
+ \ifcsname\??tabulateheader\tabulationparameter\c!header\endcsname
+ \lastnamedcs
+ \else
+ \zerocount
+ \fi
+ \else
+ \zerocount
+ \fi
+ %
+ \the\t_tabl_tabulate_initializers_first % collect more here
+ %
+ \glet\tabl_tabulate_flush_collected\empty
+ \ifdim\d_tabl_tabulate_margin>\zeropoint
+ \t_tabl_tabulate_preamble
+ {\aligntab
+ \tabl_tabulate_flush_indent
+% \global\advance\c_tabl_tabulate_noflines\plusone
+ \strut
+ \alignmark\alignmark
+ \tabskip\d_tabl_tabulate_margin
+ \strut
+ \aligntab
+ \alignmark\alignmark
+ \tabskip\zeropoint}%
+ \else
+ \t_tabl_tabulate_preamble
+ {\aligntab
+ \tabl_tabulate_flush_indent
+% \global\advance\c_tabl_tabulate_noflines\plusone
+ \strut
+ \alignmark\alignmark
+ \aligntab
+ \alignmark\alignmark
+ \tabskip\zeropoint}%
+ \fi
+ \d_tabl_tabulate_width\zeropoint
+ % these counters are set at the lua end
+ \c_tabl_tabulate_nofcolumns \zerocount
+ \c_tabl_tabulate_has_rule_spec_first\zerocount
+ \c_tabl_tabulate_has_rule_spec_last \zerocount
+ \clf_presettabulate{\detokenizedtabulationparameter\c!format}%
+ %
+ % \edef\totaltabulatecolumns{\the\numexpr3*\c_tabl_tabulate_columns+\plusfour}%
+ \d_tabl_tabulate_width\zeropoint
+ \tabl_tabulate_initialize_boxes\c_tabl_tabulate_columns
+ \toksapp\t_tabl_tabulate_preamble{%
+ \aligntab\alignmark\alignmark
+ \global\advance\c_tabl_tabulate_column\plusone % maybe just set it already
+ }%
+ \toksapp\t_tabl_tabulate_dummy{%
+ \NC\unskip\unskip\crcr\tabl_tabulate_flush_collected % no count
+ }%
+ \global\c_tabl_tabulate_column\zerocount
+ \tabl_tabulate_pheight_reset
+ \glet\tabl_tabulate_hook\tabl_tabulate_hook_yes
+ \ifx\p_indenting\v!no
+ \forgetparindent
+ \fi
+ \ifinsidefloat
+ \d_tabl_tabulate_indent\zeropoint
+ \else
+ \tabl_tabulate_check_side_float
+ \tabl_tabulate_set_local_hsize
+ \fi
+ \dontcomplain
+ \forgetall % hm, interference with preceding \forgetparindent probably bug, to be solved
+ \everypar\everytabulatepar
+ \setbox\scratchbox\vbox % outside \if because of line counting
+ {\notesenabledfalse
+ \d_tabl_tabulate_indent\zeropoint
+ \settrialtypesetting % very important
+ \anch_backgrounds_text_level_start
+ \expandafter\halign\expandafter{\the\t_tabl_tabulate_preamble\crcr\tabl_tabulate_insert_content\crcr}}%
+ \anch_backgrounds_text_level_stop
+ \ifcase\c_anch_backgrounds_text_state\else
+ \global\settrue\tablehaspositions
+ \fi
+ \ifnum\c_tabl_tabulate_nofauto>\zerocount
+ % so, even if the natural size is larger, in the final run, we force the calculated width
+ \d_tabl_tabulate_width\dimexpr\hsize-\wd\scratchbox-\d_tabl_tabulate_width_p-\d_tabl_tabulate_width_w\relax
+ \ifnum\c_tabl_tabulate_nofauto>\zerocount
+ \divide\d_tabl_tabulate_width \c_tabl_tabulate_nofauto\relax
+ \fi
+ \fi
+ \setbox\scratchbox\emptybox % free memory
+ \ifconditional\c_tabl_tabulate_split
+ \splittopskip\strutht
+ \glet\tabl_tabulate_flush_collected_indeed\empty
+ \glet\tabl_tabulate_flush_collected\tabl_tabulate_flush_second
+ \fi
+ \c_tabl_tabulate_totalnoflines\c_tabl_tabulate_noflines
+ \c_tabl_tabulate_minusnoflines\numexpr\c_tabl_tabulate_noflines+\minusone\relax
+ \global\c_tabl_tabulate_noflines\zerocount
+ %
+ \c_tabl_tabulate_pass\plustwo % final pass
+ \the\t_tabl_tabulate_initializers_second % collect more here
+ %
+ \ifx\p_line\v!line
+ \enforced\let\HL\HR
+ \enforced\let\tabulateautoline\tabulateautorule
+ \enforced\let\tabulateline \tabulaterule
+ \fi
+ %
+ \ifcase\c_tabl_tabulate_repeathead
+ \ifinsidesplitfloat
+ \global\setbox\b_tabl_tabulate\vbox \bgroup
+ \else
+ \startframedcontent[\tabulationparameter\c!frame]%
+ \fi
+ \else
+ \global\setbox\b_tabl_tabulate\vbox \bgroup
+ \fi
+ %
+ \dostarttaggedchained\t!tabulate\empty\??tabulation
+ \dostarttagged\t!tabulaterow\empty
+ \setfalse\inhibitmargindata % new per 2012.06.13 ... really needed
+% % \everycr\expandafter{\the\everycr\noalign{\the\t_tabl_tabulate_every_real_row}\dostoptagged\dostarttagged\t!tabulaterow\empty}%
+ \toksapp\everycr{\noalign{\the\t_tabl_tabulate_every_real_row\dostoptagged\dostarttagged\t!tabulaterow\empty}}%
+ \expandafter\halign\expandafter{\the\t_tabl_tabulate_preamble\crcr\tabl_tabulate_insert_content\crcr}%
+ \dostoptagged
+ \dostoptagged
+ \ifhmode\par\prevdepth\strutdp\fi % nog eens beter, temporary hack
+ \ifx\p_distance\v!grid
+ \vskip-\strutdp % experimental tm-prikkels
+ \fi
+ %
+ \ifcase\c_tabl_tabulate_repeathead
+ \ifinsidesplitfloat
+ \egroup % box
+ \egroup % settings
+ \tabl_split_box\b_tabl_tabulate
+ \else
+ \stopframedcontent
+ \egroup
+ \fi
+ \else
+ \egroup % box
+ \egroup % settings
+ \tabl_split_box\b_tabl_tabulate
+ \fi
+ %
+ \ifinsidefloat
+ \tabl_tabulate_inside_after
+ \else
+ \tabl_tabulate_outside_after
+ \fi
+ \egroup} % whole thing
+
+% \egroup
+
+% \setuptabulate[split=yes,header=text,title=Vervolg van Tabel]
+%
+% % \starttabulatehead
+% % \NC test \NC hans\NC \NR
+% % \stoptabulatehead
+%
+% \starttabulate
+% \NC test \NC \input tufte \relax \NC \NR
+% \NC test \NC \input knuth \relax \NC \NR
+% \NC test \NC \input knuth \relax \NC \NR
+% \NC test \NC \input tufte \relax \NC \NR
+% \NC test \NC \input tufte \relax \NC \NR
+% \NC test \NC \input tufte \relax \NC \NR
+% \stoptabulate
+
+\def\tabl_split_box#1% #1 <> 0/2 / derived from the one in core-ntb.tex
+ {\ifinsidesplitfloat
+ \tabl_split_box_indeed#1%
+ \orelse\ifinsidefloat
+ \unvbox#1%
+ \else
+ \tabl_split_box_indeed#1%
+ \fi}
+
+\def\tabl_split_box_indeed#1%
+ {\resettsplit
+ \c_split_minimum_free_lines\plustwo
+ \d_split_minimum_free_space\zeropoint
+ \setbox\b_split_content\box#1%
+ \ifcase\c_tabl_tabulate_repeathead\or
+ \setbox\b_split_head\vsplit\b_split_content to \lineheight
+ \setbox\b_split_head\vbox{\unvbox\b_split_head}%
+ \or
+ \setbox\b_split_head\vbox{\hbox{\strut\tabulationparameter\c!title}}%
+ \fi
+ \handletsplit}
+
+%D \starttyping
+%D \setuptabulate[split=no,rule=line]
+%D
+%D \starttabulate
+%D \NC tufte \NC \input tufte \NC \NR \tabulateautorule
+%D \NC tufte \NC \input tufte \NC \NR \tabulateautorule
+%D \NC tufte \NC \input tufte \NC \NR \tabulateautorule
+%D \NC tufte \NC \input tufte \NC \NR \tabulateautorule
+%D \NC tufte \NC \input tufte \NC \NR \tabulateautorule
+%D \NC tufte \NC \input tufte \NC \NR \tabulateautorule
+%D \stoptabulate
+%D \stoptyping
+
+%D Spacing:
+%
+% \starttabulate
+% \NC text \NC text \NC \NR
+% \TB[small]
+% \NC text \NC text \NC \NR
+% \TB[4*big]
+% \NC text \NC text \NC \NR
+% \stoptabulate
+
+\permanent\tolerant\noaligned\protected\def\tabl_tabulate_TB[#1]%
+ {\noalign\bgroup
+ \unless\iftok{#1}\emptytoks
+ \blank[#1]
+ \orelse\ifempty\m_tabl_tabulate_blank_default
+ \blank
+ \else
+ \blank[\m_tabl_tabulate_blank_default]%
+ \fi
+ \egroup}
+
+\appendtoks
+ \enforced\let\TB\tabl_tabulate_TB
+\to \everytabulate
+
+% %D Between alignment lines certain rules apply, and even a simple test can mess
+% %D up a table, which is why we have a special test facilityL
+% %D
+% %D \startbuffer
+% %D \starttabulate[|l|p|]
+% %D \NC 1test \NC test \NC \NR
+% %D \tableifelse{\doifelse{a}{a}}{\NC Xtest \NC test \NC \NR}{}%
+% %D \stoptabulate
+% %D \stopbuffer
+% %D
+% %D \typebuffer \getbuffer
+%
+% \def\tableifelse#1% should be tabulatenoalign then
+% {\tablenoalign
+% {#1%
+% {\aftergroup \firstoftwoarguments}%
+% {\aftergroup\secondoftwoarguments}}}
+%
+% \def\tableiftextelse#1{\tableifelse{\doiftextelse{#1}}}
+
+%D Some new trickery:
+%D
+%D \startbuffer
+%D \settrue\c_tabl_tabulate_splitoff_whitespace
+%D
+%D \starttabulate[|p(2cm)|p(2cm)|p(2cm)|]
+%D \NC test 1a \NC test 2a \NC test 3a
+%D \par
+%D test 3b \NC \NR
+%D \NC test 1a \NC test 2a \NC test 3a
+%D \blank[line]
+%D test 3b \NC \NR
+%D \NC test 1a \NC test 2a \NC test 3a
+%D \blank[halfline]
+%D test 3b
+%D \blank[halfline]
+%D test 3c \NC \NR
+%D \NC \blank \NC \blank \NC \blank \NC \NR
+%D \NC test 1a \NC test 2a \NC test 3a
+%D \blank[halfline]
+%D test 3b
+%D \blank[halfline]
+%D test 3c \NC \NR
+%D \NC \blank \NC \blank \NC \NC \NR
+%D \NC test 1a
+%D \par
+%D test 1b
+%D \par
+%D test 1b \NC test 2a
+%D \par
+%D test 2b
+%D \par
+%D test 2b \NC test 3a \NC \NR
+%D \NC test 1a
+%D \blank
+%D test 1b
+%D \par
+%D test 1b \NC test 2a
+%D \par
+%D test 2b
+%D \blank
+%D test 2b \NC test 3a \NC \NR
+%D \stoptabulate
+%D \stopbuffer
+%D
+%D \typebuffer \start \getbuffer \stop
+
+% \starttabulatie[|mc|]
+% \NC \digits{100.000,00} \NC\NR
+% \NC \digits{@10.000,00} \NC\NR
+% \NC \digits{@@@.100,00} \NC\NR
+% \NC \digits{@@@.@10,@@} \NC\NR
+% \NC \digits{@@@.@@1,@@} \NC\NR
+% \stoptabulatie
+%
+% \starttabulatie[|mc|]
+% \ND 100.000,00 \NC\NR
+% \ND @10.000,00 \NC\NR
+% \ND @@@.100,00 \NC\NR
+% \ND @@@.@10,@@ \NC\NR
+% \ND @@@.@@1,@@ \NC\NR
+% \stoptabulatie
+%
+% \starttabulatie[|c|]
+% \ND $100.000,00$ \NC\NR
+% \ND $@10.000,00$ \NC\NR
+% \ND $@@@.100,00$ \NC\NR
+% \ND $@@@.@10,@@$ \NC\NR
+% \ND $@@@.@@1,@@$ \NC\NR
+% \stoptabulatie
+%
+% \starttabulatie[|c|]
+% \NC $\digits 100.000,00 $ \NC\NR
+% \NC $\digits @10.000,00 $ \NC\NR
+% \NC $\digits @@@.100,00 $ \NC\NR
+% \NC $\digits @@@.@10,@@ $ \NC\NR
+% \NC $\digits @@@.@@1,@@ $ \NC\NR
+% \stoptabulatie
+%
+% \starttabulatie[|c|]
+% \NC \digits $100.000,00$ \NC\NR
+% \NC \digits $@10.000,00$ \NC\NR
+% \NC \digits $@@@.100,00$ \NC\NR
+% \NC \digits $@@@.@10,@@$ \NC\NR
+% \NC \digits $@@@.@@1,@@$ \NC\NR
+% \stoptabulatie
+
+%D Predefined categories (moved from core-mis):
+
+\mutable\let\leg \relax % column separators
+\mutable\let\fact\relax % column separators
+
+\definetabulate
+ [\v!legend]
+ [|emj1|i1|mR|]
+
+\setuptabulate
+ [\v!legend]
+ [\c!unit=.75em,\c!inner=\tabl_tabulate_set_quick\leg,EQ={=}]
+
+\definetabulate
+ [\v!legend][\v!two]
+ [|emj1|emk1|i1|mR|]
+
+\definetabulate
+ [\v!fact]
+ [|R|ecmj1|i1mR|]
+
+\setuptabulate
+ [\v!fact]
+ [\c!unit=.75em,\c!inner=\tabl_tabulate_set_quick\fact,EQ={=}]
+
+%D Another example:
+%D
+%D \starttyping
+%D \definetabulate
+%D [whatever]
+%D [|l|r|]
+%D
+%D \definetabulate
+%D [whatever][else]
+%D [|l|c|r|]
+%D
+%D \startwhatever
+%D \NC l \NC r \NC \NR
+%D \NC left \NC right \NC \NR
+%D \stopwhatever
+%D
+%D \startwhatever[else]
+%D \NC l \NC m \NC r \NC \NR
+%D \NC left \NC middle \NC right \NC \NR
+%D \stopwhatever
+%D
+%D \startwhatever[else][format={|c|c|c|c|}]
+%D \NC l \NC m \NC m \NC r \NC \NR
+%D \NC left \NC middle \NC middle \NC right \NC \NR
+%D \stopwhatever
+%D \stoptyping
+
+%D This is needed because we sometimes use the english command in tracing macros. In
+%D fact, most detailed tracing macros that are done with \LUA\ only work in the
+%D english interface anyway.
+
+% \definetabulate[tabulate] \setuptabulate[tabulate][\c!format=\v!none] % so no \v! here
+
+\newconditional\c_tabl_generic
+
+\pushoverloadmode
+
+\permanent\protected\defcsname starttabulate\endcsname
+ {\bgroup % whole thing
+ \settrue\c_tabl_generic
+ \let\currenttabulationparent\empty
+ \tabl_start_regular}
+
+\permanent\letcsname stoptabulate\endcsname\relax % testcase cvs-002.tex
+
+\popoverloadmode
+
+%D The following helpers are just there because we also have them at the \LUA\ end:
+%D
+%D \startbuffer
+%D \starttabulate[|l|c|r|]
+%D \tabulaterow {a,b,c}
+%D \tabulaterowbold{aa,bb,cc}
+%D \tabulaterowtype{aaa,bbb,ccc}
+%D \tabulaterowtyp {aaaa,bbbb,cccc}
+%D \stoptabulate
+%D \stopbuffer
+%D
+%D \typebuffer \getbuffer
+
+\def\tabl_tabulate_compact_row#1#2%
+ {\NC\tabl_tabulate_compact_step#1#2,\end,}
+
+\def\tabl_tabulate_compact_step#1#2#3,%
+ {\ifx#2\end
+ \NR
+ \expandafter\gobbleoneargument
+ \else
+ #1{#2#3}\NC
+ \expandafter\tabl_tabulate_compact_step
+ \fi#1}
+
+\permanent\protected\def\tabulaterow {\tabl_tabulate_compact_row\relax}
+\permanent\protected\def\tabulaterowbold{\tabl_tabulate_compact_row\bold}
+\permanent\protected\def\tabulaterowtype{\tabl_tabulate_compact_row\type}
+\permanent\protected\def\tabulaterowtyp {\tabl_tabulate_compact_row\typ}
+
+%D Here we plug in a row background feature. As we only have support for
+%D \type {frame=name} we can use these variables.
+%D
+%D \starttyping
+%D \startuseMPgraphic{foo}
+%D fill unitsquare
+%D xyscaled (RuleWidth,RuleHeight+RuleDepth) enlarged (ExHeight/4,ExHeight/8)
+%D randomized ExHeight
+%D shifted (-ExHeight/8,ExHeight/16)
+%D withcolor RuleColor ;
+%D \stopuseMPgraphic
+%D
+%D \setuptabulate % wel only have frame=name so we can use these:
+%D [background=foo,
+%D backgroundcolor=darkred,
+%D foregroundcolor=white]
+%D
+%D \definelinefiller[foo][mp=foo,color=darkgreen]
+%D \definelinefiller[bar][mp=foo,color=darkred]
+%D
+%D \starttabulate[|||]
+%D \DB foo \BC bar \BC \NR
+%D \NC foo \NC bar \NC \NR
+%D \NC foo \NC bar \NC \NR
+%D \NC foo \NC bar \NC \NR
+%D \NC foo \NC bar \NC \NR
+%D \stoptabulate
+%D
+%D \starttabulate[|||]
+%D \PB foo \BC bar \BC \NR
+%D \NC foo \NC bar \NC \NR
+%D \NC foo \NC bar \NC \NR
+%D \NC foo \NC bar \NC \NR
+%D \NC foo \NC bar \NC \NR
+%D \stoptabulate
+%D
+%D \starttabulate[|||]
+%D \FB[bar] foo \BC bar \BC \NR
+%D \NC foo \NC bar \NC \NR
+%D \NC foo \NC bar \NC \NR
+%D \NC foo \NC bar \NC \NR
+%D \NC foo \NC bar \NC \NR
+%D \stoptabulate
+%D
+%D \startnarrower
+%D \starttabulate[|||]
+%D \DB foo \DB bar \BC \NR
+%D \NC foo \NC bar \NC \NR
+%D \NC foo \NC bar \NC \NR
+%D \NC foo \NC bar \NC \NR
+%D \NC foo \NC bar \NC \NR
+%D \stoptabulate
+%D \stopnarrower
+%D
+%D \starttabulate[|||]
+%D \BC foo \BC bar \BC \NR
+%D \NL[magenta] foo \NC bar \NC \NR
+%D \NL[yellow] foo \NC bar \NC \NR
+%D \NL[cyan] foo \NC bar \NC \NR
+%D \NL[gray] foo \NC bar \NC \NR
+%D \stoptabulate
+%D
+%D \starttabulate
+%D \NL[red] foo \NC bar \NC \NR
+%D \NL[green] foo \NL[red] bar \NC \NR
+%D \NC foo \NC bar \NC \NR
+%D \NL[blue] foo \NC \input tufte \NC \NR
+%D \NL[gray] foo \NC bar \NC \NR
+%D \NL[yellow] foo \NC bar \NC \NR
+%D \stoptabulate
+%D \stoptyping
+
+% \setuptabulate
+% [\c!background=,
+% \c!backgroundcolor=,
+% \c!foregroundcolor=,
+% \c!foregroundstyle=]
+
+\let\m_table_current_row_background \empty
+\let\m_table_current_row_background_default \empty
+\let\m_table_current_row_background_filler \empty
+\let\m_table_current_row_background_defaultfiller\empty
+\let\m_table_current_row_background_auto \empty
+
+\protected\def\tabl_register_row_background#1%
+ {\xdef\m_table_current_row_background{#1}}
+
+\protected\def\tabl_register_row_background_filler#1%
+ {\xdef\m_table_current_row_background_filler{#1}}
+
+\protected\def\tabl_synchronize_row_background
+ {\iftrialtypesetting\else
+ \ifempty\m_table_current_row_background_filler
+ \ifempty\m_table_current_row_background
+ % nothing
+ \tabl_synchronize_row_background_dummy
+ \else
+ \tabl_synchronize_row_background_indeed\m_table_current_row_background
+ \fi
+ \else
+ \tabl_synchronize_row_background_filler_indeed\m_table_current_row_background_filler
+ \fi
+ \fi}
+
+\protected\def\tabl_synchronize_row_background_dummy
+ {\iftrialtypesetting\else
+ \begingroup
+ %\clf_setbackgroundrowdata\numexpr\c_tabl_tabulate_nofrealrows+\minusone\relax\zerocount\zeropoint
+ \clf_setbackgroundrowdata\c_tabl_tabulate_nofrealrows\zerocount\zeropoint
+ \endgroup
+ \fi}
+
+\protected\def\tabl_synchronize_row_background_indeed#1%
+ {\iftrialtypesetting\else
+ \begingroup
+ \clf_enablebackgroundalign % can be moved into \clf_setbackgroundrowdata
+ \dousecolorparameter{#1}%
+ \setbox\scratchbox\hpack{}%
+ %\clf_setbackgroundrowdata\numexpr\c_tabl_tabulate_nofrealrows+\minusone\relax\scratchbox\d_tabl_tabulate_indent
+ \clf_setbackgroundrowdata\c_tabl_tabulate_nofrealrows\scratchbox\d_tabl_tabulate_indent
+ \endgroup
+ \fi}
+
+\protected\def\tabl_synchronize_row_background_filler_indeed#1%
+ {\iftrialtypesetting\else
+ \begingroup
+ \clf_enablebackgroundalign % can be moved into \clf_setbackgroundrowdata
+ \node_linefiller_set{#1}%
+ \setbox\scratchbox\hpack{}%
+ %\clf_setbackgroundrowdata\numexpr\c_tabl_tabulate_nofrealrows+\minusone\relax\scratchbox\d_tabl_tabulate_indent
+ \clf_setbackgroundrowdata\c_tabl_tabulate_nofrealrows\scratchbox\d_tabl_tabulate_indent
+ \endgroup
+ \fi}
+
+\appendtoks
+ \glet\m_table_current_row_background\empty
+ \glet\m_table_current_row_background_filler\empty
+ \global\c_tabl_tabulate_nofrealrows\zerocount
+ \global\c_tabl_tabulate_autocolor\zerocount
+ \clf_resetbackgroundrowdata
+\to \t_tabl_tabulate_initializers_first
+
+\appendtoks
+ \glet\m_table_current_row_background\empty
+ \glet\m_table_current_row_background_filler\empty
+ \global\c_tabl_tabulate_nofrealrows\zerocount
+ \global\c_tabl_tabulate_autocolor\zerocount
+ \clf_resetbackgroundrowdata
+\to \t_tabl_tabulate_initializers_second
+
+\appendtoks
+ \tabl_synchronize_row_background
+\to \t_tabl_tabulate_every_real_row
+
+\appendtoks
+ \glet\m_table_current_row_background\empty
+ \glet\m_table_current_row_background_filler\empty
+\to \t_tabl_tabulate_every_after_row
+
+\permanent\protected\def\tabl_tabulate_NL_first[#1]%
+ {\tabl_tabulate_column_normal\zerocount\zerocount\relax
+ \ifcase\c_tabl_tabulate_column\or
+ \tabl_register_row_background{#1}%
+ \fi
+ \ignorespaces}
+
+\pushoverloadmode
+
+ % redefinition needs checking
+
+ \permanent\overloaded\protected\def\tabl_tabulate_ND_first
+ {\tabl_tabulate_column_normal\zerocount\zerocount\relax
+ \ifcase\c_tabl_tabulate_column\or
+ \tabl_register_row_background\m_table_current_row_background_default
+ \fi
+ \ignorespaces}
+
+\popoverloadmode
+
+\permanent\protected\def\tabl_tabulate_LB_first[#1]%
+ {\tabl_tabulate_column_normal\plusone\zerocount\relax
+ \ifcase\c_tabl_tabulate_column\or
+ \tabl_register_row_background{#1}%
+ \fi
+ \usetabulationstyleandcolor\c!foregroundstyle\c!foregroundcolor
+ \ignorespaces}
+
+\permanent\protected\def\tabl_tabulate_DB_first
+ {\tabl_tabulate_column_normal\plusone\zerocount\relax
+ \ifcase\c_tabl_tabulate_column\or
+ \tabl_register_row_background\m_table_current_row_background_default
+ \fi
+ \enforced\let\fontstyle\globalfontstyle
+ \usetabulationstyleandcolor\c!foregroundstyle\c!foregroundcolor
+ \ignorespaces}
+
+\permanent\protected\def\tabl_tabulate_NF_first[#1]%
+ {\tabl_tabulate_column_normal\zerocount\zerocount\relax
+ \ifcase\c_tabl_tabulate_column\or
+ \tabl_register_row_background_filler{#1}%
+ \fi
+ \ignorespaces}
+
+\permanent\protected\def\tabl_tabulate_NP_first
+ {\tabl_tabulate_column_normal\zerocount\zerocount\relax
+ \ifcase\c_tabl_tabulate_column\or
+ \tabl_register_row_background_filler\m_table_current_row_background_default_filler
+ \fi
+ \ignorespaces}
+
+\permanent\protected\def\tabl_tabulate_FB_first[#1]%
+ {\tabl_tabulate_column_normal\plusone\zerocount\relax
+ \ifcase\c_tabl_tabulate_column\or
+ \tabl_register_row_background_filler{#1}%
+ \fi
+ \usetabulationstyleandcolor\c!foregroundstyle\c!foregroundcolor
+ \ignorespaces}
+
+\permanent\protected\def\tabl_tabulate_PB_first
+ {\tabl_tabulate_column_normal\plusone\zerocount\relax
+ \ifcase\c_tabl_tabulate_column\or
+ \tabl_register_row_background_filler\m_table_current_row_background_default_filler
+ \fi
+ \enforced\let\fontstyle\globalfontstyle
+ \usetabulationstyleandcolor\c!foregroundstyle\c!foregroundcolor
+ \ignorespaces}
+
+\pushoverloadmode
+
+ \permanent\overloaded\protected\def\tabl_tabulate_BC_first
+ {\tabl_tabulate_column_normal\plusone\zerocount
+ \enforced\let\fontstyle\globalfontstyle
+ \ifempty\m_table_current_row_background
+ \ifempty\m_table_current_row_background_filler
+ \usetabulationstyleandcolor\c!headstyle\c!headcolor
+ \else
+ \usetabulationstyleandcolor\c!foregroundstyle\c!foregroundcolor
+ \fi
+ \else
+ \usetabulationstyleandcolor\c!foregroundstyle\c!foregroundcolor
+ \fi}
+
+\popoverloadmode
+
+\permanent\protected\def\tabl_tabulate_A_first
+ {\global\advance\c_tabl_tabulate_autocolor\plusone
+ \edef\m_table_current_row_background_auto{\tabulateparameter{\c!backgroundcolor:\number\c_tabl_tabulate_autocolor}}%
+ \ifempty\m_table_current_row_background_auto
+ \global\c_tabl_tabulate_autocolor\plusone
+ \edef\m_table_current_row_background_auto{\tabulateparameter{\c!backgroundcolor:\number\c_tabl_tabulate_autocolor}}%
+ \fi
+ \ifempty\m_table_current_row_background_auto
+ \let\m_table_current_row_background_auto\empty % \m_table_current_row_background_default
+ \fi
+ \tabl_register_row_background{\m_table_current_row_background_auto}}
+
+\permanent\protected\def\tabl_tabulate_NA_first
+ {\tabl_tabulate_column_normal\zerocount\zerocount\relax
+ \iftrialtypesetting\else
+ \ifcase\c_tabl_tabulate_column\or
+ \tabl_tabulate_A_first
+ \fi
+ \fi
+ \ignorespaces}
+
+\permanent\protected\def\tabl_tabulate_BA_first
+ {\tabl_tabulate_column_normal\plusone\zerocount\relax
+ \iftrialtypesetting\else
+ \ifcase\c_tabl_tabulate_column\or
+ \tabl_tabulate_A_first
+ \fi
+ \fi
+ \usetabulationstyleandcolor\c!foregroundstyle\c!foregroundcolor
+ \ignorespaces}
+
+\appendtoks
+ \enforced\let\NL\tabl_tabulate_NL_first % NC with Line
+ \enforced\let\ND\tabl_tabulate_ND_first % NC with Default Line
+ \enforced\let\LB\tabl_tabulate_LB_first % BC with Line
+ \enforced\let\DB\tabl_tabulate_DB_first % BC with Default Line
+ \enforced\let\NF\tabl_tabulate_NF_first % NC with Filler
+ \enforced\let\NP\tabl_tabulate_NP_first % NC with Predefined Filler
+ \enforced\let\FB\tabl_tabulate_FB_first % BC with Filler
+ \enforced\let\PB\tabl_tabulate_PB_first % BC with Predefined Filler
+ \enforced\let\NA\tabl_tabulate_NA_first % NC with Auto Line
+ \enforced\let\BA\tabl_tabulate_BA_first % NC with Auto Line
+\to \t_tabl_tabulate_initializers_first
+
+\appendtoks
+ \edef\m_table_current_row_background_default {\tabulateparameter\c!backgroundcolor}%
+ \edef\m_table_current_row_background_default_filler{\tabulateparameter\c!background}%
+ \let \m_table_current_row_background_auto \empty
+\to \everytabulate
+
+\setuptabulate
+ [\c!headcolor=,
+ \c!headstyle=\bf,
+ \c!backgroundcolor=\tabulationparameter\c!rulecolor,
+ \c!foregroundcolor=,
+ \c!foregroundstyle=\tabulationparameter\c!headstyle]
+
+\protect \endinput