%D \module
%D   [       file=core-spa,
%D        version=1997.03.31,
%D          title=\CONTEXT\ Core Macros,
%D       subtitle=Spacing,
%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 Spacing Macros}

% to be sorted out: dependencies, order of initialization

\unprotect

\newevery \everybodyfont    \EveryBodyFont   % just to be sure
\newevery \everyfontswitch  \EveryFontSwitch % just to be sure
\newevery \everydefinedfont \relax           % just to be sure

\appendtoks \spacing               1\to \everybodyfont
\appendtoks \presetnormallineheight \to \everybodyfont
\appendtoks \setnormalbaselines     \to \everybodyfont % check if redundant
\appendtoks \setstrut               \to \everybodyfont % check if redundant
\appendtoks \settopskip             \to \everybodyfont
\appendtoks \setmaxdepth            \to \everybodyfont
%appendtoks \spacing               1\to \everybodyfont
\appendtoks \simplesetupindenting   \to \everybodyfont
\appendtoks \simplesetupblank       \to \everybodyfont
\appendtoks \simplesetupwhitespace  \to \everybodyfont
%appendtoks \checknotes             \to \everybodyfont % not
\appendtoks \simplesetupspacing     \to \everybodyfont % nieuw
\appendtoks \setdisplayskips        \to \everybodyfont % nieuw

\appendtoks \setrelativeinterlinespace \to \everybodyfont

\appendtoks \updateraggedskips      \to \everyfontswitch  % under test

\prependtoks \let\par\endgraf       \to \everypagebody % see \fillinline

\appendtoks \simplesetupspacing     \to \everydefinedfont

% if you want to hyphenate the first word of a paragraph ... \appendtoks\hskip0pt\to\everypar

\def\stelfactorenin
  {\simplesetupwhitespace
   \simplesetupblank
   \settopskip
   \setmaxdepth}

\def\softbreak
  {\relax\ifhmode\hskip\parfillskip\break\fi}

\let\poplastnode\relax

\def\pushlastnode
  {\ifdim\lastskip=\zeropoint
     \ifnum\lastpenalty=\zerocount
       \ifnum\lastkern=\zerocount
         \let\poplastnode\relax
       \else
         \edef\poplastnode{\kern\the\lastkern\relax}\kern-\lastkern % untested
       \fi
     \else
       \edef\poplastnode{\penalty\the\lastpenalty\relax}\nobreak % untested
     \fi
   \else
     \edef\poplastnode{\vskip\the\lastskip\relax}\vskip-\lastskip % \removelastskip
   \fi}

%D The dreadful sequence \type {\bgroup} \unknown\
%D \type {\carryoverpar} \unknown\ \type {\egroup} is needed
%D when for instance sidefloats are used in combination with
%D something that starts with a group. This is because
%D otherwise the indentation as set (by the output routine)
%D inside the group are forgotten afterwards. (I must
%D not forget its existence).

\global\let\carriedoverpar\relax

\def\carryoverpar#1%
  {\expanded     % \scratchtoks{#1}%
     {\noexpand#1% \the\scratchtoks
      \hangindent\the\hangindent
      \hangafter \the\hangafter
      \parskip   \the\parskip
      \leftskip  \the\leftskip
      \rightskip \the\rightskip}}

%D A quick way to determine left|/|middle|/|right states
%D (experimental).

\setvalue{\??as\v!left }{0}
\setvalue{\??as\v!middle}{1}
\setvalue{\??as\v!right}{2}

\def\setalignmentswitch#1%
  {\chardef\alignmentswitch0\csname\??as#1\endcsname\relax}

%D There are two ways to influence the interline spacing. The
%D most general and often most consistent way is using
%D
%D \showsetup{setupinterlinespace}
%D
%D For instance
%D
%D \starttyping
%D \setupinterlinespace[line=2.8ex]
%D \stoptyping
%D
%D This setting adapts itself to the bodyfontsize, while for
%D instance saying
%D
%D \starttyping
%D \setupinterlinespace[line=12pt]
%D \stoptyping
%D
%D sets things fixed for all sizes, which is definitely not
%D what we want. Therefore one can also say:
%D
%D \starttyping
%D \definebodyfontenvironment[9pt][interlinespace=11pt]
%D \stoptyping
%D
%D One can still use \type{\setupinterlinespace} (without
%D arguments) to set the interline space according to the
%D current font, e.g. a \type{\bfa}.

\newif\iflocalinterlinespace

% font-ini

\ifx\bodyfontinterlinespecs\undefined

  \let\bodyfontinterlinespecs\empty
  \let\bodyfontinterlinespace\empty

\fi

\def\presetnormallineheight
  {\edef\normallineheight{\@@itline}%
%  done elsewhere : \spacing\!!plusone % new per 10/08/2004, else problems in otr / !! needed
   \iflocalinterlinespace \else
     \doifdefined\bodyfontinterlinespecs
       {\doifsomething\bodyfontinterlinespace
          {\edef\normallineheight{\bodyfontinterlinespace}}}%
   \fi}

\def\setupspecifiedinterlinespace[#1]%
  {\getparameters[\??it][#1]%
   \scratchdimen0\@@itheight\points
   \advance\scratchdimen 0\@@itdepth\points
   \ifdim\scratchdimen>\onepoint
     \showmessage\m!layouts{10}{\@@itheight,\@@itdepth}%
     \let\@@itheight\strutheightfactor
     \let\@@itdepth \strutdepthfactor
   \else
     \let\strutheightfactor\@@itheight
     \let\strutdepthfactor \@@itdepth
   \fi
   \let\minimumstrutheight \@@itminheight
   \let\minimumstrutdepth  \@@itmindepth
   \let\minimumlinedistance\@@itdistance
   \let\normallineheight   \@@itline % let ! ! ! ! ! ivm ex
   \doifelse\@@ittop\v!height % new, topskip does more bad than good
     {\let\topskipfactor   \@@itheight}
     {\let\topskipfactor   \@@ittop   }%
   \let\maxdepthfactor     \@@itbottom
   \let\baselinegluefactor \@@itstretch
   \setfontparameters % redundant, can be \setstrut, test first
   \updateraggedskips} % yes indeed

% \let\currentrelativeinterlinespace\empty
%
% \def\setuprelativeinterlinespace[#1]%
%   {\processallactionsinset
%      [#1]
%      [      \v!on=>\oninterlineskip,
%            \v!off=>\offinterlineskip,
%          \v!reset=>\let\currentrelativeinterlinespace\empty
%                    \setfontparameters,% just \setstrut, test first
%        \s!unknown=>\assignvalue{#1}\currentrelativeinterlinespace{1.00}{1.25}{1.50}%
%                    \spacing\currentrelativeinterlinespace]}

% \setupinterlinespace[big]      \switchtobodyfont[11pt] -> forgotten
% \setupinterlinespace[auto,big] \switchtobodyfont[11pt] -> remembered

\let\currentrelativeinterlinespace\empty

\def\setuprelativeinterlinespace[#1]%
  {\processallactionsinset
     [#1]
     [      \v!on=>\oninterlineskip,
           \v!off=>\offinterlineskip,
         \v!reset=>\let\currentrelativeinterlinespace\empty
                   \let\setrelativeinterlinespace\relax
                   \setfontparameters,
          \v!auto=>\let\setrelativeinterlinespace\dosetrelativeinterlinespace,
       \s!unknown=>\assignvalue\commalistelement\currentrelativeinterlinespace{1.00}{1.25}{1.50}%
                   \spacing\currentrelativeinterlinespace]}

\def\dosetrelativeinterlinespace
  {\ifx\currentrelativeinterlinespace\empty\else
     \spacing\currentrelativeinterlinespace
   \fi}

\let\setrelativeinterlinespace\relax

% \appendtoks \setrelativeinterlinespace \to \everybodyfont

\def\complexsetupinterlinespace[#1]% \commalistelement ipv #1
  {\doifassignmentelse{#1}\setupspecifiedinterlinespace\setuprelativeinterlinespace[#1]}

\def\setuplocalinterlinespace[#1]%
  {\localinterlinespacetrue
   \setupinterlinespace[#1]%
   \localinterlinespacefalse}

\def\simplesetupinterlinespace
  {\localinterlinespacetrue
   \setfontparameters
   \updateraggedskips % funny one here
   \localinterlinespacefalse}

\definecomplexorsimple\setupinterlinespace

% In earlier versions \type{\bigskipamount} was
% \type{\ht\strutbox} and the stretch was plus or minus
% \type{.4\dp\strutbox}. Don't ask me why. The most recent
% implementation is based on a user supplied distance, which
% is by default \type{.75\normalskipamount} where
% \type{\normalskipamount} equals the current baseline
% distance.

% can be conditionals

\newif\ifblanknowhite       \blanknowhitefalse
\newif\ifblankindeed        \blankindeedfalse
\newif\ifblankreset         \blankresetfalse
\newif\ifblankdisable       \blankdisablefalse
\newif\ifblankflexible      \blankflexibletrue
\newif\ifblankouter
\newif\ifblankforce
\newif\ifblankgoback

\newskip\blankskip          \blankskip=\bigskipamount
\newskip\blankskipamount

\def\skipfactor    {.75}
\def\skipgluefactor{.25}

\def\normalskipamount
  {\openlineheight
     \ifgridsnapping \else \ifblankflexible
       \!!plus \skipgluefactor\openlineheight
       \!!minus\skipgluefactor\openlineheight
     \fi \fi
   \relax}

\def\linedistance    {\normalskipamount}
\def\appliedblankskip{\skipfactor\linedistance}
\def\lastblankskip   {\blankskip}
\def\currentblank    {\v!big}
\def\oldprevdepth    {\prevdepth}
\def\newprevdepth    {-1001pt}
\def\mindimen        {1sp} % was: 0.00002pt

\newif\iflocalblankfixed
\newif\iflocalblankflexible
\newif\iffuzzyvskip

\def\geenblanko{\removelastskip} % will become obsolete

%%%% pas op, wordt ook in core-pos gebruikt

\def\doassignsomeskip#1\to#2% ook nog \v!halfline+fuzzysnap
  {\doifelse{#1}\v!line
     {#2\openlineheight}
     {\ifgridsnapping
        \assigndimension{#1}{#2}%
          {.25\openlineheight}{.5\openlineheight}\openlineheight
      \else
        \assigndimension{#1}{#2}%
          \smallskipamount\medskipamount\bigskipamount
      \fi}}

%%%% dus niet weg

% replaced
%
% \def\dosingleblanko#1%
%   {\doassignsomeskip#1\to\blankskipamount
%    \global\advance\blankskip \blankskipamount}
%
% \def\doblank#1%
%   {\processallactionsinset % is maar een actie
%      [#1]
%      [    \v!groot=>\dosingleblanko\v!groot, % happens often
%          \v!buiten=>\ifvmode\ifinner\blankoutertrue\fi\fi,
%           \v!reset=>\global\blankresettrue,
%        \v!flexibel=>\global\localblankflexibletrue,
%            \v!vast=>\global\localblankfixedtrue,
%            \v!back=>\geenblanko,
%             \v!wit=>\global\advance\blankskip \parskip,
%         \v!formule=>\global\advance\blankskip \medskipamount,
%         \v!geenwit=>\global\blanknowhitetrue,
%            -\v!wit=>\global\advance\blankskip -\parskip,
%        \v!blokkeer=>\global\blankdisabletrue,
%         \v!forceer=>\global\blankforcetrue,
%           \v!regel=>\global\advance\blankskip \lineheight,
%      \v!halveregel=>\ifgridsnapping\global\fuzzyvskiptrue\fi
%                     \global\advance\blankskip .5\lineheight,
%         \s!unknown=>\doindirectblanko{#1}]}
%
% \def\docomplexdoblank[#1]% pas op \relax's zijn nodig ivm volgende \if
%   {\global\blankresetfalse
%    \global\blankdisablefalse
%    \global\blanknowhitefalse
%    \global\localblankflexiblefalse
%    \global\localblankfixedfalse
%    \global\blankskip\zeropoint
%    \global\blankforcefalse
%    \blankouterfalse
%    \processcommalist[#1]\doblank
%    \ifdim\blankskip=\zeropoint\relax
%      \iflocalblankflexible \dosingleblanko\currentblank \fi
%      \iflocalblankfixed     \dosingleblanko\currentblank \fi
%    \fi
%    \ifblankouter
%    \else
%      \par
%      \ifvmode          %in pos fonts gaat dit mis
%        \ifblankforce   %\ifdim\prevdepth>\zeropoint\else
%          % -1000pt signals top of page or column (\ejectcolumn)
%          \verticalstrut\kern-\struttotal
%        \fi
%        \ifblankdisable
%          \global\blankindeedfalse
%          \edef\oldprevdepth{\the\prevdepth}%
%          \prevdepth=\newprevdepth
%        \else
%          \global\blankindeedtrue
%        \fi
%        \ifblankreset
%          \global\blankindeedtrue
%          \ifdim\prevdepth=\newprevdepth
%            \prevdepth=\oldprevdepth
%          \fi
%        \fi
%        \ifblankindeed
%          \ifdim\lastskip<\blankskip\relax
%            % else when \blanko[2*groot] + \blanko[3*groot] with parskip
%            % equaling 1*groot, gives a groot=\parskip so adding a small
%            % value makes it distinguishable; can also be done at parskip
%            % setting time (better)
%            \global\advance\blankskip by \mindimen\relax % = skip
%            % test this on 2* + 3* and parskip groot
%            \ifblanknowhite
%              \global\advance\blankskip by -\parskip
%            \else
%              \ifdim\lastskip=\parskip
%              \else  % force this due to previous comment
%                \ifdim\parskip>\zeropoint\relax
%                  \ifdim\blankskip<\parskip\relax
%                    \global\blankskip\zeropoint
%                  \else
%                    \global\advance\blankskip by -\parskip
%                  \fi
%                \fi
%              \fi
%            \fi
%            \ifblankflexible \else
%              \blankskip=1\blankskip
%            \fi
%            \iflocalblankfixed
%              \blankskip=1\blankskip
%            \fi
%            \iflocalblankflexible
%              \blankskip=1\blankskip
%                \!!plus\skipgluefactor\blankskip
%                \!!minus\skipgluefactor\blankskip
%            \fi
%            \ifdim\prevdepth=\newprevdepth
%            \else
%              \iffuzzyvskip
%                \removelastfuzzyvskip
%                \fuzzyvskip\blankskip\relax
%              \else
%                \removelastskip
%                \vskip\blankskip\relax
%              \fi
%            \fi
%          \else
%            \iffuzzyvskip
%              \removelastfuzzyvskip
%              \fuzzyvskip\blankskip\relax
%            \fi
%          \fi
%        \fi
%      \fi
%    \fi
%    \global\fuzzyvskipfalse
%    \presetindentation}
%
% \def\complexdodoblank[#1]%
%   {\flushnotes
%    \ifopelkaar
%      \ifinpagebody
%        \expanded{\docomplexdoblank[#1]}% \expanded=nieuw
%      \else
%        \par
%      \fi
%    \else
%      \expanded{\docomplexdoblank[#1]}% \expanded = nieuw
%    \fi}
%
% % old
% %
% % \def\doindirectblanko#1%
% %   {\ifundefined{\??bo#1}% <-etex \expandafter\ifx\csname\??bo#1\endcsname\relax
% %      \expanded{\complexdodoblank[#1]}%
% %    \else
% %      \expandafter\complexdoblank\expandafter[\csname\??bo#1\endcsname]%
% %    \fi}
% %
% % \def\complexdoblank[#1]% enables [force,8\bodyfontsize]
% %   {\doifinstringelse{,}{#1}
% %      {\expanded{\complexdodoblank[#1]}}
% %      {\doifnumberelse{#1}
% %         {\expanded{\complexdodoblank[#1]}}
% %         {\doindirectblanko{#1}}}}
% %
% % new, more robust
% %
% % \def\doindirectblanko#1%
% %   {\edef\ascii{#1}\convertcommand\ascii\to\ascii
% %    \ifundefined{\??bo\ascii}% <-etex \expandafter\ifx\csname\??bo#1\endcsname\rel
% %      \dorepeatwithcommand[#1]\dosingleblanko
% %    \else
% %      \expandafter\complexdoblank\expandafter[\csname\??bo\ascii\endcsname]%
% %    \fi}
% %
% % even more robust
%
% \def\doindirectblanko#1%
%   {\edef\ascii{#1}\convertcommand\ascii\to\ascii
%    \ifundefined{\??bo\ascii}% <-etex \expandafter\ifx\csname\??bo#1\endcsname
%      \expanded{\dorepeatwithcommand[#1]\noexpand\dosingleblanko}%
%    \else
%      \expandafter\complexdoblank\expandafter[\csname\??bo\ascii\endcsname]%
%    \fi}

% \def\TestBlank[#1]%
%   {blank : {\convertargument#1\to\ascii\tttf\ascii}\blanko[#1]}
%
% \defineblank[whatever][2*big,2*big]
% \TestBlank[]
% \TestBlank[big]
% \TestBlank[2*big]
% \TestBlank[big,big,2*big]
% \TestBlank[big]
% \TestBlank[whatever]
% \TestBlank[2*big,whatever]
% \TestBlank[3\lineheight]

% this will be replaced/enhanced

\def\addblankskip#1#2#3{\global\advance\blankskip#1\ifgridsnapping#3\else#2\fi}

\def\defineblankmethod[#1]#2{\setvalue{\??bo\??bo#1}{#2}}

\defineblankmethod       [\v!big] {\addblankskip+\bigskipamount      \openlineheight}
\defineblankmethod      [-\v!big] {\addblankskip-\bigskipamount      \openlineheight}
\defineblankmethod    [\v!medium] {\addblankskip+\medskipamount   {.5\openlineheight}}
\defineblankmethod   [-\v!medium] {\addblankskip-\medskipamount   {.5\openlineheight}}
\defineblankmethod     [\v!small] {\addblankskip+\smallskipamount{.25\openlineheight}}
\defineblankmethod    [-\v!small] {\addblankskip-\smallskipamount{.25\openlineheight}}
\defineblankmethod     [\v!white] {\addblankskip+\parskip            \openlineheight}
\defineblankmethod    [-\v!white] {\addblankskip-\parskip            \openlineheight}
\defineblankmethod      [\v!line] {\addblankskip+\openlineheight     \openlineheight}
\defineblankmethod     [-\v!line] {\addblankskip-\openlineheight     \openlineheight}

\defineblankmethod   [\v!formula] {\global\advance\blankskip\medskipamount}
\defineblankmethod   [\v!nowhite] {\global\blanknowhitetrue}
\defineblankmethod   [\v!disable] {\global\blankdisabletrue}
\defineblankmethod     [\v!force] {\global\blankforcetrue}
\defineblankmethod     [\v!outer] {\ifvmode\ifinner\blankoutertrue\fi\fi}
\defineblankmethod     [\v!reset] {\global\blankresettrue}
\defineblankmethod  [\v!flexible] {\global\localblankflexibletrue}
\defineblankmethod     [\v!fixed] {\global\localblankfixedtrue}
\defineblankmethod      [\v!back] {\global\blankgobacktrue} % {\geenblanko}
\defineblankmethod  [\v!halfline] {\ifgridsnapping\global\fuzzyvskiptrue\fi
                                     \global\advance\blankskip .5\lineheight}

\defineblankmethod      [\v!none] {\global\blankresettrue}
\defineblankmethod  [\v!joinedup] {\ifvmode\nointerlineskip\fi}

% happens often, so we speed this up:
%
% \defineblankmethod    [2*\v!line] {\addblankskip+{2\openlineheight}{2\openlineheight}}
% \defineblankmethod     [2*\v!big] {\addblankskip+{2\bigskipamount }{2\openlineheight}}
%
% no, with 2\whatever we loose the stretch and shrink! Taco's alternative:

\defineblankmethod
  [2*line]
  {\addblankskip+\openlineheight\openlineheight
   \addblankskip+\openlineheight\openlineheight}

\defineblankmethod
  [2*big]
  {\addblankskip+\bigskipamount\openlineheight
   \addblankskip+\bigskipamount\openlineheight}

% ETEX ! ! !

\beginETEX \ifcsname

\def\doblank#1%
  {\edef\ascii{#1}\convertcommand\ascii\to\ascii
   \ifx\ascii\empty\else
     \ifcsname\??bo\??bo\ascii\endcsname % internal def
       \csname\??bo\??bo\ascii\endcsname
     \else\ifcsname\??bo\ascii\endcsname % user def / slow
       \@EA\rawprocesscommalist\@EA[\csname\??bo\ascii\endcsname]\doblank\relax
     \else
       \dorepeatwithcommand[#1]\redoblank
     \fi\fi
   \fi}

\def\redoblank#1%
  {\edef\ascii{#1}\convertcommand\ascii\to\ascii
   \ifx\ascii\empty\else
     \ifcsname\??bo\??bo\ascii\endcsname % internal def
       \csname\??bo\??bo\ascii\endcsname
     \else\ifcsname\??bo\ascii\endcsname % user def / slow
       \@EA\rawprocesscommalist\@EA[\csname\??bo\ascii\endcsname]\doblank\relax
     \else
       \global\advance\blankskip#1\relax
     \fi\fi
   \fi}

\endETEX

\beginTEX

\def\doblank#1%
  {\edef\ascii{#1}\convertcommand\ascii\to\ascii
   \ifx\ascii\empty\else
     \@EA\ifx\csname\??bo\??bo\ascii\endcsname\relax
       \@EA\ifx\csname\??bo\ascii\endcsname\relax
         \dorepeatwithcommand[#1]\redoblank
       \else
         \@EA\rawprocesscommalist\@EA[\csname\??bo\ascii\endcsname]\doblank\relax
       \fi
     \else
       \csname\??bo\??bo\ascii\endcsname
     \fi
   \fi}

\def\redoblank#1%
  {\edef\ascii{#1}\convertcommand\ascii\to\ascii
   \ifx\ascii\empty\else
     \@EA\ifx\csname\??bo\??bo\ascii\endcsname\relax
       \@EA\ifx\csname\??bo\ascii\endcsname\relax
         \global\advance\blankskip#1\relax
       \else
         \@EA\rawprocesscommalist\@EA[\csname\??bo\ascii\endcsname]\doblank\relax
       \fi
     \else
       \csname\??bo\??bo\ascii\endcsname
     \fi
   \fi}

\endTEX

\unexpanded\def\blank % the \relax is definitely needed due to the many \if's
  {\relax\complexorsimple\doblank}

% \def\complexdoblank
%   {\flushnotes
%    \ifmmode
%      \let\next\nocomplexdoblank
%    \else
%      \ifopelkaar
%        \ifinpagebody
%          \let\next\docomplexdoblank
%        \else
%          \let\next\nocomplexdoblank
%        \fi
%      \else
%        \let\next\docomplexdoblank
%      \fi
%    \fi
%    \next}
%
% with \next removed

\def\complexdoblank
  {\flushnotes
   \ifmmode
     \@EA\nocomplexdoblank
   \else
     \ifopelkaar
       \ifinpagebody
         \@EA\@EAEAEA\@EA\docomplexdoblank
       \else
         \@EA\@EAEAEA\@EA\nocomplexdoblank
       \fi
     \else
       \@EAEAEA\docomplexdoblank
     \fi
   \fi}

\def\nocomplexdoblank[#1]%
  {% evt blokkeerfalse
   \ifmmode\else\par\fi}

% Overloaded in cont-new!

\newsignal\noblanksignal

% \def\doinhibitblank
%   {\kern\noblanksignal}

% \def\inhibitblank% the fast, local way
%   {\endgraf\ifvmode\prevdepth\newprevdepth\fi}

% \def\docomplexdoblank[#1]% pas op \relax's zijn nodig ivm volgende \if
%   {\global\blankresetfalse
%    \global\blankdisablefalse
%    \global\blanknowhitefalse
%    \global\localblankflexiblefalse
%    \global\localblankfixedfalse
%    \global\blankskip\zeropoint
%    \global\blankforcefalse
%    \global\blankgobackfalse
%    \blankouterfalse
%    \expanded{\rawprocesscommalist[#1]}\doblank
%    \ifdim\blankskip=\zeropoint\relax
%      \iflocalblankflexible
%        \doglobal\advance\blankskip \currentblank
%      \else\iflocalblankfixed
%        \doglobal\advance\blankskip \currentblank
%      \fi\fi
%    \fi
%    \ifblankouter
%    \else
%      \par
%      \ifvmode
%        \ifblankgoback
%          \removelastskip
%        \fi
%        \ifblankforce
%          % dit gaat mis in pos fonts
%          % \ifdim\prevdepth>\zeropoint\else ...
%          % -1000pt signals top of page or column (\ejectcolumn)
%          \bgroup\forgeteverypar\verticalstrut\egroup\kern-\struttotal
%        \fi
%        \ifblankdisable
%          \global\blankindeedfalse
%          \ifgridsnapping
%            \ifdim\prevdepth<\zeropoint
%              % brrr
%            \else
%              % dirty trick: smaller blanks are ignored after
%              % a larger one, so 10 lines is probably safe; first make
%              % sure that we honor penalties
%              \scratchcounter\lastpenalty
%              % now comes the trick (cross our fingers that this works
%              % well in multi columns; maybe an ifinner test is needed
%              % \vskip-10\lineheight
%              %    \ifnum\scratchcounter=\zerocount \else \penalty\lastpenalty \fi
%              %    \vskip 10\lineheight
%              % allas, this leads to overfull pages, so we try this:
%              \kern-\noblanksignal
%              \ifnum\scratchcounter=\zerocount
%              \else
%                \penalty\lastpenalty
%              \fi
%              \kern\noblanksignal
%              % end-of-dirty-trick
%            \fi
%          \else
%            \ifdim\prevdepth<\zeropoint
%              % brrr
%            \else
%              % ensure at least a proper prevdepth, this should be
%              % an option
%              \vskip-\prevdepth
%              \vskip\strutdepth
%              \prevdepth\strutdepth
%            \fi
%            % the old crappy piece of code
%            \edef\oldprevdepth{\the\prevdepth}%
%            \prevdepth\newprevdepth
%          \fi
%        \else
%          \global\blankindeedtrue
%        \fi
%        \ifblankreset
%          \global\blankindeedtrue
%          \ifgridsnapping
%             % let's play safe and not fool around with the depth, if
%             % only because it took a lot of effort to sort out the grid
%             % stuff in the first place
%          \else
%            \ifdim\prevdepth=\newprevdepth
%              \prevdepth\oldprevdepth
%            \fi
%          \fi
%        \fi
%        \ifblankindeed
%          \ifdim1\lastskip<1\blankskip\relax
%            % else when \blanko[2*groot] + \blanko[3*groot] with parskip
%            % equaling 1*groot, gives a groot=\parskip so adding a small
%            % value makes it distinguishable; can also be done at parskip
%            % setting time (better)
%            \global\advance\blankskip \mindimen\relax % = skip
%            % test this on 2* + 3* and parskip groot
%            \ifblanknowhite
%              \global\advance\blankskip -\parskip
%            \else
%              \ifdim\lastskip=\parskip
%              \else  % force this due to previous comment
%                \ifdim\parskip>\zeropoint\relax
%                  \ifdim\blankskip<\parskip\relax
%                    \global\blankskip\zeropoint
%                  \else
%                    \global\advance\blankskip -\parskip
%                  \fi
%                \fi
%              \fi
%            \fi
%            \ifblankflexible \else
%              \blankskip1\blankskip
%            \fi
%            \iflocalblankfixed
%              \blankskip1\blankskip
%            \fi
%            \iflocalblankflexible
%              \blankskip1\blankskip
%                \!!plus\skipgluefactor\blankskip
%                \!!minus\skipgluefactor\blankskip
%            \fi
%            \ifdim\lastkern=\noblanksignal % controled and grid
%              \global\blankindeedfalse
%            \else\ifgridsnapping\else\ifdim\prevdepth=\newprevdepth
%              \global\blankindeedfalse
%            \fi\fi\fi
%            \ifblankindeed
%              \iffuzzyvskip
%                \removelastfuzzyvskip
%                \fuzzyvskip\blankskip\relax
%              \else
%                \removelastskip
%                \vskip\blankskip\relax
%              \fi
%            \fi
%          \else
%            \iffuzzyvskip
%              \removelastfuzzyvskip
%              \fuzzyvskip\blankskip\relax
%            \else
%              % new, test this on pascal
%              \ifdim\blankskip<\zeropoint
%                \advance\blankskip-\lastskip
%                \removelastskip
%                \ifdim\blankskip>\zeropoint
%                  \vskip\blankskip
%                \else
%                  \vskip\zeropoint
%                \fi
%              \else
%                % also new
%                \ifdim\blankskip=\zeropoint
%                  \ifblanknowhite
%                    \geenwitruimte
%                  \fi
%                \fi
%              \fi
%            \fi
%          \fi
%        \fi
%      \fi
%    \fi
%    \global\fuzzyvskipfalse
%    \presetindentation}

% goback was broken:

% \def\doinhibitblank
%   {\kern\noblanksignal}

% \def\inhibitblank% the fast, local way
%   {\endgraf\ifvmode\prevdepth\newprevdepth\fi}

% problem: we cannot look back in the mvl so we need 3 kinds of signals

\def\noblankpsignal{1010101}

\def\inhibitgridblank % was doinhibitblank
  {\ifvmode\else\endgraf\fi
   \ifvmode
     \ifnum\lastpenalty<10000
       \kern-\noblanksignal % new
       \kern \noblanksignal
     \else
       \penalty\noblankpsignal
     \fi
   \fi}

\def\inhibittextblank % was inhibitblank
  {\endgraf
   \ifvmode
     \prevdepth\newprevdepth
   \fi}

% new macro
%
% \def\inhibitblank % need some work
%   {\endgraf
%    \ifvmode
%      \ifgridsnapping
%        \inhibitgridblank
%      \else
%        % this one spoils the grid
%        \inhibittextblank
%      \fi
%    \fi}

\def\doinhibitblank{\inhibitgridblank}
\def\inhibitblank  {\inhibittextblank}

% will become obsolete

\ifx\undefined\savedlastskip    \newskip \savedlastskip    \fi
\ifx\undefined\savedlastpenalty \newcount\savedlastpenalty \fi

% beware, prevdepth can have funny values (e.g. mvl value when in box)

\def\docomplexdoblank[#1]% pas op \relax's zijn nodig ivm volgende \if
  {\global\blankresetfalse
   \global\blankdisablefalse
   \global\blanknowhitefalse
   \global\localblankflexiblefalse
   \global\localblankfixedfalse
   \global\blankforcefalse
   \global\blankgobackfalse
   \blankouterfalse
   \global\blankskip\zeropoint
   \expanded{\rawprocesscommalist[#1]}\doblank
   \ifdim\blankskip=\zeropoint\relax
     \iflocalblankflexible
       \doglobal\advance\blankskip \currentblank
     \else\iflocalblankfixed
       \doglobal\advance\blankskip \currentblank
     \fi\fi
   \fi
   \ifblankouter
     % do nothing
   \else
     \par
     \ifvmode
       \ifblankgoback
         \ifdim\lastskip>\zeropoint \vskip-\lastskip \fi
           \savedlastskip\zeropoint
         \else\ifdim\lastskip>\zeropoint
           \savedlastskip\lastskip
         \else % todo: lastnode, dan namelijk geen skip !
           \savedlastskip\zeropoint
       \fi\fi
       \ifblankforce
         % dit gaat mis in pos fonts
         % \ifdim\prevdepth>\zeropoint\else ...
         % -1000pt signals top of page or column (\ejectcolumn)
         \bgroup\forgeteverypar\verticalstrut\egroup\kern-\struttotal
         \savedlastskip\zeropoint
       \fi
       \savedlastpenalty\lastpenalty % hm, now it gets lost
       \ifblankdisable
         \global\blankindeedfalse % keep this, i.e. disable current too
         \ifgridsnapping
           \ifdim\prevdepth<\zeropoint
             % brrr
           \else
             % dirty trick: smaller blanks are ignored after a
             % larger one, so 10 lines is probably safe; we need
             % to make sure that we honor penalties; here comes the
             % trick (cross our fingers that this works well in
             % multi columns; maybe an ifinner test is needed
             %  \scratchcounter\lastpenalty
             %  \vskip-10\lineheight
             %  \ifnum\scratchcounter=\zerocount \else \penalty\lastpenalty \fi
             %  \vskip 10\lineheight
             % alas, this leads to overfull pages, so we try this:
             \inhibitgridblank
           \fi
         \else
           \ifdim\prevdepth<\zeropoint
             % brrr
           \else
             % ensure at least a proper prevdepth, this should be
             % an option
             \vskip-\prevdepth
             \vskip\strutdepth
             \prevdepth\strutdepth
           \fi
           % the old crappy piece of code
           \edef\oldprevdepth{\the\prevdepth}%
           \prevdepth\newprevdepth % == \inhibittextblank
         \fi
       \else
         \global\blankindeedtrue
       \fi
       \ifblankreset
         \global\blankindeedtrue
         \ifgridsnapping
            % let's play safe and not fool around with the depth, if
            % only because it took a lot of effort to sort out the grid
            % stuff in the first place
         \else
           \ifdim\prevdepth=\newprevdepth
             \prevdepth\oldprevdepth
           \fi
         \fi
       \fi
       \ifblankindeed
         \ifdim1\savedlastskip<1\blankskip\relax
           % else when \blank[2*groot] + \blank[3*groot] with parskip
           % equaling 1*groot, gives a groot=\parskip so adding a small
           % value makes it distinguishable; can also be done at parskip
           % setting time (better)
           \global\advance\blankskip \mindimen\relax % = skip
           % test this on 2* + 3* and parskip groot
           \ifblanknowhite
             \global\advance\blankskip -\parskip
           \else
             \ifdim\savedlastskip=\parskip
             \else  % force this due to previous comment
               \ifdim\parskip>\zeropoint\relax
                 \ifdim\blankskip<\parskip\relax
                   \global\blankskip\zeropoint
                 \else
                   \global\advance\blankskip -\parskip
                 \fi
               \fi
             \fi
           \fi
           \ifblankflexible \else
             \blankskip1\blankskip
           \fi
           \iflocalblankfixed
             \blankskip1\blankskip
           \fi
           \iflocalblankflexible
             \blankskip1\blankskip
               \!!plus \skipgluefactor\blankskip
               \!!minus\skipgluefactor\blankskip
           \fi
           \ifdim\lastkern=\noblanksignal\relax % controlled and grid
             \global\blankindeedfalse
           \else\ifnum\savedlastpenalty=\noblankpsignal\relax % controlled and grid
             \global\blankindeedfalse
           \else\ifgridsnapping\else\ifdim\prevdepth=\newprevdepth
             \global\blankindeedfalse
           \fi\fi\fi\fi
           \ifblankindeed
             \iffuzzyvskip
               \removelastfuzzyvskip
               \fuzzyvskip\blankskip\relax
             \else
               \relax\ifdim\savedlastskip=\zeropoint\else
                 \vskip-\savedlastskip
               \fi
               \vskip\blankskip\relax
             \fi
           \fi
         \else
           \iffuzzyvskip
             \removelastfuzzyvskip
             \fuzzyvskip\blankskip\relax
           \else
             % new, test this on pascal
             \ifdim\blankskip<\zeropoint
               \relax\ifdim\savedlastskip=\zeropoint\else
                 \advance\blankskip-\savedlastskip
                 \vskip-\savedlastskip
               \fi
               \ifdim\blankskip>\zeropoint
                 \vskip\blankskip
               \else
                 \vskip\zeropoint
               \fi
             \else
               % also new
               \ifdim\blankskip=\zeropoint
                 \ifblanknowhite
                   \nowhitespace
                 \fi
               \fi
             \fi
           \fi
         \fi
       \fi
     \fi
   \fi
   \global\fuzzyvskipfalse
   \presetindentation}

%D For a long time we had:
%D
%D \starttyping
%D \def\simpledoblank%
%D   {\doifelse{\currentwhitespace}{\v!geen}
%D      {\blank[\currentblank]}
%D      {\blank[\currentwhitespace]}}
%D \stoptyping
%D
%D But Berend de Boer wanted more control, so now we have:

\def\simpledoblank % ...
  {\doifelse\currentwhitespace\v!none
     {\blank[\currentblank]}
     {\blank[\s!default]}}

%D Another useful definition would be:
%D
%D \starttyping
%D \defineblank
%D   [\s!default]
%D   [\v!groot]
%D \stoptyping

\def\dosetupblank#1% amount are an plain inheritance
  {\bigskipamount#1\relax
   \ifblankflexible \else
     \bigskipamount1\bigskipamount
   \fi
   \medskipamount  \bigskipamount \divide\medskipamount  \plustwo
   \smallskipamount\bigskipamount \divide\smallskipamount\plusfour}%

\def\complexsetupblank[#1]% more \let's
  {\ifgridsnapping
     \blankflexiblefalse
   \else
     \ExpandFirstAfter\processallactionsinset
       [#1]
       [ \v!flexible=>\blankflexibletrue,
            \v!fixed=>\blankflexiblefalse]%
   \fi
   \ExpandFirstAfter\processallactionsinset
     [#1]
     [ \v!flexible=>\dosetupblank\appliedblankskip,
          \v!fixed=>\dosetupblank\appliedblankskip,
           \v!line=>\edef\appliedblankskip{\linedistance}%
                    \dosetupblank\appliedblankskip
                    ,%\let\deblanko\v!big,
       \v!halfline=>\scratchskip.5\linedistance
                    \edef\appliedblankskip{\the\scratchskip}%
                    \dosetupblank\appliedblankskip
                    ,%\let\deblanko\v!medium,
            \v!big=>\ifgridsnapping
                      \edef\appliedblankskip{\linedistance}%
                      \dosetupblank\appliedblankskip
                    \fi
                    \let\currentblank\v!big  % was \def, why ?
                    ,%\let\deblanko\v!big,
         \v!medium=>\let\currentblank\v!medium % was \def, why ?
                    ,%\let\deblanko\v!medium,
          \v!small=>\let\currentblank\v!small  % was \def, why ?
                    ,%\let\deblanko\v!small,
         \v!normal=>\dosetupblank\appliedblankskip
                    ,%\let\deblanko\v!big,
       \v!standard=>\edef\appliedblankskip{\skipfactor\linedistance}%
                    \dosetupblank\appliedblankskip
                    ,%\let\deblanko\v!big,
        \s!default=>\dosetupblank\appliedblankskip
                    ,%\let\deblanko\v!big,
        \s!unknown=>\let\appliedblankskip\commalistelement
                    \dosetupblank\appliedblankskip
                    ]%\let\deblanko\v!big]%
   \simplesetupwhitespace}

% \definecomplexorsimpleempty\setupblank
%
% speed gain: 60 sec -> 30 sec

\definecomplexorsimple\setupblank

\def\simplesetupblank % == snelle \setupblank[\s!default]
  {\ifgridsnapping
     \blankflexiblefalse
   \fi
   \dosetupblank\appliedblankskip
   % \let\deblanko\v!big
   \simplesetupwhitespace}

\def\restorestandardblank% \v!standard
  {\edef\appliedblankskip{\skipfactor\linedistance}%
   \dosetupblank\appliedblankskip
   }%\let\deblanko\v!big}

\def\dodefineblank[#1][#2]%
  {\def\docommando##1{\setvalue{\??bo##1}{#2}}%
   \processcommalist[#1]\docommando}

\def\defineblank
  {\dodoubleargument\dodefineblank}

\def\savecurrentblank
  {\edef\restorecurrentblank
     {\bigskipamount\the\bigskipamount
      \medskipamount\the\medskipamount
      \smallskipamount\the\smallskipamount
      \noexpand\def\noexpand\currentblank{\currentblank}%
      \ifblankflexible
        \noexpand\blankflexibletrue
      \else
        \noexpand\blankflexiblefalse
      \fi}}

%D Now.

\defineblank [\s!default] [\v!white]
\defineblank [\v!height]  [\strutheight]
\defineblank [\v!depth]   [\strutdepth]

% old implementation
%
% \let\currentindentation=\empty
%
% \newdimen\ctxparindent
%
% \newif\ifindentfirstparagraph % \indentfirstparagraphtrue
%
% \def\presetindentation
%   {\doifoutervmode{\ifindentfirstparagraph\else\noindentation\fi}}
%
% \definecomplexorsimple\setupindenting
%
% \def\complexsetupindenting[#1]%
%   {\processallactionsinset
%      [#1]
%      [  \v!first=>\indentfirstparagraphtrue,
%          \v!next=>\indentfirstparagraphfalse,
%       \s!default=>\simplesetupindenting,
%       \s!unknown=>\edef\currentindentation{\commalistelement}%
%                   \simplesetupindenting]}
%
% \def\simplesetupindenting
%   {\assigndimension\currentindentation\ctxparindent{1em}{1.5em}{2em}%
%    \parindent\ctxparindent\relax}
%
% \def\indenting % watch out: \dodo and no \do
%   {\dosingleargument\dodoindenting}
%
% \def\dodoindenting[#1]% oeps, we needed a commalist handler here!
%   {\edef\currentindenting{#1}%
%    \processcommacommand[#1]\dododoindenting}
%
% \def\dododoindenting#1%
%   {\executeifdefined{\??in:#1}\donothing}
%
% \let\currentindenting\empty
%
% \def\defineindentingmethod[#1]#2%
%   {\setvalue{\??in:#1}{#2}}
%
% \defineindentingmethod [\v!no]     {\parindent\ctxparindent\noindent}
% \defineindentingmethod [\v!not]    {\parindent\ctxparindent\noindent}
%
% \defineindentingmethod [\v!first]  {\indentfirstparagraphtrue}
% \defineindentingmethod [\v!next]   {\indentfirstparagraphfalse}
%
% \defineindentingmethod [\v!yes]    {\parindent\ctxparindent\relax}   % no \indent !
% \defineindentingmethod [\v!always] {\parindent\ctxparindent\relax}   % no \indent !
%
% \defineindentingmethod [\v!never]  {\parindent\zeropoint\relax} % no \indent !
%
% \def\noindenting{\indenting[\v!no,\v!next]}   % was \nietinspringen
% \def\doindenting{\indenting[\v!yes,\v!first]} % was \welinspringen
%
% \def\dochecknextindentation#1% internal one
%   {\checknextindentation[\getvalue{#1\c!indentnext}]}
%
% \def\checknextindentation[#1]%
%   {\processaction[#1][%\v!keep=>,
%      \v!yes=>\doindentation,
%       \v!no=>\noindentation,
%     \v!auto=>\autoindentation]}
%
% \def\doindentation% too simple
%   {\gdef\checkindentation{\global\indentationtrue}}
%
% \ifx\autoindentation\undefined
%   \let\autoindentation\relax
% \fi
%
% \newif\ifindentation \indentationtrue  % documenteren, naar buiten
%
% \let\checkindentation=\relax
%
% \def\donoindentation
%   {\ifdim\parindent=\zeropoint \else
%      \bgroup \setbox\scratchbox\lastbox \egroup
%    \fi}
%
% \def\noindentation % made global
%   {\ifinpagebody \else
%      \global\indentationfalse
%      \gdef\checkindentation
%        {\donoindentation
%         \gdef\checkindentation{\global\indentationtrue}}%
%    \fi}
%
% \def\nonoindentation % bv bij floats
%   {\ifinpagebody \else
%      \global\indentationtrue
%      \gdef\checkindentation{\global\indentationtrue}%
%    \fi}
%
% \def\indentation
%   {\ifvmode \ifdim\parindent=\zeropoint \else
%      % was : \hskip\parindent
%      % can be: \indent
%      % but we test:
%      \noindent\hskip\parindent
%    \fi \fi}

\let\currentindentation\empty % amount/keyword
% \let\normalindentation \empty % used for reinstating normal indentation
\let\currentindenting  \empty % method

\newdimen\ctxparindent

\newif\ifindentfirstparagraph % \indentfirstparagraphtrue

\chardef\indentingtoggle\zerocount

%D After a blank or comparable situation (left side floats) we
%D need to check if the next paragraph has to be indented.

\def\presetindentation
  {\doifoutervmode{\ifindentfirstparagraph\else\noindentation\fi}}

%D This sets up the (normally) global indentation behavior as well
%D as the amounts.

\definecomplexorsimple\setupindenting

% \def\complexsetupindenting[#1]%
%   {\edef\currentindenting{#1}%
%    \indentfirstparagraphtrue
%    \parindent\ctxparindent
%    \chardef\indentingtoggle\zerocount
%    \processcommalist[#1]\docomplexsetupindenting
%    \ifindentfirstparagraph\else\noindentation\fi % added
%    \toggleindentation}

\indentfirstparagraphtrue
\parindent\ctxparindent
\chardef\indentingtoggle\zerocount

% \newtoks\savedeverypar \savedeverypar\everypar
% \def\restoreeverypar{\everypar\savedeverypar}

% we need a better everypar model: for each option a switch, which we
% set to false with \forgetall and can enable when needed (context 4);
% that way we can control the order of execution of options

\def\checkeverypar % currently a hack
  {\ifzeropt\parindent\else
     \doifsometokselse\everypar\donothing{\appendtoks\checkindentation\to\everypar}%
   \fi}

\def\complexsetupindenting[#1]%
  {\edef\currentindenting{#1}%
   \doifsomething\currentindenting % handy when a parameter is passed
     {% not here: \indentfirstparagraphtrue
      % not here: \parindent\ctxparindent
      % not here: \chardef\indentingtoggle\zerocount
      % we use commacommand in order to catch #1 being a command (expanded parameter)
      \processcommacommand[\currentindenting]\docomplexsetupindentingA % catch small, medium, etc
      \processcommacommand[\currentindenting]\docomplexsetupindentingB % catch rest
      \checkeverypar % only when non-empty #1
      \ifindentfirstparagraph\else\noindentation\fi % added
      \toggleindentation}}

\def\docomplexsetupindentingA#1%
  {\edef\!!stringa{#1}% catch #1=\somedimen
   \convertcommand\!!stringa\to\!!stringa
   \doifundefined{\??in:\!!stringa}%
     {\edef\currentindentation{#1}%
      \let\normalindentation\currentindentation
      \simplesetupindenting}}

\def\docomplexsetupindentingB#1%
  {\edef\!!stringa{#1}% catch #1=\somedimen
   \convertcommand\!!stringa\to\!!stringa
   \executeifdefined{\??in:\!!stringa}\donothing}

\def\simplesetupindenting % empty case, a it strange, needed this way?
  {\assigndimension\currentindentation\ctxparindent{1em}{1.5em}{2em}}

\def\indenting % kind of obsolete
  {\dosingleargument\complexsetupindenting}

% use \noindentation to suppress next indentation

\def\defineindentingmethod[#1]#2%
  {\setvalue{\??in:#1}{#2}}

\defineindentingmethod [\v!no]     {\parindent\zeropoint}% was: \ctxparindent\noindent}
\defineindentingmethod [\v!not]    {\parindent\zeropoint}% was: \ctxparindent\noindent}

\defineindentingmethod [\v!first]  {\indentfirstparagraphtrue}
\defineindentingmethod [\v!next]   {\indentfirstparagraphfalse}

\defineindentingmethod [\v!yes]    {\parindent\ctxparindent\relax} % no \indent !
\defineindentingmethod [\v!always] {\parindent\ctxparindent\relax} % no \indent !

\defineindentingmethod [\v!never]  {\parindent\zeropoint\relax     % no \indent !
                                    \chardef\indentingtoggle\zerocount}

\defineindentingmethod [\v!odd]    {\chardef\indentingtoggle\plusone}
\defineindentingmethod [\v!even]   {\chardef\indentingtoggle\plustwo}

\defineindentingmethod [\v!normal] {\ifx\normalindentation\empty\else
                                      \let\currentindentation\normalindentation
                                      \simplesetupindenting
                                    \fi}

\defineindentingmethod [\v!reset]  {\indentfirstparagraphtrue
                                    \parindent\zerocount
                                    \chardef\indentingtoggle\zerocount}

\def\noindenting{\indenting[\v!no, \v!next ]}
\def\doindenting{\indenting[\v!yes,\v!first]}

%D This one sets up the local indentation behaviour (i.e. either or not
%D a next paragraph will be indented).

\def\dochecknextindentation#1% internal one
  {\checknextindentation[\getvalue{#1\c!indentnext}]}

\def\checknextindentation[#1]%
  {\processaction
     [#1]
     [%\v!keep=>,
        \v!yes=>\doindentation,
         \v!no=>\noindentation,
       \v!auto=>\autoindentation]}

%D Here come the handlers.

\newif\ifindentation \indentationtrue  % documenteren, naar buiten

\let\checkindentation\relax

\ifx\autoindentation\undefined \let\autoindentation\relax \fi % hook

\def\doindentation
  {\gdef\checkindentation{\global\indentationtrue}}

\def\noindentation % made global
  {\ifinpagebody \else
     \global\indentationfalse
     \gdef\checkindentation
       {\donoindentation
        \gdef\checkindentation{\global\indentationtrue}}%
   \fi}

\def\nonoindentation % bv bij floats
  {\ifinpagebody \else
     \global\indentationtrue
     \gdef\checkindentation{\global\indentationtrue}%
   \fi}

\def\donoindentation
  {\ifdim\parindent=\zeropoint \else
     \bgroup \setbox\scratchbox\lastbox \egroup
   \fi}

\def\indentation
  {\ifvmode \ifdim\parindent=\zeropoint \else
     % was : \hskip\parindent
     % can be: \indent
     % but we test:
     \noindent\hskip\parindent
   \fi \fi}

\def\toggleindentation
  {\ifcase\indentingtoggle
     % nothing
   \or
     \notoggleindentation
   \or
     \dotoggleindentation
   \fi}

\def\dokillindentation
  {\gdef\checkindentation{\global\indentationfalse\donoindentation}}

\def\dotoggleindentation
  {\gdef\checkindentation{\global\indentationfalse\notoggleindentation\donoindentation}}

\def\notoggleindentation
  {\gdef\checkindentation{\global\indentationtrue\dotoggleindentation}}

% we need to save the state if we want to adapt behaviour to empty lines
%
% \def\setlasthvmode
%   {\global\chardef\savedhvmode\ifhmode\plusone\else\ifvmode\plustwo\else\zerocount\fi\fi}
%
% \def\resetlasthvmode
%   {\global\chardef\savedhvmode\zerocount}
%
% \chardef\savedhvmode\zerocount

% This is a user requested hack (using the auto-hook).

\chardef\recheckindentationmode\zerocount

\def\dontrechecknextindentation
  {\global\chardef\recheckindentationmode\zerocount}

\def\dorechecknextindentation
  {\ifcase\recheckindentationmode
     % nothing
   \or
     \dontrechecknextindentation
     \expandafter\doautoindentation
   \fi}

\def\doautoindentation
  {\doifnextcharelse\par\donothing\noindentation}

\def\autoindentation
  {\global\chardef\recheckindentationmode\plusone}

%D An example of usage:
%D
%D \starttyping
%D \setupindenting[small,yes]
%D
%D \setupitemize [indentnext=auto]
%D \setuptyping  [indentnext=auto]
%D \setupformulas[indentnext=auto]
%D
%D \input tufte
%D
%D \startitemize
%D \item itemize
%D \stopitemize
%D \input tufte
%D
%D \startitemize
%D \item itemize
%D \stopitemize
%D
%D \input tufte
%D
%D \startitemize
%D \item itemize
%D \stopitemize
%D
%D \page
%D
%D \input tufte
%D
%D \starttyping
%D verbatim
%D \stoptyping
%D \input tufte
%D
%D \starttyping
%D verbatim
%D \stoptyping
%D
%D \input tufte
%D
%D \starttyping
%D verbatim
%D \stoptyping
%D
%D \page
%D
%D \input tufte
%D
%D \startformula
%D a = b
%D \stopformula
%D \input tufte
%D
%D \startformula
%D a = b
%D \stopformula
%D
%D \input tufte
%D
%D \startformula
%D a = b
%D \stopformula

% \frenchspacing leidt soms tot afbreken tussen -, vandaar
% de variant \newfrenchspacing.

\def\dofrenchspacing#1%
  {\sfcode`\.#1 \sfcode`\,#1\relax
   \sfcode`\?#1 \sfcode`\!#1\relax
   \sfcode`\:#1 \sfcode`\;#1\relax}

\def\frenchspacing   {\dofrenchspacing{1000}}
\def\newfrenchspacing{\dofrenchspacing{1050}}

\def\nonfrenchspacing
  {\sfcode`\.3000 \sfcode`\,1250
   \sfcode`\?3000 \sfcode`\!3000
   \sfcode`\:2000 \sfcode`\;1500 }

\def\definespacingmethod[#1]#2{\setvalue{\??sg\??sg#1}{#2}}

\definespacingmethod[\v!packed]{\newfrenchspacing}
\definespacingmethod[\v!broad ]{\nonfrenchspacing}

\def\complexsetupspacing[#1]%
  {\executeifdefined{\??sg\??sg#1}\relax
   \updateraggedskips}

\def\simplesetupspacing
  {\updateraggedskips}

\definecomplexorsimple\setupspacing

\catcode`\~=\@@active % to be sure

\unexpanded\def~{\nonbreakablespace}

\def\space          { }
\def\removelastspace{\ifhmode\unskip\fi}
\def\nospace        {\removelastspace\ignorespaces}

% in tables we need:
%
% \def\fixedspace   {\hskip.5em\relax}
%
% but, since not all fonts have .5em digits:

\def\fixedspace
  {\setbox\scratchbox\normalhbox\ifmmode{$0$}\else{0}\fi
   \hskip\wd\scratchbox\relax}

\def\fixedspaces
  {\catcode`\~=\@@active
   \def~{\fixedspace}}

% \def\removeunwantedspaces{\ifhmode\unskip\unskip\unskip\unskip\unskip\fi}

\def\removeunwantedspaces
  {\ifhmode
     \doloop{\ifdim\lastskip>\zeropoint\unskip\else\exitloop\fi}%
   \fi}

% better, but not done:
%
% \def\removelastspace
%   {\ifhmode \ifdim\lastskip=\spaceamount\relax
%      \unskip
%    \fi \fi}
%
% due to backward compability

\let\space     \space
\let\hardespatie\fixedspace
\let\geenspatie \nospace

% \startbuffer
% \startlines \tt \fixedspaces
%  0~1~~2~~~3~~~~4~~~~~5
%  0~~~~~~~~~~~~~~~~~~~5
% $0~1~~2~~~3~~~~4~~~~~5$
% $0~~~~~~~~~~~~~~~~~~~5$
% \stoplines
%
% \starttabulate[|~|]
% \NC  0~1~~2~~~3~~~~4~~~~~5  \NC \NR \NC  0~~~~~~~~~~~~~~~~~~~5  \NC \NR
% \NC $0~1~~2~~~3~~~~4~~~~~5$ \NC \NR \NC $0~~~~~~~~~~~~~~~~~~~5$ \NC \NR
% \stoptabulate
%
% \starttable[||]
% \NC  0~1~~2~~~3~~~~4~~~~~5  \NC \AR \NC  0~~~~~~~~~~~~~~~~~~~5  \NC \AR
% \NC $0~1~~2~~~3~~~~4~~~~~5$ \NC \AR \NC $0~~~~~~~~~~~~~~~~~~~5$ \NC \AR
% \stoptable
% \stopbuffer
%
% \setupbodyfont[cmr] \getbuffer
% \setupbodyfont[lbr] \getbuffer

\def\packed
  {\nointerlineskip}

\def\godown[#1]%
  {\relax
   \ifhmode\endgraf\fi
   \ifvmode\nointerlineskip\vskip#1\relax\fi}

%D A couple of plain macros:

\ifx\thinspace\undefined

  \def\thinspace   {\kern .16667em }
  \def\negthinspace{\kern-.16667em }
  \def\enspace     {\kern     .5em }

\fi

\ifx\quad\undefined

  \def\enskip{\hskip.5em\relax}
  \def\quad  {\hskip 1em\relax}
  \def\qquad {\hskip 2em\relax}

\fi

\let\emspace\quad

\ifx\smallskip\undefined

  \def\smallskip{\vskip\smallskipamount}
  \def\medskip  {\vskip\medskipamount}
  \def\bigskip  {\vskip\bigskipamount}

\fi

\ifx\allowbreak\undefined

  \def\break     {\penalty\ifhmode-\plustenthousand\else\ejectpenalty\fi}
  \def\nobreak   {\penalty \plustenthousand}
  \def\allowbreak{\penalty \zeropoint}
  \def\filbreak  {\par\vfil\penalty-200\vfilneg}
  \def\goodbreak {\par\penalty-500 }

\fi

%D Made slightly more readable:

\ifx\vglue\undefined

  \def\vglue  {\afterassignment\dovglue\scratchskip=}
  \def\hglue  {\afterassignment\dohglue\scratchskip=}
  \def\topglue{\nointerlineskip\vglue-\topskip\vglue}

  \def\dovglue
    {\par
     \scratchdimen\prevdepth
     \hrule\!!height\zeropoint
     \nobreak\vskip\scratchskip
     \prevdepth\scratchdimen}

  \def\dohglue
    {\leavevmode
     \scratchcounter\spacefactor
     \vrule\!!width\zeropoint
     \nobreak\hskip\scratchskip
     \spacefactor\scratchcounter}

\fi

\ifx\eject\undefined

  \def\eject{\par\break}

\fi

\ifx\supereject\undefined

  \def\supereject{\par\penalty\superpenalty}

\fi

\ifx\dosupereject\undefined

  \def\dosupereject
    {\ifnum\insertpenalties>\z@ % something is being held over
       \line{}
       \kern-\topskip
       \nobreak
       \vfill\supereject
     \fi}

\fi

%D We adapt plain's \type {\removelastskip} a bit:

\ifx\removelastskip\undefined

  \def\removelastskip
    {\ifvmode \ifdim\lastskip=\zeropoint \else
       \vskip-\lastskip
     \fi \fi}

\fi

\ifx\smallbreak\undefined

\def\smallbreak
  {\par
   \ifdim\lastskip<\smallskipamount
     \removelastskip
     \penalty-50
     \smallskip
   \fi}

\def\medbreak
  {\par
   \ifdim\lastskip<\medskipamount
     \removelastskip
     \penalty-100
     \medskip
   \fi}

\def\bigbreak
  {\par
   \ifdim\lastskip<\bigskipamount
     \removelastskip
     \penalty-200
     \bigskip
   \fi}

\fi

\newskip\ctxparskip \ctxparskip\zeropoint

\newif\ifwitruimteflexibel \witruimteflexibeltrue

\def\blankokleinmaat  {\smallskipamount}
\def\blankomiddelmaat {\medskipamount}
\def\blankogrootmaat  {\bigskipamount}
\def\currentwhitespace {\zeropoint}

% \def\stelwitruimteopnieuwin
%   {\expanded{\setupwhitespace[\currentwhitespace]}}
%
% \newif\ifwitruimteflexibel \witruimteflexibeltrue
%
% \definecomplexorsimple\setupwhitespace
%
% \def\complexsetupwhitespace[#1]%
%   {\expanded{\dosetupwhitespace[#1]}%
%    \dodosetupwhitespace}
%
% \def\dosetupwhitespace[#1]%
%   {\processallactionsinset
%      [#1]
%      [\v!herstel=>,
%          \v!vast=>\witruimteflexibelfalse,
%      \v!flexibel=>\witruimteflexibeltrue,
%         \v!regel=>\ctxparskip\baselineskip,
%    \v!halveregel=>\ctxparskip.5\baselineskip,
%       \s!default=>\doifnot\currentwhitespace\v!geen\stelwitruimteopnieuwin,
%       \s!unknown=>\@EA\assigndimension\@EA{\commalistelement} % \@EA is nodig
%                     \ctxparskip\blankokleinmaat\blankomiddelmaat\blankogrootmaat]}   % te vangen
%
% \def\dodosetupwhitespace
%   {\edef\currentwhitespace
%      {\ifdim\ctxparskip=\zeropoint
%         \v!geen
%       \else
%         \ifgridsnapping\the\baselineskip\else\the\ctxparskip\fi
%       \fi}%
%    \ifgridsnapping
%      \witruimteflexibelfalse
%      \ctxparskip1\ctxparskip
%      \ifdim\ctxparskip>\zeropoint
%        \ctxparskip\baselineskip
%      \fi
%    \else
%      \ifwitruimteflexibel \else \ctxparskip1\ctxparskip \fi
%    \fi
%    \parskip\ctxparskip}
%
% \def\simplesetupwhitespace% == snelle \setupwhitespace[\s!default]
%   {\doifnot\currentwhitespace\v!geen\stelwitruimteopnieuwin
%    \dodosetupwhitespace}

\definecomplexorsimple\setupwhitespace

\def\simplesetupwhitespace
  {\doifnot\currentwhitespace\v!none\dosetupwhitespace}

\def\complexsetupwhitespace[#1]%
  {\doifelsenothing{#1}
     {\simplesetupwhitespace}
     {\edef\currentwhitespace{#1}%
      \dosetupwhitespace}}

\def\dosetupwhitespace
  {\processcommacommand[\currentwhitespace]\dowhitespacemethod
   \dodosetupwhitespace}

\def\dodosetupwhitespace
  {\ifgridsnapping
     \witruimteflexibelfalse
     \ctxparskip1\ctxparskip
     \ifdim\ctxparskip>\zeropoint
       \ctxparskip\baselineskip
     \fi
   \else
     \ifwitruimteflexibel \else \ctxparskip1\ctxparskip \fi
   \fi
   \parskip\ctxparskip}

\definesystemvariable {ws} % whitespace

\def\definewhitespacemethod[#1]#2{\setvalue{\??ws\??ws#1}{#2}}

\definewhitespacemethod [\v!fix]      {}
\definewhitespacemethod [\v!fixed]    {\witruimteflexibelfalse}
\definewhitespacemethod [\v!flexible] {\witruimteflexibeltrue}
\definewhitespacemethod [\v!line]     {\ctxparskip  \baselineskip}
\definewhitespacemethod [\v!halfline] {\ctxparskip.5\baselineskip}
\definewhitespacemethod [\v!none]     {\ctxparskip  \zeropoint}
\definewhitespacemethod [\v!big]      {\ctxparskip  \blankogrootmaat}
\definewhitespacemethod [\v!medium]   {\ctxparskip  \blankomiddelmaat}
\definewhitespacemethod [\v!small]    {\ctxparskip  \blankokleinmaat}

\definewhitespacemethod [\s!default]  {\stelwitruimteopnieuwin}

\def\dowhitespacemethod#1%
  {\executeifdefined{\??ws\??ws#1}{\ctxparskip#1}\relax}

\def\nowhitespace
  {\ifdim\parskip>\zeropoint\relax
     \ifdim\lastskip=-\parskip
     \else
       \vskip-\parskip
     \fi
   \fi}

\def\savecurrentwhitespace
  {\edef\restorecurrentwhitespace
     {\ctxparskip\the\ctxparskip
      \parskip\the\parskip
      \noexpand\def\noexpand\currentwhitespace{\currentwhitespace}%
      \ifwitruimteflexibel
        \noexpand\witruimteflexibeltrue
      \else
        \noexpand\witruimteflexibelfalse
      \fi}}

% deze variant is nodig binnen \startopelkaar
% steeds testen:
%
% \hoofdstuk{..}
% \plaatslijst[..]
% \hoofdstuk{..}
% \input tufte
%
% met/zonder witruimte

\def\whitespace
  {\par
   \ifdim\parskip>\zeropoint\relax
    %\ifdim\lastskip>\parskip \else
     % \removelastskip interferes with blanko blokkeer en klein
       \vskip\parskip
    %\fi
   \fi}

\def\nonoblanko[#1]%
  {\par}

\def\noblanko
  {\dosingleempty\nonoblanko}

% De onderstaande macro handelt ook de situatie dat er geen
% tekst tussen \start ... \stop is geplaatst. Daartoe wordt de
% laatste skip over de lege tekst heen gehaald. Dit komt goed
% van pas bij het plaatsen van (mogelijk lege) lijsten.

\newif\ifopelkaar

\newsignal \noparskipsignal % \def\noparskipsignal {0.00001pt}
\def\lastdoneparskip {0pt}

\def\startpacked
  {\dosingleempty\dostartpacked}

\def\dostartpacked[#1]% nesting afvangen
  {\par
   \ifvmode
     \edef\lastdoneparskip  {\the\lastskip}%
     \edef\lastdoneprevdepth{\the\prevdepth}% zeer recent toegevoegd
     \ifdim\prevdepth=-\thousandpoint % toegevoegd omdat binnen
     \else                            % een vbox een extra skip
       \whitespace                     % ongewenst is; dit kan
       \baselinecorrection %% zie in \placeregister[n=1]
       \vskip\noparskipsignal   % waarschijnlijk ook in
     \fi                        % blanko blokkeer
     \bgroup
     \doifelse{#1}\v!blank
       \opelkaarfalse
       \opelkaartrue
     \blank[\v!disable]       % dit is nog niet ok, gaat fout
     \setupwhitespace[\v!none]  % bovenin vtop (dwz, baseline)
  \fi}

\def\stoppacked
  {\par
   \ifvmode
     \egroup
     \ifdim\lastskip=\noparskipsignal\relax
       \removelastskip
       \nowhitespace
       \vskip-\lastdoneparskip
       \vskip+\lastdoneparskip
       \prevdepth-\lastdoneprevdepth % zeer recent toegevoegd
     \fi
  \fi}

\def\startunpacked
  {\blank
   \leavevmode
   \bgroup}

\def\stopunpacked
  {\egroup
   \blank}

% De onderstaande macro's moeten nog eens nader worden uitgewerkt.
% Ze spelen een rol bij de spatiering rond omkaderde teksten
% en/of boxen zonder diepte.

\def\toonregelcorrectie{\showbaselinecorrection}
\def\regelcorrectie    {\baselinecorrection}

% \prevdepth crosses pageboundaries!
%
% todo: a version that works ok inside a box

\let\doaroundlinecorrection\relax

\def\startlinecorrection
  {\dodoubleempty\dostartlinecorrection}

\def\dostartlinecorrection[#1][#2]% #2 gobbles spaces
  {\bgroup
   \processaction
     [#1]
     [  \v!blank=>\let\doaroundlinecorrection\blank,
      \s!default=>\let\doaroundlinecorrection\relax,
      \s!unknown=>{\def\doaroundlinecorrection{\blank[#1]}}]%
   \doaroundlinecorrection
   \startbaselinecorrection
   \offbaselinecorrection
   \ignorespaces}

\def\stoplinecorrection
  {\stopbaselinecorrection
   \doaroundlinecorrection
   \egroup}

\def\correctwhitespace
  {\dowithnextbox
     {\startbaselinecorrection
      \flushnextbox
      \stopbaselinecorrection}%
   \vbox}

\def\verticalstrut  {\normalvbox{\hsize\zeropoint\strut}}
\def\horizontalstrut{\normalhbox                {\strut}}

% Hieronder volgen enkele instellingen en macro's ten behoeve
% van de interlinie en \strut. De waarden 2.8, 0.07, 0.72 en
% 0.28 zijn ooit eens ontleend aan INRS-TEX en moeten wellicht
% nog eens instelbaar worden.
%
%   \lineheight        : de hoogte van een regel
%   \spacing{getal}    : instellen interlinie
%   \normalbaselines   : instellen regelafstend
%
%   \setstrut          : instellen \strut
%   \setnostrut        : resetten \strut, \endstrut, \begstrut
%
%   \setteststrut      : instellen zichtbare struts
%   \resetteststrut    : instellen onzichtbare struts
%
%   \setfontparameters : instellen na fontset
%
% De hoogte van een regel (\lineheight) is gelijk aan de
% som van de hoogte (\ht) en diepte (\dp) van \strutbox.
%
%   \strut            : denkbeeldig blokje met hoogte en diepte
%
% Een \hbox kan als deze aan het begin van een regel staat
% een breedte \hsize krijgen. Dit is soms te voorkomen met het
% commando \leavevmode. Binnen een \vbox geeft dit echter
% niet altijd het gewenste resultaat, vandaar het commando
%
%   \leaveoutervmode

% Pas op: niet zomaar \topskip en \baselineskip aanpassen
% en zeker niet \widowpenalty. Dit kan ernstige gevolgen
% hebben voor kolommen.
%
% Enige glue kan op zich geen kwaad, echter als blanko=vast,
% dan moet ook de rek 0 zijn. Binnen kolommen is rek ook
% niet bepaald mooi. Een hele kleine waarde (0.025) voldoet,
% omdat een positieve glue eindeloos rekbaar is.

\newdimen\strutdimen
\newdimen\lineheight
\newdimen\openlineheight
\newdimen\openstrutheight
\newdimen\openstrutdepth
\newdimen\topskipgap
\newdimen\struttotal

\def\strutheightfactor      {.72}
\def\strutdepthfactor       {.28}

\def\baselinefactor         {2.8}
\def\baselinegluefactor     {0}

\def\minimumstrutheight     {0pt}
\def\minimumstrutdepth      {0pt}

\def\normallineheight       {\baselinefactor ex}
\def\minimumlinedistance    {\lineskip}

\def\strutheight            {0pt}
\def\strutdepth             {0pt}
\def\strutwidth             {0pt}

\def\spacingfactor          {1}

\def\topskipfactor          {1.0}
\def\maxdepthfactor         {0.5}

\def\systemtopskipfactor    {\topskipfactor}
\def\systemmaxdepthfactor   {\maxdepthfactor}

% De onderstaande definitie wordt in de font-module overruled

\ifx\globalbodyfontsize\undefined
  \newdimen\globalbodyfontsize
  \globalbodyfontsize=12pt
\fi

\ifx\normalizedbodyfontsize\undefined
  \def\normalizedbodyfontsize{12pt}
\fi

% door een \dimen. Dit is geen probleem omdat (1) de default
% korpsgrootte 12pt is en (2) de fonts nog niet geladen zijn
% en de instellingen bij het laden nogmaals plaatsvinden.

% \def\topskipcorrection
%   {\ifdim\topskip>\openstrutheight
%      % == \vskip\topskipgap
%      \vskip\topskip
%      \vskip-\openstrutheight
%    \fi
%    \verticalstrut
%    \vskip-\struttotal}

\def\topskipcorrection
  {\simpletopskipcorrection
   \vskip-\struttotal
   \verticalstrut}

\def\simpletopskipcorrection
  {\ifdim\topskip>\openstrutheight
     % == \vskip\topskipgap
     \vskip\topskip
     \vskip-\openstrutheight
   \fi}

% \def\settopskip % the extra test is needed for the lbr family
%   {\topskip\systemtopskipfactor\globalbodyfontsize
%    \ifgridsnapping \else
%      \ifr@ggedbottom\!!plus5\globalbodyfontsize\fi
%    \fi
%    \relax % the skip
%    \topskipgap\topskip
%    \advance\topskipgap -\openstrutheight\relax
%    \ifdim\topskip<\strutheightfactor\openlineheight
%      \topskip\strutheightfactor\openlineheight\relax
%    \fi}

\def\settopskip % the extra test is needed for the lbr family
  {\topskip\systemtopskipfactor\globalbodyfontsize
   \ifgridsnapping \else
     \ifr@ggedbottom\!!plus5\globalbodyfontsize\fi
   \fi
   \relax % the skip
   \topskipgap\topskip
   \advance\topskipgap -\openstrutheight\relax
\ifdim\minimumstrutheight>\zeropoint
   \ifdim\topskip<\minimumstrutheight
     \topskip\minimumstrutheight\relax
   \fi
\else
   \ifdim\topskip<\strutheightfactor\openlineheight
     \topskip\strutheightfactor\openlineheight\relax
   \fi
\fi}

\def\setmaxdepth
  {\maxdepth\systemmaxdepthfactor\globalbodyfontsize}

\def\normalbaselines
  {\baselineskip \normalbaselineskip
   \lineskip     \normallineskip
   \lineskiplimit\normallineskiplimit}

% \def\setnormalbaselines
%   {\ifdim\normallineheight>\zeropoint
%      \lineheight\normallineheight
%    \fi
%    \openlineheight\spacingfactor\lineheight
%    \openstrutheight\strutheightfactor\openlineheight
%    \openstrutdepth \strutdepthfactor \openlineheight
%    \normalbaselineskip\openlineheight
%      \!!plus\baselinegluefactor\openlineheight
%      \!!minus\baselinegluefactor\openlineheight
%    \normallineskip\minimumlinedistance\relax % \onepoint\relax
%    \normallineskiplimit\zeropoint\relax
%    \normalbaselines}

\def\setnormalbaselines
  {\ifdim\normallineheight>\zeropoint
     \lineheight\normallineheight
   \fi
   \openlineheight\spacingfactor\lineheight
   \openstrutheight \ifdim\minimumstrutheight>\zeropoint
     \minimumstrutheight % new
   \else
     \strutheightfactor\openlineheight
   \fi
   \openstrutdepth \ifdim\minimumstrutdepth>\zeropoint
     \minimumstrutdepth % new
   \else
     \strutdepthfactor \openlineheight
   \fi
   \begingroup % avoid interference
   \scratchdimen\minimumstrutdepth
   \advance\scratchdimen\minimumstrutheight
   \ifdim\scratchdimen>\zeropoint
     \endgroup
     \openlineheight\openstrutheight % new
     \advance\openlineheight\openstrutdepth % new
   \else
     \endgroup
   \fi
   \normalbaselineskip\openlineheight
\ifgridsnapping\else
     \!!plus \baselinegluefactor\openlineheight
     \!!minus\baselinegluefactor\openlineheight
\fi
   \normallineskip\minimumlinedistance\relax % \onepoint\relax
   \normallineskiplimit\zeropoint\relax
   \normalbaselines}

\def\setspacingfactor#1\to#2\by#3\\%
  {\strutdimen#2\points
   \strutdimen#3\strutdimen
   \edef#1{\withoutpt\the\strutdimen}}

\def\spacing#1%
  {\ifgridsnapping
    %\doifnot{#1}{1}{\showmessage\m!layouts{11}{#1}}%
     \ifdim#1\points=\onepoint\else\showmessage\m!layouts{11}{#1}\fi
     \edef\spacingfactor{1}%
   \else
     \edef\spacingfactor{#1}%
   \fi
   \setspacingfactor\systemtopskipfactor \to\topskipfactor \by#1\\% why no \spacingfactor ?
   \setspacingfactor\systemmaxdepthfactor\to\maxdepthfactor\by#1\\% why no \spacingfactor ?
   \setnormalbaselines
   \setstrut}

\def\setstrutdimen#1#2#3%             % een strut is n.m maal ex
  {\strutdimen\normallineheight       % wat niet per se \lineheight
   \strutdimen#2\strutdimen           % is omdat een strut lokaal
   \strutdimen#3\strutdimen           % kan afwijken van de globale
   \edef#1{\the\strutdimen}} % macro  % strut

%D Sometimes one needs to freeze the interlinespacing
%D
%D \starttyping
%D \rm \saveinterlinespace .... {\ss \restoreinterlinespace .... \endgraf}
%D \stoptyping

\let\restoreinterlinespace\relax

\beginTEX

\def\saveinterlinespace
  {\scratchdimen\normallineheight
   \edef\restoreinterlinespace
     {\lineheight         \the\lineheight
      \openstrutheight    \the\openstrutheight
      \openstrutdepth     \the\openstrutdepth
      \openlineheight     \the\openlineheight
      \normalbaselineskip \the\normalbaselineskip
      \normallineskip     \the\normallineskip
      \normallineskiplimit\the\normallineskiplimit
      \noexpand\def\noexpand\normallineheight{\the\scratchdimen}%
      \noexpand\normalbaselines}}

\endTEX

\beginETEX

\def\saveinterlinespace
  {\edef\restoreinterlinespace
     {\lineheight         \the\lineheight
      \openstrutheight    \the\openstrutheight
      \openstrutdepth     \the\openstrutdepth
      \openlineheight     \the\openlineheight
      \normalbaselineskip \the\normalbaselineskip
      \normallineskip     \the\normallineskip
      \normallineskiplimit\the\normallineskiplimit
      \noexpand\def\noexpand\normallineheight{\the\dimexpr\normallineheight\relax}%
      \noexpand\normalbaselines}}

\endETEX

% plain definition:
%
% \def\strut{\relax\ifmmode\copy\strutbox\else\unhcopy\strutbox\fi}
%
% could be:
%
% \def\strut{\relax\ifmmode\copy\else\unhcopy\fi\strutbox}

\ifx\strutbox\undefined

  \newbox\strutbox

  \setbox\strutbox=\normalhbox{\vrule height8.5pt depth3.5pt width\z@}

 %\def\strut{\relax\ifmmode\copy\strutbox\else\unhcopy\strutbox\fi}
  \def\strut{\relax\ifmmode\copy\else\unhcopy\fi\strutbox}

\fi

\let\normalstrut=\strut

% The double \hbox construction enables us to \backtrack
% boxes.

% \def\setstrut
%   {\setstrutdimen\strutheight\strutheightfactor\spacingfactor
%    \setstrutdimen\strutdepth \strutdepthfactor \spacingfactor
%    \let\strut=\normalstrut
%    \setbox\strutbox=\normalhbox
%      {\normalhbox
%         {\vrule
%            \!!width  \strutwidth
%            \!!height \strutheight
%            \!!depth  \strutdepth
%            \normalkern-\strutwidth}}}

% \def\setstrut
%   {\setstrutdimen\strutheight\strutheightfactor\spacingfactor
%    \setstrutdimen\strutdepth \strutdepthfactor \spacingfactor
%    \dosetstrut}

% \def\setstrut
%   {\strutdimen\normallineheight
%    \strutdimen\strutheightfactor\strutdimen
%    \strutdimen\spacingfactor\strutdimen
%    \edef\strutheight{\the\strutdimen}%
%    \strutdimen\normallineheight
%    \ifgridsnapping
%      \advance\strutdimen-\strutheight
%    \else
%      \strutdimen\strutdepthfactor\strutdimen
%      \strutdimen\spacingfactor\strutdimen
%    \fi
%    \edef\strutdepth{\the\strutdimen}%
%    \dosetstrut}

% interesting, strudepth is 4.05064pt vs 4.05066pt depending on grid
% nasty rounding problem

\def\setstrut
  {% height
   \strutdimen\normallineheight
   \ifdim\minimumstrutheight>\zeropoint
     \strutdimen\minimumstrutheight
   \else
     \strutdimen\strutheightfactor\strutdimen
   \fi
   \strutdimen\spacingfactor\strutdimen
   \edef\strutheight{\the\strutdimen}%
   % depth
   \strutdimen\normallineheight
   \ifgridsnapping
     \ifdim\minimumstrutdepth>\zeropoint
       \strutdimen\minimumstrutdepth
     \else
       \advance\strutdimen-\strutheight
     \fi
   \else
     \ifdim\minimumstrutdepth>\zeropoint
       \strutdimen\minimumstrutdepth
     \else
       \strutdimen\strutdepthfactor\strutdimen
     \fi
     \strutdimen\spacingfactor\strutdimen
   \fi
   \edef\strutdepth{\the\strutdimen}%
   % finish
   \dosetstrut}

\def\setcharstrut#1%
  {\setbox\strutbox\normalhbox{#1}%
   \edef\strutheight{\the\strutht}%
   \edef\strutdepth {\the\strutdp}%
   \dosetstrut}

% \def\setfontstrut
%   {\setcharstrut{(}}
%
% better, since some fonts have small (but descending Q etc)

\def\setfontstrut
  {\setcharstrut{(gplQT}}

\def\setcapstrut% could be M, but Q has descender
  {\setcharstrut{Q}}

%D Handy for math (used in mathml):

\def\charhtstrut
  {\begingroup
   \setcharstrut{GJY}%
   \vrule\!!width\zeropoint\!!depth\zeropoint\!!height\strutht
   \endgroup}

\def\chardpstrut
  {\begingroup
   \setcharstrut{gjy}%
   \vrule\!!width\zeropoint\!!depth\strutdp\!!height\zeropoint
   \endgroup}

%D Centered looks nicer:

\def\dosetstrut
  {\let\strut\normalstrut
   \setbox\strutbox\normalhbox
     {\normalhbox to \zeropoint
        {% \hss % new, will be option
         \vrule
           \!!width \strutwidth
           \!!height\strutheight
           \!!depth \strutdepth
         \hss}}%
   \struttotal\strutht
   \advance\struttotal\strutdp}

%D The dimen \type {\struttotal} holds the exact size of the
%D strut; occasionally a one scaled point difference can show
%D up with the lineheight.

%D Sometimes a capstrut comes in handy
%D
%D \starttabulate[|Tl|l|l|]
%D \NC yes          \NC normal strut               \NC {\showstruts\setupstrut[yes]\strut}  \NC \NR
%D \NC no           \NC no strut                   \NC {\showstruts\setupstrut[no]\strut}  \NC \NR
%D \NC kap          \NC a capital strut (i.e. Q)   \NC {\showstruts\setupstrut[cap]\strut} \NC \NR
%D \NC A B \unknown \NC a character strut (e.g. A) \NC {\showstruts\setupstrut[A]\strut}   \NC \NR
%D \NC              \NC a normal strut             \NC {\showstruts\setupstrut\strut}      \NC \NR
%D \stoptabulate

\def\setupstrut
  {\dosingleempty\dosetupstrut}

\def\dosetupstrut[#1]% yet undocumented, todo: fontstrut
  {\processaction
     [#1]
     [    \v!yes=>\setstrut,
         \v!auto=>\setautostrut,
           \v!no=>\setnostrut,
          \v!cap=>\setcapstrut,
          \v!fit=>\setfontstrut,
         \v!line=>\setstrut,
      \s!default=>\setstrut,
      \s!unknown=>\setcharstrut\commalistelement]}

\def\setteststrut
  {\def\strutwidth{.8pt}%
   \setstrut}

\def\autostrutfactor{1.1}

\def\setautostrut
  {\begingroup
   \setbox\scratchbox\copy\strutbox
   \setstrut
   \ifdim\ht\strutbox>\autostrutfactor\ht\scratchbox
     \endgroup \setstrut
   \else\ifdim\dp\strutbox>\autostrutfactor\dp\scratchbox
     \endgroup \setstrut
   \else
     \endgroup
   \fi\fi}

% simple version
%
% \def\begstrut
%   {\relax\ifcase\strutht\else
%      \strut
%      \normalpenalty\plustenthousand
%      \normalhskip\zeropoint
%      \ignorespaces
%    \fi}
%
% \def\endstrut
%   {\relax\ifhmode\ifcase\strutht\else
%      \removeunwantedspaces
%      \normalpenalty\plustenthousand
%      \normalhskip\zeropoint
%      \strut
%    \fi\fi}

% when enabled, sigstruts will remove themselves if nothing
% goes inbetween

\newsignal\strutsignal \setfalse\sigstruts

\def\begstrut
  {\relax\ifcase\strutht\else
     \ifconditional\sigstruts
       \noindent\horizontalstrut
       \normalpenalty\plustenthousand
       \normalhskip-\strutsignal
       \normalhskip\strutsignal
     \else
       \strut
       \normalpenalty\plustenthousand
       \normalhskip\zeropoint
     \fi
     \expandafter \ignorespaces
   \fi}

\def\endstrut
  {\relax\ifhmode\ifcase\strutht\else
     \ifconditional\sigstruts
       \ifdim\lastskip=\strutsignal
         \unskip\unskip\unpenalty\setbox\scratchbox\lastbox
       \else
         \normalpenalty\plustenthousand
         \normalhskip\zeropoint
         \strut
       \fi
     \else
       \removeunwantedspaces
       \normalpenalty\plustenthousand
       \normalhskip\zeropoint
       \strut
     \fi
   \fi\fi}

\newbox\nostrutbox \setbox\nostrutbox\normalhbox{\normalhbox{}}

\def\setnostrut
  {\setbox\strutbox\copy\nostrutbox
   \let\strut\empty
   \let\endstrut\empty
   \let\begstrut\empty
   \let\crlfplaceholder\empty}

% unsave:
%
% \def\pseudostrut
%   {\bgroup
%    \setnostrut
%    \normalstrut
%    \egroup}
%
% try:
%
% \startchemie
%   \chemie[ONE,Z0,SB15,MOV1,SB15,Z0][C,C]
% \stopchemie
%
% so:

\def\pseudostrut
  {\noindent} % better: \dontleavehmode

\let\pseudobegstrut\pseudostrut

\let\pseudoendstrut\removeunwantedspaces

\def\resetteststrut
  {\let\strutwidth\zeropoint
   \setstrut}

\ifx\setfontparameters\undefined
  % problems ! ! ! !
  \def\setfontparameters{\the\everybodyfont}
\fi

%D Handy:

\def\baselinedistance{\the\lineheight}

%D We need \type{\normaloffinterlineskip} because the new
%D definition contains an assignment, and |<|don't ask me
%D why|>| this assignment gives troubles in for instance the
%D visual debugger.

%D The plain ones:

\def\offinterlineskip
  {\baselineskip-\thousandpoint
   \lineskip\zeropoint
   \lineskiplimit\maxdimen}

\def\nointerlineskip
  {\prevdepth-\thousandpoint}

\let\normaloffinterlineskip=\offinterlineskip % knuth's original

%D My own one:

\def\offinterlineskip
  {\ifdim\baselineskip>\zeropoint
     \edef\oninterlineskip
       {\baselineskip\the\baselineskip
        \lineskip\the\lineskip
        \lineskiplimit\the\lineskiplimit
        \let\noexpand\offinterlineskip\noexpand\normaloffinterlineskip}%
   \else
     \let\oninterlineskip\setnormalbaselines
   \fi
   \normaloffinterlineskip}

\let\oninterlineskip=\relax

\def\leaveoutervmode
  {\ifvmode\ifinner\else
     \leavevmode
   \fi\fi}

% We stellen enkele penalties anders in dan Plain TEX:

% oud
%
% \widowpenalty=\defaultwidowpenalty\relax
% \clubpenalty =\defaultclubpenalty \relax

\beginTEX widowpenalties clubpenalties interlinepenalties

  \newcount \widowpenalties
  \newcount \clubpenalties
  \newcount \interlinepenalties

\endTEX

% \setpenalties\widowpenalties2\maxdimen
%
% expands to \widowpenalty \maxdimen \maxdimen \zeropoint

\beginTEX

  \let\resetpenalties   \gobbleoneargument
  \let\setpenalties     \gobblethreearguments
  \let\doexpandedrecurse\gobbletwoarguments

\endTEX

\beginETEX \numexpr

  \def\resetpenalties#1%
    {\ifx#1\undefined\else
       #1\minusone
     \fi}

%   \def\setpenalties#1#2#3%
%     {\ifx#1\undefined\else % space before #3 prevents lookahead problems, needed when #3=text
%        #1\numexpr(#2+1)\space\doexpandedrecurse{\the\numexpr(#2)}{ #3}\zerocount\relax
%      \fi}

  \def\setpenalties#1#2#3%
    {\ifx#1\undefined\else % space before #3 prevents lookahead problems, needed when #3=text
       #1\numexpr#2+\plusone\relax\space\doexpandedrecurse{\the\numexpr#2\relax}{ #3}\zerocount\relax
     \fi}

%   \def\doexpandedrecurse#1#2%
%     {\ifnum#1>\zerocount#2\@EA\doexpandedrecurse\@EA{\the\numexpr(#1-1)}{#2}\fi}

  \def\doexpandedrecurse#1#2%
    {\ifnum#1>\zerocount#2\@EA\doexpandedrecurse\@EA{\the\numexpr#1-1\relax}{#2}\fi}

\endETEX

%D \macros
%D   {keeplinestogether}
%D
%D Dirty hack, needed in margin content that can run of a page.

\beginETEX

  \def\keeplinestogether#1%
    {\xdef\restoreinterlinepenalty{\global\resetpenalties\interlinepenalties}%
     \global\setpenalties\interlinepenalties{#1}\plustenthousand}

\endETEX

\beginTEX

  \def\keeplinestogether#1%
    {\xdef\restoreinterlinepenalty
       {\global\let\restoreinterlinepenalty\relax
        \global\interlinepenalty=\the\interlinepenalty}% keep = here
     \global\interlinepenalty\plustenthousand}

\endTEX

\newif\ifgridsnapping % to be sure

\def\defaultwidowpenalty    {2000} % was: 1000
\def\defaultclubpenalty     {2000} % was:  800

\def\defaultgridwidowpenalty   {0}
\def\defaultgridclubpenalty    {0}

% The original approach:
%
% \def\setdefaultpenalties
%   {\ifgridsnapping
%      \widowpenalty\defaultgridwidowpenalty
%      \clubpenalty \defaultgridclubpenalty
%    \else
%      \widowpenalty\defaultwidowpenalty
%      \clubpenalty \defaultclubpenalty
%    \fi}
%
% However, we will use setups:

% to be documented

\def\nopenalties
  {\widowpenalty        \zerocount
   \clubpenalty         \zerocount
   \brokenpenalty       \zerocount
   \doublehyphendemerits\zerocount
   \finalhyphendemerits \zerocount
   \adjdemerits         \zerocount}

\def\setdefaultpenalties
  {\directsetup{\systemsetupsprefix\s!default}}

\startsetups [\systemsetupsprefix\s!reset]
  \resetpenalties\widowpenalties
  \resetpenalties\clubpenalties
  \resetpenalties\interlinepenalties
\stopsetups

% we use \directsetup because it's faster and we know there is no csl

\startsetups [\systemsetupsprefix\s!default]

  \directsetup{\systemsetupsprefix\s!reset}

  \widowpenalty\defaultwidowpenalty
  \clubpenalty \defaultclubpenalty

\stopsetups

\startsetups [\v!grid] [\systemsetupsprefix\s!default]

  \directsetup{\systemsetupsprefix\s!reset}

  \widowpenalty\defaultgridwidowpenalty
  \clubpenalty \defaultgridclubpenalty

\stopsetups

% as an illustration:

\startsetups [\systemsetupsprefix\v!strict]

   \directsetup{\systemsetupsprefix\s!reset}

   \setpenalties\widowpenalties2\maxdimen
   \setpenalties\clubpenalties 2\maxdimen
                \brokenpenalty  \maxdimen

\stopsetups

\setdefaultpenalties % will happen later in \setuplayout

% Suggested by GB (not the name -):

\def\rapfillskip{.5\hsize plus .092\hsize minus .5\hsize} % D.A.'s value

% Bovendien definieren we enkele extra \fill's:

\def\hfilll{\hskip\zeropoint\!!plus1filll\relax}
\def\vfilll{\vskip\zeropoint\!!plus1filll\relax}

% De onderstaande hulpmacro's moeten nog eens instelbaar worden
% gemaakt.

\def\tfskipsize{1em\relax}
\def\tfkernsize{1ex\relax}

\def\tfskip{\dotfskip\tfskipsize}
\def\tfkern{\dotfkern\tfkernsize}

\def\dotfskip#1{{\tf\hskip#1}}
\def\dotfkern#1{{\tf\kern #1}}

\newskip\ctxleftskip
\newskip\ctxrightskip
\newskip\ctxmidskip

\def\dosinglenarrower#1%
  {\processaction
     [#1]
     [     \v!left=>\global\advance\ctxleftskip  \@@slleft,
         \v!middle=>\global\advance\ctxmidskip   \@@slmiddle,
          \v!right=>\global\advance\ctxrightskip \@@slright,
           \v!none=>,
        \s!unknown=>\global\advance\ctxmidskip   \commalistelement]}

\def\donarrower[#1]%
  {\processaction
     [#1]
     [     \v!left=>\global\advance\ctxleftskip  \@@slleft,
         \v!middle=>\global\advance\ctxmidskip   \@@slmiddle,
          \v!right=>\global\advance\ctxrightskip \@@slright,
           \v!none=>,% handy for delimitedtexts
        \s!unknown=>{\dorepeatwithcommand[#1]\dosinglenarrower}]}

\def\complexstartnarrower[#1]%
  {\par
   \bgroup
   \global\ctxleftskip \zeropoint
   \global\ctxrightskip\zeropoint
   \global\ctxmidskip  \zeropoint
   \processcommalistwithparameters[#1]\donarrower
   \advance\leftskip  \ctxleftskip
   \advance\rightskip \ctxrightskip
   \advance\leftskip  \ctxmidskip
   \advance\rightskip \ctxmidskip
   \seteffectivehsize}

\def\simplestartnarrower
  {\startnarrower[\v!middle]}

\definecomplexorsimple\startnarrower

\def\stopnarrower
  {\par % else skips forgotten
   \egroup}

\def\setupnarrower
  {\dodoubleargument\getparameters[\??sl]}

\newdimen\@@effectivehsize     \def\effectivehsize    {\hsize}
\newdimen\@@effectiveleftskip  \def\effectiveleftskip {\leftskip}
\newdimen\@@effectiverightskip \def\effectiverightskip{\rightskip}

\def\seteffectivehsize
  {\setlocalhsize
   \@@effectivehsize      \localhsize
   \@@effectiveleftskip   \leftskip
   \@@effectiverightskip  \rightskip
   \let\effectivehsize    \@@effectivehsize
   \let\effectiveleftskip \@@effectiveleftskip
   \let\effectiverightskip\@@effectiverightskip}

\def\dodefinehbox[#1][#2]%
  {\setvalue{hbox#1}##1%
     {\hbox to #2{\begstrut##1\endstrut\hss}}}

\def\definehbox
  {\dodoubleargument\dodefinehbox}

\def\iobox#1#2#3#% here #3# is not really needed
  {\vbox\bgroup  % we want to return a vbox like the others
     \hbox\bgroup% we need to pack the signal with the box
       \signalrightpage
       \dowithnextboxcontent
         {\let\\=\endgraf\forgetall\doifrightpageelse#1#2}
         {\box\nextbox\egroup\egroup}
       \vbox#3}

\def\obox{\iobox\raggedleft \raggedright} % outerbox
\def\ibox{\iobox\raggedright\raggedleft}  % innerbox

\def\dosetraggedvbox#1%
  {\processaction
     [#1]
     [   \v!left=>\let\raggedbox\lbox,
        \v!right=>\let\raggedbox\rbox,
       \v!middle=>\let\raggedbox\cbox,
        \v!inner=>\let\raggedbox\ibox,
        \v!outer=>\let\raggedbox\obox,
    \v!flushleft=>\let\raggedbox\rbox,
   \v!flushright=>\let\raggedbox\lbox,
       \v!center=>\let\raggedbox\cbox,
           \v!no=>\def\raggedbox{\vbox\bgroup\raggedright\let\next=},
      \s!default=>\let\raggedbox\vbox,
      \s!unknown=>\let\raggedbox\vbox]}

\def\dosetraggedhbox#1%
  {\processaction % slow
     [#1]
     [   \v!left=>\def\raggedbox{\doalignedline\v!left  },
        \v!right=>\def\raggedbox{\doalignedline\v!right },
       \v!middle=>\def\raggedbox{\doalignedline\v!middle},
        \v!inner=>\def\raggedbox{\doalignedline\v!inner },
        \v!outer=>\def\raggedbox{\doalignedline\v!outer },
    \v!flushleft=>\def\raggedbox{\doalignedline\v!right },
   \v!flushright=>\def\raggedbox{\doalignedline\v!left  },
       \v!center=>\def\raggedbox{\doalignedline\v!middle},
       \v!normal=>\let\raggedbox\hbox,
      \s!default=>\let\raggedbox\hbox,
      \s!unknown=>\let\raggedbox\hbox]}

\def\dosetraggedcommand#1%
  {\expanded{\dodosetraggedcommand{#1}}}

% \def\dodosetraggedcommand#1% beware: #1=empty is ignored, keep that!
%   {\let\raggedcommand      \relax
%    \let\raggedtopcommand   \empty
%    \let\raggedbottomcommand\empty
%    \chardef\raggedoneliner\zerocount
%    \doifsomething{#1}
%      {\doifinsetelse\v!broad{#1}\!!doneatrue\!!doneafalse
%       \doifinsetelse\v!wide {#1}\!!donebtrue\!!donebfalse
%       \!!donectrue
%       \rawprocesscommalist[#1]\dododosetraggedcommand}}

\newtoks\everyraggedcommand \def\raggedcommand{\the\everyraggedcommand}

\def\dodosetraggedcommand#1% beware: #1=empty is ignored, keep that!
  {\everyraggedcommand     \emptytoks
   \let\raggedtopcommand   \empty
   \let\raggedbottomcommand\empty
   \chardef\raggedoneliner\zerocount
   \doifsomething{#1}
     {\doifinsetelse\v!broad{#1}\!!doneatrue\!!doneafalse
      \doifinsetelse\v!wide {#1}\!!donebtrue\!!donebfalse
      \!!donectrue
      \rawprocesscommalist[#1]\dododosetraggedcommand}}

\def\dododosetraggedcommand#1%
  {\executeifdefined{\@@ragged@@command\string#1}\relax}

\def\@@ragged@@command{@@raggedcommand}

\setvalue{\@@ragged@@command\v!hanging      }{\appendtoks\enableprotruding    \to\everyraggedcommand}
\setvalue{\@@ragged@@command\v!nothanging   }{\appendtoks\disableprotruding   \to\everyraggedcommand}
\setvalue{\@@ragged@@command\v!hz           }{\appendtoks\enableadjusting     \to\everyraggedcommand}
\setvalue{\@@ragged@@command\v!nohz         }{\appendtoks\disableadjusting    \to\everyraggedcommand}
\setvalue{\@@ragged@@command\v!spacing      }{\appendtoks\enablespacehandling
                                                         \enablekernhandling  \to\everyraggedcommand}
\setvalue{\@@ragged@@command\v!nospacing    }{\appendtoks\disablespacehandling
                                                         \disablekernhandling \to\everyraggedcommand}
\setvalue{\@@ragged@@command\v!hyphenated   }{\appendtoks\dohyphens           \to\everyraggedcommand}
\setvalue{\@@ragged@@command\v!nothyphenated}{\appendtoks\nohyphens           \to\everyraggedcommand}

\setvalue{\@@ragged@@command\v!tolerant    }{\appendtoks\tolerance3000\relax  \to\everyraggedcommand}
\setvalue{\@@ragged@@command\v!verytolerant}{\appendtoks\tolerance4500\relax  \to\everyraggedcommand}
\setvalue{\@@ragged@@command\v!stretch     }{\appendtoks\emergencystretch\bodyfontsize\to\everyraggedcommand}

\setvalue{\@@ragged@@command\v!left}%
  {\if!!donea \appendtoks\veryraggedleft\to\everyraggedcommand
   \else      \appendtoks\raggedleft    \to\everyraggedcommand
   \fi
   \!!donecfalse}

\setvalue{\@@ragged@@command\v!right}%
  {\if!!donea \appendtoks\veryraggedright\to\everyraggedcommand
   \else      \appendtoks\raggedright    \to\everyraggedcommand
   \fi
   \!!donecfalse}

\setvalue{\@@ragged@@command\v!middle}%
  {\if!!donec
     \if!!doneb      \appendtoks\raggedwidecenter\to\everyraggedcommand
     \else\if!!donea \appendtoks\veryraggedcenter\to\everyraggedcommand
     \else           \appendtoks\raggedcenter    \to\everyraggedcommand
     \fi\fi
     \!!donecfalse
   \else
     \let\raggedbottomcommand\vfilll % bonus, pretty strong
     \let\raggedtopcommand   \vfilll % used with \framed for
   \fi}                              % instance in tables

\setvalue{\@@ragged@@command\v!flushleft }{\getvalue{\@@ragged@@command\v!right }}
\setvalue{\@@ragged@@command\v!flushright}{\getvalue{\@@ragged@@command\v!left  }}
\setvalue{\@@ragged@@command\v!center    }{\getvalue{\@@ragged@@command\v!middle}}

\setvalue{\@@ragged@@command\v!high}%
  {\let\raggedbottomcommand\vfilll}  % and since we lack a

\setvalue{\@@ragged@@command\v!low}%
  {\let\raggedtopcommand\vfilll}     % proper keyword, but

\setvalue{\@@ragged@@command\v!lohi}%
  {\let\raggedbottomcommand\vfilll   % we do support the
   \let\raggedtopcommand\vfilll}     % ugly laho (lohi)

\setvalue{\@@ragged@@command\v!no}%
  {\appendtoks\raggedright\to\everyraggedcommand}

\setvalue{\@@ragged@@command\v!yes}%
  {\appendtoks\notragged\to\everyraggedcommand}

\setvalue{\@@ragged@@command\v!normal}%
  {\appendtoks\notragged\to\everyraggedcommand}

\setvalue{\@@ragged@@command\v!inner}% not yet perfect
  {\signalrightpage % may interfere
   \doifrightpageelse
     {\getvalue{\@@ragged@@command\v!right}}
     {\getvalue{\@@ragged@@command\v!left}}}

\setvalue{\@@ragged@@command\v!outer}% not yet perfect
  {\signalrightpage % may interfere
   \doifrightpageelse
     {\getvalue{\@@ragged@@command\v!left}}
     {\getvalue{\@@ragged@@command\v!right}}}

% compare:
%
% \framed[width=4cm,align=no]     {\hfil xxx}
% \framed[width=4cm,align=disable]{\hfil xxx}

\setvalue{\@@ragged@@command\v!disable}% for one liners
  {\appendtoks\raggedright\parfillskip\zeropoint\to\everyraggedcommand}

\chardef\raggedoneliner\zerocount

\setvalue{\@@ragged@@command\v!line}%
  {\chardef\raggedoneliner\plusone}

%D Unofficial, may disappear. Now handled directly in the
%D core-rul module.

% \def\@@startraggedoneliner
%   {\ifcase\raggedoneliner\else
%      \dontleavehmode\hbox to \hsize \bgroup % hsize added, else useless
%      \ifcase\raggedstatus\or\hss\or\hss\fi
%      \ignorespaces
%      \bgroup
%      \aftergroup\removeunwantedspaces
%    \fi}

% \def\@@stopraggedoneliner
%   {\ifcase\raggedoneliner\else
%      \egroup
%      \ifcase\raggedstatus\or\or\hss\or\hss\fi
%      \egroup
%      \ignorespaces % ? ? ?
%    \fi}

% \def\@@handleoneliner
%   {\ifcase\raggedoneliner\else
%      \@@startraggedoneliner
%      \aftergroup\@@stopraggedoneliner
%    \fi}

% Nodig i.v.m. inspringen eerste alineas

\def\explicithmode{\unhbox\voidb@x} % can probably become \dontleavehmode

% Nog doen:
%
%  \goodbreak -> \allowbreak en \dosomebreak{..} in koppen
%
% bij koppen zowieso: \blanko[reset]

% Nog in commando verwerken:
%
% \voorkeur � la \blanko
%
% Om ongewenste witruimte te voorkomen kan met \dosomebreak{\break}
% een \penalty v��r witruimte worden geplaatst.

\def\removelastskip % a redefinition of plain
  {\ifvmode\ifdim\lastskip=\zeropoint\else\vskip-\lastskip\fi\fi}

% first version:
%
% \def\dosomebreak#1%
%   {\scratchskip\lastskip
%    \removelastskip
%    %\type{#1}%
%    #1\relax
%    \ifdim\scratchskip=\zeropoint \else
%      \vskip\scratchskip
%    \fi}
%
% don't change the next improvement:

\def\dosomebreak#1%
  {\endgraf % beware, this forces a newline
   \ifvmode
     \ifdim\lastskip=\zeropoint
       #1\relax
     \else
       \scratchskip\lastskip
       \removelastskip
       #1\relax
       \vskip\scratchskip
     \fi
   \fi}

% beter, vooral in \vbox; nog in \pagina toepassen s!

\def\doifoutervmode#1%
  {\ifvmode\ifinner\else#1\fi\fi}

\def\dosomebreak#1%
  {\doifoutervmode
     {\scratchskip\lastskip
      \removelastskip
      %\leavevmode\type{#1}%
      #1\relax
      \ifdim\scratchskip=\zeropoint % else interference with footnotes
      \else
        \vskip\scratchskip
      \fi}}

\def\forgeteverypar
  {\everypar{\the\neverypar}}

%\def\forgetparindent
%  {\forgeteverypar
%   \indentfirstparagraphtrue % recently added
%   \setupindenting[\v!geen]}

%\def\forgetparskip
%  {\setupwhitespace[\v!geen]}

\def\forgetparindent
  {\forgeteverypar
   \indentfirstparagraphtrue % recently added
   \let\currentindentation\v!none
   \ctxparindent\zeropoint
   \parindent\zeropoint\relax}

\def\forgetparskip
  {\let\currentwhitespace\v!none
   \ctxparskip\zeropoint
   \parskip\zeropoint\relax}

\def\forgetbothskips
  {\tolerance1500
   \leftskip\zeropoint
   \rightskip\zeropoint\relax}

\def\forgetspacing
  {\emergencystretch\zeropoint}

\def\forgetall
  {\the\everyforgetall}

\newif\ifforgotten % rather good signal for inner

\appendtoks \forgottentrue      \to \everyforgetall
\appendtoks \forgetragged       \to \everyforgetall
\appendtoks \forgetparskip      \to \everyforgetall
\appendtoks \forgetparindent    \to \everyforgetall
\appendtoks \forgetbothskips    \to \everyforgetall
\appendtoks \forgetspacing      \to \everyforgetall % i.v.m. funny spacing in pagebody
\appendtoks \spacing\!!plusone  \to \everyforgetall % new per 10/08/2004, else problems in otr / !! needed
\appendtoks \everypar\emptytoks \to \everyforgetall % indeed!

\def\localvbox#1#%
  {\vbox#1\bgroup
     \forgetparskip
     \setlocalhsize
     \hsize\localhsize
     \forgetparindent
     \forgetbothskips
     \forgeteverypar
     \let\next=}

% ach ja, hoort niet hier

% \unexpanded\def\dostartattributes#1#2#3%
%   {\begingroup  % geen \bgroup, anders in mathmode lege \hbox
%    \doifdefinedelse{#1#2}
%      {\def\fontattribute{\getvalue{#1#2}}}
%      {\let\fontattribute=\empty}%
%    \doifdefinedelse{#1#3}
%      {\def\colorattribute{\getvalue{#1#3}}}
%      {\let\colorattribute=\empty}%
%    \startcolor[\colorattribute]%
%    \@EA\doconvertfont\@EA{\fontattribute}}
%
% \unexpanded\def\dostopattributes%
%   {\stopcolor
%    \endgroup}
%
% \unexpanded\def\doattributes#1#2#3#4%
%   {\dostartattributes{#1}{#2}{#3}{#4}\dostopattributes}

%D A hardly faster implementation follows. We cannot use
%D \type {csname} testing since the first argument can be
%D anything, even a raw fontswitch. No a real improvement
%D (some 5 seconds on 260 seconds for the maps bibliography).

\let\dostopattributes\relax % in case these commands end up in an edef

\beginTEX

\unexpanded\def\dostartattributes#1#2#3%
  {\begingroup  % geen \bgroup, anders in mathmode lege \hbox
   \@EA\ifx\csname#1#3\endcsname\relax
     \let\dostopattributes\@@nostopattributes
   \else
     \let\dostopattributes\@@dostopattributes
     \startcolor[\csname#1#3\endcsname]%
   \fi
   \@EA\ifx\csname#1#2\endcsname\relax
     \expandafter\gobbleoneargument
   \else
     \expandafter\doconvertfont
   \fi{\csname#1#2\endcsname}}

\endTEX

\beginETEX \ifcsname

\unexpanded\def\dostartattributes#1#2#3%
  {\begingroup  % geen \bgroup, anders in mathmode lege \hbox
   \ifcsname#1#3\endcsname
     \let\dostopattributes\@@dostopattributes
     \startcolor[\csname#1#3\endcsname]%
   \else
     \let\dostopattributes\@@nostopattributes
   \fi
   \ifcsname#1#2\endcsname
     \expandafter\doconvertfont
   \else
     \expandafter\gobbleoneargument
   \fi{\csname#1#2\endcsname}}

\endETEX

\newconditional \parbasedattributes

\def\finishparbasedattributes
  {\ifconditional\parbasedattributes
     \setfalse\parbasedattributes
     \par
   \fi}

\def\dostopparbasedattributes
  {\settrue\parbasedattributes
   \dostopattributes}

\unexpanded\def\@@dostopattributes
  {\stopcolor
   \finishparbasedattributes
   \endgroup}

\unexpanded\def\@@nostopattributes
  {\finishparbasedattributes
   \endgroup}

\unexpanded\def\doattributes#1#2#3#4%
  {\dostartattributes{#1}{#2}{#3}{#4}\dostopattributes}

% An even faster \ETEX\ version:

\beginETEX

% \unexpanded\def\dostartattributes#1#2#3%
%   {\begingroup  % geen \bgroup, anders in mathmode lege \hbox
%    \ifcsname#1#3\endcsname
%      \let\dostopattributes\@@dostopattributes
%      \startcolor[\csname#1#3\endcsname]%
%    \else
%      \let\dostopattributes\@@nostopattributes
%    \fi
%    \ifcsname#1#2\endcsname
%      \@EAEAEA\doconvertfont\@EA\@EA\csname#1#2\endcsname
%    \fi}
%
% \unexpanded\def\@@dostopattributes%
%   {\stopcolor
%    \finishparbasedattributes
%    \endgroup}
%
% \unexpanded\def\@@nostopattributes%
%   {\finishparbasedattributes
%    \endgroup}

\unexpanded\def\dostartattributes#1#2#3%
  {\begingroup  % geen \bgroup, anders in mathmode lege \hbox
   \ifincolor
     \ifcsname#1#3\endcsname
       \let\dostopattributes\@@dostopattributes
       \doglobalstartcolor[\csname#1#3\endcsname]%
     \else
       \let\dostopattributes\@@nostopattributes
     \fi
   \else
     \let\dostopattributes\@@nostopattributes
   \fi
   \ifcsname#1#2\endcsname
   % \@EAEAEA\doconvertfont\@EA\@EA\csname#1#2\endcsname
     \@EA\doconvertfont\csname#1#2\@EA\endcsname
   \fi}

\unexpanded\def\@@dostopattributes
  {\doglobalstopcolor
   \finishparbasedattributes
   \endgroup}

\unexpanded\def\@@nostopattributes
  {\finishparbasedattributes
   \endgroup}

\endETEX

%D Bonus macro, see core-sec.tex

\beginTEX

\unexpanded\def\dosetfontattribute#1#2%
  {\@EA\ifx\csname#1#2\endcsname\relax\else
     \@EAEAEA\doconvertfont\@EA\@EA\csname#1#2\endcsname
   \fi\empty}

\endTEX

\beginETEX \ifcsname

\unexpanded\def\dosetfontattribute#1#2%
  {\ifcsname#1#2\endcsname
   % \@EAEAEA\doconvertfont\@EA\@EA\csname#1#2\endcsname
     \@EA\doconvertfont\csname#1#2\@EA\endcsname
   \fi\empty}

\endETEX

%D Since this happens a lot, and sometimes large arguments
%D are passed in \type {#4}, we just copy some code:

\beginETEX \ifcsname

\unexpanded\def\doattributes#1#2#3#4%
  {\begingroup  % geen \bgroup, anders in mathmode lege \hbox
   \ifincolor
     \ifcsname#1#3\endcsname
       \let\dostopattributes\@@dostopattributes
       \doglobalstartcolor[\csname#1#3\endcsname]%
     \else
       \let\dostopattributes\endgroup
     \fi
   \else
     \let\dostopattributes\endgroup
   \fi
   \ifcsname#1#2\endcsname
   % \@EAEAEA\doconvertfont\@EA\@EA\csname#1#2\endcsname
     \@EA\doconvertfont\csname#1#2\@EA\endcsname
   \fi
   {#4}%
   \dostopattributes}

\endETEX

% Kan vaker worden toegepast en moet bovendien sneller!

\newskip\leftskipadaption
\newskip\rightskipadaption

\def\doadaptleftskip#1%
  {\dosetleftskipadaption{#1}%
   \advance\leftskip \leftskipadaption}

\def\doadaptrightskip#1%
  {\dosetrightskipadaption{#1}%
   \advance\rightskip \rightskipadaption}

\beginTEX

\def\dosetleftskipadaption#1%
  {\leftskipadaption\zeropoint
   \processaction[#1]
     [\v!standard=>\leftskipadaption
                   \ifdim\ctxparindent=\zeropoint\@@slleft\else\ctxparindent\fi,
           \v!yes=>\leftskipadaption
                   \ifdim\ctxparindent=\zeropoint\@@slleft\else\ctxparindent\fi,
            \v!no=>,
       \s!unknown=>\leftskipadaption#1]}

\def\dosetrightskipadaption#1%
  {\rightskipadaption\zeropoint
   \processaction[#1]
     [\v!standard=>\rightskipadaption\@@slright,
           \v!yes=>\rightskipadaption\@@slright,
            \v!no=>,
       \s!unknown=>\rightskipadaption#1]}

\endTEX

\beginETEX

% installation

\setvalue{@lsa@\v!standard}{\ifdim\ctxparindent=\zeropoint\@@slleft\else\ctxparindent\fi}
\setvalue{@lsa@\v!yes     }{\ifdim\ctxparindent=\zeropoint\@@slleft\else\ctxparindent\fi}
\letvalue{@lsa@\v!no      }\zeropoint
\letvalue{@lsa@\empty     }\zeropoint
\setvalue{@rsa@\v!standard}{\@@slright}
\setvalue{@rsa@\v!yes     }{\@@slright}
\letvalue{@rsa@\v!no      }\zeropoint
\letvalue{@rsa@\empty     }\zeropoint

% not safe for 2\parindent
%
% \def\dosetleftskipadaption#1%
%   {\leftskipadaption
%      \ifcsname @lsa@#1\endcsname
%        \csname @lsa@#1\endcsname
%      \else
%        #1%
%      \fi
%    \relax}

\def\dosetleftskipadaption#1%
  {\edef\ascii{@lsa@#1}%
   \convertcommand\ascii\to\ascii
   \leftskipadaption
     \ifcsname\ascii\endcsname
       \csname\ascii\endcsname
     \else
       #1%
     \fi
   \relax}

\def\dosetrightskipadaption#1%
  {\edef\ascii{@rsa@#1}%
   \convertcommand\ascii\to\ascii
   \rightskipadaption
     \ifcsname\ascii\endcsname
       \csname\ascii\endcsname
     \else
       #1%
     \fi
   \relax}

\endETEX

% \definetwopasslist\s!paragraph
%
% \newcounter\nofraggedparagraphs
%
% \def\doparagraphreference% looks very much like domarginreference
%   {\doglobal\increment\nofraggedparagraphs
%    \edef\writeparref%
%      {\writeutilitycommand%
%         {\twopassentry%
%            {\s!paragraph}%
%            {\nofraggedparagraphs}%
%            {\noexpand\realfolio}}}%
%    \writeparref}
%
% \def\setraggedparagraphmode#1#2% combineren met \ifrightpage
%   {\ifinpagebody
%      \ifdoublesided
%        \ifodd\realpageno\relax#1\else#2\fi
%      \else
%        #2\relax
%      \fi
%    \else\ifinner
%      \ifdoublesided
%        \gettwopassdata\s!paragraph
%        \iftwopassdatafound
%          \ifodd\twopassdata\relax#1\else#2\fi
%        \else
%          \ifodd\realpageno\relax#1\else#2\fi
%        \fi
%        \doparagraphreference
%      \else
%        #2\relax
%      \fi
%    \else
%      #2\relax
%    \fi\fi}
%
% \def\doifrightpageelse % watch out: other default ! ! !
%   {\ifinpagebody
%      % optimalisation ?
%      \ifdoublesided
%        \ifodd\realpageno\relax
%          \twopassdatafoundtrue \else \twopassdatafoundfalse
%        \fi
%      \else
%        \twopassdatafoundtrue
%      \fi
%    \else
%      \ifdoublesided
%        \gettwopassdata\s!paragraph
%        \iftwopassdatafound
%          \ifodd\twopassdata\relax
%            \twopassdatafoundtrue \else \twopassdatafoundfalse
%          \fi
%        \else
%          \ifodd\realpageno\relax
%            \twopassdatafoundtrue \else \twopassdatafoundfalse
%          \fi
%        \fi
%      \else
%        \twopassdatafoundtrue
%      \fi
%    \fi
%    \iftwopassdatafound
%      \@EA\firstoftwoarguments
%    \else
%      \@EA\secondoftwoarguments
%    \fi}
%
% \def\signalrightpage
%   {\ifdoublesided \ifinpagebody \else
%      \doparagraphreference
%    \fi \fi}

% slightly adapted implementation

\newcounter \noftrackedpagestates
\newif      \ifpagestatemismatch
\let        \realpagestateno      \realfolio
\chardef    \frozenpagestate      \zerocount

\def\dotrackpagestate#1#2%
  {\ifdoublesided \ifinpagebody \else
     \doforcedtrackpagestate{#1}{#2}%
   \fi \fi}

\def\doforcedtrackpagestate#1#2%
  {\ifcase\frozenpagestate
     \doglobal\increment\noftrackedpagestates
     \doglobal\increment#2%
     \edef\dodotrackpagestate
       {\writeutilitycommand
          {\twopassentry{#1}{\noftrackedpagestates}{#2:\noexpand\realfolio}}}%
     %\llap{\infofont\noftrackedpagestates/#2}% tracing
     \dodotrackpagestate
   \fi}

\def\doifrightpagestateelse#1#2%
  {\ifcase\frozenpagestate
     \pagestatemismatchfalse
     \let\realpagestateno\realfolio
     \ifinpagebody
       \ifdoublesided
         \ifodd\realpageno\relax
           \twopassdatafoundtrue \else \twopassdatafoundfalse
         \fi
       \else
         \twopassdatafoundtrue
       \fi
     \else\ifdoublesided
       \findtwopassdata{#1}{#2:}%
       \iftwopassdatafound
         \let\realpagestateno\twopassdata
         \ifnum\twopassdata=\realpageno \else
           \pagestatemismatchtrue
         \fi
         \ifodd\twopassdata\relax
           \twopassdatafoundtrue \else \twopassdatafoundfalse
         \fi
       \else
         \ifodd\realpageno\relax
           \twopassdatafoundtrue \else \twopassdatafoundfalse
         \fi
       \fi
     \else
       \twopassdatafoundtrue
     \fi\fi
   \else
     \ifodd\realpagestateno\relax
       \twopassdatafoundtrue \else \twopassdatafoundfalse
     \fi
   \fi
   \iftwopassdatafound
     \@EA\firstoftwoarguments
   \else
     \@EA\secondoftwoarguments
   \fi}

\def\doifforcedrightpagestateelse#1#2%
  {\ifcase\frozenpagestate
     \pagestatemismatchfalse
     \let\realpagestateno\realfolio
     \findtwopassdata{#1}{#2:}%
     \iftwopassdatafound
       \let\realpagestateno\twopassdata
       \ifnum\twopassdata=\realpageno \else
         \pagestatemismatchtrue
       \fi
       \ifodd\twopassdata\relax
         \twopassdatafoundtrue \else \twopassdatafoundfalse
       \fi
     \else
       \ifodd\realpageno\relax
         \twopassdatafoundtrue \else \twopassdatafoundfalse
       \fi
     \fi
   \else
     \ifodd\realpagestateno\relax
       \twopassdatafoundtrue \else \twopassdatafoundfalse
     \fi
   \fi
   \iftwopassdatafound
     \@EA\firstoftwoarguments
   \else
     \@EA\secondoftwoarguments
   \fi}

\def\freezepagestate {\chardef\frozenpagestate\plusone  }
\def\defrostpagestate{\chardef\frozenpagestate\zerocount}

% we can make more of these on top, but how to deal with mixed frozen states

\definetwopasslist\s!paragraph \newcounter\nofraggedparagraphs

\def\signalrightpage  {\dotrackpagestate      \s!paragraph\nofraggedparagraphs}
\def\doifrightpageelse{\doifrightpagestateelse\s!paragraph\nofraggedparagraphs}

\newcounter\pagesignallevel

\def\startsignalrightpage % one may do a \postsignalrightplace
  {\increment\pagesignallevel
   \presignalrightpage
   \let\signalrightpage\relax
   \let\presignalrightpage\relax
   \let\startsignalrightpage\relax
   \doifrightpageelse\donothing\donothing
   \freezepagestate}

\def\stopsignalrightpage
  {\ifcase\pagesignallevel\or\postsignalrightpage\fi
   \decrement\pagesignallevel}

\def\setraggedparagraphmode{\signalrightpage\doifrightpageelse} % move it there

\def\doifswappedrightpageelse#1#2% alleen in box construction !
  {\doifrightpageelse
     {#1}
     {\scratchcounter\realpageno
      \realpageno\realpagestateno\relax
      \swapmargins
      \realpageno\scratchcounter
      #2}}

\newbox\signaledrightpage % this way we can avoid interference, i.e. postpone placement

\def\presignalrightpage {\global\setbox\signaledrightpage\hbox{\signalrightpage}}
\def\postsignalrightpage{\ifvoid\signaledrightpage\else\box\signaledrightpage\fi}

% The next feature is is used in:
%
% \definenumber[test][way=bypage]
%
% \def\Test
%   {\incrementnumber[test]\rawnumber[test]/%
%    \incrementnumber[test]\rawnumber[test]/%
%    \incrementnumber[test]\rawnumber[test]\space
%    \checkpagechange{oeps}\changedpage{oeps}\space
%    \ifpagechanged TRUE\else FALSE\fi}
%
% \Test\page \Test\par \Test\page \Test\par \Test\page \Test\page
%
% (adapted from cont-new.tex:)

\newif\ifpagechanged \let\lastchangedpage\empty

\def\docheckpagestatechange#1#2#3%
  {\pagechangedfalse
   \doforcedtrackpagestate{#2}{#3}%
   \findtwopassdata{#2}{#3:}%
   \iftwopassdatafound
     \ifnum\twopassdata>0\getvalue{#2:p:#1}\relax
       \pagechangedtrue
     \fi
   \fi
   \ifpagechanged
     \letgvalue{#2:p:#1}\twopassdata
     \globallet\lastchangedpage\twopassdata
   \else
     \globallet\lastchangedpage\realfolio
   \fi}

\def\changedpagestate#1#2%
  {\executeifdefined{#2:p:#1}{0}}

\def\checkpagechange#1{\docheckpagestatechange{#1}\s!paragraph\nofraggedparagraphs}
\def\changedpage    #1{\changedpagestate{#1}\s!paragraph}

% saved struts

\ifx\savedstrutbox\undefined \newbox\savedstrutbox \fi

\def\savestrut {\setbox\savedstrutbox\copy\strutbox}
\def\savedstrut{\copy  \savedstrutbox}

% De onderstaande macro's zijn opgenomen in Plain TeX.
%
% \def\raggedright%
%   {\rightskip\z@ plus2em \spaceskip.3333em \xspaceskip.5em\relax}
%
% \def\ttraggedright%
%   {\tttf\rightskip\z@ plus2em\relax}
%
% \newif\ifr@ggedbottom
%
% \def\raggedbottom%
%   {\topskip 10\p@ plus60\p@ \r@ggedbottomtrue}
%
% \def\normalbottom%
%   {\topskip 10\p@ \r@ggedbottomfalse}
%
% en worden hieronder wat aangepast.

% the three boolean will become obsolete some day in favour
% of \bottomraggedness

\chardef\bottomraggedness=0 % 0=ragged 1=normal/align 2=baseline

\def\bottomalignlimit{3\lineheight}

\newif\ifn@rmalbottom
\newif\ifr@ggedbottom
\newif\ifb@selinebottom

\def\normalbottom
  {% \topskip 10pt
   \r@ggedbottomfalse}

\def\raggedbottom
  {\chardef\bottomraggedness\zerocount
   \n@rmalbottomfalse
   \r@ggedbottomtrue
   \b@selinebottomfalse
   \settopskip}

\def\alignbottom
  {\chardef\bottomraggedness\plusone
   \n@rmalbottomtrue
   \r@ggedbottomfalse
   \b@selinebottomfalse
   \settopskip}

\def\baselinebottom
  {\chardef\bottomraggedness\plustwo
   \n@rmalbottomfalse
   \r@ggedbottomfalse
   \b@selinebottomtrue
   \settopskip}

\let\normalbottom=\alignbottom % downward compatible

% so, the new one will be
%
% \chardef\bottomraggedness=0 % 0=ragged 1=normal/align 2=baseline
%
% \def\bottomalignlimit{3\lineheight} % will be settable
%
% \def\raggedbottom  {\chardef\bottomraggedness=0 \settopskip}
% \def\alignbottom   {\chardef\bottomraggedness=1 \settopskip}
% \def\baselinebottom{\chardef\bottomraggedness=2 \settopskip}
%
% \let\normalbottom  =\alignbottom

% \hyphenpenalty  = ( 2.5 * \hsize ) / \raggedness
% \tolerance     >= 1500 % was 200
% \raggedness     = 2 .. 6\bodyfontsize

\chardef\raggedstatus=0 % normal left center right

\def\leftraggedness   {2\bodyfontsize}
\def\rightraggedness  {2\bodyfontsize}
\def\middleraggedness {6\bodyfontsize}

\def\middleraggedness {.5\hsize} % was: 6\bodyfontsize, fails on: \placefigure{x $x=x$ x}{}

%D More hyphenation control, will be combined with align
%D setup.

\def\nohyphens
  {\ifx\dohyphens\relax
     \edef\dohyphens
       {\hyphenpenalty\the\hyphenpenalty
        \exhyphenpenalty\the\exhyphenpenalty\relax}%
   \fi
   \hyphenpenalty\plustenthousand
   \exhyphenpenalty\plustenthousand}

\let\dohyphens\relax

%D To prevent unwanted side effects, we also have to check
%D for hyphens here:

% \def\setraggedness#1%
%   {\ifnum\tolerance<1500\relax    % small values have
%      \tolerance1500\relax         % unwanted side effects
%    \fi
%    \spaceskip2.5\hsize            % we misuse these registers
%    \xspaceskip#1\relax            % for temporary storage;
%    \divide\spaceskip \xspaceskip  % they are changed anyway
%    \ifx\dohyphens\relax
%      \hyphenpenalty\spaceskip     % \else no hyphens is active
%    \fi}

\newskip\@@raggedskipa
\newskip\@@raggedskipb

\def\setraggedness#1%
  {\ifnum\tolerance<1500\relax    % small values have
     \tolerance1500\relax         % unwanted side effects
   \fi
   \ifx\dohyphens\relax
     % this code will be reconsidered / kind of fuzzy (and old)
     \@@raggedskipa 2.5\hsize
     \@@raggedskipb  #1\relax
     \divide\@@raggedskipa \@@raggedskipb
     \hyphenpenalty\@@raggedskipa
   \fi}

\let\updateraggedskips\relax

\def\setraggedskips#1#2#3#4#5#6#7% never change this name
  {\def\updateraggedskips{\dosetraggedskips{#1}{#2}{#3}{#4}{#5}{#6}{#7}}%
   \updateraggedskips}

\def\dosetraggedskips#1#2#3#4#5#6#7%
  {\chardef    \raggedstatus#1\relax
   \leftskip   1\leftskip \!!plus#2\relax % zie: Tex By Topic 8.1.3
   \rightskip  1\rightskip\!!plus#3\relax % zie: Tex By Topic 8.1.3
   \spaceskip  #4\relax
   \xspaceskip #5\relax
   \parfillskip\zeropoint\!!plus#6\relax
   \parindent  #7\relax}

% \def\notragged%
%   {\setraggedskips{0}{0em}{0em}{0em}{0em}{1fil}{\parindent}}

% todo

\def\raggedfillamount    {1fil}
\def\raggedhalffillamount{.5fil}
\def\raggedspaceamount   {.3333em}
\def\raggedxspaceamount  {.5em}

\def\notragged
  {\chardef\raggedstatus\zerocount
   \leftskip1\leftskip
   \rightskip1\rightskip
   \spaceskip\zeropoint
   \xspaceskip\zeropoint
   \parfillskip\zeropoint\!!plus\raggedfillamount\relax
   \let\updateraggedskips\relax} % new

\let\forgetragged\notragged

\def\raggedleft
  {\setraggedness\leftraggedness
   \setraggedskips1\leftraggedness\zeropoint\raggedspaceamount
     \raggedxspaceamount\zeropoint\zeropoint}

\def\raggedcenter
  {\setraggedness\middleraggedness
   \setraggedskips2\middleraggedness\middleraggedness\raggedspaceamount
     \raggedxspaceamount\zeropoint\zeropoint}

%D We used to have:
%D
%D \starttyping
%D \def\raggedright
%D   {\setraggedness\rightraggedness
%D    \setraggedskips{3}{0em}{\rightraggedness}{.3333em}{.5em}{0em}{\parindent}}
%D \stoptyping
%D
%D However, the next alternative, suggested by Taco, is better.

\def\raggedright
  {\setraggedness\rightraggedness
   \setraggedskips3\zeropoint\rightraggedness\raggedspaceamount
     \raggedxspaceamount\raggedfillamount\parindent}

\def\veryraggedleft
  {\setraggedskips1\raggedfillamount\zeropoint\raggedspaceamount
     \raggedxspaceamount\zeropoint\zeropoint}

%D When we want the last line to have a natural width:
%D
%D \starttyping
%D \def\veryraggedleft%
%D   {\setraggedskips{1}{1fil}{0em}{.3333em}{.5em}{0em}{-1fil}}
%D \stoptyping
%D
%D but this one is not accepted by the macros.

\def\veryraggedcenter
  {\setraggedskips2\raggedfillamount\raggedfillamount\raggedspaceamount
     \raggedxspaceamount\zeropoint\zeropoint}

\def\veryraggedright
  {\setraggedskips3\zeropoint\raggedfillamount\raggedspaceamount
     \raggedxspaceamount\zeropoint\parindent}

\def\ttraggedright
  {\tttf
   \setraggedskips3\zeropoint\rightraggedness
     \zeropoint\zeropoint\zeropoint\parindent} % \ctxparindent

%D A bonus one:

\def\raggedwidecenter
  {\setraggedness\middleraggedness
   \setraggedskips2\raggedhalffillamount\raggedhalffillamount
     \raggedspaceamount\raggedxspaceamount\zeropoint\zeropoint}

\newif\if@@asragged \@@asraggedtrue % old method

% todo
%
% \setuplayout[grid=yes,lines=44] \showgrid
% \starttext
% test \vfill test \endgraf \strut \endgraf \vskip-\lineheight \removedepth \pagina test
% \stoptext

% Keep this one:
%
% \def\setupalign
%   {\dosingleargument\dosetupalign}
%
% \def\dosetupalign[#1]%
%   {\expanded{\dodosetupalign[#1]}}
%
% \def\dodosetupalign[#1]%
%   {\doifinsetelse\v!broad {#1}\!!doneatrue\!!doneafalse
%    \doifinsetelse\v!wide{#1}\!!donebtrue\!!donebfalse
%    \ExpandFirstAfter\processallactionsinset % expansion redundant
%      [#1]
%      [                        \v!line=>\baselinebottom,
%                             \v!bottom=>\raggedbottom,
%                             \v!height=>\normalbottom,
%                              \v!width=>\notragged,
%                             \v!normal=>\notragged,
%                                \v!yes=>\notragged,
%                                 \v!no=>\raggedright,
% \if@@asragged\v!inner\else\v!outer\fi=>\setraggedparagraphmode\raggedleft\raggedright,
% \if@@asragged\v!outer\else\v!inner\fi=>\setraggedparagraphmode\raggedright\raggedleft,
% \if@@asragged\v!left \else\v!right\fi=>\if!!donea\veryraggedleft  \else\raggedleft  \fi,
% \if@@asragged\v!right\else\v!left \fi=>\if!!donea\veryraggedright \else\raggedright \fi,
%                             \v!middle=>\if!!doneb\raggedwidecenter\else\if!!donea\veryraggedcenter\else\raggedcenter\fi\fi,
%                          \v!flushleft=>\if!!donea\veryraggedright \else\raggedright \fi,
%                         \v!flushright=>\if!!donea\veryraggedleft  \else\raggedleft  \fi,
%                             \v!center=>\if!!doneb\raggedwidecenter\else\if!!donea\veryraggedcenter\else\raggedcenter\fi\fi,
%                            \v!hanging=>\enableprotruding,
%                         \v!nothanging=>\disableprotruding,
%                                 \v!hz=>\enableadjusting,
%                               \v!nohz=>\disableadjusting,
%                         \v!hyphenated=>\dohyphens,
%                      \v!nothyphenated=>\nohyphens,
%                                \v!new=>\@@asraggedfalse, % so new will give you consistency
%                              \v!reset=>\notragged\normalbottom]}
%
% The next one is more than three times faster:

\setvalue{@@align@@\v!line         }{\baselinebottom}
\setvalue{@@align@@\v!bottom       }{\raggedbottom}
\setvalue{@@align@@\v!height       }{\normalbottom}
\setvalue{@@align@@\v!width        }{\notragged}
\setvalue{@@align@@\v!normal       }{\notragged}
\setvalue{@@align@@\v!yes          }{\notragged}
\setvalue{@@align@@\v!no           }{\raggedright}
\setvalue{@@align@@\v!inner        }{\if@@asragged
                                       \setraggedparagraphmode\raggedleft\raggedright
                                     \else
                                       \setraggedparagraphmode\raggedright\raggedleft
                                     \fi}
\setvalue{@@align@@\v!outer        }{\if@@asragged
                                       \setraggedparagraphmode\raggedright\raggedleft
                                     \else
                                       \setraggedparagraphmode\raggedleft\raggedright
                                     \fi}
\setvalue{@@align@@\v!left         }{\if@@asragged
                                       \if!!donea\veryraggedleft\else\raggedleft\fi
                                     \else
                                       \if!!donea\veryraggedright\else\raggedright\fi
                                     \fi}
\setvalue{@@align@@\v!right        }{\if@@asragged
                                       \if!!donea\veryraggedright\else\raggedright\fi
                                     \else
                                       \if!!donea\veryraggedleft\else\raggedleft\fi
                                     \fi}
\setvalue{@@align@@\v!middle       }{\if!!doneb\raggedwidecenter\else\if!!donea\veryraggedcenter\else\raggedcenter\fi\fi}
\setvalue{@@align@@\v!flushleft    }{\if!!donea\veryraggedright \else\raggedright \fi}
\setvalue{@@align@@\v!flushright   }{\if!!donea\veryraggedleft  \else\raggedleft  \fi}
\setvalue{@@align@@\v!center       }{\if!!doneb\raggedwidecenter\else\if!!donea\veryraggedcenter\else\raggedcenter\fi\fi}
\setvalue{@@align@@\v!hanging      }{\enableprotruding}
\setvalue{@@align@@\v!nothanging   }{\disableprotruding}
\setvalue{@@align@@\v!hz           }{\enableadjusting}
\setvalue{@@align@@\v!nohz         }{\disableadjusting}
\setvalue{@@align@@\v!spacing      }{\enablespacehandling \enablekernhandling}
\setvalue{@@align@@\v!nospacing    }{\disablespacehandling\disablekernhandling}
\setvalue{@@align@@\v!hyphenated   }{\dohyphens}
\setvalue{@@align@@\v!nothyphenated}{\nohyphens}
\setvalue{@@align@@\v!new          }{\@@asraggedfalse} % so new will give you consistency
\setvalue{@@align@@\v!reset        }{\notragged\normalbottom}

\setvalue{@@align@@\v!tolerant    }{\tolerance3000   \relax}
\setvalue{@@align@@\v!verytolerant}{\tolerance4500   \relax}
\setvalue{@@align@@\v!stretch     }{\emergencystretch\bodyfontsize}

\setvalue{@@ngila@@\v!broad        }{\!!doneatrue}
\setvalue{@@ngila@@\v!wide         }{\!!donebtrue}

\def\dodosetupalign#1{\getvalue{@@align@@#1}}
\def\dodosetupngila#1{\getvalue{@@ngila@@#1}}

\def\setupalign
  {\dosingleargument\dosetupalign}

\def\dosetupalign[#1]%
  {\!!doneafalse
   \!!donebfalse
   \processcommacommand[#1]\dodosetupngila
   \processcommacommand[#1]\dodosetupalign}

% \setupalign[flushleft]  \input ward \par % lijnlinks
% \setupalign[right]      \input ward \par

% \setupalign[flushright] \input ward \par % lijnrechts
% \setupalign[left]       \input ward \par

% \setupalign[middle]     \input ward \par % centreer
% \setupalign[center]     \input ward \par

\def\startalignment
  {\bgroup
   \setupalign}

\def\stopalignment
  {\par
   \egroup}

\chardef\alignstrutmode=1

% see later for the real definition, which in the simple case is:

\def\doalignline#1#2% \\ == newline
 {\begingroup
  \setlocalhsize % new
  \def\\{\egroup\par\doalignline{#1}{#2}\bgroup}%
  \dowithnextbox
    {\noindentation % was \ noindent
     \hbox to \localhsize
       {\ifcase\alignstrutmode\or\strut\fi
         #1\unhbox\nextbox#2}\endgroup}
    \hbox}

% directe commando's

\def\leftaligned {\doalignline \relax \hss  }
\def\midaligned  {\doalignline \hss   \hss  }
\def\rightaligned{\doalignline \hss   \relax}

\def\regelbegrensd#1{\limitatetext{#1}{\hsize}{\unknown}} % to be translated

% indirecte commando's

\letvalue{\s!do\v!line\v!left  }\leftaligned
\letvalue{\s!do\v!line\v!right }\rightaligned
\letvalue{\s!do\v!line\v!middle}\midaligned

\letvalue{\s!do\v!line\v!flushleft }\rightaligned
\letvalue{\s!do\v!line\v!flushright}\leftaligned
\letvalue{\s!do\v!line\v!center    }\midaligned

\def\doalignedline#1{\csname\s!do\v!line#1\endcsname}

%D Experimental:

% simple version
%
% \def\doxalignline#1#2%
%   {\bgroup
%    \setlocalhsize
%    \def\\{\egroup\par\doxalignline{#1}{#2}\bgroup}% inefficient
%    \dowithnextbox
%      {\noindent\hbox to \localhsize
%         {\ifcase\alignstrutmode\or\strut\fi
%          \signalrightpage
%          \doifrightpageelse{#1\unhbox\nextbox#2}{#2\unhbox\nextbox#1}}%
%       \egroup}
%      \hbox}
%
% \setvalue{\s!do\v!regel\v!binnen}{\doxalignline\relax\hss}
% \setvalue{\s!do\v!regel\v!buiten}{\doxalignline\hss\relax}
%
% more extensive:

\def\doxalignline#1#2#3#4#5#6%
  {\bgroup
   \setlocalhsize
   \def\\{\egroup\par\doxalignline#1#2#3#4#5#6\bgroup}% inefficient
   \dowithnextbox
     {\noindent
      \hbox to \localhsize
        {#1\hskip\ifdone#2\else#3\fi#4%
         \hbox to \localhsize
           {\ifcase\alignstrutmode\or\strut\fi
            \ifdone#5\unhbox\nextbox#6\else#6\unhbox\nextbox#5\fi}%
         \hss}%
        \egroup}
     \hbox}

\def\doxcheckline
  {\signalrightpage\doifrightpageelse\donetrue\donefalse}

\setvalue{\s!do\v!line\v!inner      }{\doxalignline\doxcheckline++\zeropoint       \relax\hss  }
\setvalue{\s!do\v!line\v!outer      }{\doxalignline\doxcheckline++\zeropoint       \hss  \relax}
\setvalue{\s!do\v!line\v!innermargin}{\doxalignline\doxcheckline-+\innermargintotal\relax\hss  }
\setvalue{\s!do\v!line\v!outermargin}{\doxalignline\doxcheckline+-\outermargintotal\hss  \relax}
\setvalue{\s!do\v!line\v!inneredge  }{\doxalignline\doxcheckline-+\inneredgetotal  \relax\hss  }
\setvalue{\s!do\v!line\v!outeredge  }{\doxalignline\doxcheckline+-\outeredgetotal  \hss  \relax}
\setvalue{\s!do\v!line\v!backspace  }{\doxalignline\doxcheckline-+\backspace       \relax\hss  }
\setvalue{\s!do\v!line\v!cutspace   }{\doxalignline\doxcheckline+-\cutspace        \hss  \relax}

\setvalue{\s!do\v!line\v!leftmargin }{\doxalignline\donefalse   --\leftmargintotal \hss  \relax}
\setvalue{\s!do\v!line\v!rightmargin}{\doxalignline\donefalse   ++\rightmargintotal\relax\hss  }
\setvalue{\s!do\v!line\v!leftedge   }{\doxalignline\donefalse   --\leftedgetotal   \hss  \relax}
\setvalue{\s!do\v!line\v!rightedge  }{\doxalignline\donefalse   ++\rightedgetotal  \relax\hss  }

% ! ! ! beware, redefining \doalignline gives the wrong results ! ! !
%
% \def\doalignline{\doxalignline\donefalse++\zeropoint}

%D Better:

\def\doalignedline#1{\csname\s!do\v!line#1\endcsname}

\def\alignedline#1#2% setting default
  {\csname
     \s!do\v!line
     \ifundefined{\s!do\v!line#1}#2\else#1\fi
   \endcsname}

% \def\doalignedline#1%
%   {\alignedline{#1}\v!links}

%D ...

\def\dosetuptolerance[#1]%
  {\doifinsetelse\v!vertical{#1}%
     {\ExpandFirstAfter\processallactionsinset
        [#1]
        [  \v!verystrict=>\def\bottomtolerance{},
               \v!strict=>\def\bottomtolerance{.050},
             \v!tolerant=>\def\bottomtolerance{.075},
         \v!verytolerant=>\def\bottomtolerance{.100}]}%
     {\ExpandFirstAfter\processallactionsinset
        [#1]
        [     \v!stretch=>\emergencystretch\bodyfontsize,
                \v!space=>\spaceskip.5em\!!plus.25em\!!minus.25em\relax,
           \v!verystrict=>\tolerance 200,
               \v!strict=>\tolerance1500,
             \v!tolerant=>\tolerance3000,
         \v!verytolerant=>\tolerance4500]}}

\def\setuptolerance
  {\dosingleargument\dosetuptolerance}

% \def\woordrechts
%   {\groupedcommand{\hfill\hbox}{\parfillskip\zeropoint}}

% beware: \wordright{whatever\kern-\rightskip} should work!
% so, no funny boxing here

\def\dowordright[#1]%
  {% don't change
   \groupedcommand
     {\removeunwantedspaces
      \hfill
      \allowbreak % changed back from \hskip\zeropoint
      \strut
      \hfill
      \quad % decent spacing
      \hbox}
     {\doifelse{#1}\v!right{\kern-\rightskip}{\doifsomething{#1}{\kern-#1}}%
      \parfillskip\zeropoint
      \par}}

\def\wordright
  {\dosingleempty\dowordright}

% \dorecurse{5}{something } \wordright{--someone} \endgraf
% \dorecurse{6}{something } \wordright{--someone} \endgraf
% \dorecurse{7}{something } \wordright{--someone} \endgraf
%
% \dorecurse{5}{something } \wordright{--someone else entirely} \endgraf
% \dorecurse{6}{something } \wordright{--someone else entirely} \endgraf
% \dorecurse{7}{something } \wordright{--someone else entirely} \endgraf
%
% \wordright[\rightskip]{whatever}

%D \macros
%D   {pushindentation,popindentation}
%D
%D The pushing and popping is done by:

\newbox\indentationboxA
\newbox\indentationboxB

\def\pushindentation
  {\bgroup
   \ifhmode
     \unskip
     \setbox\indentationboxA\lastbox       % get \strut if present
     \unskip
     \setbox\indentationboxB\lastbox       % get \indent generated box
     \unskip
   \else
     \hskip\zeropoint                      % switch to horizontal mode
     \unskip
     \setbox\indentationboxA\lastbox       % get \indent generated box
     \setbox\indentationboxB\box\voidb@x
   \fi}

\def\popindentation
  {\box\indentationboxB\box\indentationboxA % put back the boxes
   \egroup}

%D The only complication lays in \type{\strut}. In \PLAIN\
%D \TEX\ a \type{\strut} is defined as:
%D
%D \starttyping
%D \def\strut%
%D   {\relax\ifmmode\copy\strutbox\else\unhcopy\strutbox\fi}
%D \stoptyping
%D
%D But what is a \type{\strut}? Normally it's a rule of width
%D zero, but when made visual, it's a rule and a negative skip.
%D The mechanism for putting things in the margins described
%D here cannot handle this situation very well. One
%D characteristic of \type{\strut} is that the \type{\unhcopy}
%D results in entering horizontal mode, which in return leads
%D to some indentation.
%D
%D To serve our purpose a bit better, the macro \type{\strut}
%D can be redefined as:
%D
%D \starttyping
%D \def\strut
%D   {\relax\ifmmode\else\hskip0pt\fi\copy\strutbox}
%D \stoptyping
%D
%D Or more compatible:
%D
%D \starttyping
%D \def\strut
%D   {\relax\ifmmode
%D      \copy\strutbox
%D    \else
%D      \bgroup\setbox\strutbox=\normalhbox{\box\strutbox}\unhcopy\strutbox\egroup
%D    \fi}
%D \stoptyping
%D
%D In \CONTEXT\ however we save some processing time by putting
%D an extra \type{\hbox} around the \type{\strutbox}.

% moved from page-lin.tex to here (due to visualization added
% in august 2003)
%
% \unexpanded \def\crlf
%   {\ifhmode\unskip\else\strut\fi\ifcase\raggedstatus\hfil\fi\break}

\unexpanded \def\crlf
  {\ifhmode
     \unskip
     \prewordbreak\crlfplaceholder
     \ifcase\raggedstatus\hfil\or\or\or\hfil\fi
     \break
   \else
     \crlfplaceholder
     \endgraf
   \fi}

\def\crlfplaceholder
  {\strut}

\def\settestcrlf
  {\def\crlfplaceholder
     {\hbox to \zeropoint
        {\strut{\infofont\kern.25em}\lohi{\infofont CR}{\infofont LF}\hss}}}

%D \starttyping
%D % \setuplayout[gridgrid=yes] \showgrid
%D
%D \startbuffer
%D test 1\crlf
%D test 2\crlf
%D
%D \crlf test 3
%D
%D test 4\crlf
%D test 5
%D
%D \crlf
%D \crlf
%D \crlf
%D test 6
%D \stopbuffer
%D
%D \hbox
%D   {\hsize5em
%D    \ruledvtop{\getbuffer}\enspace
%D    \ruledvtop{\showstruts\getbuffer}\enspace
%D    \hsize15em \setuptyping[before=,after=]%
%D    \ruledvtop{\typebuffer}}
%D \stoptyping

\def\opeenregel % to be used grouped
  {\def\crlf{\removelastspace\space}\let\\\crlf}

\def\showstruts
  {\setteststrut
   \settestcrlf}

\def\definehspace
  {\dotripleempty\dodefinehspace}

\def\dodefinehspace[#1][#2][#3]% #1 = optional namespace
  {\ifthirdargument
     \setvalue{\??hs#1:#2}{#3}%
   \else
     \setvalue{\??hs:#1}{#2}%
   \fi}

\unexpanded\def\hspace
  {\dodoubleempty\dohspace}

%\def\dohspace[#1][#2]%
%  {\ifhmode
%     \removeunwantedspaces
%     \hskip
%     \ifsecondargument
%       \hspaceamount{#1}{#2}%
%     \else
%       \hspaceamount\empty{\iffirstargument#1\else\s!default\fi}%
%     \fi
%     \expandafter\ignorespaces
%   \fi}

\def\dohspace[#1][#2]%
  {\ifsecondargument
     \dodohspace[#1][#2]%
   \else\iffirstargument
     \hspace[][#1]%
   \else
     \hspace[][\s!default]%
   \fi\fi}

% \def\dodohspace[#1][#2#3]%
%   {\ifhmode
%      \removeunwantedspaces
%      \doifelse{#2}{-}
%        {{\scratchskip\hspaceamount{#1}{#3}\hskip-\scratchskip}}
%        {\hskip\hspaceamount{#1}{#2#3}}%
%      \expandafter\ignorespaces
%     \fi}
%
% not needed, tex handles -- as +

\def\dodohspace[#1][#2]%
  {\ifhmode
     \removeunwantedspaces
     \hskip\hspaceamount{#1}{#2}%
     \expandafter\ignorespaces
    \fi}

\def\hspaceamount#1#2%
  {\executeifdefined{\??hs#1:#2}{\executeifdefined{\??hs:#2}\zeropoint}}

\def\emspaceamount{\fontdimen6\font}
\def\spaceamount  {\fontdimen2\font}

\definehspace [\v!small]   [.25\emspaceamount]
\definehspace [\v!medium]  [.5\emspaceamount]
\definehspace [\v!big]     [1\emspaceamount]
\definehspace [\v!normal]  [1\spaceamount]
\definehspace [\v!default] [\spaceamount]

%D Taken from Taco's math module (cq. \AMS\ macros), but
%D adapted to \type {\hspace}:

\unexpanded\def\textormathspace#1#2#3%
  {\ifmmode\mskip#1#2\else\kern#1\hspaceamount\empty{#3}\fi\relax}

\def\thinspace    {\textormathspace+\thinmuskip 1}
\def\medspace     {\textormathspace+\medmuskip  2}
\def\thickspace   {\textormathspace+\thickmuskip3}
\def\negthinspace {\textormathspace-\thinmuskip 1}
\def\negmedspace  {\textormathspace-\medmuskip  2}
\def\negthickspace{\textormathspace-\thickmuskip3}

\let \, \thinspace
\let \: \medspace
\let \; \thickspace
\let \! \negthinspace

\definehspace[1][.1667em]
\definehspace[2][.2222em]
\definehspace[3][.2777em]

% this will become an alternative bunch of \blank settings
%
% \startlines
% \scratchskip=.23pt plus 10pt minus 4pt \relax \number\scratchskip \space \the\scratchskip
% \setsimplifiedskip\scratchskip1 \number\scratchskip \space \the\scratchskip
% \setsimplifiedskip\scratchskip2 \number\scratchskip \space \the\scratchskip
% \getsimplifiedskip\scratchskip\scratchcounter \number\scratchcounter
% \stoplines
%
% \hrule width10cm \endgraf
%   \discardedskip{10pt}
%   \retainedskip  {4pt}
%   \discardedskip {5pt}
% \hrule width10cm \endgraf
%   \blockedskip{0pt}
%   \discardedskip{10pt}
%   \retainedskip  {4pt}
%   \discardedskip {5pt}
% \hrule width10cm \endgraf
%   \frozenskip    {4cm}
% \hrule width10cm \endgraf
%   \vskip10pt
% \hrule width10cm \endgraf

% ! ! ! etex only, evt splitskip macro gebruiken (syst-new)

\newskip\simplifiedskip
\newskip\simplifiedcounter

\chardef\@@discardedskip1
\chardef\@@retainedskip 2
\chardef\@@forcedskip   3
\chardef\@@blockedskip  4
\chardef\@@frozenskip   5 % after heads, no break

\def\setsimplifiedskip#1#2%
  {#1\dimexpr(10\dimexpr(#1/10)) plus \gluestretch#1 minus \glueshrink#1\relax
   \advance#1\numexpr(#2)sp\relax}

\def\getsimplifiedskip#1#2%
  {\simplifiedskip#1\relax
   \ifzeropt\simplifiedskip % \ifdim\simplifiedskip=\zeropoint
     #2\zerocount
   \else
     \simplifiedcounter\dimexpr10\dimexpr#1/10\relax\relax
     \advance\simplifiedskip-\simplifiedcounter
     #2\number\simplifiedskip\relax
   \fi}

\def\conditionalskip#1#2%
  {\scratchskip#1\relax
   \setsimplifiedskip\scratchskip#2\relax
   \vskip\scratchskip\relax}

\def\defrostskip
  {\scratchskip\lastskip\penalty50000\normalvskip-\scratchskip\penalty50000\relax}

\def\frozenskip#1%
  {\endgraf
   \ifvmode
     \getsimplifiedskip\lastskip\scratchcounter
     \ifdim\lastskip>#1\else
       \defrostskip
       \conditionalskip{#1}\@@frozenskip
     \fi
   \fi}

\def\discardedskip#1%
  {\endgraf
   \ifvmode
     \getsimplifiedskip\lastskip\scratchcounter
     \ifcase\scratchcounter
       \conditionalskip{#1}\@@discardedskip
     \or % discard
       \ifdim\lastskip>#1\else
         \normalvskip-\lastskip
         \conditionalskip{#1}\@@discardedskip
       \fi
     \or % retain
       \ifdim\lastskip>#1\else
         \normalvskip-\lastskip
         \conditionalskip{#1}\@@discardedskip
       \fi
     \or % forced
       \conditionalskip{#1}\@@discardedskip
     \or % ignored
     \or % frozen
       \ifdim\lastskip>#1\else
         \defrostskip
         \conditionalskip{#1}\@@frozenskip
       \fi
     \else\ifdim#1=\zeropoint\else
       \vskip#1\relax
     \fi\fi
   \fi}

\def\retainedskip#1%
  {\endgraf
   \ifvmode
     \getsimplifiedskip\lastskip\scratchcounter
     \ifcase\scratchcounter
       \conditionalskip{#1}\@@retainedskip
     \or % discard
       \normalvskip-\lastskip
       \conditionalskip{#1}\@@retainedskip
     \or % retain
       \ifdim\lastskip>#1\else
         \normalvskip-\lastskip
         \conditionalskip{#1}\@@retainedskip
       \fi
     \or % forced
       \conditionalskip{#1}\@@retainedskip
     \or % ignored
     \or % frozen
       \ifdim\lastskip>#1\else
         \defrostskip
         \conditionalskip{#1}\@@frozenskip
       \fi
     \else\ifdim#1=\zeropoint\else
       \vskip#1\relax
     \fi\fi
  \fi}

\def\forcedskip#1%
  {\endgraf
   \ifvmode
     \conditionalskip{#1}\@@forcedskip
   \fi}

\def\blockedskip#1%
  {\endgraf
   \ifvmode
     \getsimplifiedskip\lastskip\scratchcounter
     \ifcase\scratchcounter
       \conditionalskip{#1}\@@blockedskip
     \or % discard
       \conditionalskip{#1}\@@blockedskip
     \or % retain
       \conditionalskip{#1}\@@blockedskip
     \or % forced
       \conditionalskip{#1}\@@blockedskip
     \or % ignored
     \or % frozen
       \ifdim\lastskip>#1\else
         \defrostskip
         \conditionalskip{#1}\@@frozenskip
       \fi
     \else\ifdim#1=\zeropoint\else
       \vskip#1\relax
     \fi\fi
   \fi}

% beware, changing this will break some code (like pos/backgrounds)

\newtoks\everyfirstparagraphintro
\newtoks\everynextparagraphintro
\newtoks\@@everyparagraphtoks

\chardef\everyparagraphintro\zerocount

\def\setupparagraphintro
  {\dodoubleempty\dosetupparagraphintro}

\def\dosetupparagraphintro[#1][#2]%
  {\processallactionsinset
     [#1]
     [   \v!reset=>\global\chardef\everyparagraphintro\zerocount
                   \global\everyfirstparagraphintro\emptytoks
                   \global\everynextparagraphintro \emptytoks,
         \v!first=>\global\chardef\everyparagraphintro\plusone
                   \doglobal\appendtoks#2\to\everyfirstparagraphintro,
          \v!next=>\ifcase\everyparagraphintro\global\chardef\everyparagraphintro\plusone\fi
                   \doglobal\appendtoks#2\to\everynextparagraphintro,
          \v!each=>\ifcase\everyparagraphintro\global\chardef\everyparagraphintro\plustwo\fi
                   \doglobal\appendtoks#2\to\everyfirstparagraphintro
                   \doglobal\appendtoks#2\to\everynextparagraphintro]}

%D We can say:
%D
%D \starttyping
%D \setupparagraphintro[first][\index{Knuth}]
%D \stoptyping
%D
%D Maybe more convenient is:
%D
%D \starttyping
%D \flushatparagraph{\index{Zapf}}
%D \stoptyping

\def\flushatparagraph#1%
  {\global\chardef\everyparagraphintro\plusone
   \global\appendtoks{#1}\to\everyfirstparagraphintro}

% \def\doinsertparagraphintro
%   {\ifcase\everyparagraphintro\relax
%      % no data
%      \@@everyparagraphtoks\emptytoks
%    \or
%      % first data
%      \global\chardef\everyparagraphintro\plustwo
%      \@@everyparagraphtoks\everyfirstparagraphintro
%      \global\everyfirstparagraphintro\emptytoks
%    \or
%      % next data
%      \@@everyparagraphtoks\everynextparagraphintro
%    \fi
%    \the\@@everyparagraphtoks}

\def\doinsertparagraphintro
  {\begingroup
   \everypar\emptytoks
   \ifcase\everyparagraphintro\relax
     % no data
     \@@everyparagraphtoks\emptytoks
   \or
     % first data
     \global\chardef\everyparagraphintro\plustwo
     \@@everyparagraphtoks\everyfirstparagraphintro
     \global\everyfirstparagraphintro\emptytoks
   \or
     % next data
     \@@everyparagraphtoks\everynextparagraphintro
   \fi
   \the\@@everyparagraphtoks
   \endgroup}

\def\insertparagraphintro
  {\ifcase\everyparagraphintro\else\@EA\doinsertparagraphintro\fi}

%  \appendtoksonce\insertparagraphintro\to\everypar % should come last

%D \starttyping
%D \setupparagraphintro[first][\hbox to 3.5em{\tt FIRST \hss}]
%D \setupparagraphintro[first][\hbox to 3.5em{\tt TSRIF \hss}]
%D \setupparagraphintro[next] [\hbox to 3.5em{\tt NEXT  \hss}]
%D \setupparagraphintro[next] [\hbox to 3.5em{\tt TXEN  \hss}]
%D \setupparagraphintro[each] [\hbox to 3.0em{\tt EACH  \hss}]
%D \setupparagraphintro[each] [\hbox to 3.0em{\tt HCEA  \hss}]
%D
%D some paragraph \par
%D some paragraph \par
%D some paragraph \par
%D
%D \definelabel[parnumber]
%D
%D \setupparagraphintro[reset,each][\inleft{\slxx\parnumber}]
%D
%D some paragraph \par
%D some paragraph \par
%D some paragraph \par
%D \stoptyping

%D \macros
%D   {flushatnextpar}
%D
%D This macro collects data that will be flushed at the next paragraph.
%D By using this macro you can avoid interfering nodes (writes, etc).

\newbox \postponednodedata

\def\flushatnextpar
  {\bgroup
   \dowithnextbox
     {\global\setbox\postponednodedata\hbox{\box\postponednodedata\box\nextbox}\egroup}%
     \hbox}

\def\flushpostponednodedata
  {\ifvoid\postponednodedata\else
     \hbox{\smashedbox\postponednodedata}%
   \fi}

% Very nasty but needed for margin stuff inside colored
% paragraphs.

\let\normalvadjust\vadjust

% \def\graphicvadjust % bad, those low level color calls here
%   {\dowithnextbox
%      {\normalvadjust
%         {\dostartgraphicgroup
%          \localstarttextcolor
%          \unvbox\nextbox
%          \localstoptextcolor
%          \dostopgraphicgroup}}%
%      \vbox}

% test this prikkels/pascal margin text before heads (mode
% 1) as well as uitwerkingen (mode 2)

%chardef\graphicvadjustmode=0 % fake
%chardef\graphicvadjustmode=1 % normal
\chardef\graphicvadjustmode=2 % normal + compensate (== default)

\def\graphicvadjust % bad, those low level color calls here
  {\dowithnextboxcontent
     {\forgetall}
     {\ifcase\graphicvadjustmode \@EA \fakedvadjust \else \@EA\normalvadjust \fi
        {\dostartgraphicgroup % don't ask
         \localstarttextcolor
         \unvbox\nextbox
         \localstoptextcolor  % don't ask
         \dostopgraphicgroup
         \ifcase\graphicvadjustmode \or \or
           % corrects for one line paragraphs
           \nointerlineskip
           \kern-\struttotal
           \nointerlineskip
           \verticalstrut
         \fi}}%
     \vbox}

%D This works only in a properly strutted line, and is meant
%D for deeply burried operations, like in heads.

\def\fakedvadjust
  {\dowithnextbox
     {\setbox\nextbox\hbox{\llap{\lower\strutdepth\box\nextbox}}%
      \smashedbox\nextbox}%
   \vtop}

\def\flexiblespaceamount#1#2#3%
         {#1\fontdimen2\font
   \!!plus#2\fontdimen3\font
  \!!minus#3\fontdimen4\font}

\def\fixedspaceamount#1%
  {#1\fontdimen2\font}

%D This is a dangerous feature because it makes the \TEX\ source
%D less portable, i.e. any parser now needs to apply exactly the
%D same algorithm when it wants to interpret the source. We
%D strongly recommend not to mention this feature in manuals! It's
%D provided for users who are hooked to such a mechanism.
%D
%D \starttyping
%D \setupsorting[logo][next=\autoinsertnextspace] \logo[TEX]{\TeX}
%D
%D bla bla \TEX bla bla \TEX (bla) bla (\TEX)
%D \stoptyping

\def\autoinsertnextspace{\futurelet\nexttoken\doautoinsertnextspace}

\def\doautoinsertnextspace % slightly extended version of a user supplied macro
  {\ifx\nexttoken \bgroup\else \ifx\nexttoken\begingroup\else
   \ifx\nexttoken \egroup\else \ifx\nexttoken  \endgroup\else
   \ifx\nexttoken      \/\else \ifx\nexttoken           /\else \ifx\nexttoken      ~\else
   \ifx\nexttoken      \ \else \ifx\nexttoken \blankspace\else \ifx\nexttoken \space\else
   \ifx\nexttoken       .\else \ifx\nexttoken           ,\else
   \ifx\nexttoken       !\else \ifx\nexttoken           ?\else
   \ifx\nexttoken       :\else \ifx\nexttoken           ;\else
   \ifx\nexttoken       '\else \ifx\nexttoken           "\else
   \ifx\nexttoken       )\else \ifx\nexttoken           -\else \ifx\nexttoken      |\else
   \ifx\nexttoken      \%\else \ifx\nexttoken          \&\else
     \space
   \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi}

\setupwhitespace
  [\v!none]

% still old-fachioned

\indenting
  [\v!never]

\setupindenting
  [\v!none]

\setupblank
  [\v!standard,
   \v!big]

\defineblank[\v!default]  [\currentblank]
\defineblank[\v!before]   [\v!default]
\defineblank[\v!inbetween][\v!default]
\defineblank[\v!after]    [\v!before]

\setupinterlinespace
  [\c!minheight=0pt, % only special purpose
   \c!mindepth=0pt, % only special purpose
   \c!height=.72,
   \c!depth=.28,
   \c!top=1.0,
   \c!bottom=0.4,
   \c!distance=1pt,
   \c!line=2.8ex,
   \c!stretch=0]

\setupnarrower
  [\c!left=1.5em,
   \c!right=1.5em,
   \c!middle=1.5em]

\setuptolerance
  [\v!horizontal,\v!verystrict]

\setuptolerance
  [\v!vertical,\v!strict]

\setupalign
  [\v!bottom,
   \v!width]

\setupspacing
  [\v!packed]

\protect \endinput
