%D \module
%D   [       file=core-tbl,
%D        version=1998.11.03,
%D          title=\CONTEXT\ Core Macros,
%D       subtitle=Text Flow Tabulation,
%D         author=Hans Hagen,
%D           date=\currentdate,
%D      copyright={PRAGMA / Hans Hagen \& Ton Otten}]
%C
%C This module is part of the \CONTEXT\ macro||package and is
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for 
%C details. 

\writestatus{loading}{Context Core Macros / Tabulation}

\unprotect

% |p2|p3| 2:3
% spanning 

% In-text tabbing environment
%
% \starttabulate[| separated template] % eg [|l|p|] or [|l|p|p|]
%   \NC ... \NC ... \NC\NR
% \stoptabulate
%
% with: two pass auto width calculation when no p-width
% specified, even with multiple p's, see examples.

%  TaBlE compatible specifications:
%
%  l  align column/paragraph left
%  r  align column/paragraph right
%  c  align column/paragraph center
%  p  p(dimen) of automatisch als alleen p
%  w  column width
%  f  font#1
%  B  bold
%  I  italic
%  S  slanted
%  T  type
%  R  roman
%  m  math
%  M  display math
%  h  hook (inner level or par lines)
%  b  before (may be command#1)
%  a  after
%  i  i<n> skip left of column
%  j  i<n> skip right of column
%  k  i<n> skip around column

%  Still to be done

% nesting, push en pop gebruiken 

%  N      math numbers (best hook into existing digits mechanism)
%  n      numbers (best hook into existing digits mechanism)
%  Q      math numbers (best hook into existing digits mechanism)
%  q      numbers (best hook into existing digits mechanism)
%  ~      \hskip.5em
%  |      check

%  10     evt auto stack; dan wel andere signal dan void nodig

%  present but not yet 100% ok
%
%  \FL    top hrule
%  \ML    mid hrule (with auto split)
%  \LL    bottom hrule
%  \HL 

%  \VL    as soon as needed
%  color  as soon as needed

%  \EQ \RQ \HQ  equal  (raw, hook)
%  \NC \RC \HC  normal (raw, hook)
%
%  \NR 

% tricky: align scans ahead, over # and expands ones before 
% while doing  

\newtoks    \tabulatepreamble
\newtoks    \tabulatebefore
\newtoks    \tabulateafter
\newtoks    \tabulatebmath
\newtoks    \tabulateemath
\newtoks    \tabulatefont
\newtoks    \tabulatesettings
\newtoks    \tabulatedummy

\newcounter \nofautotabulate
\newcounter \tabulatecolumns
\newcounter \tabulateminplines
\newcounter \tabulatemaxplines

\newif      \ifautotabulate
\newif      \ifsplittabulate         \splittabulatetrue
\newif      \ifhandletabulatepbreak  \handletabulatepbreaktrue
\newif      \iftabulateequal
\newif      \iftracetabulate 

\newdimen   \tabulatepwidth
\newdimen   \tabulatewidth
\newdimen   \tabulateunit
\newdimen   \tabulatemaxpheight

\newbox     \tabulatebox

\def\noftabcolumns{16} % quick and dirty stack

\def\@@tabbox@@ {@@tabbox@}
\def\@@tabhook@@{@@tabhook@}

\dorecurse\noftabcolumns
  {\@EA\newbox\csname\@@tabbox@@\recurselevel\endcsname}

\def\dotabulatenobreak%
  {\noalign
     {\nobreak
      \iftracetabulate
        \red\hrule\!!height.5\linewidth\!!depth.5\linewidth
        \par
        \kern-\linewidth
        \nobreak
      \fi}} 

\def\checktabulatehook%
  {\ifnum\tabulatetype<2        
     \let\tabulatehook\relax
   \fi}

\def\dodosettabulatepreamble#1#2%
  {\ifzeropt\tabulatewidth 
     \ifcase\tabulatemodus\relax
       \let\preamblebox\empty
     \else
       \def\preamblebox{\autotabulatetrue}%
     \fi
   \else
     \ifcase\tabulatemodus\relax
       \edef\preamblebox{\hbox to \the\tabulatewidth}%
     \else
       \edef\preamblebox{\hsize\the\tabulatewidth}%
     \fi
   \fi 
  %
  % less bytes 
  %
  %\edef\preamblebox%
  %  {\ifcase\tabulatewidth 
  %     \ifcase\tabulatemodus\relax\else\noexpand\autotabulatetrue\fi
  %   \els
  %     \ifcase\tabulatemodus\relax\hbox to\else\hsize\fi\the\tabulatewidth
  %   \fi}%
  %
  % 0 = NC column next   EQ equal column 
  % 1 = RC column raw    RQ equal column raw   
  % 2 = HC column hook   HQ equal column hook 
   \@EA\appendtoks                     \@EA&\@EA\hskip\pretabskip##&\to\!!toksa
   \@EA\appendtoks\@EA\xdef\@EA\tabulatecolumn\@EA{\tabulatecolumns}\to\!!toksa
   \@EA\appendtoks                                      \preamblebox\to\!!toksa
       \appendtoks                           \bgroup\bbskip\bgroup#1\to\!!toksa
       \appendtoks                                \checktabulatehook\to\!!toksa
       \appendtoks\ifnum\tabulatetype=1 \else                       \to\!!toksa
   \@EA\appendtoks                                \the\tabulatebmath\to\!!toksa
   \@EA\appendtoks                                 \the\tabulatefont\to\!!toksa
   \@EA\appendtoks                             \the\tabulatesettings\to\!!toksa
   \@EA\appendtoks                               \the\tabulatebefore\to\!!toksa
       \appendtoks\fi                                               \to\!!toksa
       \appendtoks                              \bgroup\ignorespaces\to\!!toksa
       \appendtoks                                   \tabulatehook##\to\!!toksa
       \appendtoks      \unskip\unskip\ifmmode\else\endgraf\fi\egroup\to\!!toksa
       \appendtoks\ifnum\tabulatetype=1 \else                        \to\!!toksa
   \@EA\appendtoks                                \the\tabulateafter\to\!!toksa
   \@EA\appendtoks                                \the\tabulateemath\to\!!toksa
       \appendtoks\fi                                               \to\!!toksa
       \appendtoks                                  #2\egroup\egroup\to\!!toksa
   \@EA\appendtoks                      \@EA&\@EA\hskip\postabskip##\to\!!toksa
   \appendtoks\NC\to\tabulatedummy
   \let\bbskip\empty
   \def\pretabskip{.5\tabulateunit}%
   \let\postabskip\pretabskip
   \let\gettabulateexit\dogettabulateexit
   \tabulatewidth\!!zeropoint}

\def\dosettabulatepreamble%
  {\ifx\next\relax
     \let\nextnext\relax
   \else
     \let\nextnext\settabulatepreamble
     \ifx      x\next \chardef\tabulatealign=0
     \else\ifx l\next \chardef\tabulatealign=1
     \else\ifx r\next \chardef\tabulatealign=2
     \else\ifx c\next \chardef\tabulatealign=3
     \else\ifx p\next \let\nextnext\gettabulateparagraph
     \else\ifx w\next \let\nextnext\gettabulatewidth
     \else\ifx f\next \let\nextnext\gettabulatefont
     \else\ifx B\next \tabulatefont{\bf}%
     \else\ifx I\next \tabulatefont{\it}%
     \else\ifx S\next \tabulatefont{\sl}%
     \else\ifx T\next \tabulatefont{\tt}%
     \else\ifx R\next \tabulatefont{\rm}%
     \else\ifx m\next \tabulatebmath{$}\tabulateemath{$}%
     \else\ifx M\next \tabulatebmath{$\displaystyle}\tabulateemath{$}%
     \else\ifx h\next \let\nextnext\gettabulatehook
     \else\ifx b\next \let\nextnext\gettabulatebefore
     \else\ifx a\next \let\nextnext\gettabulateafter
     \else\ifx i\next \let\nextnext\gettabulatepreskip
     \else\ifx j\next \let\nextnext\gettabulateposskip
     \else\ifx k\next \let\nextnext\gettabulatepreposskip
     \else\ifx X\next \let\nextnext\gettabulateexit
     \else\ifx e\next \appendtoks\global\tabulateequaltrue\to\tabulatesettings
     \else\ifx ~\next \appendtoks\fixedspaces\to\tabulatesettings
     \else            \message{unknown preamble key [\meaning\next]}%
     \fi\fi\fi \fi\fi\fi\fi\fi \fi\fi\fi\fi\fi \fi\fi\fi\fi\fi \fi\fi\fi\fi\fi
   \fi
   \nextnext}

\def\dogettabulateexit%
  {\let\postabskip\!!zeropoint
   \settabulatepreamble}

\let\gettabulateexit\dogettabulateexit

\def\gettabulatepreskip#1%
  {\doifnumberelse{#1}
     {\scratchdimen=#1\tabulateunit\let\next\empty}
     {\scratchdimen=.5\tabulateunit\def\next{#1}}%
   \edef\pretabskip{\the\scratchdimen}%
   \@EA\settabulatepreamble\next}

\def\gettabulateposskip#1%
  {\doifnumberelse{#1}
     {\scratchdimen=#1\tabulateunit\let\next\empty}
     {\scratchdimen=.5\tabulateunit\def\next{#1}}%
   \edef\postabskip{\the\scratchdimen}%
   \let\gettabulateexit\settabulatepreamble
   \@EA\settabulatepreamble\next}

\def\gettabulatepreposskip#1%
  {\doifnumberelse{#1}
     {\scratchdimen=#1\tabulateunit\let\next\empty}
     {\scratchdimen=.5\tabulateunit\def\next{#1}}%
   \edef\pretabskip{\the\scratchdimen}%
   \let\postabskip\pretabskip
   \let\gettabulateexit\settabulatepreamble
   \@EA\settabulatepreamble\next}

\def\gettabulatehook#1%
  {\setvalue{\@@tabhook@@\tabulatecolumns}{#1}%
   \settabulatepreamble}

\def\gettabulatebefore#1%
  {\tabulatebefore{#1}%
   \settabulatepreamble}

\def\gettabulateafter#1%
  {\tabulateafter{#1}%
   \settabulatepreamble}

\def\gettabulatefont#1%
  {\tabulatefont{#1}%
   \settabulatepreamble}

\def\gettabulatewidth% why was this split = 0 
  {\chardef\tabulatemodus=0
   \doifnextcharelse{(}
     {\chardef\tabulatedimen=0
      \dogettabulatewidth}
     {\chardef\tabulatedimen=0
      \settabulatepreamble}}

%D So: 

\def\gettabulatewidth%
  {\chardef\tabulatemodus=0
   \chardef\tabulatedimen=0
   \doifnextcharelse(\dogettabulatewidth\settabulatepreamble}

\def\gettabulateparagraph%
  {\doifnextcharelse{(}
     {\chardef\tabulatemodus=1
      \chardef\tabulatedimen=1
      \dogettabulatewidth}
     {\chardef\tabulatemodus=2
      \chardef\tabulatedimen=0
      \settabulatepreamble}}

\def\dogettabulatewidth(#1)%
  {\tabulatewidth=#1\relax
   \ifnum\tabulatedimen=1
     \global\advance\tabulatepwidth\tabulatewidth
   \fi
   \settabulatepreamble}

\def\settabulatepreamble%
  {\afterassignment\dosettabulatepreamble\let\next=}

\def\tabulateraggedright {\ifnum\tabulatetype=1 \else\raggedright \fi}
\def\tabulateraggedcenter{\ifnum\tabulatetype=1 \else\raggedcenter\fi}
\def\tabulateraggedleft  {\ifnum\tabulatetype=1 \else\raggedleft  \fi}
\def\tabulatenotragged   {\ifnum\tabulatetype=1 \else\notragged   \fi}
\def\tabulatehss         {\ifnum\tabulatetype=1 \else\hss         \fi}

\def\nexttabulate#1|%
  {\chardef\tabulatealign=\@@tabulatealign
   \chardef\tabulatemodus=0
   \chardef\tabulatedimen=0
   \tabulatebefore  \emptytoks
   \tabulateafter   \emptytoks
   \tabulatebmath   \emptytoks
   \tabulateemath   \emptytoks
   \tabulatefont    \emptytoks
   \tabulatesettings\emptytoks
   \doglobal\increment\tabulatecolumns
   \settabulatepreamble#1\relax\relax % permits i without n
   \ifcase\tabulatemodus\relax
     \ifcase\tabulatealign\relax
       \dodosettabulatepreamble\empty      \tabulatehss   \or
       \dodosettabulatepreamble\empty      \tabulatehss   \or
       \dodosettabulatepreamble\tabulatehss\empty         \or
       \dodosettabulatepreamble\tabulatehss\tabulatehss   \fi
   \or % fixed width
     \ifcase\tabulatealign\relax
       \dodosettabulatepreamble \bskip                      \eskip \or
       \dodosettabulatepreamble{\bskip\tabulateraggedright }\eskip \or
       \dodosettabulatepreamble{\bskip\tabulateraggedleft  }\eskip \or
       \dodosettabulatepreamble{\bskip\tabulateraggedcenter}\eskip \fi
   \or % auto width
     \doglobal\increment\nofautotabulate\relax
     \ifcase\tabulatealign\relax
       \dodosettabulatepreamble \bskip                      \eskip \or
       \dodosettabulatepreamble{\bskip\tabulateraggedright }\eskip \or
       \dodosettabulatepreamble{\bskip\tabulateraggedleft  }\eskip \or
       \dodosettabulatepreamble{\bskip\tabulateraggedcenter}\eskip \fi
   \fi
   \futurelet\next\donexttabulate}

\def\donexttabulate%
  {\ifx\next\relax\else
     \expandafter\nexttabulate
   \fi}

\def\splitofftabulatebox%
  {\dontcomplain
   \@EA\global\@EA\setbox\@EA\tabulatebox\@EA
     \vsplit\csname\@@tabbox@@\tabulatecolumn\endcsname to \lineheight
   \setbox\tabulatebox=\vbox
     {\unvbox\tabulatebox}%
   \setbox\tabulatebox=\hbox to \wd\tabulatebox
     {\hss\dotabulatehook{\box\tabulatebox}\hss}%
   \ht\tabulatebox=\ht\strutbox
   \dp\tabulatebox=\dp\strutbox
   \box\tabulatebox}

\def\dotabulatehook%
  {\getvalue{\@@tabhook@@\tabulatecolumn}}

\def\resettabulatepheight%
  {\xdef\tabulateminplines{1}%
   \getnoflines\tabulatemaxpheight
   \xdef\tabulatemaxplines{\the\noflines}%
   \global\tabulatemaxpheight=\!!zeropoint}

\def\settabulatepheight%
  {\scratchdimen=\ht\csname\@@tabbox@@\tabulatecolumn\endcsname\relax
   \ifdim\scratchdimen>\tabulatemaxpheight 
     \global\tabulatemaxpheight=\scratchdimen 
   \fi}

\def\handletabulatepbreak%
  {\TABLEnoalign
     {\ifhandletabulatepbreak \ifnum\tabulatemaxplines>1 
        \ifnum\tabulateminplines=1 
          \dotabulatenobreak
        \fi
        \doglobal\increment\tabulateminplines
        \ifnum\tabulateminplines=\tabulatemaxplines\relax 
          \dotabulatenobreak
        \fi
      \fi \fi}}

%D \startbuffer 
%D \starttabulatie[|c|p|p|]
%D \NC \bf Alpha \NC \bf Beta        \NC \bf Gamma          \NC\NR
%D \NC 1         \NC right indeed    \NC definitely wrong   \NC\NR
%D \NC 2         \NC \thinrules[n=3] \NC \thinrules[n=3]    \NC\NR
%D \NC 3         \NC oh yes          \NC simply no          \NC\NR
%D \NC 4         \NC very true       \NC as false as can be \NC\NR
%D \NC 5         \NC \thinrules[n=5] \NC \thinrules[n=5]    \NC\NR
%D \NC 6         \NC \thinrules[n=3] \NC \thinrules[n=4]    \NC\NR
%D \stoptabulate
%D \stopbuffer 
%D 
%D \typebuffer {\tracetabulatetrue\haalbuffer}
%D
%D \startbuffer 
%D \starttabulatie[|c|p|p|]
%D \NC \bf Alpha \NC \bf Beta        \NC \bf Gamma          \NC\NR
%D \NC 1         \NC right indeed    \NC definitely wrong   \NC\NR
%D \NC 2         \NC oh yes          \NC simply no          \NC\NR
%D \NC 3         \NC very true       \NC as false as can be \NC\NR
%D \NC 4         \NC the whole truth \NC but the truth      \NC\NR
%D \stoptabulatie
%D \stopbuffer 
%D
%D \typebuffer {\tracetabulatetrue\haalbuffer}

% \definetabulate
% \redefinetabulate
% \starttabulate[preamble]
% \starttabulate -> \starttabulate[|l|p|]

\def\definetabulate%
  {\dotripleempty\dodefinetabulate}

\def\dodefinetabulate[#1][#2][#3]%
  {\ifthirdargument
     \doifundefined{\??tt#1::\c!eenheid}
       {\copyparameters
          [\??tt#1::][\??tt\e!tabulate::]%
          [\c!afstand,\c!eenheid,\c!voor,\c!na,\c!binnen,\c!inspringen,
           \c!uitlijnen,\c!lijnkleur,\c!lijndikte,EQ]}%
     \copyparameters
       [\??tt#1::#2][\??tt#1::]% 
       [\c!eenheid,\c!afstand,\c!voor,\c!na,\c!binnen,\c!inspringen,
        \c!uitlijnen,\c!lijnkleur,\c!lijndikte,EQ]%
     \setvalue{\e!start#1::#2}{\dofinalstarttabulate[#1][#2][#3]}%
     \setvalue{\e!start#1}{\bgroup\dosubstarttabulate[#1]}%
   \else\ifsecondargument
     \definetabulate[#1][][#2]%
   \else
     \definetabulate[#1][][|l|p|]%
   \fi\fi}

\def\dosubstarttabulate%
  {\dodoubleempty\dodosubstarttabulate}

\def\dodosubstarttabulate[#1][#2]%
  {\getvalue{\e!start#1::\ifundefined{\e!start#1::#2}\else#2\fi}}

\setvalue{\e!start\e!tabulate}%
  {\bgroup\dodoubleempty\donormalstarttabulate}

\def\donormalstarttabulate[#1][#2]%
  {\ifsecondargument
     \getparameters[\??tt\e!tabulate::][#2]%
   \fi
   \iffirstargument
     \def\next{\dofinalstarttabulate[\e!tabulate][][#1]}% 
   \else
     \def\next{\dofinalstarttabulate[\e!tabulate][][|l|p|]}% 
   \fi
   \next}

\newtoks\everytabulate 

\def\dofinalstarttabulate[#1][#2][#3]% identifier sub preamble 
  {\edef\currenttabulate{#1::#2}%
   \ifinsidefloat \else
     \witruimte
     \getvalue{\??tt\currenttabulate\c!voor}%
   \fi
   \bgroup 
   \the\everytabulate 
   \getvalue{\??tt\currenttabulate\c!binnen}%
   \scratchdimen=\leftskip
   \advance\scratchdimen by \hangindent
   \doifvalue{\??tt\currenttabulate\c!inspringen}{\v!ja}
     {\advance\scratchdimen by \parindent}% \voorwit
   \edef\tabulateindent{\the\scratchdimen}%
   \!!toksb\emptytoks
   \def\dorepeat*##1##2%
     {\dorecurse{##1}{\appendtoks##2\to\!!toksb}\do}%
   \def\do%
     {\futurelet\next\dodo}%
   \def\dodo%
     {\ifx\next\relax
        % exit
      \else\ifx*\next
        \let\next\dorepeat
      \else\ifx\bgroup\next
        \let\next\dododo
      \else
        \let\next\dodododo
      \fi\fi\fi
      \next}%
   \def\dododo##1%
     {\appendtoks{##1}\to\!!toksb\do}%
   \def\dodododo##1%
     {\appendtoks##1\to\!!toksb\do}%
   \xdef\tabulatecolumn{0}%
   \do#3\relax
   \processcontent
     {\e!stop#1}% \currenttabulate}
     \tabulatecontent
     {\@EA\processtabulate\@EA[\the\!!toksb]}}

\chardef\tabulatetype=0

% 0 = NC column next   EQ equal column 
% 1 = RC column raw    RQ equal column raw   
% 2 = HC column hook   HQ equal column hook 

\def\tabulateEQ%
  {\getvalue{\??tt\currenttabulate EQ}\global\tabulateequalfalse} 

\def\tabulatenormalcolumn#1%
  {&\iftabulateequal\tabulateEQ\fi&\global\chardef\tabulatetype=#1&}

\def\tabulateequalcolumn#1%
  {&\tabulateEQ&\global\chardef\tabulatetype=#1&}

\def\tabulateautocolumn%
  {\tabulatenormalcolumn0\relax
   \ifnum\tabulatecolumn>\tabulatecolumns\relax
     \expandafter\NR
   \else
     \expandafter\ignorespaces % interferes with the more tricky hooks 
   \fi}

\def\setquicktabulate#1% see \startlegend \startgiven 
  {\let#1=\tabulateautocolumn
   \let\\=\tabulateautocolumn}

%\def\tabulateruleseperator
%  {\vskip\dp\strutbox}

\def\tabulateruleseperator%
  {\bgroup
   \def\factor{1}%
   \scratchskip=\dp\strutbox 
   \ExpandFirstAfter\processallactionsinset
     [\getvalue{\??tt\currenttabulate\c!afstand}]
     [ \v!blanko=>\scratchskip=\bigskipamount,
       \v!diepte=>\scratchskip=\dp\strutbox,
        \v!klein=>\def\factor{.25},
       \v!middel=>\def\factor{.5},
        \v!groot=>,
         \v!geen=>\scratchskip=\!!zeropoint\def\factor{0},
      \s!unknown=>\scratchskip=\commalistelement]%
   \scratchdimen=\factor\scratchskip
   \vskip\scratchdimen\relax
   \egroup}

\def\tabulaterule%
  {\color
     [\getvalue{\??tt\currenttabulate\c!lijnkleur}]
     {\scratchdimen=\getvalue{\??tt\currenttabulate\c!lijndikte}%
      \hrule\!!height.5\scratchdimen\!!depth.5\scratchdimen}}

%D When set to true, no (less) break optimization is done. 

\newif\iftolerantTABLEbreak

%D The main processing macro is large but splitting it up 
%D would make things less clear. 

\def\processtabulate[|#1|]% in the process of optimizing
  {\tabulateunit=\getvalue{\??tt\currenttabulate\c!eenheid}%
   \ExpandFirstAfter\processaction 
     [\getvalue{\??tt\currenttabulate\c!uitlijnen}]
     [ \v!rechts=>\def\@@tabulatealign{1},
        \v!links=>\def\@@tabulatealign{2},
       \v!midden=>\def\@@tabulatealign{3},
      \s!default=>\def\@@tabulatealign{0},
      \s!unknown=>\def\@@tabulatealign{0}]%
   \dorecurse\noftabcolumns % NEW
     {\global\setbox\csname\@@tabbox@@\recurselevel\endcsname=\box\voidb@x}%
   \let\pretabskip\!!zeropoint
   \def\postabskip{.5\tabulateunit}%
   \doglobal\newcounter\tabulatecolumns
   \doglobal\newcounter\nofautotabulate
   \doglobal\newcounter\noftabulatelines
   \let\totalnoftabulatelines\noftabulatelines
   \let\minusnoftabulatelines\noftabulatelines
   \global\tabulatepwidth=\!!zeropoint
   \global\tabulateequalfalse
   \resettabulatepheight
   \def\NC{\tabulatenormalcolumn0}%
   \def\RC{\tabulatenormalcolumn1}%
   \def\HC{\tabulatenormalcolumn2}%
   \def\EQ{\tabulateequalcolumn 0}%
   \def\RQ{\tabulateequalcolumn 1}%
   \def\HQ{\tabulateequalcolumn 2}%
   \def\NR% next row
     {\doglobal\increment\noftabulatelines
      \global\tabulateequalfalse
      \xdef\tabulatecolumn{0}%
      \resettabulatepheight
      \unskip\unskip\crcr\flushtabulated
      \TABLEnoalign
        {\iftolerantTABLEbreak\else
           \ifnum\noftabulatelines=1                          
             \dotabulatenobreak
           \else\ifnum\noftabulatelines=\minusnoftabulatelines
             \ifnum\tabulatemaxplines<2 
               \dotabulatenobreak
             \fi
           \fi\fi
         \fi}}%
   \let\HL\empty \let\SR\NR \let\AR\NR
   \let\FL\empty \let\FR\NR
   \let\ML\empty \let\MR\NR
   \let\LL\empty \let\LR\NR
   \global\let\flushtabulated\empty
   \let\savedbar=|\let|=\nexttabulate
   \tabskip\!!zeropoint
   \!!toksa{&\hbox to \tabulateindent{}##\strut&##}%
   \tabulatewidth\!!zeropoint
   |#1X|\relax
   \appendtoks&##\to\!!toksa
   \appendtoks\doglobal\increment\tabulatecolumn\to\!!toksa
   \appendtoks\NC\unskip\unskip\crcr\flushtabulated\to\tabulatedummy % no count
   \xdef\tabulatecolumn{0}%
   \resettabulatepheight
   \def\bskip%
     {\setbox\tabulatebox=\vbox\bgroup
        \global\let\tabulatehook\empty}%
   \def\eskip
     {\par\egroup
      \global\let\tabulatehook\dotabulatehook}%
   \let|\savedbar
   \global\let\tabulatehook\dotabulatehook
   \doifvalue{\??tt\currenttabulate\c!inspringen}{\v!nee}
     {\forgetparindent}%
   \ifinsidefloat
     \let\tabulateindent\!!zeropoint
   \else
     \setlocalhsize \hsize=\localhsize
   \fi
   \dontcomplain
   \forgetall
   \setbox0=\vbox % outside if because of line counting
     {\footnotesenabledfalse
      \let\tabulateindent\!!zeropoint
      \@EA\halign\@EA{\the\!!toksa\cr\tabulatecontent\crcr}}%
   \ifnum\nofautotabulate>0
     \tabulatewidth\hsize
     \advance\tabulatewidth by -\wd0
     \advance\tabulatewidth by -\tabulatepwidth
     \ifnum\nofautotabulate>0
       \divide\tabulatewidth by \nofautotabulate\relax
     \fi
   \fi
   \ifsplittabulate
     \splittopskip\ht\strutbox
     \global\let\flushtabulatedindeed\empty
     \long\def\bbskip%
       {\ifvoid\csname\@@tabbox@@\tabulatecolumn\endcsname
          \ifx\flushtabulatedindeed\empty\else
            \setbox0\hbox
          \fi
       \fi}%
     \def\bskip%
       {\ifvoid\csname\@@tabbox@@\tabulatecolumn\endcsname
          \global\setbox\csname\@@tabbox@@\tabulatecolumn\endcsname=\vbox
          \bgroup
          \global\let\tabulatehook\empty
          \ifautotabulate\hsize\tabulatewidth\fi
         %\begstrut % interferes with pre-\pars
          \ignorespaces
          \def\eskip%
            {\par\egroup
             \settabulatepheight
             \global\let\tabulatehook\dotabulatehook
             \splitofftabulatebox}%
        \else
          \let\eskip\empty
          \dontcomplain
          \global\let\tabulatehook\dotabulatehook
          \expandafter\splitofftabulatebox
        \fi}%
     \gdef\flushtabulated%
       {\TABLEnoalign % noalign % no interference !
          {\global\let\flushtabulatedindeed\empty
           \handletabulatepbreak
           \dorecurse\noftabcolumns
             {\ifvoid\csname\@@tabbox@@\recurselevel\endcsname\else
                \gdef\flushtabulatedindeed{\the\tabulatedummy}%
              \fi}}%
        \flushtabulatedindeed}%
   \else
    % tabhook op alles ?
     \def\bskip%
       {\vtop\bgroup
          \ifautotabulate\hsize\tabulatewidth\fi
         %\begstrut % interferes with pre-\pars
          \ignorespaces}%
     \def\eskip%
       {\par\egroup}%
   \fi
   \let\totalnoftabulatelines\noftabulatelines
   \let\minusnoftabulatelines\noftabulatelines
   \decrement\minusnoftabulatelines
   \doglobal\newcounter\noftabulatelines
   \def\HL{\TABLEnoalign
     {\ifnum\noftabulatelines=0                                 \FL
      \else\ifnum\noftabulatelines<\totalnoftabulatelines\relax \ML
      \else                                                     \LL
      \fi\fi}}%
   \def\tablebaselinecorrection
     {\def\dobaselinecorrection
        {\vskip-\prevdepth
         \vskip\dp\strutbox
         \vskip\dp\strutbox}%
      \baselinecorrection}%
   \def\FL{\TABLEnoalign
     {\ifinsidefloat\else
        \doifemptyvalue{\??tt\currenttabulate\c!voor} % no expansion
          {\tablebaselinecorrection}%
      \fi
      \tabulaterule
      \dotabulatenobreak
      \tabulateruleseperator
      \prevdepth\dp\strutbox
      \dotabulatenobreak}}%
   \def\ML{\TABLEnoalign
     {\tabulateruleseperator
      \tabulaterule
      \ifnum\noftabulatelines>1 \ifnum\noftabulatelines<\minusnoftabulatelines
        \vskip\topskip\allowbreak\vskip-\topskip\vskip-.4pt
        \tabulaterule
      \fi\fi
      \tabulateruleseperator}}%
   \def\LL{\TABLEnoalign
     {\dotabulatenobreak
      \tabulateruleseperator
      \dotabulatenobreak
      \tabulaterule
      \ifinsidefloat\else
        \doifemptyvalue{\??tt\currenttabulate\c!na} % no expansion
          {\vskip\dp\strutbox
           \vbox{\strut}
           \vskip-\lineheight}%
      \fi}}%
   \@EA\halign\@EA{\the\!!toksa\cr\tabulatecontent\crcr}%
   \prevdepth\dp\strutbox % nog eens beter, temporary hack
   \egroup
   \ifinsidefloat \else
     \getvalue{\??tt\currenttabulate\c!na}%
   \fi
   \egroup}

\def\setuptabulate%
  {\dotripleempty\dosetuptabulate}

\def\dosetuptabulate[#1][#2][#3]%
  {\ifthirdargument
     \getparameters[\??tt#1::#2][#3]%
   \else\ifsecondargument
     \getparameters[\??tt#1::][#2]%
   \else
     \getparameters[\??tt\e!tabulate::][#1]%
   \fi\fi}

\setuptabulate
  [\c!eenheid=1em,
   EQ={:},
   \c!lijnkleur=,
   \c!lijndikte=\linewidth,
   \c!binnen=,
   \c!voor=\blanko,
   \c!na=\blanko,
   \c!afstand={\v!diepte,\v!middel},
   \c!uitlijnen=\v!normaal,
   \c!inspringen=\v!nee]

\protect

\endinput
