summaryrefslogtreecommitdiff
path: root/tex
diff options
context:
space:
mode:
Diffstat (limited to 'tex')
-rw-r--r--tex/context/base/context-version.pngbin106386 -> 106383 bytes
-rw-r--r--tex/context/base/mult-aux.mkiv91
-rw-r--r--tex/context/base/pack-rul.mkiv4
-rw-r--r--tex/context/base/status-files.pdfbin23993 -> 23971 bytes
-rw-r--r--tex/context/base/status-lua.pdfbin168036 -> 168035 bytes
-rw-r--r--tex/context/base/strc-des.mkiv5
-rw-r--r--tex/context/base/tabl-xtb.lua65
-rw-r--r--tex/context/base/tabl-xtb.mkvi249
8 files changed, 318 insertions, 96 deletions
diff --git a/tex/context/base/context-version.png b/tex/context/base/context-version.png
index fc4f24730..3603c06cb 100644
--- a/tex/context/base/context-version.png
+++ b/tex/context/base/context-version.png
Binary files differ
diff --git a/tex/context/base/mult-aux.mkiv b/tex/context/base/mult-aux.mkiv
index beb6ae5d1..453661d19 100644
--- a/tex/context/base/mult-aux.mkiv
+++ b/tex/context/base/mult-aux.mkiv
@@ -98,14 +98,16 @@
\expandafter\noexpand\csname detokenizedroot#2parameter\endcsname
\expandafter\noexpand\csname root#2parameter\endcsname}}
-\unexpanded\def\doinstallparameterhashhandler#1#2#3#4#5#6#7#8%
+\unexpanded\def\doinstallparameterhashhandler#1#2#3#4#5#6#7#8#9%
{\ifx#2\relax\let#2\empty\fi
\def#3##1{#4{#1#2}{##1}:}%
\def#4##1##2{\ifcsname##1:##2\endcsname##1\else\expandafter#5\csname##1:\s!parent\endcsname{##2}\fi}%
\def#5##1##2{\ifx##1\relax\else#4{##1}{##2}\fi}% is {} needed around ##1 ?
\def#6{#1#2:}%
\def#7##1{#1##1:}%
- \def#8{\ifx#2\empty\else\ifcsname#1#2:\s!parent\endcsname\else\expandafter\let\csname#1#2:\s!parent\endcsname#1\fi\fi}}
+ \def#8{\ifx#2\empty\else\ifcsname#1#2:\s!parent\endcsname\else\expandafter\let\csname#1#2:\s!parent\endcsname#1\fi\fi}%
+ \def#9##1{\expandafter\edef\csname#1##1:\s!parent\endcsname{#1#2}}}
+
\unexpanded\def\installparameterhashhandler#1#2%
{\normalexpanded
@@ -117,7 +119,8 @@
\expandafter\noexpand\csname do#2parentparameterhash\endcsname
\expandafter\noexpand\csname current#2hash\endcsname
\expandafter\noexpand\csname named#2hash\endcsname
- \expandafter\noexpand\csname check#2parent\endcsname}}
+ \expandafter\noexpand\csname check#2parent\endcsname
+ \expandafter\noexpand\csname chaintocurrent#2\endcsname}}
\unexpanded\def\doinstallparametersethandler#1#2#3#4#5% we can speed this up for english
{\ifx#2\relax\let#2\empty\fi
@@ -199,7 +202,7 @@
\expandafter\noexpand\csname define#2\endcsname
{\noexpand#3}% root
\expandafter\noexpand\csname current#2\endcsname
- \expandafter\noexpand\csname d@define#2\endcsname
+ \expandafter\noexpand\csname d@define#2\endcsname % sort of public
\expandafter\noexpand\csname everypreset#2\endcsname
\expandafter\noexpand\csname everydefine#2\endcsname
\expandafter\noexpand\csname current#2parent\endcsname}}
@@ -207,7 +210,7 @@
\unexpanded\def\doinstallsetuphandler#1#2#3#4#5#6%
{\ifx#3\relax\let#3\empty\fi
\unexpanded\def#2{\dodoubleempty#4}%
- \unexpanded\def#6{\getparameters[#1#3:]}%
+ \unexpanded\def#6{\getparameters[#1#3:]}% no every ! don't change it
\newtoks#5%
\def#4[##1][##2]% maybe helper
{\let\savedsetupwhatever#3%
@@ -230,7 +233,7 @@
{\noexpand#1}% \??aa
\expandafter\noexpand\csname setup#2\endcsname
\expandafter\noexpand\csname current#2\endcsname
- \expandafter\noexpand\csname d@setup#2\endcsname
+ \expandafter\noexpand\csname d@setup#2\endcsname % sort of public
\expandafter\noexpand\csname everysetup#2\endcsname
\expandafter\noexpand\csname setupcurrent#2\endcsname}}
@@ -270,32 +273,70 @@
\expandafter\noexpand\csname everysetup#2\endcsname
\expandafter\noexpand\csname setupcurrent#2\endcsname}}
-\unexpanded\def\installcommandhandler#1#2#3% \??self name \??parent (can be \??self)
+\unexpanded\def\doinstallautosetuphandler#1#2#3#4#5#6%
+ {\ifx#3\relax\let#3\empty\fi
+ \unexpanded\def#2{\dotripleempty#4}%
+ \unexpanded\def#6{\getparameters[#1#3:]}%
+ \newtoks#5%
+ \def#4[##1][##2][##3]%
+ {\let\savedsetupwhatever#3%
+ \ifthirdargument
+ \def\docommand####1%
+ {\edef#3{####1}%
+ \getparameters[#1#3:][\s!parent=#1##2,##3]%
+ \the#5}%
+ \processcommalist[##1]\docommand
+ \else\ifsecondargument
+ \def\docommand####1%
+ {\edef#3{####1}%
+ \getparameters[#1#3:][##2]%
+ \the#5}%
+ \processcommalist[##1]\docommand
+ \else
+ \let#3\empty
+ \getparameters[#1:][##1]%
+ \the#5%
+ \fi\fi
+ \let#3\savedsetupwhatever}}
+
+\unexpanded\def\installautosetuphandler#1#2%
+ {\normalexpanded
+ {\doinstallautosetuphandler
+ {\noexpand#1}% \??aa
+ \expandafter\noexpand\csname setup#2\endcsname
+ \expandafter\noexpand\csname current#2\endcsname
+ \expandafter\noexpand\csname d@setup#2\endcsname % sort of public
+ \expandafter\noexpand\csname everysetup#2\endcsname
+ \expandafter\noexpand\csname setupcurrent#2\endcsname}}
+
+\def\installbasicparameterhandler#1#2%
{\installparameterhandler {#1}{#2}%
\installparameterhashhandler{#1}{#2}%
\installparametersethandler {#1}{#2}%
- \installrootparameterhandler{#1}{#2}%
- \installdefinehandler {#1}{#2}{#3}%
- \installsetuphandler {#1}{#2}%
- \installattributehandler {#1}{#2}}
+ \installrootparameterhandler{#1}{#2}}
+
+\unexpanded\def\installcommandhandler#1#2#3% \??self name \??parent (can be \??self)
+ {\installbasicparameterhandler{#1}{#2}%
+ \installdefinehandler {#1}{#2}{#3}%
+ \installsetuphandler {#1}{#2}%
+ \installattributehandler {#1}{#2}}
\unexpanded\def\installswitchcommandhandler#1#2#3% \??self name \??parent (can be \??self)
- {\installparameterhandler {#1}{#2}%
- \installparameterhashhandler{#1}{#2}%
- \installparametersethandler {#1}{#2}%
- \installrootparameterhandler{#1}{#2}%
- \installdefinehandler {#1}{#2}{#3}%
- \installswitchsetuphandler {#1}{#2}%
- \installattributehandler {#1}{#2}}
+ {\installbasicparameterhandler{#1}{#2}%
+ \installdefinehandler {#1}{#2}{#3}%
+ \installswitchsetuphandler {#1}{#2}%
+ \installattributehandler {#1}{#2}}
-\unexpanded\def\installsimplecommandhandler#1#2#3% no define (experiment)
- {\installparameterhandler {#1}{#2}%
- \installparameterhashhandler{#1}{#2}%
- \installparametersethandler {#1}{#2}%
- \installrootparameterhandler{#1}{#2}%
- \installsetuphandler {#1}{#2}%
- \installattributehandler {#1}{#2}}
+\unexpanded\def\installautocommandhandler#1#2#3% automatically defined cloned setups
+ {\installbasicparameterhandler{#1}{#2}%
+ \installdefinehandler {#1}{#2}{#3}%
+ \installautosetuphandler {#1}{#2}%
+ \installattributehandler {#1}{#2}}
+\unexpanded\def\installsimplecommandhandler#1#2#3% no define (experiment)
+ {\installbasicparameterhandler{#1}{#2}%
+ \installsetuphandler {#1}{#2}%
+ \installattributehandler {#1}{#2}}
\unexpanded\def\installnamespace#1%
{\setvalue{????#1}{@@@@#1}}
diff --git a/tex/context/base/pack-rul.mkiv b/tex/context/base/pack-rul.mkiv
index 86f5effe5..80196c098 100644
--- a/tex/context/base/pack-rul.mkiv
+++ b/tex/context/base/pack-rul.mkiv
@@ -936,6 +936,10 @@
{\installcommandhandler{#1}{#2}{#3}%
\installinheritedframed{#2}}
+\unexpanded\def\installframedautocommandhandler#1#2#3%
+ {\installautocommandhandler{#1}{#2}{#3}%
+ \installinheritedframed{#2}}
+
% done
\def\c!fr!analyze{fr:analyze} % private option
diff --git a/tex/context/base/status-files.pdf b/tex/context/base/status-files.pdf
index e904eb043..c0e065411 100644
--- a/tex/context/base/status-files.pdf
+++ b/tex/context/base/status-files.pdf
Binary files differ
diff --git a/tex/context/base/status-lua.pdf b/tex/context/base/status-lua.pdf
index 3b51dc7e0..61e3e61e4 100644
--- a/tex/context/base/status-lua.pdf
+++ b/tex/context/base/status-lua.pdf
Binary files differ
diff --git a/tex/context/base/strc-des.mkiv b/tex/context/base/strc-des.mkiv
index 113d1e665..18467fb41 100644
--- a/tex/context/base/strc-des.mkiv
+++ b/tex/context/base/strc-des.mkiv
@@ -15,6 +15,9 @@
\registerctxluafile{strc-des}{1.001}
+%D TODO: commandhandler
+%D TODO: \startxxx[reference=...]
+
%D In order to be more flexible with theorems Aditya Mahajan added
%D support for titles and endsymbols. At the same time we added more
%D flexible support for inheriting numbers.
@@ -1093,6 +1096,8 @@
\c!command=,
\c!titlecommand=]
+% way=bychapter,prefix=yes,prefixsegments=2:2
+
\setupenumerations
[\c!location=\v!top,
\c!text=,
diff --git a/tex/context/base/tabl-xtb.lua b/tex/context/base/tabl-xtb.lua
index de52b933c..fffda698f 100644
--- a/tex/context/base/tabl-xtb.lua
+++ b/tex/context/base/tabl-xtb.lua
@@ -49,8 +49,11 @@ local vpack_node_list = node.vpack
local slide_node_list = node.slide
local flush_node_list = node.flush_list
-local new_glue = nodes.pool.glue
-local new_kern = nodes.pool.kern
+local nodepool = nodes.pool
+
+local new_glue = nodepool.glue
+local new_kern = nodepool.kern
+local new_penalty = nodepool.penalty
local v_stretch = variables.stretch
local v_normal = variables.normal
@@ -434,6 +437,26 @@ function xtables.reflow_height()
data.currentcolumn = 0
end
+local function showspans(data)
+ local rows = data.rows
+ local nofcolumns = data.nofcolumns
+ local nofrows = data.nofrows
+ for r=1,nofrows do
+ local line = { }
+ for c=1,nofcolumns do
+ local cell =rows[r][c]
+ if cell.list then
+ line[#line+1] = "list"
+ elseif cell.span then
+ line[#line+1] = "span"
+ else
+ line[#line+1] = "none"
+ end
+ end
+ report_xtable("%3d : %s",r,concat(line," "))
+ end
+end
+
function xtables.construct()
local rows = data.rows
local heights = data.heights
@@ -452,20 +475,7 @@ function xtables.construct()
-- ranges can be mixes so we collect
if trace_xtable then
- for r=1,data.nofrows do
- local line = { }
- for c=1,data.nofcolumns do
- local cell =rows[r][c]
- if cell.list then
- line[#line+1] = "list"
- elseif cell.span then
- line[#line+1] = "span"
- else
- line[#line+1] = "none"
- end
- end
- report_xtable("%3d : %s",r,concat(line," "))
- end
+ showspans(data)
end
local ranges = {
@@ -493,8 +503,12 @@ function xtables.construct()
start = new_kern(leftmargindistance)
stop = start
end
+ local hasspan = false
for c=1,nofcolumns do
local drc = row[c]
+ if not hasspan then
+ hasspan = drc.span
+ end
local list = drc.list
if list then
list.shift = list.height + list.depth
@@ -530,21 +544,26 @@ function xtables.construct()
kern.prev = stop
-- stop = kern
end
- return start, heights[r] + depths[r]
+ return start, heights[r] + depths[r], hasspan
end
end
local function collect_range(range)
- local result = { }
+ local result, nofr = { }, 0
local nofrange = #range
for i=1,#range do
local r = range[i]
- local row = rows[r]
- local list, size = packaged_column(r)
+ -- local row = rows[r]
+ local list, size, hasspan = packaged_column(r)
if list then
- result[#result+1] = {
+ if hasspan and nofr > 0 then
+ result[nofr][4] = true
+ end
+ nofr = nofr + 1
+ result[nofr] = {
hpack_node_list(list),
size,
i < nofrange and rowdistance > 0 and rowdistance or false, -- might move
+ false
}
end
end
@@ -577,7 +596,9 @@ local function inject(row,copy,package)
context(new_kern(row[2]))
context_endvbox()
context_nointerlineskip() -- figure out a better way
- if row[3] then
+ if row[4] then
+ -- nothing as we have a span
+ elseif row[3] then
context_blank(row[3] .. "sp")
else
context(new_glue(0))
diff --git a/tex/context/base/tabl-xtb.mkvi b/tex/context/base/tabl-xtb.mkvi
index d29ede5a1..a848642a3 100644
--- a/tex/context/base/tabl-xtb.mkvi
+++ b/tex/context/base/tabl-xtb.mkvi
@@ -95,7 +95,11 @@
\newcount\x_table_nesting
\newcount\x_table_skip_mode % 1 = skip
-\installframedcommandhandler \??lt {xtable} \??lt
+% \setupxtable[one][parent][a=b,c=d]
+% \setupxtable[one] [a=b,c=d]
+% \setupxtable [a=b,c=d]
+
+\installframedautocommandhandler \??lt {xtable} \??lt
\appendtoks
\checkxtableparent % so we can deal with undefined settings, not that it's efficient
@@ -162,7 +166,7 @@
{\x_table_prepare{#settings}%
\let\start_x_table\normal_start_x_table}
-%D We can also define xtables:
+%D We can also define xtables.
\appendtoks
\setuevalue{\e!start\currentxtable}{\start_named_x_table{\currentxtable}}%
@@ -214,28 +218,34 @@
footer = "\xtableparameter\c!footer",
} }%
\begingroup
- \let\start_x_row \start_x_row_reflow_width
- \let\stop_x_row \stop_x_row_reflow_width
- \let\start_x_cell\start_x_cell_reflow_width
- \let\stop_x_cell \stop_x_cell_reflow_width
+ \let\start_x_row_yes \start_x_row_reflow_width_yes
+ \let\start_x_row_nop \start_x_row_reflow_width_nop
+ \let\stop_x_row \stop_x_row_reflow_width
+ \let\start_x_cell_yes\start_x_cell_reflow_width_yes
+ \let\start_x_cell_nop\start_x_cell_reflow_width_nop
+ \let\stop_x_cell \stop_x_cell_reflow_width
\settrialtypesetting
\x_table_get_buffer
\ctxcommand{x_table_reflow_width()}\relax
\endgroup
\begingroup
- \let\start_x_row \start_x_row_reflow_height
- \let\stop_x_row \stop_x_row_reflow_height
- \let\start_x_cell\start_x_cell_reflow_height
- \let\stop_x_cell \stop_x_cell_reflow_height
+ \let\start_x_row_yes \start_x_row_reflow_height_yes
+ \let\start_x_row_nop \start_x_row_reflow_height_nop
+ \let\stop_x_row \stop_x_row_reflow_height
+ \let\start_x_cell_yes\start_x_cell_reflow_height_yes
+ \let\start_x_cell_nop\start_x_cell_reflow_height_nop
+ \let\stop_x_cell \stop_x_cell_reflow_height
\settrialtypesetting
\x_table_get_buffer
\ctxcommand{x_table_reflow_height()}\relax
\endgroup
\begingroup
- \let\start_x_row \start_x_row_construct
- \let\stop_x_row \stop_x_row_construct
- \let\start_x_cell\start_x_cell_construct
- \let\stop_x_cell \stop_x_cell_construct
+ \let\start_x_row_yes \start_x_row_construct_yes
+ \let\start_x_row_nop \start_x_row_construct_nop
+ \let\stop_x_row \stop_x_row_construct
+ \let\start_x_cell_yes\start_x_cell_construct_yes
+ \let\start_x_cell_nop\start_x_cell_construct_nop
+ \let\stop_x_cell \stop_x_cell_construct
\x_table_get_buffer
\ctxcommand{x_table_construct()}\relax
\endgroup
@@ -284,27 +294,31 @@
\unexpanded\def\startxrow
{\begingroup
- \dosingleempty\start_x_row}
+ \doifnextoptionalelse\start_x_row_yes\start_x_row_nop}
-\def\start_x_row_reflow_width[#settings]%
- {\iffirstargument
- \setupcurrentxtable[#settings]%
- \fi
+\def\start_x_row_reflow_width_yes[#settings]%
+ {\setupcurrentxtable[#settings]%
\ctxcommand{x_table_next_row()}}
+\def\start_x_row_reflow_width_nop
+ {\ctxcommand{x_table_next_row()}}
+
\def\stop_x_row_reflow_width
{}
-\let\start_x_row_reflow_height\start_x_row_reflow_width
-\let\stop_x_row_reflow_height \stop_x_row_reflow_width
+\let\start_x_row_reflow_height_yes\start_x_row_reflow_width_yes
+\let\start_x_row_reflow_height_nop\start_x_row_reflow_width_nop
+\let\stop_x_row_reflow_height \stop_x_row_reflow_width
-\def\start_x_row_construct[#settings]%
- {\iffirstargument
- \setupcurrentxtable[#settings]%
- \fi
+\def\start_x_row_construct_yes[#settings]%
+ {\setupcurrentxtable[#settings]%
\dostarttagged\t!tablerow\empty
\ctxcommand{x_table_next_row()}}
+\def\start_x_row_construct_nop
+ {\dostarttagged\t!tablerow\empty
+ \ctxcommand{x_table_next_row()}}
+
\def\stop_x_row_construct
{\dostoptagged}
@@ -313,7 +327,7 @@
\endgroup}
\unexpanded\def\startxcell
- {\dosingleempty\start_x_cell}
+ {\doifnextoptionalelse\start_x_cell_yes\start_x_cell_nop}
\unexpanded\def\stopxcell
{\stop_x_cell}
@@ -345,36 +359,42 @@
% Although this becomes kind of messy. It saves already time that we only check
% for it when we have settings.
-\def\before_x_cell_settings
- {\letxtableparameter\c!nx\plusone
+\unexpanded\def\start_x_cell_reflow_width_yes[#settings]%
+ {\setbox\x_table_box\hbox\bgroup
+ \ifnum\x_table_nesting>\plusone
+ \letxtableparameter\c!width \v!fit % overloads given width
+ \letxtableparameter\c!height\v!fit % overloads given height
+ \fi
+ %
+ \letxtableparameter\c!nx\plusone
\letxtableparameter\c!ny\plusone
\letxtableparameter\c!nc\plusone
- \letxtableparameter\c!nr\plusone}
-
-\def\after_x_cell_settings
- {\x_table_nx\directxtableparameter\c!nc\relax
+ \letxtableparameter\c!nr\plusone
+ %
+ \setupcurrentxtable[#settings]%
+ %
+ \x_table_nx\directxtableparameter\c!nc\relax
\x_table_ny\directxtableparameter\c!nr\relax
\ifnum\x_table_nx=\plusone
\x_table_nx\directxtableparameter\c!nx\relax
\fi
\ifnum\x_table_ny=\plusone
\x_table_ny\directxtableparameter\c!ny\relax
- \fi}
+ \fi
+ %
+ \x_table_distance\xtableparameter\c!distance\relax
+ \ctxcommand{x_table_init_reflow_width()}%
+ \inheritedxtableframed\bgroup
+ \begin_of_cell}
-\unexpanded\def\start_x_cell_reflow_width[#settings]%
+\unexpanded\def\start_x_cell_reflow_width_nop
{\setbox\x_table_box\hbox\bgroup
\ifnum\x_table_nesting>\plusone
\letxtableparameter\c!width \v!fit % overloads given width
\letxtableparameter\c!height\v!fit % overloads given height
\fi
- \iffirstargument
- \before_x_cell_settings
- \setupcurrentxtable[#settings]%
- \after_x_cell_settings
- \else
- \x_table_nx\plusone
- \x_table_ny\plusone
- \fi
+ \x_table_nx\plusone
+ \x_table_ny\plusone
\x_table_distance\xtableparameter\c!distance\relax
\ctxcommand{x_table_init_reflow_width()}%
\inheritedxtableframed\bgroup
@@ -386,15 +406,26 @@
\egroup
\ctxcommand{x_table_set_reflow_width()}}
-\unexpanded\def\start_x_cell_reflow_height[#settings]%
+\unexpanded\def\start_x_cell_reflow_height_yes[#settings]%
{\setbox\x_table_box\hbox\bgroup
\ctxcommand{x_table_init_reflow_height()}%
\ifcase\x_table_skip_mode % can be sped up
\ifnum\x_table_nesting>\plusone
\letxtableparameter\c!height\v!fit % overloads given height
\fi
- \iffirstargument
- \setupcurrentxtable[#settings]%
+ \setupcurrentxtable[#settings]%
+ \relax
+ \letxtableparameter\c!width\x_table_width % overloads given width
+ \inheritedxtableframed\bgroup
+ \begin_of_cell
+ \fi}
+
+\unexpanded\def\start_x_cell_reflow_height_nop
+ {\setbox\x_table_box\hbox\bgroup
+ \ctxcommand{x_table_init_reflow_height()}%
+ \ifcase\x_table_skip_mode % can be sped up
+ \ifnum\x_table_nesting>\plusone
+ \letxtableparameter\c!height\v!fit % overloads given height
\fi
\relax
\letxtableparameter\c!width\x_table_width % overloads given width
@@ -410,12 +441,20 @@
\egroup
\ctxcommand{x_table_set_reflow_height()}}
-\unexpanded\def\start_x_cell_construct[#settings]%
+\unexpanded\def\start_x_cell_construct_yes[#settings]%
+ {\dostarttagged\t!tablecell\empty % can't we just tag the box
+ \setbox\x_table_box\hbox\bgroup
+ \setupcurrentxtable[#settings]%
+ \letxtableparameter\c!width \x_table_width % overloads given width
+ \letxtableparameter\c!height\x_table_height % overloads given height
+ \ctxcommand{x_table_init_construct()}%
+ \inheritedxtableframed\bgroup
+ \begin_of_cell
+ \dotagxtablecell}
+
+\unexpanded\def\start_x_cell_construct_nop
{\dostarttagged\t!tablecell\empty % can't we just tag the box
\setbox\x_table_box\hbox\bgroup
- \iffirstargument
- \setupcurrentxtable[#settings]%
- \fi
\letxtableparameter\c!width \x_table_width % overloads given width
\letxtableparameter\c!height\x_table_height % overloads given height
\ctxcommand{x_table_init_construct()}%
@@ -495,6 +534,118 @@
\let\stopembeddedxtable\relax
+%D This is an experiment! Beware: you can create loops by using nested
+%D references to already chained settings.
+%D
+%D \startbuffer
+%D \setupxtable[suffix][align=middle,foregroundcolor=red]
+%D \setupxtable[blabla][foregroundstyle=slanted]
+%D \setupxtable[bold] [foregroundstyle=bold]
+%D
+%D \startxtable[frame=off]
+%D \startxtablehead
+%D \startxrow[bold]
+%D \startxcell[suffix] a 0 \stopxcell
+%D \startxcell[blabla] a 1 \stopxcell
+%D \startxcell a 2 \stopxcell
+%D \stopxrow
+%D \stopxtablehead
+%D \startxtablebody
+%D \startxrow \startxcell[suffix][ny=2] a 1 \stopxcell \startxcell b 1 \stopxcell \startxcell c 1 \stopxcell \stopxrow
+%D \startxrow \startxcell b 2 \stopxcell \startxcell c 2 \stopxcell \stopxrow
+%D \startxrow \startxcell[suffix] a 3 \stopxcell \startxcell b 3 \stopxcell \startxcell c 3 \stopxcell \stopxrow
+%D \startxrow \startxcell[suffix] a 4 \stopxcell \startxcell b 4 \stopxcell \startxcell c 4 \stopxcell \stopxrow
+%D \startxrow \startxcell[suffix] a 5 \stopxcell \startxcell b 5 \stopxcell \startxcell c 5 \stopxcell \stopxrow
+%D \stopxtablebody
+%D \stopxtable
+%D \stopbuffer
+%D
+%D \typebuffer \placetable{}{\getbuffer}
+
+\appendtoks
+ \letvalue{\??lt\currentxtable\s!check}\relax % faster than checking parent
+\to \everysetupxtable
+
+% groups
+
+\unexpanded\def\startxgroup
+ {\begingroup
+ \doifnextoptionalelse\start_x_group_delayed_one\relax}
+
+\unexpanded\def\stopxgroup
+ {\endgroup}
+
+\def\start_x_group_delayed_one[#tag]%
+% {\ifcsname\namedxtablehash{#tag}\s!parent\endcsname
+ {\ifcsname\??lt#tag\s!check\endcsname
+ \expandafter\start_x_group_delayed_two
+ \else
+ \expandafter\setupcurrentxtable
+ \fi[#tag]}
+
+\def\start_x_group_delayed_two[#tag]%
+ {\ifx\currentxtable\empty \else
+ \chaintocurrentxtable{#tag}%
+ \fi
+ \edef\currentxtable{#tag}%
+ \doifnextoptionalelse\setupcurrentxtable\relax}
+
+\let\startxrowgroup \startxgroup
+\let\stopxrowgroup \stopxgroup
+\let\startxcellgroup\startxgroup
+\let\stopxcellgroup \stopxgroup
+
+% cells (maybe also check for 1 etc but it becomes messy)
+
+\unexpanded\def\startxcell
+ {\begingroup
+ \doifnextoptionalelse\start_x_cell_delayed_one\start_x_cell_nop}
+
+\def\start_x_cell_delayed_one[#tag]%
+% {\ifcsname\namedxtablehash{#tag}\s!parent\endcsname
+ {\ifcsname\??lt#tag\s!check\endcsname
+ \expandafter\start_x_cell_delayed_two
+ \else
+ \expandafter\start_x_cell_yes
+ \fi[#tag]}
+
+\def\start_x_cell_delayed_two[#tag]%
+ {\ifx\currentxtable\empty \else
+ \chaintocurrentxtable{#tag}%
+ \fi
+ \edef\currentxtable{#tag}%
+ \doifnextoptionalelse\start_x_cell_yes\start_x_cell_nop}
+
+\unexpanded\def\stopxcell
+ {\stop_x_cell
+ \endgroup}
+
+% rows
+
+\unexpanded\def\startxrow
+ {\begingroup
+ \doifnextoptionalelse\start_x_row_delayed_one\start_x_row_nop}
+
+\def\start_x_row_delayed_one[#tag]%
+% {\ifcsname\namedxtablehash{#tag}\s!parent\endcsname
+ {\ifcsname\??lt#tag\s!check\endcsname
+ \expandafter\start_x_row_delayed_two
+ \else
+ \expandafter\start_x_row_yes
+ \fi[#tag]}
+
+\def\start_x_row_delayed_two[#tag]%
+ {\ifx\currentxtable\empty \else
+ \chaintocurrentxtable{#tag}%
+ \fi
+ \edef\currentxtable{#tag}%
+ \doifnextoptionalelse\start_x_row_yes\start_x_row_nop}
+
+\unexpanded\def\stopxrow
+ {\stop_x_row
+ \endgroup}
+
\protect
% \continueifinputfile{tabl-xtb.mkvi}
+