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