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