tabl-ntb.mkiv /size: 84 Kb    last modification: 2020-07-01 14:35
1%D \module
2%D   [       file=tabl-ntb,
3%D        version=2000.04.18,
4%D          title=\CONTEXT\ Table Macros,
5%D       subtitle=Natural Tables,
6%D         author=Hans Hagen,
7%D           date=\currentdate,
8%D      copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
9%C
10%C This module is part of the \CONTEXT\ macro||package and is
11%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
12%C details.
13
14%D This module has a more modern variant in xtables but as we follow a bit different
15%D approach with settings there, this mechanism will stay. In fact each of them has
16%D its advantages. This module could be sped up a bit and made more efficient by
17%D delegating some housekeeping to \LUA\ but it's not worth the effort. The code
18%D could me made more readable but again, there is no real purpose in it. If needed
19%D I can squeeze out a few more percentages runtime.
20
21% columndistance 'optimized' ... needs checking
22%
23% we don't need the alignment mechanism .. we can just pack the row in a box
24
25\writestatus{loading}{ConTeXt Table Macros / Natural Tables}
26
27% sometimes this helps (with nc going wild): \setupTABLE[maxwidth=100cm]
28%
29% bug: width 3cm is not honored and column becomes too wide as given width is added
30% to distributed width
31%
32% \bTABLE
33%     \bTR
34%         \bTD test \eTD
35%         \bTD \framed[height=3cm]{test} \eTD
36%         \bTD[width=3cm] \dorecurse{30}{a } \eTD
37%         \bTD \input ward \eTD
38%     \eTR
39%     \bTR
40%         \bTD test \eTD
41%         \bTD \framed[height=3cm]{test} \eTD
42%         \bTD \dorecurse{30}{a } \eTD
43%         \bTD \input ward \eTD
44%     \eTR
45% \eTABLE
46
47% \unexpanded\def\startrow            {\bTR}
48% \unexpanded\def\stoprow             {\eTR}
49% \unexpanded\def\startcell#1\stopcell{\bTD#1\eTD}
50%            \let\stopcell             \relax
51%            \let\startcelltable       \bTABLE
52%            \let\stopcelltable        \eTABLE
53
54% \starttext
55%     \startcelltable
56%         \startrow \startcell a \stopcell \stoprow
57%         \startrow \startcell a \stopcell \stoprow
58%         \startrow \startcell a \stopcell \stoprow
59%         \startrow \startcell a \stopcell \stoprow
60%     \stopcelltable
61% \stoptext
62
63%D As always, this is the n\high{th} version. Much time went in trying to speed up
64%D the many cell calculations, some optimizations were rejected in order not to
65%D complicate this module too much (and in order to prevail extensibility). In the
66%D meantime we've sacrified some speed for readability.
67
68\unprotect
69
70%D The next alternative also takes care of preceding and following white space.
71%D
72%D \startbuffer
73%D \bTABLE[left={(},right={)},top=\startnarrower,bottom=\stopnarrower]
74%D \bTR \bTD something \eTD \eTR
75%D \eTABLE
76%D \stopbuffer
77%D
78%D \typebuffer \getbuffer
79
80\ifdefined\dotagTABLEcell   \else \let\dotagTABLEcell  \relax \fi % todo: namespace
81\ifdefined\dotagTABLEsignal \else \let\dotagTABLEsignal\relax \fi % todo: namespace
82
83\let\tabl_ntb_next_level\relax
84
85\newtoks\t_tabl_ntb_cell_start
86\newtoks\t_tabl_ntb_cell_stop
87
88\appendtoks
89    \naturaltablelocalparameter\c!left
90    \delayedbegstrut
91\to \t_tabl_ntb_cell_start
92
93\appendtoks
94    \delayedendstrut
95    \naturaltablelocalparameter\c!right
96\to \t_tabl_ntb_cell_stop
97
98\appendtoks
99    \flushpostponednodedata
100    % maybe: \the\neverypar
101\to \t_tabl_ntb_cell_start
102
103\unexpanded\def\tabl_ntb_cell_start
104  {% \inhibitblank
105   \dotagTABLEcell
106  %\tabl_ntb_next_level
107   \font_styles_math_reset
108   \usenaturaltablelocalstyleandcolor\c!style\c!color
109   \everypar\t_tabl_ntb_cell_start
110   \font_styles_math_start}
111
112\unexpanded\def\tabl_ntb_cell_stop
113  {\font_styles_math_stop
114   \ifhmode
115     \the\t_tabl_ntb_cell_stop
116     \par % added 13/4/2006
117   \else
118     % not sure yet:\naturaltablelocalparameter\c!right
119     \ifdim\prevdepth<\zeropoint % =-1000pt ?
120       \vskip-\strutdp
121     \else
122       \removebottomthings
123     \fi
124   \fi}
125
126% maybe:
127%
128% \unexpanded\def\tabl_ntb_cell_stop
129%   {\ifhmode
130%      \the\t_tabl_ntb_cell_stop
131%      \par % added 13/4/2006
132%    \else
133%      % not sure yet:\naturaltablelocalparameter\c!right
134%      \par
135%      \ifhmode
136%         % \removeunwantedspaces
137%      \else\ifdim\prevdepth<\zeropoint % =-1000pt ?
138%        \vskip-\strutdp
139%      \else
140%        \removebottomthings
141%      \fi\fi
142%    \fi}
143
144\newcount\c_tabl_ntb_row
145\newcount\c_tabl_ntb_col
146\newcount\c_tabl_ntb_spn
147
148\newcount\c_tabl_ntb_nx
149\newcount\c_tabl_ntb_ny
150
151\setnewconstant\c_tabl_ntb_cell \plusone
152\setnewconstant\c_tabl_ntb_none \plustwo
153
154\newcount\c_tabl_ntb_current_row
155\newcount\c_tabl_ntb_current_col
156\newcount\c_tabl_ntb_current_row_one
157\newcount\c_tabl_ntb_current_col_one
158\newcount\c_tabl_ntb_current_row_two
159\newcount\c_tabl_ntb_current_col_two
160\newcount\c_tabl_ntb_current_row_three
161\newcount\c_tabl_ntb_current_col_three
162\newcount\c_tabl_ntb_current_row_four
163\newcount\c_tabl_ntb_current_col_four
164
165\newcount\c_tabl_ntb_running_col
166\newcount\c_tabl_ntb_maximum_row
167\newcount\c_tabl_ntb_maximum_col
168\newcount\c_tabl_ntb_maximum_row_span
169\newcount\c_tabl_ntb_maximum_col_span
170
171\newcount\c_tabl_ntb_encountered_col
172\newcount\c_tabl_ntb_encountered_max
173
174\newtoks\t_tabl_ntb
175\newtoks\t_tabl_ntb_row
176
177\newconstant\c_tabl_tbl_pass
178
179\newtoks\t_tabl_ntb_head
180\newtoks\t_tabl_ntb_next
181\newtoks\t_tabl_ntb_body
182\newtoks\t_tabl_ntb_foot
183
184\newcount\c_tabl_ntb_n_of_head_lines
185\newcount\c_tabl_ntb_n_of_next_lines
186\newcount\c_tabl_ntb_n_of_hdnx_lines
187
188\newdimen\d_tabl_ntb_height
189\newdimen\d_tabl_ntb_width
190
191\newdimen\d_tabl_ntb_leftmargindistance
192\newdimen\d_tabl_ntb_rightmargindistance
193\newdimen\d_tabl_ntb_columndistance
194\newdimen\d_tabl_ntb_maxwidth
195
196\newtoks\everyTABLEpass    % public
197
198\newcount\tablecellrows    % public (needs checking)
199\newcount\tablecellcolumns % public (needs checking)
200
201\newbox\b_tabl_ntb_final
202
203%D For tagging and export:
204
205\newconstant    \c_tabl_ntb_head
206\newconstant    \c_tabl_ntb_body
207\newconstant    \c_tabl_ntb_foot
208\newconditional \c_tabl_ntb_okay
209
210%D We have already prepared the previous macros for nesting, so we only have to pop
211%D in the right ones:
212
213\newcount\c_tabl_level
214
215\installglobalmacrostack\m_tabl_ntb_saved_row
216\installglobalmacrostack\m_tabl_ntb_saved_col
217
218\unexpanded\def\tabl_ntb_table_push
219  {\ifnum\m_tabl_tbl_level>\plusone
220     \tabl_ntb_parameters_reset
221     % we need a proper count push/pop
222     \xdef\m_tabl_ntb_saved_row{\the\c_tabl_ntb_row}\push_macro_m_tabl_ntb_saved_row
223     \xdef\m_tabl_ntb_saved_col{\the\c_tabl_ntb_col}\push_macro_m_tabl_ntb_saved_col
224   \else
225     \global\intabletrue
226   \fi}
227
228\unexpanded\def\tabl_ntb_table_pop
229  {\ifnum\m_tabl_tbl_level>\plusone
230     \pop_macro_m_tabl_ntb_saved_row\global\c_tabl_ntb_row\m_tabl_ntb_saved_row
231     \pop_macro_m_tabl_ntb_saved_col\global\c_tabl_ntb_col\m_tabl_ntb_saved_col
232   \else
233     \global\intablefalse
234   \fi}
235
236\unexpanded\def\tabl_ntb_next_level
237  {\advance\c_tabl_level\plusone
238   \edef\m_tabl_tbl_level{\the\c_tabl_level}}
239
240\unexpanded\def\tabl_ntb_prev_level
241  {\advance\c_tabl_level\minusone
242   \edef\m_tabl_tbl_level{\the\c_tabl_level}}
243
244\tabl_ntb_next_level % go to level 1
245
246%D This is for the special cases where for instance a table is in a header or footer
247%D line and we have a split table in progress. (See mail to list from Taco.)
248
249\installcorenamespace{naturaltable}      % was tbl
250\installcorenamespace{naturaltablelocal} % was tbltbl
251
252\installdirectcommandhandler       \??naturaltable      {naturaltable}      % \??naturaltable
253\installsimpleframedcommandhandler \??naturaltablelocal {naturaltablelocal} \??naturaltablelocal
254
255\unexpanded\def\bTABLEnested{\tabl_ntb_next_level\bTABLE}
256\unexpanded\def\eTABLEnested{\eTABLE\tabl_ntb_prev_level}
257
258\installcorenamespace{naturaltabletal}
259\installcorenamespace{naturaltablegal}
260\installcorenamespace{naturaltablenob}
261\installcorenamespace{naturaltabletag}
262\installcorenamespace{naturaltablecol}
263\installcorenamespace{naturaltablerow}
264\installcorenamespace{naturaltablewd}
265\installcorenamespace{naturaltableht}
266\installcorenamespace{naturaltabledp}
267\installcorenamespace{naturaltablewid}
268\installcorenamespace{naturaltablehei}
269\installcorenamespace{naturaltabledis}
270\installcorenamespace{naturaltableaut}
271\installcorenamespace{naturaltablebck}
272%installcorenamespace{naturaltablefwd} % forcedwidth
273\installcorenamespace{naturaltabletxt}
274\installcorenamespace{naturaltablespn}
275\installcorenamespace{naturaltableref}
276\installcorenamespace{naturaltableset}
277\installcorenamespace{naturaltablecell}
278\installcorenamespace{naturaltablesqueeze}
279\installcorenamespace{naturaltabletok}
280
281\letvalue{\??naturaltablesqueeze        }\donefalse
282\letvalue{\??naturaltablesqueeze\v!fit  }\donetrue
283\letvalue{\??naturaltablesqueeze\v!fixed}\donetrue
284\letvalue{\??naturaltablesqueeze\v!broad}\donetrue
285\letvalue{\??naturaltablesqueeze\v!local}\donetrue
286
287\def\tabl_ntb_let_gal{\expandafter\glet\csname\??naturaltablegal\m_tabl_tbl_level\endcsname}
288\def\tabl_ntb_get_gal{\csname\??naturaltablegal\m_tabl_tbl_level\endcsname}
289
290\def\tabl_ntb_let_tal#1{\expandafter\glet\csname\??naturaltabletal\m_tabl_tbl_level:\number#1\endcsname}
291\def\tabl_ntb_get_tal#1{\csname\??naturaltabletal\m_tabl_tbl_level:\number#1\endcsname}
292
293\def\tabl_ntb_set_nob#1{\expandafter\let\csname\??naturaltablenob\m_tabl_tbl_level:\number#1\endcsname\plusone}
294\def\tabl_ntb_get_nob#1{\ifcsname\??naturaltablenob\m_tabl_tbl_level:\number#1\endcsname\plusone\else\zerocount\fi}
295
296%def\tabl_ntb_set_tag#1#2{\expandafter\edef\csname\??naturaltabletag\m_tabl_tbl_level:\number#1:\number#2\endcsname}
297\def\tabl_ntb_set_col#1#2{\expandafter\edef\csname\??naturaltablecol\m_tabl_tbl_level:\number#1:\number#2\endcsname}
298\def\tabl_ntb_set_row#1#2{\expandafter\edef\csname\??naturaltablerow\m_tabl_tbl_level:\number#1:\number#2\endcsname}
299
300\def\tabl_ntb_let_tag#1#2{\expandafter\let\csname\??naturaltabletag\m_tabl_tbl_level:\number#1:\number#2\endcsname}
301\def\tabl_ntb_let_col#1#2{\expandafter\let\csname\??naturaltablecol\m_tabl_tbl_level:\number#1:\number#2\endcsname}
302\def\tabl_ntb_let_row#1#2{\expandafter\let\csname\??naturaltablerow\m_tabl_tbl_level:\number#1:\number#2\endcsname}
303
304%def\tabl_ntb_set_wd#1#2{\expandafter\xdef\csname\??naturaltablewd\m_tabl_tbl_level:\number#1:\number#2\endcsname} % global !
305\def\tabl_ntb_set_ht#1#2{\expandafter\xdef\csname\??naturaltableht\m_tabl_tbl_level:\number#1:\number#2\endcsname} % global !
306
307%def\tabl_ntb_let_wd#1#2{\expandafter\glet\csname\??naturaltablewd\m_tabl_tbl_level:\number#1:\number#2\endcsname} % global !
308\def\tabl_ntb_let_ht#1#2{\expandafter\glet\csname\??naturaltableht\m_tabl_tbl_level:\number#1:\number#2\endcsname} % global !
309
310\def\tabl_ntb_get_tag#1#2{\csname\??naturaltabletag\m_tabl_tbl_level:\number#1:\number#2\endcsname}
311\def\tabl_ntb_get_col#1#2{\csname\??naturaltablecol\m_tabl_tbl_level:\number#1:\number#2\endcsname}
312\def\tabl_ntb_get_row#1#2{\csname\??naturaltablerow\m_tabl_tbl_level:\number#1:\number#2\endcsname}
313
314%def\tabl_ntb_get_wd#1#2{\csname\??naturaltablewd\m_tabl_tbl_level:\number#1:\number#2\endcsname}
315\def\tabl_ntb_get_ht#1#2{\csname\??naturaltableht\m_tabl_tbl_level:\number#1:\number#2\endcsname}
316
317\def\tabl_ntb_set_wid#1{\expandafter\xdef\csname\??naturaltablewid\m_tabl_tbl_level:\number#1\endcsname} % {#2} global !
318\def\tabl_ntb_set_hei#1{\expandafter\xdef\csname\??naturaltablehei\m_tabl_tbl_level:\number#1\endcsname} % {#2} global !
319\def\tabl_ntb_set_dis#1{\expandafter\xdef\csname\??naturaltabledis\m_tabl_tbl_level:\number#1\endcsname} % {#2} global !
320\def\tabl_ntb_set_aut#1{\expandafter\xdef\csname\??naturaltableaut\m_tabl_tbl_level:\number#1\endcsname} % {#2} global !
321
322\def\tabl_ntb_let_wid#1{\expandafter\glet\csname\??naturaltablewid\m_tabl_tbl_level:\number#1\endcsname} % {#2} global !
323\def\tabl_ntb_let_hei#1{\expandafter\glet\csname\??naturaltablehei\m_tabl_tbl_level:\number#1\endcsname} % {#2} global !
324\def\tabl_ntb_let_dis#1{\expandafter\glet\csname\??naturaltabledis\m_tabl_tbl_level:\number#1\endcsname} % {#2} global !
325\def\tabl_ntb_let_aut#1{\expandafter\glet\csname\??naturaltableaut\m_tabl_tbl_level:\number#1\endcsname} % {#2} global !
326
327\def\tabl_ntb_get_wid#1{\ifcsname\??naturaltablewid\m_tabl_tbl_level:\number#1\endcsname\lastnamedcs\else\zeropoint\fi}
328\def\tabl_ntb_get_hei#1{\ifcsname\??naturaltablehei\m_tabl_tbl_level:\number#1\endcsname\lastnamedcs\else\zeropoint\fi}
329\def\tabl_ntb_get_dis#1{\ifcsname\??naturaltabledis\m_tabl_tbl_level:\number#1\endcsname\lastnamedcs\else\zeropoint\fi}
330\def\tabl_ntb_get_aut#1{\csname  \??naturaltableaut\m_tabl_tbl_level:\number#1\endcsname}
331
332\def\tabl_ntb_let_bck#1#2{\global\expandafter\chardef\csname\??naturaltablebck\m_tabl_tbl_level:\number#1:\number#2\endcsname}
333
334\def\tabl_ntb_get_bck#1#2{\csname\??naturaltablebck\m_tabl_tbl_level:\number#1:\number#2\endcsname}
335
336\def\tabl_ntb_tag_pattern#1#2{\??naturaltabletag\m_tabl_tbl_level:\number#1:\number#2}
337\def\tabl_ntb_row_pattern#1#2{\??naturaltablerow\m_tabl_tbl_level:\number#1:\number#2}
338\def\tabl_ntb_col_pattern#1#2{\??naturaltablecol\m_tabl_tbl_level:\number#1:\number#2}
339
340\def\tabl_ntb_tag_doif    #1#2{\ifcsname\??naturaltabletag\m_tabl_tbl_level:\number#1:\number#2\endcsname\expandafter\firstofoneargument \else\expandafter\gobbleoneargument   \fi}
341\def\tabl_ntb_tag_doifnot #1#2{\ifcsname\??naturaltabletag\m_tabl_tbl_level:\number#1:\number#2\endcsname\expandafter\gobbleoneargument  \else\expandafter\firstofoneargument  \fi}
342\def\tabl_ntb_tag_doifelse#1#2{\ifcsname\??naturaltabletag\m_tabl_tbl_level:\number#1:\number#2\endcsname\expandafter\firstoftwoarguments\else\expandafter\secondoftwoarguments\fi}
343\def\tabl_ntb_row_doif    #1#2{\ifcsname\??naturaltablerow\m_tabl_tbl_level:\number#1:\number#2\endcsname\expandafter\firstofoneargument \else\expandafter\gobbleoneargument   \fi}
344\def\tabl_ntb_col_doif    #1#2{\ifcsname\??naturaltablecol\m_tabl_tbl_level:\number#1:\number#2\endcsname\expandafter\firstofoneargument \else\expandafter\gobbleoneargument   \fi}
345\def\tabl_ntb_col_doifnot #1#2{\ifcsname\??naturaltablecol\m_tabl_tbl_level:\number#1:\number#2\endcsname\expandafter\gobbleoneargument  \else\expandafter\firstofoneargument  \fi}
346
347%D If we ever run into memory issues we can do:
348%
349% \def\tabl_ntb_let_tag#1#2#3%
350%   {\ifx#3\c_tabl_ntb_none\else
351%      \expandafter\let\csname\??naturaltabletag\m_tabl_tbl_level:\number#1:\number#2\endcsname#3%
352%    \fi}
353%
354% \def\tabl_ntb_get_tag#1#2%
355%   {\ifcsname\??naturaltabletag\m_tabl_tbl_level:\number#1:\number#2\endcsname
356%      \lastnamedcs
357%    \else
358%      \c_tabl_ntb_none
359%    \fi}
360
361% not used
362%
363% \def\tabl_ntb_tag_state#1#2{\ifcsname\??naturaltabletag\m_tabl_tbl_level:\number#1:\number#2\endcsname\zerocount\else\plusone\fi}
364% \def\tabl_ntb_row_state#1#2{\ifcsname\??naturaltablerow\m_tabl_tbl_level:\number#1:\number#2\endcsname\zerocount\else\plusone\fi}
365% \def\tabl_ntb_col_state#1#2{\ifcsname\??naturaltablecol\m_tabl_tbl_level:\number#1:\number#2\endcsname\zerocount\else\plusone\fi}
366
367%def\tabl_ntb_set_spn     #1{\expandafter\let\csname\??naturaltablespn\m_tabl_tbl_level:\number#1\endcsname \!!plusone}
368%def\tabl_ntb_spn_doifelse#1{\doifelse      {\csname\??naturaltablespn\m_tabl_tbl_level:\number#1\endcsname}\!!plusone}
369
370%def\tabl_ntb_set_spn     #1{\setvalue     {\??naturaltablespn\m_tabl_tbl_level:\number#1}{1}}
371%def\tabl_ntb_spn_doifelse#1{\doifelsevalue{\??naturaltablespn\m_tabl_tbl_level:\number#1}{1}}
372
373\def\tabl_ntb_let_ref   #1#2{\expandafter\glet\csname\??naturaltableref\m_tabl_tbl_level:\number#1:\number#2\endcsname}
374\def\tabl_ntb_set_ref   #1#2{\expandafter\xdef\csname\??naturaltableref\m_tabl_tbl_level:\number#1:\number#2\endcsname}
375%def\tabl_ntb_get_ref   #1#2{\ifcsname\??naturaltableref\m_tabl_tbl_level:\number#1:\number#2\endcsname\csname\??naturaltableref\m_tabl_tbl_level:\number#1:\number#2\endcsname\fi}
376\def\tabl_ntb_get_ref   #1#2{\begincsname\??naturaltableref\m_tabl_tbl_level:\number#1:\number#2\endcsname}
377
378\def\tabl_ntb_set_spn     #1{\expandafter\let\csname\??naturaltablespn\m_tabl_tbl_level:\number#1\endcsname \!!plusone}
379\def\tabl_ntb_spn_doifelse#1{\ifcase0\csname\??naturaltablespn\m_tabl_tbl_level:\number#1\endcsname\relax % could be inlined
380                               \expandafter\secondoftwoarguments % unset
381                             \else
382                               \expandafter\firstoftwoarguments  % a span
383                             \fi}
384
385% keep for a while:
386%
387% \unexpanded\def\tabl_ntb_set_txt_process#1#2#3#4#5#6% nasty: we restore the level
388%   {\expandafter\def\csname\??naturaltabletxt\m_tabl_tbl_level:\number#1:\number#2\expandafter\endcsname\expandafter
389%      {\expandafter\def\expandafter\m_tabl_tbl_level\expandafter{\m_tabl_tbl_level}\tabl_ntb_cell_process{#3}{#4}[#5]{#6}}}
390
391\unexpanded\def\tabl_ntb_set_txt_process#1#2#3#4#5#6%
392  {\expandafter\def\csname\??naturaltabletxt\m_tabl_tbl_level:\number#1:\number#2\endcsname
393     {\tabl_ntb_cell_process{#3}{#4}[#5]{\tabl_ntb_next_level#6\tabl_ntb_prev_level}}}
394
395\def\tabl_ntb_get_txt#1#2%
396  {\csname\??naturaltabletxt\m_tabl_tbl_level:\number#1:\number#2\endcsname}
397
398% to be changed:
399
400\newif\ifsqueezeTBLspan     \squeezeTBLspantrue     % spans one column cell over multi column par cells
401\newif\ifautosqueezeTBLspan \autosqueezeTBLspantrue % unless explicit widths are given
402\newif\ifautoTBLspread      \autoTBLspreadfalse
403\newif\ifautoTBLhsize       \autoTBLhsizetrue
404\newif\ifautoTBLrowspan     \autoTBLrowspantrue
405\newif\ifautoTBLemptycell   \autoTBLemptycelltrue
406\newif\ifautoTBLcheckwidth  \autoTBLcheckwidthtrue
407\newif\ifappendTBLsetups    \appendTBLsetupstrue
408\newif\ifenableTBLbreak     \enableTBLbreakfalse
409\newif\ifmultipleTBLheads   \multipleTBLheadsfalse
410\newif\iftightTBLrowspan    \tightTBLrowspantrue
411\newif\iftightTBLcolspan    \tightTBLcolspanfalse
412
413\newconditional \c_tabl_ntb_trace_widths
414
415\installtextracker
416  {tables.natural.widths}
417  {\settrue \c_tabl_ntb_trace_widths}
418  {\setfalse\c_tabl_ntb_trace_widths}
419
420% so far
421
422\unexpanded\def\tabl_ntb_cell_process#1#2[#3]{}
423
424\unexpanded\def\bTC#1\eTC{\bTD#1\eTD} \let\eTC\relax
425\unexpanded\def\bTX#1\eTX{\bTD#1\eTD} \let\eTX\relax
426\unexpanded\def\bTY#1\eTY{\bTR#1\eTR} \let\eTY\relax
427
428\unexpanded\def\setupTABLE
429  {\dotripleempty\tabl_ntb_setup}
430
431\let\tabl_ntb_parameters_get\setupcurrentnaturaltablelocal
432
433\def\tabl_ntb_setup
434  {\ifthirdargument
435     \expandafter\tabl_ntb_setup_three
436   \else\ifsecondargument
437     \doubleexpandafter\tabl_ntb_setup_two
438   \else
439     \doubleexpandafter\tabl_ntb_setup_one
440   \fi\fi}
441
442\def\tabl_ntb_setup_one[#1][#2][#3]%
443  {\setupcurrentnaturaltablelocal[#1]}
444
445\def\tabl_ntb_setup_xy[#1][#2][#3]%
446  {\def\tabl_ntb_setup_step##1{\tabl_ntb_parameters_set[#1##1][#3]}%
447   \processcommalist[#2]\tabl_ntb_setup_step}
448
449\def\tabl_ntb_setup_un[#1][#2][#3]%
450  {\def\tabl_ntb_setup_step##1%
451     {\def\tabl_ntb_setup_step_step####1{\tabl_ntb_parameters_set[\c!x##1\c!y####1][#3]}%
452      \processcommalist[#2]\tabl_ntb_setup_step_step}%
453   \processcommalist[#1]\tabl_ntb_setup_step}
454
455\def\tabl_ntb_setup_each[#1][#2][#3]% ignores #3
456  {\tabl_ntb_parameters_set[#1\v!each][#2]}
457
458\def\tabl_ntb_setup_ux[#1][#2][#3]% ignores #3
459  {\def\tabl_ntb_setup_step##1{\tabl_ntb_parameters_set[\c!x##1][#2]}%
460   \processcommalist[#1]\tabl_ntb_setup_step}
461
462\installcorenamespace{naturaltablesetupthree}
463\installcorenamespace{naturaltablesetuptwo}
464
465%def\tabl_ntb_setup_three[#1]{\csname\??naturaltablesetupthree\ifcsname\??naturaltablesetupthree#1\endcsname#1\else\s!unknown\fi\endcsname[#1]}
466%def\tabl_ntb_setup_two  [#1]{\csname\??naturaltablesetuptwo  \ifcsname\??naturaltablesetuptwo  #1\endcsname#1\else\s!unknown\fi\endcsname[#1]}
467
468\def\tabl_ntb_setup_three[#1]{\ifcsname\??naturaltablesetupthree#1\endcsname\expandafter\lastnamedcs\else\expandafter\tabl_ntb_setup_un\fi[#1]}
469\def\tabl_ntb_setup_two  [#1]{\ifcsname\??naturaltablesetuptwo  #1\endcsname\expandafter\lastnamedcs\else\expandafter\tabl_ntb_setup_ux\fi[#1]}
470
471\setvalue{\??naturaltablesetupthree    \v!row}[#1]{\tabl_ntb_setup_xy  [\c!y]}
472\setvalue{\??naturaltablesetupthree \v!column}[#1]{\tabl_ntb_setup_xy  [\c!x]}
473\setvalue{\??naturaltablesetupthree  \v!start}[#1]{\tabl_ntb_setup_xy  [\v!start]}
474\setvalue{\??naturaltablesetupthree \v!header}[#1]{\tabl_ntb_setup_xy  [\v!header]}
475
476\setvalue{\??naturaltablesetuptwo      \v!row}[#1]{\tabl_ntb_setup_each[\c!y]}
477\setvalue{\??naturaltablesetuptwo   \v!column}[#1]{\tabl_ntb_setup_each[\c!x]}
478\setvalue{\??naturaltablesetuptwo    \v!start}[#1]{\tabl_ntb_setup_each[\v!start]}
479\setvalue{\??naturaltablesetuptwo   \v!header}[#1]{\tabl_ntb_setup_each[\v!header]}
480
481\letvalue{\??naturaltablesetupthree\s!unknown}\tabl_ntb_setup_un
482\letvalue{\??naturaltablesetuptwo  \s!unknown}\tabl_ntb_setup_ux
483
484\letcsnamecsname\csname\??naturaltablesetupthree r\endcsname\csname\??naturaltablesetupthree   \v!row\endcsname
485\letcsnamecsname\csname\??naturaltablesetupthree c\endcsname\csname\??naturaltablesetupthree\v!column\endcsname
486\letcsnamecsname\csname\??naturaltablesetupthree y\endcsname\csname\??naturaltablesetupthree   \v!row\endcsname
487\letcsnamecsname\csname\??naturaltablesetupthree x\endcsname\csname\??naturaltablesetupthree\v!column\endcsname
488
489\letcsnamecsname\csname\??naturaltablesetuptwo   r\endcsname\csname\??naturaltablesetuptwo     \v!row\endcsname
490\letcsnamecsname\csname\??naturaltablesetuptwo   c\endcsname\csname\??naturaltablesetuptwo  \v!column\endcsname
491\letcsnamecsname\csname\??naturaltablesetuptwo   y\endcsname\csname\??naturaltablesetuptwo     \v!row\endcsname
492\letcsnamecsname\csname\??naturaltablesetuptwo   x\endcsname\csname\??naturaltablesetuptwo  \v!column\endcsname
493
494\def\tabl_ntb_parameters_set[#1][#2]%
495  {\ifappendTBLsetups
496     \ifcsname\??naturaltableset\m_tabl_tbl_level:#1\endcsname
497       \def\tabl_ntb_parameters_get[##1]%
498         {\setvalue{\??naturaltableset\m_tabl_tbl_level:#1}{\tabl_ntb_parameters_get[##1,#2]}}%
499       \csname\??naturaltableset\m_tabl_tbl_level:#1\endcsname
500       \let\tabl_ntb_parameters_get\setupcurrentnaturaltablelocal
501     \else
502       \setvalue{\??naturaltableset\m_tabl_tbl_level:#1}{\tabl_ntb_parameters_get[#2]}%
503     \fi
504   \else
505     \setvalue{\??naturaltableset\m_tabl_tbl_level:#1}{\tabl_ntb_parameters_get[#2]}%
506   \fi}
507
508% % \setupTABLE [y]    [first][background=color,backgroundcolor=blue,frame=off,bottomframe=on,topframe=on,framecolor=white]
509% \setupTABLE [first][first][backgroundcorner=2,corner=10,frame=on]
510% \setupTABLE [last] [first][backgroundcorner=4,corner=12,frame=on]
511%
512% \setupTABLE [row]  [each] [background=color,backgroundcolor=blue,frame=on,framecolor=white]
513% \setupTABLE [first][2]    [corner=8]
514% \setupTABLE [last] [2]    [corner=5]
515% \setupTABLE [first][last] [corner=7]
516% \setupTABLE [last] [last] [corner=6]
517%
518% \startTEXpage
519% \bTABLE[frame=off,align=middle]
520% \bTR \bTD one   \eTD \bTD two    \eTD \bTD three \eTD \eTR
521% \bTR \bTD first \eTD \bTD second \eTD \bTD third \eTD \eTR
522% \bTR \bTD alpha \eTD \bTD beta   \eTD \bTD gamma \eTD \eTR
523% \eTABLE
524% \stopTEXpage
525%
526% \setupTABLE [first] [two][corner=2] % special case
527% \setupTABLE [last]  [two][corner=4] % special case
528%
529% % % \setupTABLE [one] [first] ... special case of span
530%
531% \startTEXpage
532% \bTABLE[frame=off,align=middle]
533% \bTR \bTD one   \eTD \bTD two    \eTD \bTD three \eTD \eTR
534% \bTR \bTD first \eTD \bTD second \eTD \bTD third \eTD \eTR
535% \eTABLE
536% \stopTEXpage
537
538%D By default rowspans are tight but you can change that:
539%D
540%D \startbuffer
541%D \bTABLE
542%D \bTR[height=20pt] \bTH 1. col                \eTH \bTH 2. col                 \eTH  \eTR
543%D \bTR[height=20pt] \bTD 1 row in 1. col       \eTD \bTD[nr=2] 2 rows in 2. col \eTD  \eTR
544%D \bTR[height=20pt] \bTD[nr=2] 2 rows in 1. col\eTD                                   \eTR
545%D \bTR[height=20pt]                                 \bTD[nr=3] 3 rows in 2. col \eTD  \eTR
546%D \bTR[height=20pt] \bTD 1 row in 1. col       \eTD                                   \eTR
547%D \bTR[height=20pt] \bTD 1 row in 1. col       \eTD                                   \eTR
548%D \eTABLE
549%D
550%D \bTABLE
551%D \bTR[height=20pt] \bTH 2. col                 \eTH  \bTH 1. col                \eTH \eTR
552%D \bTR[height=20pt] \bTD[nr=2] 2 rows in 2. col \eTD  \bTD 1 row in 1. col       \eTD \eTR
553%D \bTR[height=20pt]                                   \bTD[nr=2] 2 rows in 1. col\eTD \eTR
554%D \bTR[height=20pt] \bTD[nr=3] 3 rows in 2. col \eTD                                  \eTR
555%D \bTR[height=20pt]                                   \bTD 1 row in 1. col       \eTD \eTR
556%D \bTR[height=20pt]                                   \bTD 1 row in 1. col       \eTD \eTR
557%D \eTABLE
558%D \stopbuffer
559%D
560%D \typebuffer
561%D
562%D \getbuffer
563%D
564%D With \type {\tightTBLrowspanfalse} we get:
565%D
566%D \start \tightTBLrowspanfalse \getbuffer \stop
567
568\let\tabl_ntb_setup_section\relax
569
570\unexpanded\def\tabl_ntb_setup_cell#1#2% cell over col over row
571  {\tabl_ntb_setup_section % already forgotten
572   \edef\m_tabl_ntb_positive_row{\number#1}%
573   \edef\m_tabl_ntb_positive_col{\number#2}%
574   \edef\m_tabl_ntb_negative_row{\the\numexpr-\c_tabl_ntb_maximum_row+#1+\minusone\relax}%
575   \edef\m_tabl_ntb_negative_col{\the\numexpr-\c_tabl_ntb_maximum_col+#2+\minusone\relax}%
576   % saves tokens (no speed gain)
577   \edef\m_tabl_ntb_prefix{\??naturaltableset\m_tabl_tbl_level:}%
578   % each each
579   \begincsname\m_tabl_ntb_prefix\c!x\v!each\c!y\v!each\endcsname
580   \begincsname\m_tabl_ntb_prefix\c!y\v!each\endcsname
581   \begincsname\m_tabl_ntb_prefix\c!x\v!each\endcsname
582   % odd even
583   \begincsname\m_tabl_ntb_prefix\c!y\v!oddeven\m_tabl_ntb_positive_row\endcsname
584   \begincsname\m_tabl_ntb_prefix\c!x\v!oddeven\m_tabl_ntb_positive_col\endcsname
585   \begincsname\m_tabl_ntb_prefix\c!x\v!oddeven\m_tabl_ntb_positive_col\c!y\v!oddeven\m_tabl_ntb_positive_row\endcsname
586   % row/col number combinations
587   \begincsname\m_tabl_ntb_prefix\c!y\m_tabl_ntb_positive_row\endcsname
588   \begincsname\m_tabl_ntb_prefix\c!y\m_tabl_ntb_negative_row\endcsname
589   \naturaltablelocalparameter\c!extras
590   \letnaturaltablelocalparameter\c!extras\relax % new, see x-fo
591   \begincsname\m_tabl_ntb_prefix\c!x\m_tabl_ntb_positive_col\endcsname
592   \begincsname\m_tabl_ntb_prefix\c!x\m_tabl_ntb_negative_col\endcsname
593   \naturaltablelocalparameter\c!extras
594   \letnaturaltablelocalparameter\c!extras\relax % new, see x-fo
595   % first/last combinations
596   \ifnum\m_tabl_ntb_positive_row=\plusone
597     \begincsname\m_tabl_ntb_prefix\c!y\v!first\endcsname
598     \begincsname\m_tabl_ntb_prefix\c!x\m_tabl_ntb_positive_col\c!y\v!first\endcsname
599   \fi
600   \ifnum\m_tabl_ntb_positive_col=\plusone
601     \begincsname\m_tabl_ntb_prefix\c!x\v!first\endcsname
602     \begincsname\m_tabl_ntb_prefix\c!x\v!first\c!y\m_tabl_ntb_positive_row\endcsname
603   \fi
604   \ifnum\m_tabl_ntb_positive_row=\c_tabl_ntb_maximum_row\relax
605     \begincsname\m_tabl_ntb_prefix\c!y\v!last\endcsname
606     \begincsname\m_tabl_ntb_prefix\c!x\m_tabl_ntb_positive_col\c!y\v!last\endcsname
607   \fi
608   \ifnum\m_tabl_ntb_positive_col=\c_tabl_ntb_maximum_col\relax
609     \begincsname\m_tabl_ntb_prefix\c!x\v!last\endcsname
610     \begincsname\m_tabl_ntb_prefix\c!x\v!last\c!y\m_tabl_ntb_positive_row\endcsname
611   \fi
612   \ifnum\m_tabl_ntb_positive_row=\c_tabl_ntb_maximum_row\relax \ifnum\m_tabl_ntb_positive_col=\c_tabl_ntb_maximum_col\relax
613     \begincsname\m_tabl_ntb_prefix\c!x\v!last\c!y\v!last\endcsname
614   \fi\fi
615   \ifnum\m_tabl_ntb_positive_row=\plusone \ifnum\m_tabl_ntb_positive_col=\plusone
616     \begincsname\m_tabl_ntb_prefix\c!x\v!first\c!y\v!first\endcsname
617   \fi\fi
618   \ifnum\m_tabl_ntb_positive_row=\plusone \ifnum\m_tabl_ntb_positive_col=\c_tabl_ntb_maximum_col\relax
619     \begincsname\m_tabl_ntb_prefix\c!x\v!last\c!y\v!first\endcsname
620   \fi\fi
621   \ifnum\m_tabl_ntb_positive_row=\c_tabl_ntb_maximum_row\relax \ifnum\m_tabl_ntb_positive_col=\plusone
622     \begincsname\m_tabl_ntb_prefix\c!x\v!first\c!y\v!last\endcsname
623   \fi\fi
624   % special case: two rows and last row : two&first and two&last (round corners)
625   \ifnum\c_tabl_ntb_maximum_row=\plustwo\relax
626     \ifnum\m_tabl_ntb_positive_row=\c_tabl_ntb_maximum_row\relax \ifnum\m_tabl_ntb_positive_col=\plusone
627       \begincsname\m_tabl_ntb_prefix\c!x\v!first\c!y\v!two\endcsname
628     \fi\fi
629     \ifnum\m_tabl_ntb_positive_row=\c_tabl_ntb_maximum_row\relax \ifnum\m_tabl_ntb_positive_col=\c_tabl_ntb_maximum_col\relax
630       \begincsname\m_tabl_ntb_prefix\c!x\v!last\c!y\v!two\endcsname
631     \fi\fi
632   \fi
633   \ifnum\tabl_ntb_get_col\m_tabl_ntb_positive_row\m_tabl_ntb_positive_col=\c_tabl_ntb_maximum_col\relax % top span over whole width
634     \ifnum\m_tabl_ntb_positive_row=\plusone
635       \begincsname\m_tabl_ntb_prefix\c!x\v!one\c!y\v!first\endcsname
636     \fi
637     \ifnum\m_tabl_ntb_positive_row=\c_tabl_ntb_maximum_row\relax
638       \begincsname\m_tabl_ntb_prefix\c!x\v!one\c!y\v!last\endcsname
639     \fi
640   \fi
641   % header things
642   \ifnum#1>\c_tabl_ntb_n_of_hdnx_lines\else
643     \begincsname\m_tabl_ntb_prefix\v!header\v!each\endcsname
644     \begincsname\m_tabl_ntb_prefix\v!header\m_tabl_ntb_positive_col\endcsname
645   \fi
646   % explicit cells
647   \begincsname\m_tabl_ntb_prefix\c!x\m_tabl_ntb_positive_col\c!y\m_tabl_ntb_positive_row\endcsname
648   \begincsname\m_tabl_ntb_prefix\c!x\m_tabl_ntb_negative_col\c!y\m_tabl_ntb_negative_row\endcsname
649   % local
650   \begincsname\m_tabl_ntb_prefix\c!y++\m_tabl_ntb_positive_row\endcsname
651   % done
652   \relax}
653
654% we cannot use +n (checking on number/last/first would slow down too much)
655%
656% \setupTABLE[r]  [2][color=red]
657% \setupTABLE[r] [-2][color=red]
658% \setupTABLE[c]  [2][color=green]
659% \setupTABLE[c] [-2][color=green]
660% \setupTABLE[4]  [4][color=blue]
661% \setupTABLE[-4][-4][color=blue]
662%
663% \bTABLE
664% \dorecurse{10}{\bTR \dorecurse{6}{\bTD xxx \eTD} \eTR}
665% \eTABLE
666
667\let\m_tabl_ntb_before_split\empty
668\let\m_tabl_ntb_after_split \empty
669\let\m_tabl_ntb_same_page   \empty
670
671% split + page:
672%
673% \bTABLE[split=yes]
674% \bTR \bTD left \eTD\bTD right \eTD\eTR
675% \bTR[after=\page] \bTD left \eTD\bTD right \eTD\eTR
676% \bTR \bTD left \eTD\bTD right \eTD\eTR
677% \eTABLE
678
679\unexpanded\def\tabl_ntb_tr
680  {\c_tabl_ntb_running_col\zerocount
681   \c_tabl_ntb_encountered_col\zerocount
682   \advance\c_tabl_ntb_maximum_row\plusone
683   \iffirstargument
684     \expandafter\tabl_ntb_tr_yes
685   \else
686     \expandafter\gobbleoneoptional
687   \fi}
688
689\def\tabl_ntb_tr_yes[#1]%
690  {\setvalue{\??naturaltableset\m_tabl_tbl_level:\c!y++\the\c_tabl_ntb_maximum_row}{\setupcurrentnaturaltablelocal[#1]}}
691
692\def\m_tabl_ntb_default_nr{\naturaltableparameter\c!nr}
693\def\m_tabl_ntb_default_nc{\naturaltableparameter\c!nc}
694
695\unexpanded\def\tabl_ntb_td
696  {\advance\c_tabl_ntb_encountered_col\plusone
697   \iffirstargument
698     \expandafter\tabl_ntb_td_yes
699   \else
700     \expandafter\tabl_ntb_td_nop
701   \fi}
702
703\def\tabl_ntb_td_yes[#1]#2\eTD
704  {\letnaturaltableparameter\c!ny    \m_tabl_ntb_default_nr
705   \letnaturaltableparameter\c!nx    \m_tabl_ntb_default_nc
706   \letnaturaltableparameter\c!nc    \plusone
707   \letnaturaltableparameter\c!nr    \plusone
708   \letnaturaltableparameter\c!n     \c_tabl_ntb_running_col
709   \letnaturaltableparameter\c!m     \empty
710   \letnaturaltableparameter\c!action\empty % not that important
711   \setupcurrentnaturaltable[#1]%
712   %
713   \c_tabl_ntb_nx\naturaltableparameter\c!nx\relax
714   \c_tabl_ntb_ny\naturaltableparameter\c!ny\relax
715   % goto first cell n/m=cellnumber
716   \edef\m_tabl_ntb_n{\naturaltableparameter\c!n}%
717   \edef\m_tabl_ntb_m{\naturaltableparameter\c!m}%
718   %
719   \ifx\m_tabl_ntb_n\empty
720     \global\advance\c_tabl_ntb_spn\c_tabl_ntb_nx\relax
721   \else\ifnum\m_tabl_ntb_n=\c_tabl_ntb_running_col\else
722     \tabl_ntb_td_pass_n{#1}%
723   \fi\fi
724   \ifx\m_tabl_ntb_m\empty \else
725     \ifnum\m_tabl_ntb_m=\c_tabl_ntb_running_col\else
726       \tabl_ntb_td_pass_m{#1}%
727     \fi
728   \fi
729   \doloop % skip over columns that result from earlier span
730     {\advance\c_tabl_ntb_running_col\plusone
731      \ifcsname\tabl_ntb_tag_pattern\c_tabl_ntb_maximum_row\c_tabl_ntb_running_col\endcsname \else
732        \exitloop
733      \fi}%
734   % fill r*c cells and set span
735   \c_tabl_ntb_nx\naturaltableparameter\c!nx\relax
736   \c_tabl_ntb_ny\naturaltableparameter\c!ny\relax
737   \ifnum\c_tabl_ntb_nx=\plusone
738     \ifnum\c_tabl_ntb_ny=\plusone
739       \ifnum\c_tabl_ntb_running_col>\c_tabl_ntb_maximum_col\relax
740         \c_tabl_ntb_maximum_col\c_tabl_ntb_running_col
741       \fi
742     \else
743       \tabl_ntb_cell_preset
744     \fi
745   \else
746     \tabl_ntb_cell_preset
747   \fi
748   % set values
749   \tabl_ntb_let_tag\c_tabl_ntb_maximum_row\c_tabl_ntb_running_col\c_tabl_ntb_cell
750   \tabl_ntb_set_col\c_tabl_ntb_maximum_row\c_tabl_ntb_running_col{\the\c_tabl_ntb_nx}%
751   \tabl_ntb_set_row\c_tabl_ntb_maximum_row\c_tabl_ntb_running_col{\the\c_tabl_ntb_ny}%
752   % the action key will change!
753   \tabl_ntb_set_ref\c_tabl_ntb_maximum_row\c_tabl_ntb_running_col{\naturaltableparameter\c!action}%
754   % save text
755   \normalexpanded
756     {\tabl_ntb_set_txt_process\c_tabl_ntb_maximum_row\c_tabl_ntb_running_col{\the\c_tabl_ntb_maximum_row}{\the\c_tabl_ntb_running_col}}%
757     {#1}{#2}%
758   \ifnum\c_tabl_ntb_encountered_col>\c_tabl_ntb_encountered_max
759     \c_tabl_ntb_encountered_max\c_tabl_ntb_encountered_col
760   \fi}
761
762\def\tabl_ntb_td_nop[#1]#2\eTD
763  {\global\advance\c_tabl_ntb_spn\plusone\relax
764   \doloop
765     {\advance\c_tabl_ntb_running_col\plusone
766      \ifcsname\tabl_ntb_tag_pattern\c_tabl_ntb_maximum_row\c_tabl_ntb_running_col\endcsname \else
767        \exitloop
768      \fi}%
769   \c_tabl_ntb_nx\plusone
770   \c_tabl_ntb_ny\plusone
771   \ifnum\c_tabl_ntb_running_col>\c_tabl_ntb_maximum_col\relax
772     \c_tabl_ntb_maximum_col\c_tabl_ntb_running_col
773   \fi
774   \tabl_ntb_let_tag\c_tabl_ntb_maximum_row\c_tabl_ntb_running_col\c_tabl_ntb_cell
775   \tabl_ntb_set_col\c_tabl_ntb_maximum_row\c_tabl_ntb_running_col{\the\c_tabl_ntb_nx}%
776   \tabl_ntb_set_row\c_tabl_ntb_maximum_row\c_tabl_ntb_running_col{\the\c_tabl_ntb_ny}%
777   \tabl_ntb_let_ref\c_tabl_ntb_maximum_row\c_tabl_ntb_running_col\empty
778   \normalexpanded
779     {\tabl_ntb_set_txt_process\c_tabl_ntb_maximum_row\c_tabl_ntb_running_col{\the\c_tabl_ntb_maximum_row}{\the\c_tabl_ntb_running_col}}%
780     {#1}{#2}%
781   \ifnum\c_tabl_ntb_encountered_col>\c_tabl_ntb_encountered_max
782     \c_tabl_ntb_encountered_max\c_tabl_ntb_encountered_col
783   \fi}
784
785\def\tabl_ntb_td_pass_n#1%
786  {\scratchcounter\numexpr\m_tabl_ntb_n-\c_tabl_ntb_running_col+\minusone-\c_tabl_ntb_spn\relax
787   \ifnum\scratchcounter>\zerocount
788     \normalexpanded{\tabl_ntb_td[\c!nx=\the\scratchcounter,\c!n=,\c!m=,*sq=\v!no]}\eTD
789   \fi
790   \letnaturaltableparameter\c!ny\m_tabl_ntb_default_nr
791   \letnaturaltableparameter\c!nx\m_tabl_ntb_default_nc
792   \letnaturaltableparameter\c!nc\plusone
793   \letnaturaltableparameter\c!nr\plusone
794   \setupcurrentnaturaltable[#1]%
795   \letnaturaltableparameter\c!n \empty
796   \letnaturaltableparameter\c!m \empty}
797
798\def\tabl_ntb_td_pass_m#1%
799  {\scratchcounter\numexpr\m_tabl_ntb_m-\c_tabl_ntb_running_col+\minusone-\c_tabl_ntb_spn\relax
800   \dorecurse\scratchcounter{\normalexpanded{\tabl_ntb_td[\c!n=,\c!m=]}\eTD}%
801   % can be sped up
802   \letnaturaltableparameter\c!ny\m_tabl_ntb_default_nr
803   \letnaturaltableparameter\c!nx\m_tabl_ntb_default_nc
804   \letnaturaltableparameter\c!nc\plusone
805   \letnaturaltableparameter\c!nr\plusone
806   \setupcurrentnaturaltable[#1]%
807   \letnaturaltableparameter\c!n \empty
808   \letnaturaltableparameter\c!m \empty}
809
810\def\tabl_ntb_cell_preset
811  {\c_tabl_ntb_current_row\c_tabl_ntb_maximum_row
812   \c_tabl_ntb_current_col\c_tabl_ntb_running_col
813   \dorecurse\c_tabl_ntb_ny\tabl_ntb_cell_preset_rows
814   % check max column
815   \advance\c_tabl_ntb_current_col\minusone
816   \ifnum\c_tabl_ntb_current_col>\c_tabl_ntb_maximum_col\relax
817     \c_tabl_ntb_maximum_col\c_tabl_ntb_current_col
818   \fi}
819
820\def\tabl_ntb_cell_preset_rows
821  {\c_tabl_ntb_current_col\c_tabl_ntb_running_col
822   \tabl_ntb_set_col\c_tabl_ntb_current_row\c_tabl_ntb_current_col{\the\c_tabl_ntb_nx}%
823   \ifnum\c_tabl_ntb_nx>\c_tabl_ntb_maximum_row_span\relax
824     \c_tabl_ntb_maximum_row_span\c_tabl_ntb_nx
825   \fi
826   \dorecurse\c_tabl_ntb_nx\tabl_ntb_cell_preset_cells
827   \advance\c_tabl_ntb_current_row\plusone}
828
829\def\tabl_ntb_cell_preset_cells
830  {\tabl_ntb_let_tag\c_tabl_ntb_current_row\c_tabl_ntb_current_col\c_tabl_ntb_none
831   \advance\c_tabl_ntb_current_col\plusone}
832
833%D The usage of n and m:
834%D
835%D \startbuffer
836%D \bTABLE[width=3em]
837%D \bTR\bTD d1 \eTD\bTD[n=2] d2 \eTD\bTD[n=5] d5 \eTD\bTD[n=7] d7 \eTD\eTR
838%D \bTR\bTD f1 \eTD\bTD[n=4] f4 \eTD\bTD[n=5] f5 \eTD\bTD[n=7] f7 \eTD\eTR
839%D \eTABLE
840%D \stopbuffer
841%D
842%D \typebuffer \getbuffer
843%D
844%D \startbuffer
845%D \bTABLE[width=3em]
846%D \bTR\bTD d1 \eTD\bTD[m=2] d2 \eTD\bTD[m=5] d5 \eTD\bTD[m=7] d7 \eTD\eTR
847%D \bTR\bTD f1 \eTD\bTD[m=4] f4 \eTD\bTD[m=5] f5 \eTD\bTD[m=7] f7 \eTD\eTR
848%D \eTABLE
849%D \stopbuffer
850%D
851%D \typebuffer \getbuffer
852%D
853%D \startbuffer
854%D \bTABLE[frame=on]
855%D \bTR \bTH[nc=3] One \eTH \bTH[m=4] Four \eTH\eTR
856%D \bTR \bTD a \eTD\bTD b \eTD\bTD c \eTD\bTD d \eTD\eTR
857%D \eTABLE
858%D
859%D \bTABLE[frame=on]
860%D \bTR \bTH[nr=2] One \eTH \bTH[m=3] Three \eTH\eTR
861%D \bTR \bTD[m=3] a \eTD\bTD b \eTD\bTD c \eTD\bTD d \eTD\eTR
862%D \bTR \bTD[m=3] a \eTD\bTD b \eTD\bTD c \eTD\bTD d \eTD\eTR
863%D \eTABLE
864%D \stopbuffer
865%D
866%D \typebuffer \getbuffer
867
868\def\tabl_ntb_th[#1]#2\eTH
869  {\tabl_ntb_td[#1,\c!color=\naturaltablelocalparameter\c!headcolor,\c!style=\naturaltablelocalparameter\c!headstyle,\c!aligncharacter=\v!no]#2\eTD}
870
871\def\tabl_ntb_tn[#1]#2\eTN
872  {\tabl_ntb_td[#1]\digits#2\relax\eTD}
873
874%D Vit Zyka needed the option to create a distance between columns, so I added
875%D support for individual column distances.
876%D
877%D \startbuffer
878%D % \setupTABLE[c][each][distance=2em]
879%D \setupTABLE[c][1][distance=2em]
880%D \setupTABLE[c][2][distance=3em]
881%D
882%D \bTABLE
883%D \bTR \bTD test \eTD  \bTD test \eTD  \bTD test \eTD \eTR
884%D \bTR \bTD[nx=2] test \eTD  \bTD test \eTD \eTR
885%D \bTR \bTD test \eTD  \bTD[nx=2] test \eTD \eTR
886%D \eTABLE
887%D
888%D \bTABLE[option=stretch]
889%D \bTR \bTD test \eTD  \bTD test \eTD  \bTD test \eTD \eTR
890%D \bTR \bTD[nx=2] test \eTD  \bTD test \eTD \eTR
891%D \bTR \bTD test \eTD  \bTD[nx=2] test \eTD \eTR
892%D \eTABLE
893%D \stopbuffer
894%D
895%D \typebuffer \startlinecorrection \getbuffer \stoplinecorrection
896%D
897%D and he provided patches for the global left and right margin distances as well as
898%D the columndistance (although i changed the names -). Here is his testcase:
899%D
900%D \startbuffer
901%D \framed[offset=overlay]\bgroup
902%D     \setupTABLE[column][2][align=left]%
903%D     \setupTABLE[column][3][align=right]%
904%D     \bTABLE[columndistance=2cm,leftmargindistance=.3cm,rightmargindistance=.5cm]
905%D         \bTR \bTH[nc=3] Table head\eTH \eTR
906%D         \bTR \bTD[nc=2] AB\eTD \bTD C\eTD \eTR
907%D         \bTR \bTD[nc=2,align=left] AB\eTD \bTD C\eTD \eTR
908%D         \bTR \bTD[nc=2,align=middle] AB\eTD \bTD C\eTD \eTR
909%D         \bTR \bTD A\eTD \bTD B\eTD \bTD C\eTD \eTR
910%D         \bTR \bTD Aa\eTD \bTD Bb\eTD \bTD Cccc\eTD \eTR
911%D         \bTR \bTD[nc=3,align=middle] ABC\eTD \eTR
912%D     \eTABLE
913%D \egroup
914%D \stopbuffer
915%D
916%D \typebuffer \startlinecorrection \getbuffer \stoplinecorrection
917
918% to be done: head <raw> foot, dus state var
919
920\unexpanded\def\bTABLEhead{\dosingleempty\tabl_ntb_head} \let\eTABLEhead\relax
921\unexpanded\def\bTABLEnext{\dosingleempty\tabl_ntb_next} \let\eTABLEnext\relax
922\unexpanded\def\bTABLEbody{\dosingleempty\tabl_ntb_body} \let\eTABLEbody\relax
923\unexpanded\def\bTABLEfoot{\dosingleempty\tabl_ntb_foot} \let\eTABLEfoot\relax
924
925\def\tabl_ntb_head[#1]#2\eTABLEhead{\appendtoks\tabl_ntb_section[#1]{#2}\to\t_tabl_ntb_head}
926\def\tabl_ntb_next[#1]#2\eTABLEnext{\appendtoks\tabl_ntb_section[#1]{#2}\to\t_tabl_ntb_next}
927\def\tabl_ntb_body[#1]#2\eTABLEbody{\appendtoks\tabl_ntb_section[#1]{#2}\to\t_tabl_ntb_body}
928\def\tabl_ntb_foot[#1]#2\eTABLEfoot{\appendtoks\tabl_ntb_section[#1]{#2}\to\t_tabl_ntb_foot}
929
930\def\tabl_ntb_section[#1]#2% also used in tabl-nte
931  {\unexpanded\def\tabl_ntb_setup_section{\setupcurrentnaturaltablelocal[#1]}%
932   #2%
933   \let\tabl_ntb_setup_section\relax}
934
935\def\tabl_ntb_preset_parameters% each odd|even level / can be sped up but only once per table
936  {\begincsname\??naturaltableset\m_tabl_tbl_level:\v!start\v!each\endcsname
937   \begincsname\??naturaltableset\m_tabl_tbl_level:\v!start\v!oddeven\m_tabl_tbl_level\endcsname
938   \begincsname\??naturaltableset\m_tabl_tbl_level:\v!start\m_tabl_tbl_level\endcsname}
939
940\unexpanded\def\bTABLE
941  {\dosingleempty\tabl_ntb_table}
942
943\def\tabl_ntb_table[#1]%
944  {\tabl_ntb_table_push
945   % box not here
946   \bgroup
947   \pushpostponednodedata
948   \t_tabl_ntb_head\emptytoks
949   \t_tabl_ntb_next\emptytoks
950   \t_tabl_ntb_body\emptytoks
951   \t_tabl_ntb_foot\emptytoks
952   \ifhmode\kern\zeropoint\fi  % blocks \removeunwantedspaces: check this on icare handelingsschema
953   \resetcharacteralign % new
954   \setupcurrentnaturaltablelocal[\c!align={\v!right,\v!broad,\v!high},#1]%
955   %
956   \d_tabl_ntb_leftmargindistance \naturaltablelocalparameter\c!leftmargindistance\relax
957   \d_tabl_ntb_rightmargindistance\naturaltablelocalparameter\c!rightmargindistance\relax
958   \d_tabl_ntb_columndistance     \naturaltablelocalparameter\c!columndistance\relax
959   \d_tabl_ntb_maxwidth           \naturaltablelocalparameter\c!maxwidth\relax
960   %
961   \usesetupsparameter\naturaltablelocalparameter
962   \doifelse{\naturaltablelocalparameter\c!textwidth}\v!local
963     {\hsize\availablehsize}
964     {\hsize\naturaltablelocalparameter\c!textwidth}%
965   \enableTBLbreakfalse
966   \multipleTBLheadsfalse
967   \autoTBLspreadfalse
968   \tightTBLcolspanfalse
969   \processaction
970     [\naturaltablelocalparameter\c!split]
971     [     \v!yes=>\enableTBLbreaktrue,
972        \v!repeat=>\enableTBLbreaktrue\multipleTBLheadstrue,
973          \v!auto=>\ifinsidesplitfloat\enableTBLbreaktrue\fi]
974   \processaction
975     [\naturaltablelocalparameter\c!header]
976     [\v!repeat=>\multipleTBLheadstrue]%
977   \tabl_ntb_preset_parameters
978   \processallactionsinset
979     [\naturaltablelocalparameter\c!option]
980     [\v!stretch=>\autoTBLspreadtrue,%
981        \v!tight=>\tightTBLcolspantrue]%
982   \linewidth\naturaltablelocalparameter\c!rulethickness % needs to be frozen
983   \dontcomplain
984   \c_tabl_ntb_running_col     \zerocount
985   \c_tabl_ntb_maximum_col     \zerocount
986   \c_tabl_ntb_maximum_row     \zerocount
987   \c_tabl_ntb_maximum_row_span\plusone
988   \let\currentTABLErow   \tabl_ntb_current_row
989   \let\currentTABLEcolumn\tabl_ntb_current_column
990   \let\nofTABLErows      \tabl_ntb_n_of_rows
991   \let\nofTABLEcolumns   \tabl_ntb_n_of_columns
992   \let\bTR\dobTR
993   \let\bTD\dobTD
994   \let\bTH\dobTH
995   \let\bTN\dobTN}
996
997\def\tabl_ntb_current_row   {\m_tabl_ntb_positive_row}
998\def\tabl_ntb_current_column{\m_tabl_ntb_positive_col}
999\def\tabl_ntb_n_of_rows     {\number\c_tabl_ntb_maximum_row}
1000\def\tabl_ntb_n_of_columns  {\number\c_tabl_ntb_maximum_col}
1001
1002\let\currentTABLErow   \!!zerocount
1003\let\currentTABLEcolumn\!!zerocount
1004\let\nofTABLErows      \!!zerocount
1005\let\nofTABLEcolumns   \!!zerocount
1006
1007% there is no gain in a \doifelsenextoptionalcs variant
1008
1009\unexpanded\def\dobTR{\dosingleempty\tabl_ntb_tr} % also used in tabl-nte
1010\unexpanded\def\dobTD{\dosingleempty\tabl_ntb_td} % also used in tabl-nte
1011\unexpanded\def\dobTH{\dosingleempty\tabl_ntb_th} % also used in tabl-nte
1012\unexpanded\def\dobTN{\dosingleempty\tabl_ntb_tn} % also used in tabl-nte
1013
1014% permits \expanded{\bTD ... \eTD}
1015
1016\let\bTR\relax \unexpanded\def\eTR{\ignorespaces} % handy in case we use a macro to generate rows
1017\let\bTD\relax \unexpanded\def\eTD{\ignorespaces}
1018\let\bTH\relax \unexpanded\def\eTH{\ignorespaces}
1019\let\bTN\relax \unexpanded\def\eTN{\ignorespaces}
1020
1021\unexpanded\def\eTABLE % beware, we need to get rid of spurious spaces when in hmode
1022  {% tricky and dirty order -)
1023   \setfalse\c_tabl_ntb_okay
1024   % head
1025   \doifelsesometoks\t_tabl_ntb_head % slow, better a flag
1026     {\c_tabl_ntb_head\numexpr\c_tabl_ntb_maximum_row+\plusone\relax
1027      \the\t_tabl_ntb_head
1028      \c_tabl_ntb_n_of_head_lines\c_tabl_ntb_maximum_row\relax
1029      \doifelsesometoks\t_tabl_ntb_next
1030        {\the\t_tabl_ntb_next
1031         \c_tabl_ntb_n_of_next_lines\numexpr\c_tabl_ntb_maximum_row-\c_tabl_ntb_n_of_head_lines\relax}%
1032        {\c_tabl_ntb_n_of_next_lines\zerocount}% was 1
1033      \c_tabl_ntb_n_of_hdnx_lines\c_tabl_ntb_maximum_row}
1034     {\c_tabl_ntb_head\zerocount
1035      \c_tabl_ntb_n_of_head_lines\zerocount % was 1
1036      \c_tabl_ntb_n_of_next_lines\zerocount
1037      \c_tabl_ntb_n_of_hdnx_lines\zerocount}%
1038   % body
1039   \c_tabl_ntb_body\numexpr\c_tabl_ntb_maximum_row+\plusone\relax
1040   \the\t_tabl_ntb_body
1041   % foot
1042   \doifelsesometoks\t_tabl_ntb_foot
1043     {\c_tabl_ntb_foot\numexpr\c_tabl_ntb_maximum_row+\plusone\relax
1044      \the\t_tabl_ntb_foot}%
1045     {\c_tabl_ntb_foot\zerocount}%
1046   % done
1047   \removeunwantedspaces % only if hmode
1048   % finish cells
1049   \tabl_ntb_loop_one
1050   % to be sure
1051   \tabl_ntb_loop_two
1052   % check and do
1053   \ifcase\c_tabl_ntb_maximum_col\else
1054     \startTBLprocessing
1055       \tabl_ntb_table_start
1056         \dorecurse\c_tabl_ntb_maximum_row
1057           {\tabl_ntb_row_start
1058              \c_tabl_ntb_current_row\recurselevel\relax
1059              \dorecurse\c_tabl_ntb_maximum_col
1060                {\c_tabl_ntb_current_col\recurselevel\relax
1061                 \normalexpanded{\tabl_ntb_cell{\the\c_tabl_ntb_current_row}{\the\c_tabl_ntb_current_col}}}%
1062            \tabl_ntb_row_stop}%
1063         \removeunwantedspaces % only if hmode
1064       \tabl_ntb_table_stop
1065     \stopTBLprocessing
1066     % wrong ! ! ! better to have an auto-offset-overlay
1067     % \ifnum\m_tabl_tbl_level>1
1068     %   \vskip-\strutdp
1069     % \fi
1070   \fi
1071   % tracing
1072   % \iftrue
1073   %   \blank \tttf
1074   %   \dorecurse\c_tabl_ntb_maximum_row
1075   %     {\c_tabl_ntb_current_row\recurselevel\relax
1076   %      \dorecurse\c_tabl_ntb_maximum_col
1077   %        {\c_tabl_ntb_current_col\recurselevel\relax
1078   %         [r=\the\c_tabl_ntb_current_row,c=\the\c_tabl_ntb_current_col,h=\the\dimexpr\tabl_ntb_get_ht\c_tabl_ntb_current_row\c_tabl_ntb_current_col,w=\the\dimexpr\tabl_ntb_get_wd\c_tabl_ntb_current_row\c_tabl_ntb_current_col]}%
1079   %      \par}%
1080   %   \blank
1081   % \fi
1082   \poppostponednodedata
1083   \egroup
1084   \tabl_ntb_table_pop}
1085
1086\def\tabl_ntb_loop_one
1087  {\dorecurse\c_tabl_ntb_maximum_row{\tabl_ntb_loop_one_rows}}
1088
1089\def\tabl_ntb_loop_one_rows
1090  {\c_tabl_ntb_current_row\recurselevel\relax
1091   \dorecurse\c_tabl_ntb_maximum_col\tabl_ntb_loop_one_cells}
1092
1093\def\tabl_ntb_loop_one_cells
1094  {\c_tabl_ntb_current_col\recurselevel\relax
1095   \ifcsname\tabl_ntb_tag_pattern\c_tabl_ntb_current_row\c_tabl_ntb_current_col\endcsname \else
1096     \tabl_ntb_loop_one_cells_indeed
1097   \fi}
1098
1099\def\tabl_ntb_loop_one_cells_indeed
1100  {\c_tabl_ntb_current_col_two\c_tabl_ntb_current_col
1101   \c_tabl_ntb_current_row_two\c_tabl_ntb_current_row
1102   \c_tabl_ntb_current_row_one\c_tabl_ntb_current_row
1103   \doloop
1104     {\c_tabl_ntb_current_col_one\c_tabl_ntb_current_col
1105      \doloop
1106        {\ifcsname\tabl_ntb_tag_pattern\c_tabl_ntb_current_row_one\c_tabl_ntb_current_col_one\endcsname
1107           \exitloop
1108         \else
1109           \advance\c_tabl_ntb_current_col_one\plusone
1110           \ifnum\c_tabl_ntb_current_col_one>\c_tabl_ntb_maximum_col\relax
1111             \exitloop
1112           \fi
1113         \fi}%
1114      \ifcsname\tabl_ntb_tag_pattern\c_tabl_ntb_current_row_one\c_tabl_ntb_current_col_one\endcsname
1115        \exitloop
1116      \else
1117        \c_tabl_ntb_current_row_two\c_tabl_ntb_current_row_one
1118        \c_tabl_ntb_current_col_two\c_tabl_ntb_current_col_one
1119        \advance\c_tabl_ntb_current_row_one\plusone
1120        \ifnum\c_tabl_ntb_current_row_one>\c_tabl_ntb_maximum_row
1121          \exitloop
1122        \fi
1123      \fi}%
1124   \ifnum\c_tabl_ntb_current_row_two>\c_tabl_ntb_maximum_row\c_tabl_ntb_current_row_two\c_tabl_ntb_maximum_row\fi
1125   \ifnum\c_tabl_ntb_current_col_two>\c_tabl_ntb_maximum_col\c_tabl_ntb_current_col_two\c_tabl_ntb_maximum_col\fi
1126   \c_tabl_ntb_current_row_two\numexpr\c_tabl_ntb_current_row_two-\c_tabl_ntb_current_row+\plusone\relax
1127   \c_tabl_ntb_current_col_two\numexpr\c_tabl_ntb_current_col_two-\c_tabl_ntb_current_col+\plusone\relax
1128   \c_tabl_ntb_current_row_one\c_tabl_ntb_current_row
1129   \dorecurse\c_tabl_ntb_current_row_two
1130     {\c_tabl_ntb_current_col_one\c_tabl_ntb_current_col
1131      \tabl_ntb_set_col\c_tabl_ntb_current_row_one\c_tabl_ntb_current_col_one{\the\c_tabl_ntb_current_col_two}%
1132      \dorecurse\c_tabl_ntb_current_col_two
1133        {\tabl_ntb_let_tag\c_tabl_ntb_current_row_one\c_tabl_ntb_current_col_one\c_tabl_ntb_none
1134         \advance\c_tabl_ntb_current_col_one\plusone}%
1135      \advance\c_tabl_ntb_current_row_one\plusone}%
1136   \tabl_ntb_let_tag\c_tabl_ntb_current_row\c_tabl_ntb_current_col\c_tabl_ntb_cell
1137   \tabl_ntb_set_col\c_tabl_ntb_current_row\c_tabl_ntb_current_col{\the\c_tabl_ntb_current_col_two}%
1138   \tabl_ntb_set_row\c_tabl_ntb_current_row\c_tabl_ntb_current_col{\the\c_tabl_ntb_current_row_two}%
1139   \ifautoTBLemptycell
1140      \normalexpanded
1141         {\tabl_ntb_set_txt_process\c_tabl_ntb_current_row\c_tabl_ntb_current_col{\the\c_tabl_ntb_current_row}{\the\c_tabl_ntb_current_col}}%
1142         {\c!option=\v!tight}{\strut\kern\scaledpoint}% the kern forces the tight
1143   \fi}
1144
1145\def\tabl_ntb_loop_two
1146  {\dorecurse\c_tabl_ntb_maximum_row\tabl_ntb_loop_two_rows}
1147
1148\def\tabl_ntb_loop_two_rows
1149  {\c_tabl_ntb_current_row\recurselevel\relax
1150   \dorecurse\c_tabl_ntb_maximum_col\tabl_ntb_loop_two_cells}
1151
1152\def\tabl_ntb_loop_two_cells
1153  {\c_tabl_ntb_current_col\recurselevel\relax
1154   \ifcsname\tabl_ntb_row_pattern\c_tabl_ntb_current_row\c_tabl_ntb_current_col\endcsname
1155     \scratchcounter\numexpr\c_tabl_ntb_maximum_row-\c_tabl_ntb_current_row+\plusone\relax
1156     \ifnum\tabl_ntb_get_row\c_tabl_ntb_current_row\c_tabl_ntb_current_col>\scratchcounter
1157       \tabl_ntb_set_row\c_tabl_ntb_current_row\c_tabl_ntb_current_col{\the\scratchcounter}%
1158     \fi
1159   \fi
1160   \tabl_ntb_let_ht\c_tabl_ntb_current_row\c_tabl_ntb_current_col\zeropoint
1161   %tabl_ntb_let_wd\c_tabl_ntb_current_row\c_tabl_ntb_current_col\zeropoint
1162   \ifcsname\tabl_ntb_col_pattern\c_tabl_ntb_current_row\c_tabl_ntb_current_col\endcsname \else
1163     \tabl_ntb_let_col\c_tabl_ntb_current_row\c_tabl_ntb_current_col\zerocount
1164   \fi
1165   \ifcsname\tabl_ntb_tag_pattern\c_tabl_ntb_current_row\c_tabl_ntb_current_col\endcsname \else
1166     \tabl_ntb_let_tag\c_tabl_ntb_current_row\c_tabl_ntb_current_col\c_tabl_ntb_none
1167   \fi}
1168
1169\let\startTBLprocessing\relax % public
1170\let\stopTBLprocessing \relax % public
1171
1172\newcount\c_tabl_prelocated_rows % \prelocateTBLrows{1000} may speed up large tables
1173
1174% \def\tabl_ntb_row_start{\t_tabl_ntb_row\emptytoks}
1175% \def\tabl_ntb_row_stop {\normalexpanded{\t_tabl_ntb{\the\t_tabl_ntb\noexpand\tabl_ntb_row_align_start\the\t_tabl_ntb_row\tabl_ntb_row_align_stop}}}
1176
1177\def\tabl_ntb_row_start
1178  {\t_tabl_ntb_row\emptytoks}
1179
1180\def\tabl_ntb_row_stop
1181  {\ifenableTBLbreak
1182     \tabl_ntb_row_stop_split
1183   \else
1184     \tabl_ntb_row_stop_boxed
1185   \fi}
1186
1187\def\tabl_ntb_row_stop_boxed
1188  {% \noindent % no, else double leftskip in narrower
1189   \etoksapp\t_tabl_ntb
1190     {% no need for init
1191      \tabl_ntb_row_align_start
1192      \the\t_tabl_ntb_row
1193      \tabl_ntb_row_align_stop}}
1194
1195\def\tabl_ntb_row_stop_split
1196  {\ifcsname\??naturaltableset\m_tabl_tbl_level:\c!y++\the\c_tabl_ntb_current_row\endcsname
1197     \tabl_ntb_row_stop_split_yes
1198   \else
1199     \tabl_ntb_row_stop_split_nop
1200   \fi}
1201
1202\def\tabl_ntb_row_stop_split_nop
1203  {\etoksapp\t_tabl_ntb
1204     {\tabl_ntb_row_align_reset
1205      \tabl_ntb_row_align_start
1206      \the\t_tabl_ntb_row
1207      \tabl_ntb_row_align_stop}}
1208
1209\def\tabl_ntb_row_stop_split_yes
1210  {\begingroup
1211   \csname\??naturaltableset\m_tabl_tbl_level:\c!y++\the\c_tabl_ntb_current_row\endcsname
1212   \xdef\m_tabl_ntb_before_split{\naturaltablelocalparameter\c!before}% to be checked
1213   \xdef\m_tabl_ntb_after_split {\naturaltablelocalparameter\c!after}% to be checked
1214   \xdef\m_tabl_ntb_same_page   {\naturaltablelocalparameter\c!samepage}%
1215   \endgroup
1216   \etoksapp\t_tabl_ntb
1217     {\tabl_ntb_row_align_set{\m_tabl_ntb_before_split}{\m_tabl_ntb_after_split}{\m_tabl_ntb_same_page}%
1218      \tabl_ntb_row_align_start
1219      \the\t_tabl_ntb_row
1220      \tabl_ntb_row_align_stop}}
1221
1222\unexpanded\def\tabl_ntb_row_align_set#1#2#3%
1223  {\xdef\m_tabl_ntb_before_split{#1}%
1224   \xdef\m_tabl_ntb_after_split {#2}%
1225   \xdef\m_tabl_ntb_same_page   {#3}}
1226
1227\unexpanded\def\tabl_ntb_row_align_reset
1228  {\glet\m_tabl_ntb_before_split\empty
1229   \glet\m_tabl_ntb_after_split \empty
1230   \glet\m_tabl_ntb_same_page   \empty}
1231
1232\def\tabl_ntb_prelocate_error
1233  {\writestatus\m!TABLE{fatal error: use \string\prelocateTBLrows\space to increase table memory (now: \the\c_tabl_prelocated_rows)}}
1234
1235% \prelocateTBLrows{1000} % may speed up large tables
1236
1237\def\prelocateTBLrows#1% we start at zero so we have one to much, better play safe anyway
1238  {\dostepwiserecurse\c_tabl_prelocated_rows{#1}\plusone
1239     {\expandafter\newtoks\csname\??naturaltabletok\recurselevel\endcsname}%
1240   \def\tabl_ntb_row_start
1241     {\ifnum\c_tabl_ntb_row<\c_tabl_prelocated_rows\relax
1242        \tabl_ntb_prelocate_okay
1243      \else
1244        \tabl_ntb_prelocate_error
1245      \fi}%
1246   \def\tabl_ntb_row_stop
1247     {\etoksapp\t_tabl_ntb
1248        {\tabl_ntb_row_align_start
1249         \the\csname\??naturaltabletok\the\c_tabl_ntb_row\endcsname
1250         \tabl_ntb_row_align_stop}}%
1251   \global\c_tabl_prelocated_rows#1\relax}
1252
1253\def\tabl_ntb_prelocate_okay
1254  {\expandafter\let\expandafter\t_tabl_ntb_row\csname\??naturaltabletok\the\c_tabl_ntb_row\endcsname\t_tabl_ntb_row\emptytoks}
1255
1256%D We use aligments to handle the empty (skipped) columns, so that we don't have to
1257%D (re|)|calculate these.
1258
1259\let\m_tabl_ntb_saved_row\!!zerocount
1260\let\m_tabl_ntb_saved_col\!!zerocount
1261
1262\def\tabl_ntb_start_tagged
1263  {\scratchcounter\numexpr\c_tabl_ntb_row+\plusone\relax
1264   \ifnum\scratchcounter=\c_tabl_ntb_head
1265     \ifconditional\c_tabl_ntb_okay
1266       \dostoptagged
1267     \else
1268       \settrue\c_tabl_ntb_okay
1269     \fi
1270     \dostarttagged\t!tablehead\empty
1271   \else\ifnum\scratchcounter=\c_tabl_ntb_body
1272     \ifconditional\c_tabl_ntb_okay
1273       \dostoptagged
1274     \else
1275       \settrue\c_tabl_ntb_okay
1276     \fi
1277     \dostarttagged\t!tablebody\empty
1278   \else\ifnum\scratchcounter=\c_tabl_ntb_foot
1279     \ifconditional\c_tabl_ntb_okay
1280       \dostoptagged
1281     \else
1282       \settrue\c_tabl_ntb_okay
1283     \fi
1284     \dostarttagged\t!tablefoot\empty
1285   \fi\fi\fi
1286   \dostarttagged\t!tablerow\empty}
1287
1288\def\tabl_ntb_stop_tagged
1289  {\dostoptagged
1290   \ifconditional\c_tabl_ntb_okay
1291     \scratchcounter\numexpr\c_tabl_ntb_row+\plustwo\relax
1292     \ifnum\scratchcounter=\c_tabl_ntb_body
1293       \dostoptagged
1294       \setfalse\c_tabl_ntb_okay
1295     \else\ifnum\scratchcounter=\c_tabl_ntb_foot
1296       \dostoptagged
1297       \setfalse\c_tabl_ntb_okay
1298     \else\ifnum\scratchcounter>\c_tabl_ntb_maximum_row
1299       \dostoptagged
1300       \setfalse\c_tabl_ntb_okay
1301     \fi\fi\fi
1302   \fi}
1303
1304\unexpanded\def\tabl_ntb_row_align_start
1305  {\global\advance\c_tabl_ntb_row\plusone
1306   \global\c_tabl_ntb_col\plusone
1307   \global\c_tabl_ntb_spn\zerocount
1308   \tabl_ntb_row_align_start_inject
1309   \ifconditional\c_strc_tags_enabled
1310     \tabl_ntb_start_tagged
1311   \fi
1312   % we are in sync but just to be sure:
1313   \synchronizedisplaydirection
1314   \synchronizeinlinedirection
1315   \hbox
1316     \usedirectionparameterreverse\naturaltablelocalparameter
1317     \bgroup
1318     \kern\dimexpr\d_tabl_ntb_leftmargindistance\relax}
1319
1320\unexpanded\def\tabl_ntb_row_align_stop
1321  {\kern\dimexpr\d_tabl_ntb_rightmargindistance-\d_tabl_ntb_columndistance\relax
1322   \egroup
1323   \ifconditional\c_strc_tags_enabled
1324     \tabl_ntb_stop_tagged
1325   \fi
1326   \tabl_ntb_row_align_stop_inject}
1327
1328\unexpanded\def\tabl_ntb_before_page
1329  {\ifx\m_tabl_ntb_same_page\v!before
1330   % \blank[\v!samepage,\v!strong]%
1331     \unpenalty
1332     \nobreak
1333   \else\ifx\m_tabl_ntb_same_page\v!both
1334   % \blank[\v!samepage,\v!strong]%
1335     \unpenalty
1336     \nobreak
1337   \fi\fi}
1338
1339\unexpanded\def\tabl_ntb_after_page
1340  {\ifnum\c_tabl_ntb_row>\c_tabl_ntb_n_of_head_lines
1341     \ifnum\tabl_ntb_get_nob\c_tabl_ntb_row=\zerocount
1342       \unpenalty
1343       \ifx\m_tabl_ntb_same_page\v!after
1344       % \blank[\v!samepage,\v!strong]%
1345         \nobreak
1346       \else\ifx\m_tabl_ntb_same_page\v!both
1347       % \blank[\v!samepage,\v!strong]%
1348         \nobreak
1349       \else
1350       % \blank[\v!preference,\v!weak]%
1351         \allowbreak
1352       \fi\fi
1353     \fi
1354   \else
1355   % \blank[\v!preference,\v!weak]%
1356     \allowbreak % else no proper head split off
1357   \fi}
1358
1359\unexpanded\def\tabl_ntb_inbetween
1360  {\scratchcounter\numexpr\c_tabl_ntb_row+\plusone\relax
1361   \ifnum\scratchcounter>\c_tabl_ntb_n_of_hdnx_lines\relax
1362     \ifnum\scratchcounter<\c_tabl_ntb_maximum_row\relax
1363       \edef\p_spaceinbetween{\naturaltablelocalparameter\c!spaceinbetween}%
1364       \ifx\p_spaceinbetween\empty\else
1365         \blank[\p_spaceinbetween]%
1366       \fi
1367     \fi
1368   \fi}
1369
1370\unexpanded\def\tabl_ntb_row_align_start_inject
1371  {\bgroup % protect local vars
1372     \m_tabl_ntb_before_split
1373   \egroup
1374   \ifenableTBLbreak
1375     \tabl_ntb_before_page
1376   \fi}
1377
1378\unexpanded\def\tabl_ntb_row_align_stop_inject
1379  {\par
1380   \nointerlineskip
1381   \ifenableTBLbreak
1382     \tabl_ntb_after_page
1383   \fi
1384   \bgroup % protect local vars
1385     \m_tabl_ntb_after_split
1386   \egroup
1387   \bgroup % protect local vars
1388     \tabl_ntb_inbetween
1389   \egroup}
1390
1391\def\tabl_ntb_flush_content
1392  {\the\everyTABLEpass
1393   \global\c_tabl_ntb_spn\zerocount
1394   \global\c_tabl_ntb_col\zerocount
1395   \global\c_tabl_ntb_row\zerocount
1396   \global\advance\c_tabl_ntb_row\minusone
1397   \dostarttaggedchained\t!table\empty\??naturaltable
1398  %\registerparoptions % (*) triggers max hsize
1399   \the\t_tabl_ntb
1400   \dostoptagged}
1401
1402\unexpanded\def\tabl_ntb_span#1%
1403  {\hskip\tabl_ntb_get_dis\c_tabl_ntb_col
1404   \dorecurse{#1}
1405     {\hskip\tabl_ntb_get_wid\c_tabl_ntb_col\relax
1406      \global\advance\c_tabl_ntb_col\plusone}}
1407
1408\unexpanded\def\tabl_ntb_skip#1%
1409  {\global\advance\c_tabl_ntb_col#1\relax}
1410
1411\unexpanded\def\tabl_ntb_plus
1412  {\global\advance\c_tabl_ntb_col\plusone
1413   \kern\d_tabl_ntb_columndistance}
1414
1415\setvalue{\??naturaltablecell\the\c_tabl_ntb_none}#1#2%
1416  {\scratchcounter\tabl_ntb_get_col{#1}{#2}\relax
1417   \ifnum\scratchcounter>\zerocount
1418     \etoksapp\t_tabl_ntb_row
1419       {\tabl_ntb_span{\the\scratchcounter}}%
1420   \fi}
1421
1422\setvalue{\??naturaltablecell\the\c_tabl_ntb_cell}#1#2%
1423  {\toksapp\t_tabl_ntb_row{\tabl_ntb_pass #1 #2 }% space delimited -> less tokens
1424   \scratchcounter\tabl_ntb_get_col{#1}{#2}\relax
1425   \ifnum\scratchcounter>\zerocount
1426     \etoksapp\t_tabl_ntb_row
1427        {\ifnum\scratchcounter=\plusone
1428           \tabl_ntb_plus
1429         \else
1430           \tabl_ntb_skip{\the\scratchcounter}%
1431         \fi}%
1432   \fi}
1433
1434\unexpanded\def\tabl_ntb_cell#1#2%
1435  {\csname\??naturaltablecell\the\tabl_ntb_get_tag{#1}{#2}\endcsname{#1}{#2}}
1436
1437\unexpanded\def\tabl_ntb_table_start
1438  {\global\c_tabl_ntb_spn\zerocount
1439   \global\c_tabl_ntb_row\zerocount
1440   \global\c_tabl_ntb_col\zerocount
1441   \c_tabl_tbl_pass\zerocount
1442   \t_tabl_ntb\emptytoks}
1443
1444\def\tabl_ntb_pass_one#1 #2 %
1445  {\tabl_ntb_get_txt{#1}{#2}}%
1446
1447\def\tabl_ntb_pass_two#1 #2 % meer in cellD
1448  {\d_tabl_ntb_width\zeropoint
1449   \scratchcounter\c_tabl_ntb_col
1450   \!!counta\tabl_ntb_get_col{#1}{#2}\relax
1451   \ifcase\!!counta\or
1452     \advance\d_tabl_ntb_width\dimexpr
1453       \tabl_ntb_get_wid\scratchcounter
1454     \relax
1455     \advance\scratchcounter\plusone
1456   \else
1457     \dorecurse\!!counta
1458       {\advance\d_tabl_ntb_width\dimexpr
1459          \tabl_ntb_get_wid\scratchcounter
1460          \ifnum\recurselevel<\!!counta
1461            +\d_tabl_ntb_columndistance
1462            +\tabl_ntb_get_dis\scratchcounter
1463          \fi
1464        \relax
1465        \advance\scratchcounter\plusone}%
1466   \fi
1467   \setbox\scratchbox\hbox{\tabl_ntb_get_txt{#1}{#2}}%
1468   \tabl_ntb_set_ht{#1}{#2}{\the\ht\scratchbox}%
1469   %tabl_ntb_set_wd{#1}{#2}{\the\wd\scratchbox}%
1470   \ifdim\ht\scratchbox>\tabl_ntb_get_hei{#1}\relax
1471     \tabl_ntb_set_hei{#1}{\the\ht\scratchbox}%
1472   \fi}%
1473
1474\def\tabl_ntb_pass_three#1 #2 %
1475  {% height
1476   \dostarttagged\t!tablecell\empty
1477   \!!counta \tabl_ntb_get_col{#1}{#2}\relax
1478   \!!countb \tabl_ntb_get_row{#1}{#2}\relax
1479   \!!heighta\tabl_ntb_get_ht {#1}{#2}\relax
1480   \tablecellcolumns\!!counta % used later so don't adapt these
1481   \tablecellrows   \!!countb % used later so don't adapt these
1482   \d_tabl_ntb_height\zeropoint
1483   \ifnum\!!counta=\c_tabl_ntb_maximum_col\relax
1484     % case: nc=maxcolumns
1485   \else
1486     \scratchcounter#1\relax
1487     \dorecurse\!!countb
1488       {\advance\d_tabl_ntb_height\tabl_ntb_get_hei\scratchcounter
1489        \advance\scratchcounter\plusone}%
1490     \ifdim\d_tabl_ntb_height<\!!heighta\relax
1491       \d_tabl_ntb_height\!!heighta
1492     \fi
1493   \fi
1494   % width
1495   \d_tabl_ntb_width\zeropoint
1496   \scratchcounter\c_tabl_ntb_col
1497   \ifcase\!!counta\or
1498     \advance\d_tabl_ntb_width\dimexpr
1499       \tabl_ntb_get_wid\scratchcounter
1500     \relax
1501     \advance\scratchcounter\plusone
1502   \else
1503     \dorecurse\!!counta
1504       {\advance\d_tabl_ntb_width\dimexpr
1505          \tabl_ntb_get_wid\scratchcounter
1506          \ifnum\recurselevel<\!!counta
1507            +\d_tabl_ntb_columndistance
1508            +\tabl_ntb_get_dis\scratchcounter
1509          \fi
1510        \relax
1511        \advance\scratchcounter\plusone}%
1512   \fi
1513   % cell
1514   \setbox\scratchbox\hbox attr \taggedattribute \c_attr_tagged \bgroup
1515      \dotagTABLEsignal % maybe we need to add some packaging in this case
1516      \tabl_ntb_get_txt{#1}{#2}%
1517   \egroup
1518   \ifnum\!!counta=\c_tabl_ntb_maximum_col\relax
1519     % case: nc=maxcolumns
1520   \else
1521     \scratchdimen\tabl_ntb_get_hei{#1}%
1522     \setbox\scratchbox\hpack
1523       {\lower\ht\scratchbox\hpack{\raise\scratchdimen\box\scratchbox}}%
1524     \ht\scratchbox\scratchdimen
1525   \fi
1526   \dp\scratchbox\zeropoint
1527   \edef\!!stringa{\tabl_ntb_get_ref{#1}{#2}}%
1528   \ifx\!!stringa\empty
1529     \box\scratchbox
1530   \else
1531     \normalexpanded{\noexpand\directgotobox{\box\scratchbox}[\!!stringa]}% to be checked
1532   \fi
1533   \dostoptagged} % right spot
1534
1535% \def\tabl_ntb_cell_finalize
1536%   {\doifnotinset\localwidth{\v!fit,\v!broad}% user set
1537%      {\scratchdimen\tabl_ntb_get_aut\c_tabl_ntb_col\relax
1538%       \ifdim\localwidth>\scratchdimen
1539%         \tabl_ntb_set_aut\c_tabl_ntb_col{\the\dimexpr\localwidth}%
1540%       \fi}}
1541
1542\def\tabl_ntb_cell_finalize
1543  {\ifx\localwidth\v!fit
1544      % nothing
1545   \else\ifx\localwidth\v!broad
1546      % nothing
1547   \else\ifx\localwidth\empty
1548      % nothing (safeguard)
1549   \else
1550     \tabl_ntb_cell_finalize_indeed
1551   \fi\fi\fi}
1552
1553\def\tabl_ntb_cell_finalize_indeed
1554  {\scratchdimen\tabl_ntb_get_aut\c_tabl_ntb_col\relax
1555   \ifdim\localwidth>\scratchdimen
1556     \tabl_ntb_set_aut\c_tabl_ntb_col{\the\dimexpr\localwidth}%
1557   \fi}
1558
1559\let\tabl_ntb_preroll\relax
1560
1561\def\tabl_ntb_table_get_max_width
1562  {\scratchdimen\wd\scratchbox\relax}
1563
1564% enable dper 2018-02-22
1565
1566\def\tabl_ntb_table_get_max_width_step
1567  {\advance\scratchdimen\tabl_ntb_get_wid\fastloopindex
1568   \advance\scratchdimen\tabl_ntb_get_dis\fastloopindex}
1569
1570\def\tabl_ntb_table_get_max_width
1571  {\scratchdimen\zeropoint
1572   \dofastloopcs\c_tabl_ntb_maximum_col\tabl_ntb_table_get_max_width_step
1573   \ifdim\scratchdimen<\wd\scratchbox\relax
1574     \scratchdimen\wd\scratchbox\relax
1575   \fi}
1576
1577\def\tabl_ntb_table_stop
1578  {\forgetall % new, here see narrower-004.tex
1579  %\setbox\scratchbox\hbox
1580  %  {\letnaturaltablelocalparameter\c!frame\v!off
1581  %   \letnaturaltablelocalparameter\c!background\empty
1582  %   \letnaturaltablelocalparameter\c!align\v!no
1583  %   \inheritednaturaltablelocalframed{\strut}}%
1584  %\edef\minimalcellheight{\the\ht\scratchbox}% not used
1585   \dorecurse\c_tabl_ntb_maximum_col
1586     {\tabl_ntb_let_aut\recurselevel\zeropoint
1587      % new
1588      \c_tabl_ntb_current_col_one\recurselevel\relax
1589      \dorecurse\c_tabl_ntb_maximum_row
1590        {%tabl_ntb_let_wd\recurselevel\c_tabl_ntb_current_col_one\zeropoint
1591         \tabl_ntb_let_ht\recurselevel\c_tabl_ntb_current_col_one\zeropoint}%
1592      % till here
1593      \tabl_ntb_let_tal\recurselevel\zerocount
1594      \tabl_ntb_let_wid\recurselevel\zeropoint
1595      \tabl_ntb_let_dis\recurselevel\zeropoint}%
1596   \dorecurse\c_tabl_ntb_maximum_row
1597     {\tabl_ntb_let_hei\recurselevel\maxdimen}%
1598   \tabl_ntb_let_gal\zerocount
1599   \tabl_ntb_preroll\relax
1600   \c_tabl_tbl_pass\plusone
1601   \let\tabl_ntb_pass\tabl_ntb_pass_one
1602   \let\tabl_ntb_cell_process\tabl_ntb_cell_process_a
1603   \setbox\scratchbox\vbox{\settrialtypesetting \tabl_ntb_flush_content}%
1604   \ifcase\tabl_ntb_get_gal\or
1605    % \c_tabl_tbl_pass\plusone
1606    % \let\tabl_ntb_pass\tabl_ntb_pass_one
1607      \let\tabl_ntb_cell_process\tabl_ntb_cell_process_a_extra
1608      \setbox\scratchbox\vbox{\settrialtypesetting \tabl_ntb_flush_content}%
1609   \fi
1610   \tabl_ntb_let_dis\c_tabl_ntb_maximum_col\zeropoint
1611   %
1612   \tabl_ntb_table_get_max_width % \scratchdimen\scratchbox
1613   %
1614   \ifautoTBLspread
1615     % experimental, stretch non fixed cells to \hsize
1616     \tabl_ntb_check_widths_one   % trial run
1617     \tabl_ntb_check_widths_two   % real run
1618     \tabl_ntb_stretch_widths
1619     \let\tabl_ntb_cell_process\tabl_ntb_cell_process_b
1620     \setbox\scratchbox\vbox{\settrialtypesetting \tabl_ntb_flush_content}%
1621 % \else\ifdim\wd\scratchbox>\hsize
1622   \else\ifdim\scratchdimen>\hsize
1623     \ifautoTBLhsize
1624       \tabl_ntb_check_widths_one % trial run
1625       \tabl_ntb_check_widths_two % real run
1626       \let\tabl_ntb_cell_process\tabl_ntb_cell_process_b
1627       \setbox\scratchbox\vbox{\settrialtypesetting \tabl_ntb_flush_content}%
1628     \fi
1629   \else\ifautoTBLrowspan\ifnum\c_tabl_ntb_maximum_row_span>\plusone % max ?
1630     % added jan 2002 because nx=* did no longer work
1631     \ifnum\c_tabl_ntb_encountered_max<\c_tabl_ntb_maximum_col
1632       % added jun 2014 because someone had less columns than nx .. sigh / see *nx*
1633       \writestatus\m!TABLE{missing\space\number\numexpr\c_tabl_ntb_maximum_col-\c_tabl_ntb_encountered_max\relax\space column(s), guessing widths}%
1634     \fi
1635     \edef\savedhsize{\the\hsize}%
1636   % \hsize\wd\scratchbox\relax % new per 17/04/2006
1637     \hsize\scratchdimen\relax % new per 17/04/2006
1638     \tabl_ntb_check_widths_one % trial run
1639     \tabl_ntb_check_widths_two % real run
1640     \hsize\savedhsize
1641     \let\tabl_ntb_cell_process\tabl_ntb_cell_process_c
1642     \setbox\scratchbox\vbox{\settrialtypesetting \tabl_ntb_flush_content}%
1643   \fi\fi\fi\fi
1644   \let\tabl_ntb_cell_process\tabl_ntb_cell_process_d
1645   \c_tabl_tbl_pass\plustwo
1646   \let\tabl_ntb_pass\tabl_ntb_pass_two
1647   \setbox\scratchbox\vbox{\settrialtypesetting \tabl_ntb_flush_content}%
1648   \tabl_ntb_check_heights_one
1649   \tabl_ntb_check_heights_two
1650   \let\tabl_ntb_cell_process\tabl_ntb_cell_process_e
1651   \c_tabl_tbl_pass\plusthree
1652   \let\tabl_ntb_pass\tabl_ntb_pass_three
1653   \ifnum\m_tabl_tbl_level>\plusone
1654     \tabl_tbl_split_nop
1655   \else\ifenableTBLbreak
1656     \tabl_tbl_split_yes
1657   \else
1658     \tabl_tbl_split_nop
1659   \fi\fi}
1660
1661\def\tabl_ntb_stretch_widths % more variants, e.g. a max to \dimend
1662  {\ifcase\c_tabl_ntb_maximum_col\else % else division by zero
1663     \!!dimend\zeropoint
1664     \!!dimene\dimexpr
1665        \hsize
1666       -\d_tabl_ntb_leftmargindistance
1667       -\d_tabl_ntb_rightmargindistance
1668       +\d_tabl_ntb_columndistance
1669     \relax
1670     \dorecurse\c_tabl_ntb_maximum_col
1671       {\advance\!!dimend\dimexpr
1672          \tabl_ntb_get_wid\recurselevel
1673        \relax
1674        \advance\!!dimene\dimexpr
1675          -\tabl_ntb_get_dis\recurselevel
1676          -\d_tabl_ntb_columndistance
1677        \relax}%
1678     \relax
1679     % distribute width (stretch)
1680     \ifdim\!!dimend<\!!dimene
1681       \advance\!!dimend-\!!dimene
1682       \divide\!!dimend\c_tabl_ntb_maximum_col
1683       \dorecurse\c_tabl_ntb_maximum_col
1684         {\tabl_ntb_set_wid\recurselevel{\the\dimexpr\tabl_ntb_get_wid\recurselevel-\!!dimend\relax}}%
1685     \fi
1686   \fi}
1687
1688\def\tabl_tbl_split_nop
1689  {\setbox\b_tabl_ntb_final\vbox{\tabl_ntb_flush_content}%
1690   \postprocessTABLEbox\b_tabl_ntb_final
1691   \beforeTABLEbox
1692 % packaging prevents max hsized box
1693 % \hbox{\registerparoptions\box\b_tabl_ntb_final}% (*) better here
1694 % better :
1695   \ifinsidefloat
1696     % no \dontleavehmode else too wide, otherwise we get a \hsized box
1697   \else
1698     \registerparoptions % (*) better here (also does a \dontleavehmode)
1699     \ifhmode\else\dontleavehmode\fi
1700   \fi
1701   \box\b_tabl_ntb_final
1702   \afterTABLEbox}
1703
1704\def\tabl_tbl_split_yes
1705  {\ifinsidesplitfloat
1706     \donetrue
1707   \else\ifinsidefloat
1708     \donefalse
1709   \else
1710     \donetrue
1711   \fi\fi
1712   \ifdone
1713     \expandafter\tabl_ntb_split_box
1714   \else
1715     \expandafter\tabl_tbl_split_nop
1716   \fi}
1717
1718\newbox\TABLEsplitbox % public, don't change
1719
1720\let\extratblsplitheight\zeropoint % additional space taken by before/afterTABLEsplitbox
1721
1722\def\tabl_ntb_split_box
1723  {\resettsplit
1724   \def\tsplitminimumfreelines{2}%
1725   \def\tsplitminimumfreespace{\dimexpr\extratblsplitheight+\naturaltablelocalparameter\c!splitoffset\relax}%
1726   \def\tsplitbeforeresult    {\beforeTABLEsplitbox}%
1727   \def\tsplitafterresult     {\afterTABLEsplitbox}%
1728   \def\tsplitafter           {\m_tabl_ntb_after_split}%
1729   \def\tsplitbefore          {\m_tabl_ntb_before_split}% supported ?
1730   \setbox\tsplitcontent\vbox{\tabl_ntb_flush_content}%
1731   \ifmultipleTBLheads
1732     \dorecurse\c_tabl_ntb_n_of_head_lines
1733       {\setbox\scratchbox\vsplit\tsplitcontent to \lineheight
1734        \setbox\tsplithead\vbox{\unvcopy\tsplithead\unvcopy\scratchbox}}% \vpack ?
1735     \dorecurse\c_tabl_ntb_n_of_next_lines
1736       {\setbox\scratchbox\vsplit\tsplitcontent to \lineheight
1737        \setbox\tsplitnext\vbox{\unvcopy\tsplitnext\unvcopy\scratchbox}}% \vpack ?
1738   \fi
1739   \edef\p_spaceinbetween{\naturaltablelocalparameter\c!spaceinbetween}%
1740   \ifx\p_spaceinbetween\empty\else
1741     \blank[\p_spaceinbetween]%
1742   \fi
1743   \def\postprocesstsplit{\postprocessTABLEsplitbox{\box\tsplitresult}}%
1744   \handletsplit}
1745
1746% ! ! ! ! TODO: naast \postprocessTABLEsplitbox ook evt \postprocessTABLEbox voor niet split
1747
1748\let\postprocessTABLEsplitbox\gobbleoneargument
1749\let\postprocessTABLEbox     \gobbleoneargument
1750
1751\let\beforeTABLEsplitbox\relax
1752\let\afterTABLEsplitbox \relax
1753\let\beforeTABLEbox     \relax
1754\let\afterTABLEbox      \relax
1755
1756\def\tabl_ntb_check_widths_one{\tabl_ntb_check_widths_indeed\zerocount} % 0 = trial run
1757\def\tabl_ntb_check_widths_two{\tabl_ntb_check_widths_indeed\plusone  } % 1 = real run
1758
1759\def\tabl_ntb_check_widths_indeed#1%
1760  {\ifconditional\c_tabl_ntb_trace_widths\tabl_ntb_show_widths B#1\fi
1761   \!!counta\zerocount
1762   \!!dimena\dimexpr
1763     \hsize
1764    -\d_tabl_ntb_leftmargindistance
1765    -\d_tabl_ntb_rightmargindistance
1766    -\d_tabl_ntb_columndistance
1767   \relax
1768   \dorecurse\c_tabl_ntb_maximum_col
1769     {\scratchdimen\tabl_ntb_get_aut\recurselevel\relax
1770      \advance\!!dimena\dimexpr
1771        -\tabl_ntb_get_dis\recurselevel
1772        -\d_tabl_ntb_columndistance
1773      \relax
1774      \ifdim\scratchdimen>\zeropoint\relax
1775        \advance\!!dimena -\scratchdimen
1776      \else
1777        \scratchdimen\tabl_ntb_get_wid\recurselevel\relax
1778        \ifdim\scratchdimen>\d_tabl_ntb_maxwidth\relax
1779          \ifcase#1\else\tabl_ntb_let_wid\recurselevel\zeropoint\fi
1780          \advance\!!counta \plusone
1781        \else
1782          \ifdim\scratchdimen>\zeropoint\relax
1783            \advance\!!dimena -\scratchdimen
1784          \else
1785            % eigenlijk moet dit alleen als de kolom wordt overspannen door een
1786            % vorige, maw extra dubbele loop en status var
1787            \ifnum\c_tabl_ntb_encountered_max=\c_tabl_ntb_maximum_col % *nx* bah
1788              \advance\!!counta \plusone % setting maxwidth to a large value also works
1789            \fi
1790          \fi
1791        \fi
1792      \fi}%
1793   \ifconditional\c_tabl_ntb_trace_widths\tabl_ntb_show_widths M#1\fi
1794   \ifcase\!!counta \else \divide\!!dimena \!!counta \fi
1795   \dorecurse\c_tabl_ntb_maximum_col
1796     {\scratchdimen\tabl_ntb_get_wid\recurselevel\relax
1797      \ifcase#1\relax
1798        \ifdim\scratchdimen<\!!dimena  % take natural width
1799          \tabl_ntb_set_aut\recurselevel{\the\scratchdimen}%
1800        \fi
1801      \else
1802        \ifzeropt\scratchdimen % auto set width
1803          \tabl_ntb_set_wid\recurselevel{\the\!!dimena}%
1804        \fi
1805      \fi}%
1806   \ifconditional\c_tabl_ntb_trace_widths\tabl_ntb_show_widths E#1\fi}
1807
1808% todo: use scratchcounters, not !! ones
1809
1810\def\tabl_ntb_check_heights_one_indeed
1811  {\!!countb\tabl_ntb_get_row\c_tabl_ntb_current_row_three\c_tabl_ntb_current_col_three\relax
1812    % check row span
1813   \ifnum\!!countb>\plusone
1814     % current height in row
1815     \dimen0=\tabl_ntb_get_ht\c_tabl_ntb_current_row_three\c_tabl_ntb_current_col_three
1816     % find nearest height in row
1817     \dimen2=\zeropoint
1818     \dorecurse\c_tabl_ntb_maximum_col
1819       {\ifnum\recurselevel=\c_tabl_ntb_current_col_three\else
1820          \ifcsname\tabl_ntb_row_pattern\c_tabl_ntb_current_row_three\recurselevel\endcsname
1821            \!!countc=\tabl_ntb_get_row\c_tabl_ntb_current_row_three\recurselevel\relax
1822            \ifnum\!!countc=\plusone
1823              \dimen4=\tabl_ntb_get_ht\c_tabl_ntb_current_row_three\recurselevel\relax
1824              \ifdim\dimen2<\dimen4
1825                \dimen2=\dimen4
1826              \fi
1827            \fi
1828          \fi
1829        \fi}%
1830     \c_tabl_ntb_current_row_four\c_tabl_ntb_current_row_three
1831     % calculate cummulative height
1832     \dimen4=\dimen2
1833     \!!countc\c_tabl_ntb_current_row_three
1834     \advance\!!countc\minusone
1835     \dorecurse\!!countb
1836       {\ifnum\c_tabl_ntb_current_row_four=\c_tabl_ntb_current_row_three\else
1837          \advance\dimen4 \tabl_ntb_get_hei\c_tabl_ntb_current_row_four
1838        \fi
1839        \ifnum\recurselevel=\!!countb\else
1840          \tabl_ntb_set_nob\!!countc
1841          \advance\!!countc\plusone
1842       \fi
1843        \advance\c_tabl_ntb_current_row_four\plusone}%
1844     % distribute overshoot equally
1845     \ifdim\dimen2>\zeropoint % new: test on natural-003
1846       \ifdim\dimen4<\dimen0
1847         \advance\dimen0 -\dimen4
1848         \divide\dimen0 \!!countb
1849         \c_tabl_ntb_current_row_four\c_tabl_ntb_current_row_three
1850         \tabl_ntb_set_hei\c_tabl_ntb_current_row_three{\the\dimen2}%
1851         \dorecurse\!!countb
1852           {\dorecurse\c_tabl_ntb_maximum_col
1853              {\ifnum\recurselevel=\c_tabl_ntb_current_col_three\else
1854                 \scratchdimen\dimexpr\tabl_ntb_get_ht\c_tabl_ntb_current_row_four\recurselevel+\dimen0\relax
1855                 \tabl_ntb_set_ht\c_tabl_ntb_current_row_four\recurselevel{\the\scratchdimen}%
1856                 \ifdim\tabl_ntb_get_hei\c_tabl_ntb_current_row_four<\scratchdimen
1857                   \tabl_ntb_set_hei\c_tabl_ntb_current_row_four{\the\scratchdimen}%
1858                 \fi
1859               \fi}%
1860            \advance\c_tabl_ntb_current_row_four\plusone}%
1861       \else\ifdim\dimen4>\dimen0
1862         \iftightTBLrowspan
1863           \tabl_ntb_set_hei\c_tabl_ntb_current_row_three{\the\dimen2}%
1864         \fi
1865       \fi\fi
1866     \fi
1867   \fi}
1868
1869\def\tabl_ntb_check_heights_one
1870  {\dorecurse\c_tabl_ntb_maximum_row
1871     {\c_tabl_ntb_current_row_three\recurselevel\relax
1872      \dorecurse\c_tabl_ntb_maximum_col
1873        {\c_tabl_ntb_current_col_three\recurselevel\relax
1874         \ifcsname\tabl_ntb_row_pattern\c_tabl_ntb_current_row_three\c_tabl_ntb_current_col_three\endcsname
1875           \tabl_ntb_check_heights_one_indeed
1876         \fi}}}
1877
1878\def\tabl_ntb_check_heights_two
1879  {}
1880
1881\def\tabl_ntb_show_widths#1#2%
1882  {\begingroup
1883   \scratchdimen\zeropoint
1884   \dorecurse\c_tabl_ntb_maximum_col
1885     {\advance\scratchdimen\tabl_ntb_get_wid\recurselevel\relax}%
1886   \writestatus\m!TABLE{#1 \ifcase#2trial\else real\fi: hsize: \the\hsize, total: \the\scratchdimen}%
1887   \dorecurse\c_tabl_ntb_maximum_col
1888     {\writestatus\m!TABLE{\space\space\recurselevel: \the\dimexpr\tabl_ntb_get_wid\recurselevel}}%
1889   \endgroup}
1890
1891\def\tabl_ntb_char_align % called often
1892  {\edef\p_characteralign{\naturaltablelocalparameter\c!aligncharacter}%
1893   \ifx\p_characteralign\v!yes
1894     \ifcase\c_tabl_tbl_pass\or
1895       \tabl_ntb_let_tal\currentTABLEcolumn\plusone
1896       \tabl_ntb_let_gal\plusone
1897     \fi
1898     \expandafter\tabl_ntb_char_align_indeed
1899   \else
1900     \expandafter\gobbletwoarguments
1901   \fi}
1902
1903\def\tabl_ntb_char_align_indeed#1#2% row column
1904  {\ifcase\c_tabl_tbl_pass \or
1905     \setcharacteralign{#2}{\naturaltablelocalparameter\c!alignmentcharacter}% we could store the character in tal
1906   \fi
1907   \typo_charalign_adapt_font
1908   \signalcharacteralign{#2}{#1}}
1909
1910\unexpanded\def\tabl_ntb_cell_process_a_extra#1#2%
1911  {\ifcase\tabl_ntb_get_tal{#2}\relax
1912     \expandafter\tabl_ntb_cell_process_x
1913   \else
1914     \expandafter\tabl_ntb_cell_process_a
1915   \fi{#1}{#2}}
1916
1917\unexpanded\def\tabl_ntb_cell_process_x#1#2[#3]#4%
1918  {}
1919
1920% problem: when span doesn't break we can have a span that is the sum of cells but
1921% still to small .. chicken egg problem ... for that we should also have a smallest
1922% width run
1923%
1924% nilling the background makes a run upto 25% faster
1925
1926\def\tabl_ntb_cell_process_a_check_span_one
1927  {\ifautosqueezeTBLspan
1928     \edef\p_width{\naturaltablelocalparameter\c!width}%
1929     \ifcsname\??naturaltablesqueeze\p_width\endcsname\lastnamedcs\else\donefalse\fi
1930   \else
1931     \donetrue
1932   \fi
1933   \ifdone % brr, 0
1934     \ifnum\scratchcounter>\plusone
1935       \tabl_ntb_set_spn\c_tabl_ntb_col
1936     \fi
1937   \fi}
1938
1939\let\tabl_ntb_cell_process_a_check_span_two_yes\relax
1940
1941\def\tabl_ntb_cell_process_a_check_span_two_nop
1942  {\ifdim\tabl_ntb_get_wid\c_tabl_ntb_col<\wd\scratchbox
1943     \tabl_ntb_set_wid\c_tabl_ntb_col{\the\wd\scratchbox}%
1944   \fi}
1945
1946\unexpanded\def\tabl_ntb_cell_process_a#1#2[#3]#4% grouping added ! ! !
1947  {\bgroup
1948   \letnaturaltablelocalparameter\c!option\empty
1949   \tabl_ntb_setup_cell{#1}{#2}%
1950   \setupcurrentnaturaltablelocal[#3]%
1951   \letnaturaltablelocalparameter\c!background\empty
1952   \letnaturaltablelocalparameter\c!frame\v!off
1953   \scratchcounter\tabl_ntb_get_col{#1}{#2}\relax
1954   \setbox\scratchbox\hbox
1955     {\scratchdimen\naturaltablelocalparameter\c!distance\relax
1956      \ifdim\scratchdimen>\tabl_ntb_get_dis{#2}\relax
1957        \tabl_ntb_set_dis{#2}{\the\scratchdimen}%
1958      \fi
1959      \anch_backgrounds_text_level_start
1960      \inheritednaturaltablelocalframed{\tabl_ntb_cell_start\tabl_ntb_char_align{#1}{#2}#4\tabl_ntb_cell_stop\tabl_ntb_cell_finalize}%
1961      \anch_backgrounds_text_level_stop
1962      \ifcase\c_anch_backgrounds_text_count\else
1963        \tabl_ntb_let_bck{#1}{#2}\c_anch_backgrounds_text_state
1964      \fi
1965     }%
1966   \scratchdimen\tabl_ntb_get_wid\c_tabl_ntb_col\relax
1967   \ifdim\wd\scratchbox>\scratchdimen
1968     \ifsqueezeTBLspan
1969       \tabl_ntb_cell_process_a_check_span_one
1970     \fi
1971     \tabl_ntb_spn_doifelse\c_tabl_ntb_col
1972       \tabl_ntb_cell_process_a_check_span_two_yes
1973       \tabl_ntb_cell_process_a_check_span_two_nop
1974   \fi
1975   \scratchcounter\numexpr\c_tabl_ntb_row+\plusone\relax
1976   \scratchdimen\tabl_ntb_get_hei\scratchcounter\relax
1977   \ifdim\ht\scratchbox<\scratchdimen
1978     \tabl_ntb_set_hei\scratchcounter{\the\ht\scratchbox}% auto set
1979   \fi
1980   \tabl_ntb_set_ht{#1}{#2}{\the\ht\scratchbox}%
1981   %tabl_ntb_set_wd{#1}{#2}{\the\wd\scratchbox}%
1982   \ifautoTBLcheckwidth
1983     \ifdim\wd\scratchbox<.75\hsize % fuzzy guess
1984       \ifdim\ht\scratchbox>2\openlineheight % honor width since this
1985         \scratchdimen\tabl_ntb_get_aut\c_tabl_ntb_col\relax % can be a figure or so
1986         \ifzeropt\scratchdimen
1987           % side effect: when width is set to 0pt,
1988           % we can force a span that fits the sum of spans widths
1989           \tabl_ntb_set_aut\c_tabl_ntb_col{\the\scratchdimen}%
1990         \else\ifdim\wd\scratchbox>\scratchdimen
1991           % unless span
1992           \tabl_ntb_set_aut\c_tabl_ntb_col{\the\wd\scratchbox}%
1993           % to be translated
1994           \writestatus\m!TABLE{no auto width in (\number#1,\number#2)\space\the\wd\scratchbox/\the\hsize}%
1995         \fi\fi
1996       \fi
1997     \fi
1998   \fi
1999   \setbox\scratchboxone\emptyhbox
2000   \wd\scratchboxone\wd\scratchbox
2001   \ht\scratchboxone\ht\scratchbox
2002   \dp\scratchboxone\dp\scratchbox
2003   \box\scratchboxone
2004   \egroup}
2005
2006\unexpanded\def\tabl_ntb_cell_process_b_c#1#2#3[#4]#5%
2007  {\setbox\scratchbox\hbox
2008     {\tabl_ntb_setup_cell{#2}{#3}%
2009      \setupcurrentnaturaltablelocal[#4,#1]%
2010      \letnaturaltablelocalparameter\c!background\empty
2011      \letnaturaltablelocalparameter\c!frame\v!off
2012      \inheritednaturaltablelocalframed{\tabl_ntb_cell_start#5\tabl_ntb_cell_stop}}%
2013   \setbox2\emptyhbox
2014   \wd2\wd\scratchbox
2015   \ht2\ht\scratchbox
2016   \dp2\dp\scratchbox
2017   \ifautoTBLrowspan
2018     \scratchcounter\numexpr\c_tabl_ntb_row+\plusone\relax
2019     \ifcsname\tabl_ntb_row_pattern\scratchcounter\c_tabl_ntb_col\endcsname
2020       \scratchdimen\tabl_ntb_get_hei\scratchcounter\relax
2021       \ifnum\tabl_ntb_get_row\scratchcounter\c_tabl_ntb_col>\plusone
2022         \ifdim\ht\scratchbox>\scratchdimen
2023           \ht2\dimexpr-\scratchdimen-\ht\scratchbox\relax
2024         \fi
2025       \fi
2026     \fi
2027   \fi
2028   \box2 }
2029
2030\unexpanded\def\tabl_ntb_cell_process_b#1#2[#3]#4%
2031   {\scratchdimen\tabl_ntb_get_aut\c_tabl_ntb_col\relax
2032    \ifdim\scratchdimen>\zeropoint\relax
2033    \else
2034      \scratchdimen\tabl_ntb_get_wid\c_tabl_ntb_col\relax
2035      \ifdim\scratchdimen>\zeropoint\relax
2036        \ifnum\tabl_ntb_get_col{#1}{#2}=\c_tabl_ntb_maximum_col\relax
2037          \scratchdimen\hsize
2038        \fi
2039      \fi
2040    \fi
2041    \normalexpanded{\tabl_ntb_cell_process_b_c{\ifdim\scratchdimen>\zeropoint \c!width=\the\scratchdimen\fi}}%
2042      {#1}{#2}[#3]{\tabl_ntb_char_align{#1}{#2}#4}}
2043
2044\unexpanded\def\tabl_ntb_cell_process_c
2045  {\tabl_ntb_cell_process_b_c{}}
2046
2047\unexpanded\def\tabl_ntb_cell_process_d#1#2[#3]#4%
2048  {\tabl_ntb_setup_cell{#1}{#2}%
2049   \bgroup
2050   \setupcurrentnaturaltablelocal[#3]%
2051   \letnaturaltablelocalparameter\c!background\empty
2052   \letnaturaltablelocalparameter\c!frame\v!off
2053   \setnaturaltablelocalparameter\c!width{\d_tabl_ntb_width}%
2054   \inheritednaturaltablelocalframed{\tabl_ntb_cell_start\tabl_ntb_char_align{#1}{#2}#4\tabl_ntb_cell_stop}%
2055   \egroup}
2056
2057\unexpanded\def\tabl_ntb_cell_process_e#1#2[#3]#4%
2058  {\tabl_ntb_setup_cell{#1}{#2}%
2059   \setupcurrentnaturaltablelocal[#3]% to get the color right, the way we
2060   \color % handle color here prevents interference due to whatsit nodes
2061     [\naturaltablelocalparameter\c!color] % as well as permits local colors to take precedence
2062     {\letnaturaltablelocalparameter\c!color\empty
2063      \setnaturaltablelocalparameter\c!width{\d_tabl_ntb_width}%
2064      \ifzeropt\d_tabl_ntb_height % case: nc=maxcolumns
2065      \else
2066        \setnaturaltablelocalparameter\c!height{\d_tabl_ntb_height}%
2067      \fi
2068      \ifcase\c_anch_backgrounds_text_count\else
2069        \edef\p_region{\naturaltablelocalparameter\c!region}%
2070        \ifx\p_region\empty\ifnum\tabl_ntb_get_bck{#1}{#2}>\zerocount
2071          \letnaturaltablelocalparameter\c!region\v!yes
2072        \fi\fi
2073      \fi
2074      \inheritednaturaltablelocalframed{\tabl_ntb_cell_start\tabl_ntb_char_align{#1}{#2}#4\tabl_ntb_cell_stop}}%
2075   \hskip\tabl_ntb_get_dis{#2}}
2076
2077\newtoks\everyresetTABLEyes
2078\newtoks\everyresetTABLEnop
2079
2080\appendtoks
2081    \setupTABLE [%
2082        %
2083        % framed defaults
2084        %
2085        \c!width=\v!fit,%
2086        \c!height=\v!fit,%
2087        \c!lines=,%
2088        \c!offset=.25\exheight,%
2089        \c!empty=\v!no,%
2090        \c!frame=\v!on,%
2091        \c!topframe=,%
2092        \c!bottomframe=,%
2093        \c!leftframe=,%
2094        \c!rightframe=,%
2095        \c!radius=.5\bodyfontsize,%
2096        \c!rulethickness=\linewidth,%
2097        \c!corner=\v!rectangular,%
2098        \c!depth=\zeropoint,%
2099        \c!foregroundcolor=,%
2100        \c!foregroundstyle=,%
2101        \c!background=,%
2102        \c!backgroundcolor=,%
2103        \c!backgroundoffset=\v!frame,%
2104        \c!framecolor=,%
2105        \c!frameoffset=.5\linewidth,%
2106      % \c!backgroundcorner=\framedparameter\c!corner,%
2107      % \c!backgrounddepth=\framedparameter\c!depth,%
2108      % \c!backgroundradius=\framedparameter\c!radius,%
2109      % \c!framecorner=\framedparameter\c!corner,%
2110      % \c!framedepth=\framedparameter\c!depth,%
2111      % \c!frameradius=\framedparameter\c!radius,%
2112        \c!component=,%
2113        \c!region=,%
2114        \c!align=,%
2115        \c!bottom=\vss,%
2116        \c!top=,%
2117        \c!strut=\v!yes,%
2118        \c!autostrut=\v!no,%
2119        \c!location=\v!normal,%
2120        \c!orientation=,%
2121        \c!autowidth=\v!yes,%
2122        \c!setups=,%
2123        \c!loffset=\zeropoint,%
2124        \c!roffset=\zeropoint,%
2125        \c!toffset=\zeropoint,%
2126        \c!boffset=\zeropoint,%
2127        %
2128        % table specific
2129        %
2130        \c!aligncharacter=\v!no,%
2131        \c!alignmentcharacter={,},%
2132        \c!color=,%
2133        \c!columndistance=\zeropoint,%       each column (whole table)
2134        \c!distance=\zeropoint,%             individual column
2135        \c!headcolor=,%
2136        \c!header=,%
2137        \c!headstyle=\v!bold,%
2138        \c!left=,%
2139        \c!leftmargindistance=\zeropoint,%   whole table
2140        \c!maxwidth=8\emwidth,%
2141        \c!option=,%                         \v!stretch
2142        \c!right=,%
2143        \c!rightmargindistance=\zeropoint,%  whole table
2144        \c!spaceinbetween=,%
2145        \c!split=\v!auto,%
2146        \c!splitoffset=\zeropoint,%
2147        \c!style=,%
2148        \c!textwidth=\v!local,%              was \hsize
2149    ]%
2150\to \everyresetTABLEyes
2151
2152\appendtoks
2153    \setupTABLE [%
2154        \c!width=\v!fit,%
2155        \c!height=\v!fit%
2156    ]%
2157\to \everyresetTABLEnop
2158
2159\the\everyresetTABLEyes
2160
2161% \bgroup
2162% \setupTABLE[column][1][aligncharacter=yes, alignmentcharacter={,}]
2163% \bTABLE
2164%     \bTR  \bTD  1,2 \eTD  \bTD 2 \eTD \eTR
2165%     \bTR  \bTD 11,2 \eTD  \bTD
2166%         {\setupTABLE[column][1][aligncharacter=yes, alignmentcharacter={,}]
2167%          \bTABLE
2168%             \bTR  \bTD 1,2 \eTD  \bTD 2 \eTD \eTR
2169%             \bTR  \bTD  11,22 \eTD  \bTD 2 \eTD \eTR
2170%             \bTR  \bTD 11,2 \eTD  \bTD 2 \eTD \eTR \eTABLE} \eTD \eTR
2171%     \bTR  \bTD  11,22 \eTD  \bTD 2 \eTD \eTR
2172% \eTABLE
2173% \egroup
2174
2175\newconditional\resetTABLEmode \settrue\resetTABLEmode
2176
2177\def\tabl_ntb_parameters_reset % we can use setters instead
2178  {\ifnum\m_tabl_tbl_level>\plusone % in ieder geval
2179     \ifconditional\resetTABLEmode
2180        \the\everyresetTABLEyes
2181     \else
2182        \the\everyresetTABLEnop
2183     \fi
2184  \fi}
2185
2186% new (for Olivier Turlier)
2187%
2188% \defineTABLEsetup [xx] [foregroundcolor=red]
2189%
2190% \bTABLE
2191%     \bTR      \bTD      oeps \eTD  \bTD oeps \eTD \eTR
2192%     \bTR      \bTDs[xx] oeps \eTDs \bTD oeps \eTD \eTR
2193%     \bTRs[xx] \bTD      oeps \eTD  \bTD oeps \eTD \eTRs
2194% \eTABLE
2195
2196\installcorenamespace{naturaltablesetup}
2197
2198\unexpanded\def\defineTABLEsetup
2199  {\dodoubleargument\tabl_ntb_define_setup}
2200
2201\def\tabl_ntb_define_setup[#1][#2]%
2202  {\setvalue{\??naturaltablesetup#1}{#2}}
2203
2204\let\eTDs\relax
2205\let\eTRs\relax
2206
2207\unexpanded\def\bTDs[#1]#2\eTDs
2208  {\normalexpanded{\bTD[\begincsname\??naturaltablesetup#1\endcsname]}#2\eTD}
2209
2210\unexpanded\def\bTRs[#1]#2\eTRs
2211  {\normalexpanded{\bTR[\begincsname\??naturaltablesetup#1\endcsname]}#2\eTR}
2212
2213\protect \endinput
2214
2215% todo: mode: first|next (of niets)
2216