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