%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 ADE \& \CONTEXT\ Development Team}]
%C
%C This module is part of the \CONTEXT\ macro||package and is
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.

\writestatus{loading}{ConTeXt Core Macros / Spacing}

% to be sorted out: dependencies, order of initialization / also some dutch code here

\unprotect

% some will move to core-var

\newif \ifgridsnapping
\newif \iffuzzyvskip
\let   \fuzzyvskip              \gobbleoneargument
\let   \removelastfuzzyvskip    \relax

\let   \startbaselinecorrection \relax
\let   \stopbaselinecorrection  \relax
\let   \baselinecorrection      \relax
\let   \offbaselinecorrection   \relax

\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 \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.

% \lineskiplimit = -\maxdimen -> freezes baselineskip

% 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

\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}%
   \relax}

% \relax is really needed, else we may loose stretch due to lookahead; somehow
% this bug was introduced a while ago but somehow went unnoticed; fixed 2/7/2008

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

\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}
\defineblankmethod[\v!synchronize] {\verticalstrut\vskip-2\lineheight\verticalstrut}

% \vtop{\blank[synchronize]\blank[line]test}

\defineblankmethod    [\v!always] {\redowhitespace} % experimental

% 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*\v!line]
  {\addblankskip+\openlineheight\openlineheight
   \addblankskip+\openlineheight\openlineheight}

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

\def\doblank#1%
  {\edefconvertedargument\ascii{#1}%
   \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
   \relax}

\def\redoblank#1%
  {\edefconvertedargument\ascii{#1}%
   \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
   \relax}

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

\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
%
\edefconvertedargument\ascii{#1}% todo fast check for simple
\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
  \expanded{\rawprocesscommalist[#1]}\doblank
\fi\fi
%
   \relax % to be sure
   \ifdim\blankskip=\zeropoint\relax
     \iflocalblankflexible
       \doglobal\advance\blankskip \currentblank
     \else\iflocalblankfixed
       \doglobal\advance\blankskip \currentblank
     \fi\fi
   \fi
   \relax % to be sure
   \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 -> this also wil become installable
  {\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,
       \v!halfline=>\scratchskip.5\linedistance
                    \edef\appliedblankskip{\the\scratchskip}%
                    \dosetupblank\appliedblankskip,
            \v!big=>\ifgridsnapping
                      \edef\appliedblankskip{\linedistance}%
                      \dosetupblank\appliedblankskip
                    \fi
                    \let\currentblank\v!big,
         \v!medium=>\let\currentblank\v!medium,
          \v!small=>\let\currentblank\v!small,
         \v!global=>\let\currentblank\v!global,
         \v!normal=>\dosetupblank\appliedblankskip,
       \v!standard=>\edef\appliedblankskip{\skipfactor\linedistance}%
                    \dosetupblank\appliedblankskip,
        \s!default=>\dosetupblank\appliedblankskip,
        \s!unknown=>\let\appliedblankskip\commalistelement
                    \dosetupblank\appliedblankskip]%
   \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\docommand##1{\setvalue{\??bo##1}{#2}}%
   \processcommalist[#1]\docommand}

\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%
  {\edefconvertedargument\!!stringa{#1}%
   \doifundefined{\??in:\!!stringa}%
     {\edef\currentindentation{#1}%
      \let\normalindentation\currentindentation
      \simplesetupindenting}}

\def\docomplexsetupindentingB#1%
  {\edefconvertedargument\!!stringa{#1}% catch #1=\somedimen
   \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\zeropoint
                                    \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}}

\appendtoks
   \pushmacro\checkindentation
   \pushmacro\ifindentation
\to \everypushsomestate

\appendtoks
   \popmacro\ifindentation
   \popmacro\checkindentation
\to \everypopsomestate

% 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


%D \macros
%D   {frenchspacing,nonfrenchspacing}
%D
%D Smehow \type{\frenchspacing} can lead to hyphenation between
%D dashes so we now have \type {\newfrenchspacing} (moved from
%D \type {syst-chr}).

%D Hm ... todo:

\sfcode`\)=0
\sfcode`\'=0
\sfcode`\]=0

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

\def\frenchspacing
  {\setfrenchspacing{1000}}

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

\def\frenchspacing   {\setfrenchspacing{1000}}
\def\newfrenchspacing{\setfrenchspacing{1050}}
\def\nonfrenchspacing{\resetfrenchspacing}

\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

\let\normalspaceprimitive=\ % space-comment is really needed else \<newline>

\unexpanded\def\nonbreakablespace{\penalty\plustenthousand\normalspaceprimitive}

\letcatcodecommand \ctxcatcodes `\~ \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:

\unexpanded\def\fixedspace
  {\setbox\scratchbox\normalhbox{\mathortext{0}{0}}%
   \hskip\wd\scratchbox\relax}

\def\fixedspaces
  {\letcatcodecommand \ctxcatcodes `\~ \fixedspace}

\def\removeunwantedspaces
  {\ifhmode % we also need to unskip 0pt skips
     \unskip\unskip\unskip\unskip\unskip
     \unskip\unskip\unskip\unskip\unskip
   \fi}

\appendtoks
  \let~\space
  \let\ \space
\to\simplifiedcommands

% still not fixed in aleph / luatex
%
% \def\removeunwantedspaces
%   {\ifhmode \ifnum\lastnodetype=\@@gluenode
%       \unskip \@EAEAEA\removeunwantedspaces
%    \fi \fi}

%D For old time sake, will disappear soon.

\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 }

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

\fi

\ifx\quad\undefined

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

    \def\enskip{\hskip.5\emwidth}
    \def\quad  {\hskip  \emwidth}
    \def\qquad {\hskip 2\emwidth}

\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
    {\dontleavehmode % \leavevmode
     \scratchcounter\spacefactor
     \vrule\!!width\zeropoint
     \nobreak\hskip\scratchskip
     \spacefactor\scratchcounter}

\fi

\unexpanded\def\textormathglue#1#2#3% cleaned up one
  {\begingroup
   \ifmmode
     \mskip#1#2%
   \else
     \scratchdimen#1\hspaceamount\empty{#3}%
     \scratchskip\scratchdimen\!!plus.5\scratchdimen\!!minus.3\scratchdimen
     \hskip\scratchskip
   \fi
   \endgroup}

\def\thinglue {\textormathglue+\thinmuskip 1}
\def\medglue  {\textormathglue+\medmuskip  2}
\def\thickglue{\textormathglue+\thickmuskip3}

\ifx\eject\undefined

  \def\eject{\par\break}

\fi

\ifx\supereject\undefined

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

\fi

\ifx\dosupereject\undefined

  \def\dosupereject
    {\ifnum\insertpenalties>\zerocount % 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

\newconditional \flexiblewhitespace \settrue\flexiblewhitespace

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

\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\simplesetupwhitespace
  {\doifnot\currentwhitespace\v!none\dosetupwhitespace}

\def\complexsetupwhitespace[#1]%
  {\edef\nextcurrentwhitespace{#1}%
   \ifx\nextcurrentwhitespace\empty
     \simplesetupwhitespace
   \else
     \let\currentwhitespace\nextcurrentwhitespace
     \dosetupwhitespace
   \fi}

\def\dosetupwhitespace % quick test for no list
  {\doifdefinedelse{\??ws\??ws\currentwhitespace}% no ifcsname due to nested \lineheight
     {\getvalue{\??ws\??ws\currentwhitespace}}%
     {\processcommacommand[\currentwhitespace]\dowhitespacemethod}%
   \ifgridsnapping
     \setfalse\flexiblewhitespace
     \ifdim\ctxparskip>\zeropoint
       \ctxparskip
       \ifcase\baselinegridmode
         \baselineskip % normal ! ! ! ! !!
       \or
         \ifdim\scratchdimen=\baselineskip % maybe range
           \baselineskip % normal ! ! ! ! !!
         \else
           \numexpr\ctxparskip/\dimexpr.5\lineheight\relax\relax\dimexpr.5\lineheight\relax
         \fi
       \else
         \baselineskip % normal ! ! ! ! !!
       \fi
     \fi
   \else
     \ifconditional\flexiblewhitespace \else \ctxparskip1\ctxparskip \fi
   \fi
   \parskip\ctxparskip}

\chardef\baselinegridmode=0 % option in layout / 1=permit_half_lines

\def\dodosetupwhitespace
  {\ifgridsnapping
     \setfalse\flexiblewhitespace
     \ctxparskip1\ctxparskip
     \ifdim\ctxparskip>\zeropoint
       \ifcase\baselinegridmode
         \ctxparskip\baselineskip % normal ! ! ! ! !!
       \or
         \ifdim\scratchdimen=\baselineskip % maybe range
           \ctxparskip\baselineskip % normal ! ! ! ! !!
         \else
           \ctxparskip\numexpr\ctxparskip/\dimexpr.5\lineheight\relax\relax\dimexpr.5\lineheight\relax
         \fi
       \else
         \ctxparskip\baselineskip % normal ! ! ! ! !!
       \fi
     \fi
   \else
     \ifconditional\flexiblewhitespace \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]    {\setfalse\flexiblewhitespace}
\definewhitespacemethod [\v!flexible] {\settrue\flexiblewhitespace}
\definewhitespacemethod [\v!line]     {\ctxparskip  \baselineskip}
\definewhitespacemethod [\v!halfline] {\ctxparskip.5\baselineskip}
\definewhitespacemethod [\v!none]     {\ctxparskip  \zeropoint}
\definewhitespacemethod [\v!big]      {\ctxparskip  \bigskipamount}
\definewhitespacemethod [\v!medium]   {\ctxparskip  \medskipamount}
\definewhitespacemethod [\v!small]    {\ctxparskip  \smallskipamount}

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

% \def\dowhitespacemethod#1%
%   {\executeifdefined{\??ws\??ws#1}{\ctxparskip#1}\relax}

\def\dowhitespacemethod#1% \doifdefined because of \lineheight
  {\doifdefinedelse{\??ws\??ws#1}{\getvalue{\??ws\??ws#1}}{\ctxparskip#1}\relax}

\def\nowhitespace
  {\ifdim\parskip>\zeropoint\relax
     \ifdim\lastskip=-\parskip
     \else
       \vskip-\parskip
     \fi
   \fi}

\def\nowhitespaceunlessskip
  {\ifdim\lastskip>\zeropoint \else
     \nowhitespace
   \fi}

\def\redowhitespace
  {\ifdim\lastskip>-\parskip \else
     \vskip\parskip
   \fi}

\def\savecurrentwhitespace
  {\edef\restorecurrentwhitespace
     {\ctxparskip\the\ctxparskip
      \parskip\the\parskip
      \noexpand\def\noexpand\currentwhitespace{\currentwhitespace}%
      \ifconditional\flexiblewhitespace
        \noexpand\settrue\flexiblewhitespace
      \else
        \noexpand\setfalse\flexiblewhitespace
      \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\forgetall\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

\ifdefined\globalbodyfontsize\else
  \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
   \ifdim\dimexpr\minimumstrutdepth+\minimumstrutheight\relax>\zeropoint
     \openlineheight\dimexpr\openstrutheight+\openstrutdepth\relax % new
   \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\setspacingfactor#1#2#3%
%   {\edef#1{\withoutpt\the\dimexpr#2\points*#3\relax}}

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

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

\let\restoreinterlinespace\relax

\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}%
      \noexpand\normalbaselines}}

% 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\zeropoint}

 %\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\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

% \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

% \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, strutdepth 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\setstrut
%   {% height
%    \ifdim\minimumstrutheight>\zeropoint
%      \edef\strutheight{\the\dimexpr\spacingfactor\dimexpr\minimumstrutheight}%
%    \else
%      \edef\strutheight{\the\dimexpr\spacingfactor\dimexpr\strutheightfactor\dimexpr\normallineheight}%
%    \fi
%    % depth
%    \ifgridsnapping
%      \ifdim\minimumstrutdepth>\zeropoint
%        \edef\strutdepth{\the\dimexpr\minimumstrutdepth}%
%      \else
%        \edef\strutdepth{\the\dimexpr\normallineheight-\strutheight}%
%      \fi
%    \else
%      \ifdim\minimumstrutdepth>\zeropoint
%        \edef\strutdepth{\the\dimexpr\spacingfactor\dimexpr\minimumstrutdepth}%
%      \else
%        \edef\strutdepth{\the\dimexpr\spacingfactor\dimexpr\strutdepthfactor\dimexpr\normallineheight}%
%      \fi
%    \fi
%    % finish
%    \dosetstrut}

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

\unexpanded\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)

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

\unexpanded\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\dimexpr\strutht+\strutdp\relax}
%
% because of all the callbacks in mkiv, we avoid unnecessary boxes ...
% maybe use an attribute so that we can tag boxes that don't need a
% treatment; tests with using an attribute so far have shown that
% it's slower because testing the attribute takes time too

\def\dosetstrut
  {\let\strut\normalstrut
   \ifdim\strutwidth=\zeropoint
       \setbox\strutbox\normalhbox
         {\vrule
            \!!width \zeropoint
            \!!height\strutheight
            \!!depth \strutdepth}%
   \else
       \setbox\strutbox\normalhbox
         {\normalhbox to \zeropoint
            {% \hss % new, will be option
             \vrule
               \!!width \strutwidth
               \!!height\strutheight
               \!!depth \strutdepth
             \hss}}%
   \fi
   \struttotal\dimexpr\strutht+\strutdp\relax}

%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

\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+\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\relax}{#2}\fi}

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

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

\newif\ifgridsnapping % to be sure

\def\defaultwidowpenalty         {2000} % was: 1000
\def\defaultclubpenalty          {2000} % was:  800
\def\defaultdisplaywidowpenalty    {50}
\def\defaultbrokenpenalty         {100}

\def\defaultgridwidowpenalty        {0}
\def\defaultgridclubpenalty         {0}
\def\defaultgriddisplaywidowpenalty {0}
\def\defaultgridbrokenpenalty       {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
  \displaywidowpenalty\defaultdisplaywidowpenalty
  \brokenpenalty      \defaultbrokenpenalty

\stopsetups

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

  \directsetup{\systemsetupsprefix\s!reset}

  \widowpenalty       \defaultgridwidowpenalty
  \clubpenalty        \defaultgridclubpenalty
  \displaywidowpenalty\defaultgriddisplaywidowpenalty
  \brokenpenalty      \defaultgridbrokenpenalty

\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}}

% needs a proper \definenarrower or installnarrower

\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!left=>\global\advance\ctxleftskip -\@@slleft,
        -\v!middle=>\global\advance\ctxmidskip  -\@@slmiddle,
         -\v!right=>\global\advance\ctxrightskip-\@@slright,
          \v!reset=>\global\ctxleftskip \zeropoint
                    \global\ctxmidskip  \zeropoint
                    \global\ctxrightskip\zeropoint,
          \v!none=>,
        \s!unknown=>\global\advance\ctxmidskip   \commalistelement]}

% \def\donarrower[#1]% hm, can be dorepeat directly
%   {\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\donarrower[#1]% hm, can be dorepeat directly
  {\dorepeatwithcommand[#1]\dosinglenarrower}

\def\complexstartnarrower[#1]%
  {\@@slbefore % was hard coded \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}

% todo: definenarrower

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

\definecomplexorsimple\startnarrower

\def\stopnarrower
  {\@@slafter % was hard coded \par / needed, 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%
  {\let\raggedbox\vbox
   \processfirstactioninset
     [#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=}]}

\def\dosetraggedhbox#1%
  {\let\raggedbox\hbox
   \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}]}

\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}}}

\setvalue{\@@ragged@@command\v!lesshyphenation}%
  {\appendtoks\lesshyphens\to\everyraggedcommand}
\setvalue{\@@ragged@@command\v!morehyphenation}%
  {\appendtoks\morehyphens\to\everyraggedcommand}

% 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}

% 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 voor 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}

\ifx\dosomebreak\undefined % defined in mkiv

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

\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}

\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

\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}}

\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:

\unexpanded\def\dostartattributes#1#2#3%
  {\begingroup  % geen \bgroup, anders in mathmode lege \hbox
   \ifincolor
     \ifcsname#1#3\endcsname
       \let\dostopattributes\@@dostopattributes
       \faststartcolor[\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
  {\faststopcolor
   \finishparbasedattributes
   \endgroup}

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

%D Bonus macro, see core-sec.tex

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

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

\unexpanded\def\doattributes#1#2#3#4%
  {\begingroup  % geen \bgroup, anders in mathmode lege \hbox
   \ifincolor
     \ifcsname#1#3\endcsname
       \let\dostopattributes\@@dostopattributes
       \faststartcolor[\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}

% 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}

\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%
  {\edefconvertedargument\ascii{@lsa@#1}%
   \leftskipadaption
     \ifcsname\ascii\endcsname
       \csname\ascii\endcsname
     \else
       #1%
     \fi
   \relax}

\def\dosetrightskipadaption#1%
  {\edefconvertedargument\ascii{@rsa@#1}%
   \rightskipadaption
     \ifcsname\ascii\endcsname
       \csname\ascii\endcsname
     \else
       #1%
     \fi
   \relax}

\newcount \noftrackedpagestates
\newif    \ifpagestatemismatch
\newcount \realpagestateno
\chardef  \frozenpagestate      \zerocount

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

\def\doforcedtrackpagestate#1#2%
  {\ifcase\frozenpagestate
     \global\advance\noftrackedpagestates\plusone
     \global\advance#2\plusone
     \lazysavetaggedtwopassdata{#1}{\number\noftrackedpagestates}{\number#2}{\noexpand\realfolio}%
     %\llap{\infofont\number\noftrackedpagestates/\number#2}% tracing
   \fi}

\def\doifrightpagestateelse#1#2%
  {\ifcase\frozenpagestate
     \pagestatemismatchfalse
     \realpagestateno\realfolio
     \ifinpagebody
       \ifdoublesided
         \ifodd\realpageno\relax
           \twopassdatafoundtrue \else \twopassdatafoundfalse
         \fi
       \else
         \twopassdatafoundtrue
       \fi
     \else\ifdoublesided
       \findtwopassdata{#1}{\number#2}%
       \iftwopassdatafound
         \realpagestateno\twopassdata\relax
         \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
     \realpagestateno\realfolio
     \findtwopassdata{#1}{\number#2}%
     \iftwopassdatafound
       \realpagestateno\twopassdata\relax
       \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 \newcount \nofraggedparagraphs

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

\newcount\pagesignallevel

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

\def\stopsignalrightpage
  {\ifcase\pagesignallevel\or\postsignalrightpage\fi
   \advance\pagesignallevel\minusone}

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

\ifx\swapmargins\undefined \let\swapmargins\undefined \fi % todo

\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}{\number#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\zeropoint plus2em \spaceskip.3333em \xspaceskip.5em\relax}
%
% \def\ttraggedright%
%   {\tttf\rightskip\zeropoint plus2em\relax}
%
% \newif\ifr@ggedbottom
%
% \def\raggedbottom%
%   {\topskip 10\points plus60\points \r@ggedbottomtrue}
%
% \def\normalbottom%
%   {\topskip 10\points \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}{}

% oeps, hsize can be 0pt in which case we get a strange division

\def\middleraggedness {\ifdim\hsize=\zeropoint6\bodyfontsize\else.5\hsize\fi} % 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}}

% older (context) names:

\let\spaceamount  \interwordspace
\let\emspaceamount\emwidth

% tracing:

\def\doshowpardata#1%
  {\ifx#1\relax\else
     \hbox{\string#1: \the#1}\endgraf
     \expandafter\doshowpardata
   \fi}

\def\showpardata
  {\edef\thepardata
     {\hbox{font: \fontname\font}\endgraf
      \doshowpardata
        \interwordspace \interwordstretch \interwordshrink \emwidth \exheight \extraspace
        \hsize     \vsize
        \leftskip  \rightskip
        \spaceskip \xspaceskip
        \parindent \parfillskip
        \hyphenpenalty \exhyphenpenalty
        \displaywidowpenalty \widowpenalty \clubpenalty \brokenpenalty
        \doublehyphendemerits \finalhyphendemerits \adjdemerits
      \relax}%
   \begingroup
   \dontshowcomposition
   \inleftmargin{\vsmash
     {\switchtobodyfont[7pt,tt]%
      \framed[\c!align=\v!right]{\thepardata}}}%
   \endgroup}

\def\startshowpardata
  {\begingroup
   \showcomposition
   \showstruts\tracepositionstrue \tracingparagraphs\maxdimen
   \appendtoksonce\showpardata\let\showpardata\relax\to\everypar}

\def\stopshowpardata
  {\endgraf
   \endgroup}

% \defineXMLenvironment[showpardata] \startshowpardata \stopshowpardata
% \defineXMLsingular   [showpardata] \showpardata

% defaults

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

\def\notragged
  {\chardef\raggedstatus\zerocount
   \leftskip  1\leftskip
   \rightskip 1\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

% \setupalign[reset,new,right,old]

\def\@@align@@rl{\if!!donea\veryraggedleft  \else\raggedleft  \fi}
\def\@@align@@rr{\if!!donea\veryraggedright \else\raggedright \fi}
\def\@@align@@rc{\if!!donea\veryraggedcenter\else\raggedcenter\fi}

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

\def\installalign#1#2{\setvalue{@@align@@#1}{#2}} % can be used for overloads

\installalign \v!new           {\@@asraggedfalse}
\installalign \v!old           {\@@asraggedtrue}
\installalign \empty           {}

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

\installalign \v!tolerant      {\tolerance3000   \relax}
\installalign \v!verytolerant  {\tolerance4500   \relax}
\installalign \v!stretch       {\emergencystretch\bodyfontsize}

\newcount\hyphenminoffset

\ifx\sethyphenationvariables\undefined \let\sethyphenationvariables\relax \fi

\def\lesshyphens
  {\advance\hyphenminoffset\plusone
   \sethyphenationvariables}

\def\morehyphens
  {\ifcase\hyphenminoffset \else
     \advance\hyphenminoffset\minusone
   \fi
   \sethyphenationvariables}

\installalign \v!lesshyphenation {\lesshyphens}
\installalign \v!morehyphenation {\morehyphens}

\def\dodosetupalign#1{\csname @@align@@#1\endcsname}
\def\dodosetupngila#1{\csname @@ngila@@#1\endcsname}

\def\setupalign
  {\dosingleargument\dosetupalign}

\def\dosetupalign[#1]% can be made faster by checking for defined #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:

\newtoks \everyleftofalignedline
\newtoks \everyrightofalignedline

\def\shiftalignedline#1#2#3#4% left, right, inner, outer
  {\rightorleftpageaction
     {\everyleftofalignedline {\hskip\dimexpr#1+#3\relax}%
      \everyrightofalignedline{\hskip\dimexpr#2+#4\relax}}
     {\everyleftofalignedline {\hskip\dimexpr#1+#4\relax}%
      \everyrightofalignedline{\hskip\dimexpr#2+#3\relax}}}

% \def\doalignline#1#2% \\ == newline
%   {\begingroup
%    \setlocalhsize % new
%    \def\\{\egroup\par\doalignline{#1}{#2}\bgroup}%
%    \dowithnextbox
%      {\noindentation % was \noindent
%       \dontleavehmode % added in marrakesch at TUG 2006
%       \hbox to \localhsize
%         {\ifcase\alignstrutmode\or\strut\fi
%          \the\everyleftofalignedline
%          #1\unhbox\nextbox#2\relax
%          \the\everyrightofalignedline}%
%       \endgroup}
%      \hbox}

\def\doalignline#1#2% \\ == newline
  {\noindentation  % was \noindent
   \dontleavehmode % added in marrakesch at TUG 2006\begingroup
   \begingroup
   \setlocalhsize % new
   \def\\{\egroup\par\doalignline{#1}{#2}\bgroup}%
   \dowithnextbox
     {\hbox to \localhsize
        {\ifcase\alignstrutmode\or\strut\fi
         \the\everyleftofalignedline
         #1\unhbox\nextbox#2\relax
         \the\everyrightofalignedline}%
      \endgroup}
     \hbox}

% plain commands

\ifx\undefined\line       \def\line        {\hbox to\hsize}    \fi
\ifx\undefined\leftline   \def\leftline  #1{\line{#1\hss}}     \fi
\ifx\undefined\rightline  \def\rightline #1{\line{\hss#1}}     \fi
\ifx\undefined\centerline \def\centerline#1{\line{\hss#1\hss}} \fi

% directe commando's

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

\let\centeraligned\midaligned

\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%
  {\noindentation  % was \noindent
   \dontleavehmode % added in marrakesch at TUG 2006\begingroup
   \begingroup
   \setlocalhsize
   \def\\{\egroup\par\doxalignline#1#2#3#4#5#6\bgroup}% inefficient
   \dowithnextbox
     {%\noindent moved up
      \hbox to \localhsize
        {#1\hskip\ifdone#2\else#3\fi#4%
         \hbox to \localhsize
           {\the\everyleftofalignedline
            \ifcase\alignstrutmode\or\strut\fi
            \ifdone#5\unhbox\nextbox#6\else#6\unhbox\nextbox#5\fi
            \the\everyrightofalignedline}%
         \hss}%
        \endgroup}
     \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\alignedline#1#2% setting default
  {\csname\s!do\v!line\ifcsname\s!do\v!line#1\endcsname#1\else#2\fi\endcsname}

%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
     %\finalhyphendemerits\zerocount % yes or no
      \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}

% \simplealignedbox{2cm}{right}{x}

\setvalue{\s!simple\c!align\v!right      }#1#2{\hbox to #1{#2\hss}}
\setvalue{\s!simple\c!align\v!left       }#1#2{\hbox to #1{\hss#2}}
\setvalue{\s!simple\c!align\v!flushright }#1#2{\hbox to #1{\hss#2}}
\setvalue{\s!simple\c!align\v!flushleft  }#1#2{\hbox to #1{#2\hss}}
\setvalue{\s!simple\c!align\v!middle     }#1#2{\hbox to #1{\hss#2\hss}}

\def\simplealignedbox#1{\executeifdefined{\s!simple\c!align#1}{\getvalue{\s!simple\c!align\v!right}}}

%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\emptybox
   \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}}

\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}

\newmuskip\hairmuskip \hairmuskip=.15mu

\def\hairspace    {\textormathspace+\hairmuskip{.5}}
\def\thinspace    {\textormathspace+\thinmuskip 1}
\def\medspace     {\textormathspace+\medmuskip  2}
\def\thickspace   {\textormathspace+\thickmuskip3}
\def\neghairspace {\textormathspace-\thinmuskip{.5}}
\def\negthinspace {\textormathspace-\thinmuskip 1}
\def\negmedspace  {\textormathspace-\medmuskip  2}
\def\negthickspace{\textormathspace-\thickmuskip3}

% needed for unicode:

\def\twoperemspace           {\hskip\dimexpr\emwidth/2\relax} % == \enspace
\def\threeperemspace         {\hskip\dimexpr\emwidth/3\relax}
\def\fourperemspace          {\hskip\dimexpr\emwidth/4\relax}
\def\fiveperemspace          {\hskip\dimexpr\emwidth/5\relax} % goodie
\def\sixperemspace           {\hskip\dimexpr\emwidth/6\relax}
\def\figurespace             {\begingroup\setbox\scratchbox\hbox{0}\hskip\wd\scratchbox\endgroup} % there is a command for this
\def\punctuationspace        {\begingroup\setbox\scratchbox\hbox{.}\hskip\wd\scratchbox\endgroup}
\def\ideographicspace        {\hskip\dimexpr\emwidth/1\relax}
\def\ideographichalffillspace{\hskip\dimexpr\emwidth/2\relax}
%def\nobreakspace            {\penalty\plustenthousand\space}
\def\nobreakspace            {\penalty\plustenthousand\kern\interwordspace}
\def\narrownobreakspace      {\penalty\plustenthousand\thinspace}
%def\zerowidthnobreakspace   {\penalty\plustenthousand\hskip\zeropoint}
\def\zerowidthnobreakspace   {\penalty\plustenthousand\kern\zeropoint}
\def\zerowidthspace          {\hskip\zeropoint}

\definehspace[.5][.1250\emspaceamount] % could also be [.1250\spaceamount]
\definehspace[1] [.1667\emspaceamount]
\definehspace[2] [.2222\emspaceamount]
\definehspace[3] [.2777\emspaceamount]

\let \, \thinspace
\let \: \medspace
\let \; \thickspace
\let \! \negthinspace

% 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\interwordspace
   \!!plus#2\interwordstretch
  \!!minus#3\interwordshrink}

\def\fixedspaceamount#1%
  {#1\interwordspace}

%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}

% moved from page-lin

\def\installspacehandler#1#2% needs to set \obeyedspace
  {\setvalue{\??sr#1}{#2}}

\installspacehandler \v!on
  {\obeyspaces
   \def\obeyedspace{\mathortext\normalspace{\dontleavehmode{\tt\controlspace}}}%
   \let\ =\obeyedspace}

\installspacehandler \v!yes
  {\obeyspaces
   \def\obeyedspace{\mathortext\normalspace{\dontleavehmode    \normalspace  }}%
   \let\ =\obeyedspace}

\installspacehandler \v!off % == default
  {\normalspaces
   \let\obeyedspace\normalspace
   \let\ =\normalspaceprimitive} % was \normalspace

\installspacehandler \v!fixed
  {\obeyspaces
   \def\obeyedspace{\mathortext\normalspace{\dontleavehmode\fixedspace}}%
   \let\ =\obeyedspace}

\def\activatespacehandler#1%
  {\executeifdefined{\??sr#1}{\activatespacehandler\v!off}}

% moved from page-lin

%D When spacing is active we need to handle commands in
%D a special way:
%D
%D \starttyping
%D \setuplines[space=on]
%D
%D \startlines
%D Let's talk about this{\ttsl\gobbleoneargument or}that.
%D \stoplines
%D
%D \startlines
%D Let's talk about this{\getvalue{ttsl}or}that.
%D \stoplines
%D \stoptyping
%D
%D One can indent in several ways:
%D
%D \starttyping
%D \setupindenting[medium] \setuplines[indenting=odd] % no yes odd even
%D
%D \startlines
%D first
%D second
%D third
%D fourth
%D \stoplines
%D \stoptyping

\def\setuplines
  {\dodoubleargument\getparameters[\??rg]}

\def\startlines
  {\@@rgbefore
   \pushmacro\checkindentation
   \whitespace
  %\page[\v!preference]} gaat mis na koppen, nieuw: later \nobreak
   \begingroup
   \setupindenting[\@@rgindenting]%
   \typesettinglinestrue
   \setupwhitespace[\v!none]%
   \obeylines
   \ignorespaces
   \gdef\afterfirstobeyedline % tzt two pass, net als opsomming
     {\gdef\afterfirstobeyedline
        {\nobreak
         \doifnot\@@rgoption\v!packed{\global\let\afterfirstobeyedline\relax}}}%
   \def\obeyedline
     {\par
      \futurelet\next\dobetweenthelines}%
   \activatespacehandler\@@rgspace
   \GotoPar}

\def\stoplines
  {\endgroup
   \popmacro\checkindentation
   \@@rgafter}

\def\dobetweenthelines
  {\doifmeaningelse\next\obeyedline
    {\@@rginbetween}
    {\afterfirstobeyedline}}

\setuplines
  [\c!option=,
   \c!before=\blank,
   \c!after=\blank,
   \c!inbetween=\blank,
   \c!indenting=\v!no,
   \c!space=\v!default]

\def\emptylines
  {\dosingleempty\doemptylines}

\def\doemptylines[#1]%
  {\endgraf\dorecurse{\iffirstargument#1\else3\fi}\crlf}

\setupwhitespace
  [\v!none]

% still old-fashioned

\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!before=\endgraf,
   \c!after=\endgraf,
   \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
