%D \module
%D   [       file=cont-new,
%D        version=1995.10.10,
%D          title=\CONTEXT\ Miscellaneous Macros,
%D       subtitle=New Macros,
%D         author=Hans Hagen,
%D           date=\currentdate,
%D      copyright={PRAGMA / Hans Hagen \& Ton Otten}]
%C
%C This module is part of the \CONTEXT\ macro||package and is
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.

%D This file is loaded at runtime, thereby providing an
%D excellent place for hacks, patches, extensions and new
%D features.

% \font\f=dummyfont  \rpcode\f0=500 \hbox{..}\char0

% todo: mp-new
% caption: grid=top|bottom in xml defs

\unprotect

\writestatus{\m!systems}{beware: some patches loaded from cont-new.tex}

% \tracefilestrue
%
% \unexpanded\def\readfile#1#2#3%
%   {\readlocfile{#1}{#2}
%      {\readjobfile{#1}{#2}
%         {\readsysfile{#1}{#2}{#3}}}}

\unexpanded\def\readfile#1#2#3%
  {\readlocfile{#1}{#2}{\readsysfile{#1}{#2}{#3}}}

\chardef\preprocessmethod 2 % 0=no check 1=present_check 2=log_check
\chardef\preprocessstate  0 % 1=found 2=not_present (skip)
\def    \preprocesssuffix {.prep}

\def\loadctxpreplist
  {\ifcase\preprocessmethod
     % no checking
   \or
     % simple checking
   \or
     \doiffileexistselse{./\jobname.ctl}
       {\bgroup
        \defineXMLenvironment[ctx:preplist]
          {\writestatus\m!systems{loading ctx log file}}
          {}%
        \defineXMLenvironmentsave[ctx:prepfile][done=no]
          {}
          {\writestatus\m!systems{registering \XMLflush{ctx:prepfile} -> \XMLop{done}}%
           \setxvalue{fp..\XMLflush{ctx:prepfile}}{\XMLop{done}}}%
        \processXMLfile{./\jobname.ctl}%
        \egroup}%
       {\global\chardef\preprocessmode\plusone}%
   \fi
   \global\let\loadctxpreplist\relax}

\appendtoks\loadctxpreplist\to\everystarttext % will become: \prependtoks\loadctxpreplist\to\everyjob

\def\docheckprepfile
  {\ifcase\preprocessmethod
     % no preprocessing
   \or
     % only check for existence
     \doiffileexistselse{\readfilename\preprocesssuffix}
       {\chardef\preprocessstate\plusone}
       \donothing
   \or
     % check when in list, otherwise assume normal file
     \bgroup
     \splitfilename\readfilename
     \ifx\splitofftype\empty
       % saveguard and speed up
       \egroup
     \else
       \doifdefinedelse{fp..\splitoffname.\splitofftype}
         {\egroup
          \doiffileexistselse{\readfilename\preprocesssuffix}
            {\chardef\preprocessstate\plusone}
            {\chardef\preprocessstate\plustwo}}%
         {\egroup}%
     \fi
   \fi}

% beware, \readfilename keeps the original one, but we load and store the
% suffixed with .prep file (if present)

\def\doreadfile#1#2#3#4% beware, this one already works at format generation time!
  {\sanitizefilename#2\to\readfilename
   \ifx\readfilename\empty
     % silently ignore
   \else
     \let\trackedfilename\readfilename
     \chardef\preprocessstate\zerocount
     \ifconditional\trackfilenames
       \doifundefinedelse{fn..\trackedfilename}\donetrue\donefalse
     \else
       \donetrue
     \fi
     \ifdone
       \checkfilename\readfilename
       \ifcase\kindoffile
         % not a full path or url, check for existence
         \doifelsenothing{#1}
           {\iftracefiles\writestatus\m!systems{searching for \readfilename\space on tex path}\fi
            \def\next{\redoreadfile\readfilename{#3}{#4}}}%
           {\iftracefiles\writestatus\m!systems{searching for \readfilename\space on #1}\fi
            \def\next{\redoreadfile{\pathplusfile{#1}{\readfilename}}{#3}{#4}}}%
       \else
         % a full path or url, no further checking done
         \docheckprepfile
         \ifcase\preprocessstate
           \doiffileexistselse\readfilename
             {\iftracefiles\writestatus\m!systems{located \readfilename}\fi
              \def\next{#3\dodoreadfile}}%
             {\iftracefiles\writestatus\m!systems{not found \readfilename}\fi
              \def\next{#4}}%
         \or
           \iftracefiles\writestatus\m!systems{located \readfilename\preprocesssuffix}\fi
           \def\next{#3\dodoreadfile}%
         \or
           \iftracefiles\writestatus\m!systems{not found \readfilename\preprocesssuffix}\fi
           \def\next{#4}%
         \fi
       \fi
     \else
       \edef\readfilename{\getvalue{fn..\readfilename}}%
       \iftracefiles\writestatus\m!systems{already located \readfilename}\fi
       \def\next{#3\dodoreadfile}%
     \fi
     \expandafter\next
   \fi}

\def\redoreadfile#1#2#3%
  {\docheckprepfile
   \ifcase\preprocessstate
     \doiffileexistselse{#1}%
       {\edef\readfilename{#1}%
        \iftracefiles\writestatus\m!systems{#1 located}\fi
        \def\next{#2\dodoreadfile}}%
       {\iftracefiles\writestatus\m!systems{cannot locate #1}\fi
        \decrement\readlevel\relax
        \ifnum\readlevel>\zerocount
          \edef\readfilename{\pathplusfile{\f!parentpath}{\readfilename}}%
          \def\next{\redoreadfile\readfilename{#2}{#3}}%
        \else
          \def\next{#3}%
        \fi}%
   \or
     \edef\readfilename{#1}%
     \iftracefiles\writestatus\m!systems{#1\preprocesssuffix\space located}\fi
     \def\next{#2\dodoreadfile}%
   \or
     \def\next{#3}%
   \fi
   \next}

\def\dodoreadfile % we provide hooks, for instance for \enableXML
  {\ifconditional\trackfilenames
     \setxvalue{fn..\trackedfilename}{\readfilename\ifcase\preprocessstate\or\preprocesssuffix\fi}%
   \fi
   \the\everybeforereadfile
   \ifcase\preprocessstate
     % no checking or not found when using method 1
     \normalinput\readfilename
   \or
     % found when using method 1 or 2
     \normalinput\readfilename\preprocesssuffix
   \or
     % not found when using method 2
   \fi
   \relax
   \the\everyafterreadfile}

\def\headparameter#1% to do: everywhere in core-sec
  {\csname\??ko\currenthead#1\endcsname}

% The following may be a solution for the fact that one cannot
% change catcodes of characters like : and ; inside an environment.

\appendtoks
  \enablelanguagespecifics[\currentlanguage]%
\to \everystarttext

% Peter M\"unster's test case:
%
% \defineoverlay[Draft][{\scale[factor=max]{\rotate[rotation=60]{~MY||DRAFT~}}}]
% \setupbackgrounds[page][background=Draft]
% \starttext
% \starttables[|l|]
% \dorecurse{200}{\NC hallo \NC\AR}
% \stoptables
% \stoptext
%
% \let\normalactivetilde~
% \let\normalactivebar  |
%
% \appendtoks\let~\normalactivetilde\to\everypagebody
% \appendtoks\let|\normalactivebar  \to\everypagebody

\let\cs\getvalue

%D Krzysztof Leszczynski suggested to provide access to the level by
%D means of a \type {#1}. I decided to pass the more frquently used
%D level as \type {#1} and the less favoured depth as \type {#2}. The
%D intended usage is:
%D
%D \starttyping
%D \dorecurse{3}{\definesymbol[test-#1][xx-#1]}
%D
%D \def\test{\dorecurse{3}{\definesymbol[test-##1][xx-##1]}} \test
%D
%D \symbol[test-1]\quad\symbol[test-2]\quad\symbol[test-3]
%D \stoptyping
%D
%D Since the hashed arguments are expanded, we don't need tricky
%D expansion here.
%D
%D \starttyping
%D \dorecurse{3}{\expanded{\definesymbol[test-\recurselevel][xx-\recurselevel]}}
%D \stoptyping

\def\expandrecursecontent
  {\csname\@@arecurse\recursedepth\@EA\@EA\@EA\endcsname\@EA\@EA\@EA{\@EA\recurselevel\@EA}\@EA{\recursedepth}}

\long\def\xdorecurse#1#2%
  {\global\advance\outerrecurse \plusone
   \long\global\@EA\def\csname\@@arecurse\recursedepth\endcsname##1##2{#2}%
   \global\@EA\let\csname\@@irecurse\recursedepth\endcsname\recurselevel
   \@EA\dodorecurse\@EA1\@EA{\number#1}}

\long\def\dostepwiserecurse#1#2#3#4% can be made faster by postponing #4
  {\global\advance\outerrecurse \plusone
   \long\global\@EA\def\csname\@@arecurse\recursedepth\endcsname##1##2{#4}%
   \global\@EA\let\csname\@@irecurse\recursedepth\endcsname\recurselevel
   \ifnum#3>0\relax
     \ifnum#2<#1\relax
       \let\nextrecurse\exitstepwiserecurse
     \else
       \let\nextrecurse\dodostepwiserecurse
     \fi
   \else
     \ifnum#3<0\relax
       \ifnum#1<#2\relax
         \let\nextrecurse\exitstepwiserecurse
       \else
         \let\nextrecurse\dodostepwisereverse
       \fi
     \else
       \let\nextrecurse\exitstepwiserecurse
     \fi
   \fi\expanded{\nextrecurse{\number#1}{\number#2}{\number#3}}}

\long\def\doloop#1%
  {\global\advance\outerrecurse \plusone
   \long\global\@EA\def\csname\@@arecurse\recursedepth\endcsname##1##2{#1}%
   \global\@EA\let\csname\@@irecurse\recursedepth\endcsname\recurselevel
   \let\endofloop\dodoloop
   \dodoloop1} % no \plusone else \recurselevel wrong

\ifx\normalcompound\undefined \let\normalcompound=| \fi

% experimental so this may change

\def\startdescriptions
  {\dosingleempty\dostartdescriptions}

\def\dostartdescriptions[#1]%
  {\begingroup
   \def\item{\getvalue{#1}}%
   \let\dostoppairdescription \donothing
   \let\@@description         \dostartpairdescription
   \let\@@startsomedescription\dostartsomedescription}

\def\stopdescriptions
  {\dostoppairdescription
   \endgroup}

\def\dostartpairdescription[#1][#2]%
  {\dostoppairdescription
   \def\dostoppairdescription{\@@stopdescription{#1}}%
   \bgroup
   \def\currentdescription{#1}%
   \doifelse{\descriptionparameter{\s!do\c!state}}\v!start
     {\@@makedescription{#1}[#2]{}}
     {\@@makedescription{#1}[#2]}}

\def\dostartsomedescription% #1[#2]#3%
  {\bgroup
   \@@makedescription} % {#1}[#2]{#3}}

% \starttext
%
% \definedescription[test]
%
% \startdescriptions
% \test{Foo} Bar bar bar
% \test{Foo} Bar bar bar
% \test{Foo} Bar bar bar
% \stopdescriptions
%
% \startdescriptions[test]
% \item{Foo} Bar bar bar
% \item{Foo} Bar bar bar
% \item{Foo} Bar bar bar
% \stopdescriptions
%
% \startdescriptions
% \starttest{Foo} Bar bar bar \stoptest
% \starttest{Foo} Bar bar bar \stoptest
% \starttest{Foo} Bar bar bar \stoptest
% \stopdescriptions
%
% \startdescriptions[test]
% \item{Foo} Bar bar bar
% \item{Foo} Bar bar bar
% \item{Foo} Bar bar bar
% \stopdescriptions
%
% \stoptext

% to do:
%
% \def\defineshapesynonym
%   {\dodoubleargument\dodefineshapesynonym}
%
% \def\dodefineshapesynonym[#1][#2]%
%   {\setvalue{shsy:#1}{#2}}
%
% \def\shapesynonym#1%
%   {\ifcsname shsy:#1\endcsname
%      \expandafter\shapesynonym\csname shsy:#1\endcsname\else#1%
%    \fi}
%
% \beginTEX
%
% \def\shapesynonym#1%
%   {\expandafter\ifx\csname shsy:#1\endcsname\relax
%      #1\else\expandafter\shapesynonym\csname shsy:#1\endcsname
%    \fi}
%
% \endTEX
%
%\defineshapesynonym[eacute] [e]
%\defineshapesynonym[egrave] [e]
%\defineshapesynonym[eumlaut [e]
%\defineshapesynonym[eogonek][e]
%
% more reduction
%
%\defineshapesynonym[e][o]
%\defineshapesynonym[w][v]
%\defineshapesynonym[m][n]
%
% \shapesynonym{eacute}

% new: \forcebaselinecorrection --> core-spa & core-grd

\chardef\baselinecorrectionmode\plusone

\def\onbaselinecorrection   {\chardef\baselinecorrectionmode\plusone  }
\def\offbaselinecorrection  {\chardef\baselinecorrectionmode\plustwo  }
\def\forcebaselinecorrection{\chardef\baselinecorrectionmode\plusthree}

\def\topbaselinecorrection
  {\ifvmode \ifdim\pagegoal<\maxdimen
     \forcedtopbaselinecorrection
   \fi \fi}

\def\forcedtopbaselinecorrection
  {\ifvmode
     \bgroup
     \setbaselinecorrections
     \whitespace
     \nointerlineskip
     \dotopbaselinecorrection
     \egroup
   \fi}

\let\forcedbotbaselinecorrection\botbaselinecorrection

\def\startbaselinecorrection
  {\ifcase\baselinecorectionmode
   \or % normal
     \baselinecorrection
     \ifvmode
       \bgroup
       \setbox\scratchbox\vbox\bgroup
       \ignorespaces
       \let\stopbaselinecorrection\donormalstopbaselinecorrection
     \else
       \bgroup
       \let\stopbaselinecorrection\egroup
     \fi
   \or % off
     \bgroup
     \let\stopbaselinecorrection\egroup
   \or % force
     \baselinecorrection
     \ifvmode
       \bgroup
       \setbox\scratchbox\vbox\bgroup
       \ignorespaces
       \let\stopbaselinecorrection\doforcedstopbaselinecorrection
     \else
       \bgroup
       \let\stopbaselinecorrection\egroup
     \fi
   \fi}

\def\startbaselinecorrection
  {\bgroup
   \let\stopbaselinecorrection\egroup
   \ifcase\baselinecorrectionmode
   \or % normal
     \baselinecorrection
     \ifvmode
       \setbox\scratchbox\vbox\bgroup\ignorespaces
       \let\stopbaselinecorrection\donormalstopbaselinecorrection
     \fi
   \or % off
   \or % force
     \baselinecorrection
     \ifvmode
       \setbox\scratchbox\vbox\bgroup\ignorespaces
       \let\stopbaselinecorrection\doforcedstopbaselinecorrection
     \fi
   \fi}

\let\stopbaselinecorrection\relax

\def\donormalstopbaselinecorrection % I have to check columns yet.
  {\egroup
   \topbaselinecorrection
   \box\scratchbox
   \botbaselinecorrection
   \egroup}

\def\doforcedstopbaselinecorrection % I have to check columns yet.
  {\egroup
   \forcedtopbaselinecorrection
   \box\scratchbox
   \forcedbotbaselinecorrection
   \egroup}

% core-grd:

\let\normalstartbaselinecorrection=\startbaselinecorrection

\def\startbaselinecorrection
  {\ifgridsnapping
     \centertogrid\bgroup
     \let\stopbaselinecorrection\egroup
   \else
     \normalstartbaselinecorrection
   \fi}

% todo: fast processor

\def\gettwopassdatalist#1%
  {\loadtwopassdata
   \ifcsname#1:\s!list\endcsname
     \letcscsname\twopassdatalist\csname#1:\s!list\endcsname
   \else
     \let\twopassdatalist\empty
   \fi}

% \def\literateencodedtokens
%   {% \let\dohandleaccent   \keephandleaccent  % assumes named chars % defineaccent    "e {name}
%    % \let\dohandlecommand  \keephandlecommand % assumes named chars % definecommand crap {name}
%    \let\dohandlecharacter\keephandlecharacter}
%
% \def\convertmeaning#1\to % watch the double expansion !
%   {\bgroup
%      \honorunexpanded
%     %\dontexpandencoding % new
%      \literateencodedtokens % newer
%      \xdef\@@globalexpanded{#1}%
%      \xdef\@@globalexpanded{\@@globalexpanded}%
%    \egroup
%    \convertcommand\@@globalexpanded\to}

\def\defXMLattributestring#1#2#3#4%
  {\ifcsname\@@XMLvariable:#2:#3\endcsname
     \@EA\convertcommand\csname\@@XMLvariable:#2:#3\endcsname\to#1%
   \else
     \convertargument#4\to#1%
   \fi}

\bgroup \catcode`\<=\active

% usage: \expanded{\rescanXMLatttributes{fo:table-cell}}

\gdef\rescanXMLattributes  #1{\noexpand\dogetXMLarguments{#1}\currentXMLarguments>}
\gdef\parseXMLattributes #1#2{\dogetXMLarguments{#1}#2>}

\egroup

% \page[left]
% \definecolumntextarea[intro][left][x=1,y=1,nx=4,ny=20,state=start,background=introlayer]
% \setupcolumntextareatext[intro][left][\setups{intro}]
% \flushcolumntextareas

\def\flushcolumntextareas
  {\initializecolumntextareas
   \setvsize}

% And so, after a few years of keeping this potentially dangerous
% speedup in cont-exp, we now move it to the kernel: the next
% patch is 30\% faster on main interface (seconds) (9->7 sec on
% 1 million calls). Another speed up is still under testing.

\startinterface english

  \def\dosetevalue  #1#2{\@EA\edef\csname#1#2\endcsname}
  \def\dosetgvalue  #1#2{\@EA\gdef\csname#1#2\endcsname}
  \def\dosetvalue   #1#2{\@EA\def \csname#1#2\endcsname}
  \def\docopyvalue#1#2#3{\@EA\def \csname#1#3\@EA\endcsname\@EA{\csname#2#3\endcsname}}

\stopinterface

\def\XMLprocess#1%
  {\begingroup\enableXML\XMLflush{#1}\endgroup}

%D (Inspired by a discussion on the \CONTEXT\ mailing list)
%D
%D In \TEX\ each character can have one of 16 catcodes. This way the
%D backslash, dollar, ampersand, hash and some more characters get
%D their  special meaning. If you want to process tokens under a
%D certain catcode  regime, passing arguments can interfere badly.
%D
%D \startbuffer[a]
%D \def\whatever#1{[#1]}
%D \whatever{whatever \type {\whatever{you want}} $or$ not!}
%D \stopbuffer
%D
%D \typebuffer[a]
%D
%D Here we pass an argument to \type {\whatever} but part of that
%D argument is to be processed under a different catcode regime, i.e.\
%D all characters that need to be typeset verbatim need to get
%D the catcode that makes it a letter. This is what we get when we typeset
%D the text verbatim:
%D
%D \starttyping
%D whatever \type {\whatever{you want}} $or$ not!
%D \stoptyping
%D
%D However, when passed to \type {\whatever} we get:
%D
%D \getbuffer[a]
%D
%D In \ETEX\ one can use  \type {\scantokens} to circumvent this problem.
%D
%D \startbuffer[b]
%D \def\rescan#1{\scantokens{#1}}
%D \def\whatever#1{[\rescan{#1}]}
%D \whatever{whatever \type {\whatever{you want}} $or$ not!}
%D \stopbuffer
%D
%D \getbuffer[b] \typebuffer[b]
%D
%D This time the \type {\whatever} call gives:
%D
%D \getbuffer[b]
%D
%D In this example, two spaces have crept in. The first one, after the
%D macro name, is inserted by \TEX\ and cannot be avoided. The last space
%D is inserted by \type {\scantokens}, and is the consequence of the fact
%D that this macro mimics reading from a file. You can avoid the last
%D space by a slightly different definition:
%D
%D \startbuffer[c]
%D \def\rescan#1{\scantokens{#1\ignorespaces}}
%D \def\whatever#1{[\rescan{#1}]}
%D \whatever{whatever \type {\whatever{you want}} $or$ not!}
%D \stopbuffer
%D
%D \typebuffer[c]
%D
%D Unfortunately we still keep the first space, but at least it's better than
%D a failure:
%D
%D \getbuffer[c]

\long\def\rescan#1{\scantokens{#1\ignorespaces}}
\long\def\rescanwithsetup#1#2{\bgroup\directsetup{#1}\scantokens{#2\ignorespaces}\egroup}

% In 2005 we will abandon support for font encodings that don't have
% the ascii characters { } $ etc in their normal slot, i.e. latin modern
% instead of computer modern. Then we can also clean up some of the ugly
% xml internals that are a result from the need to deal with funny
% encodings.
%
% a solution:
%
% \defineXMLargument[ctx:c]{\getXMLcharacter}
% \defineXMLargument[ctx:e]{\getXMLentity   }
% \defineXMLargument[ctx:u]{\unicodechar    }
%
% \bgroup \catcode`\<=\active \catcode`\&=\active
%
% \gdef\dontexpandutf
%   {\def\getXMLcharacter##1{<ctx:c>##1</ctx:c>}%
%    \def\getXMLentity   ##1{<ctx:e>##1</ctx:e>}%
%    \def\unicodechar    ##1{<ctx:u>##1</ctx:u>}}
%
% \egroup
%
% more generic

\def\XMLexpanded#1%
  {\bgroup
   \honorunexpanded
%    \dontexpandencoding
%    \dontexpandutf
   \let\dohandleactivecharacter\donthandleactivecharacter
   \xdef\@@globalexpanded{#1}%
   \egroup
   \@@globalexpanded}

\def\setXMLexpandedmark#1#2% using a tok prevents unwanted expansion in mark
  {\XMLexpanded{\scratchtoks{\enableXML#2}}%
   \expanded{\normalsetnormalmark{#1}{\the\scratchtoks}}}

%D Ok, I got tired of making dedicated clean up macros using the
%D same mechanism again and again, so now we have:
%D
%D \starttyping
%D \def\xxxx{abc.d} \replacecharacters\xxxx{a.}{-} \xxxx
%D \stoptyping

\def\replacecharacters#1#2#3% macro characters replacement
  {\bgroup
   \edef\ascii{#1}%
   \retainlccodes
   \def\docommand##1{\lccode\expandafter`\csname##1\endcsname=\expandafter`\csname#3\endcsname}%
   \handletokens#2\with\docommand
   \lowercase\@EA{\@EA\xdef\@EA\globalascii\@EA{\ascii}}%
   \egroup
   \dodoglobal\let#1\globalascii}

\ifx\pagediscards\undefined \let\pagediscards\relax \fi

\installoutput\synchronizeoutput % maybe add pagediscards
  {\ifvoid\normalpagebox\else
     \unvbox\normalpagebox
     \pagediscards
   \fi}

% temp hack, else no proper default fall back (like \textmultiply); todo: sync encoding

\appendtoks
   \let\characterencoding\nocharacterencoding
\to \everymathematics

% \separatestring123 456\to\test [\test]

% \def\separatestring#1\to#2%
%   {\let#2\empty
%    \def\docommand##1{\edef#2{\ifx#2\empty\else#2,\fi##1}}%
%    \processseparatedlist[#1][ ]\docommand}
%
% \processseparatedlist[aap noot][]\ruledhbox

% this will be activated when

% \newinsert\thispageinsert % <- installinsertion

% \def\flushatthispage
%   {\bgroup
%    \dowithnextbox{\insert\thispageinsert{\box\nextbox}\egroup}%
%    \hbox}

% \appendtoks
%     \ifvoid\thispageinsert\else\hbox{\smashedbox\thispageinsert}\fi
% \to \everyshipout

% \definemarkedpage[nobackgrounds]
% \markpage[nobackgrounds]
% \doifmarkedpageelse{nobackgrounds}

\def\gettwopassdatalist#1%
  {\loadtwopassdata
   \letcscsname\twopassdatalist\csname#1:\s!list\endcsname
   \ifx\twopassdatalist\relax\let\twopassdatalist\empty\fi}

\newcounter\nofmarkedpages

\def\definemarkedpage[#1]%
  {\definetwopasslist{\v!page:#1}}

\def\markpage[#1]% looks very much like domarginreference
  {\iftrialtypesetting\else
     \doglobal\increment\nofmarkedpages\relax
     \edef\writeparref%
       {\writeutilitycommand%
          {\twopassentry%
             {\v!page:#1}%
             {\nofmarkedpages}%
             {\noexpand\realfolio}}}%
     \writeparref
   \fi}

\def\doifmarkedpageelse#1%
  {\gettwopassdatalist{\v!page:#1}%
   \expanded{\doifinsetelse{\realfolio}{\twopassdatalist}}}

% Just a simple and fast hanger, for usage in macros.

\def\setuphanging
  {\dodoubleempty\getparameters[\??ha]}

\setuphanging
  [\c!distance=.5em]

\def\starthanging
  {\noindent\bgroup
   \dowithnextbox
     {\setbox\nextbox\hbox{\flushnextbox\hskip\@@hadistance}%
      \hangindent\nextboxwd
      \hangafter\plusone
      \flushnextbox\ignorespaces}
   \hbox}

\def\stophanging
  {\endgraf
   \egroup}

% experimental

\def\stophangaround
  {\endgraf
   \egroup}

\def\starthangaround
  {\noindent\bgroup
   \dowithnextbox
     {\ifdim\nextboxht>\strutht\setbox\nextbox\tbox{\flushnextbox}\fi
      \setbox\nextbox\hbox{\flushnextbox\hskip\@@hadistance}%
      \getboxheight\scratchdimen\of\box\nextbox
      \getnoflines\scratchdimen
      \nextboxht\strutht
      \nextboxdp\strutdp
      \hangindent\nextboxwd
      \hangafter-\noflines
      \llap{\flushnextbox}\ignorespaces}
   \hbox}

\def\modevalue#1#2#3%
  {\@EA\ifx\csname\@mode@\systemmodeprefix#1\endcsname\endcsname\enabledmode#2\else#2\fi}

\def\systemmodevalue#1%
  {\modevalue{\systemmodeprefix#1}}

% \getmulticolumnlines -> now in cont-loc, to be tested and really needed

\long\def\startprocesscommalist[#1]#2\stopprocesscommalist
  {\long\def\currentcommalistcommand##1{\def\currentcommalistitem{##1}#2}%
   \processcommalist[#1]\currentcommalistcommand}

% \tracefonthandlingtrue

% new, still to be improved
%
% \dorecurse{10}
%   {\input thuan
%    \placefigure{}{\framed[height=1.5cm]{test}}
%    \placefloatplaceholder}

\def\placefloatplaceholder
  {\ifroomforfloat \else
     \scratchdimen\pagegoal
     \advance\scratchdimen-\pagetotal
     \advance\scratchdimen-3\lineheight
     \ifdim\scratchdimen>\zeropoint
       \startlinecorrection[blank]
       \mhbox{\inframed{\labeltexts{placeholder}{\lastcaptiontag}}}%
       \stoplinecorrection
     \else
       \allowbreak
     \fi
   \fi}

\setuplabeltext
  [placeholder={, moved}]

% etex only, of course we could just parse (scan for \% in string)

\newif\ifpercentdimendone

\bgroup % usage: \setpercentdimen\somedimen{% or dimen} todo: pct
\catcode124=\@@comment
\catcode 37=\@@active
\gdef\setpercentdimen#1#2|
  {\xdef\@@expanded{#2}|
   \ifx\@@expanded\empty\else
     \bgroup
     \global\percentdimendonefalse
     \def\%{\dimexpr(#1/100)\global\percentdimendonetrue\ignorespaces}| scantokens add's a space
     \catcode`%=\@@active
     \catcode`\\=\@@escape
     \let%\%|
     \scratchdimen#1|
     \xdef\@@expanded{\@@expanded\scratchdimen\!!zeropoint}| trick: when 1.2 => .2\scratchdimen and 0pt typeset
     \startnointerference
     \global\globalscratchdimen\scantokens\@EA{\@@expanded}| i'm lazy and use etex
     \stopnointerference
     \egroup
     #1\globalscratchdimen
   \fi}
\egroup

% TEX alternative, in principle accurate enough and also a bit faster

% \bgroup
%
% \catcode`\%=\@@other
% \catcode`\|=\@@comment
%
% \gdef\setpercentdimen#1#2|
%   {\beforesplitstring#2\at%\to\ascii
%    \doifelse\ascii{#2}
%     {#1=#2}
%     {\divide#1by100\relax#1=\ascii#1\relax}} | or: {#1=\ascii#1\divide#1by100\relax}}
%
% \egroup
%
% \dimen0=1000pt \setpercentdimen{\dimen0}{10%} \the\dimen0
% \dimen0= 100pt \setpercentdimen{\dimen0}{10%} \the\dimen0
% \dimen0=  95pt \setpercentdimen{\dimen0}{10%} \the\dimen0
% \dimen0=  10pt \setpercentdimen{\dimen0}{10%} \the\dimen0
% \dimen0=   1pt \setpercentdimen{\dimen0}{10%} \the\dimen0

\bgroup

\obeylines % don't remove %'s !

\gdef\collapsedspace#1%
  {\ifx#1^^M%
     \expandafter\collapsedspace
   \else
     \space
     \expandafter#1%
   \fi}

\gdef\collapsespaces%
  {\prependtoksonce\relax\to\everyeof%
   \ignorelines%
   \ignoretabs%
   \let\obeyedspace\collapsedspace%
   \obeyspaces}

\egroup

% \def\doshowpardata#1#2{\hbox{\string#1: \the#2}\endgraf}
%
% \def\showpardata
%   {\edef\thepardata
%      {\hbox{font: \fontname\font}\endgraf
%       \doshowpardata{interword space}{\fontdimen2\font}%
%       \doshowpardata{interword stretch}{\fontdimen3\font}%
%       \doshowpardata{interword shrink}{\fontdimen4\font}%
%       \doshowpardata{quad space}{\fontdimen6\font}%
%       \doshowpardata{extra space}{\fontdimen7\font}%
%       \doshowpardata\hsize\hsize
%       \doshowpardata\leftskip\leftskip
%       \doshowpardata\rightskip\rightskip
%       \doshowpardata\spaceskip\spaceskip
%       \doshowpardata\xspaceskip\xspaceskip
%       \doshowpardata\parindent\parindent
%       \doshowpardata\parfillskip\parfillskip
%       \doshowpardata\hyphenpenalty\hyphenpenalty
%       \doshowpardata\exhyphenpenalty\exhyphenpenalty
%       \doshowpardata\displaywidowpenalty\displaywidowpenalty
%       \doshowpardata\widowpenalty\widowpenalty
%       \doshowpardata\clubpenalty\clubpenalty
%       \doshowpardata\brokenpenalty\brokenpenalty
%       \doshowpardata\doublehyphendemerits\doublehyphendemerits
%       \doshowpardata\finalhyphendemerits\finalhyphendemerits
%       \doshowpardata\adjdemerits\adjdemerits}%
%    \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

% todo : test low level translation (nl->en) and optimize script

% \definestylecollection[mine]

% \definestyleinstance[mine][default][sorry]
% \definestyleinstance[mine][tt][bs][ttbs:\rm\sl]
% \definestyleinstance[mine][tt][bf][ttbf:\rm\sl]
% \definestyleinstance[mine][bf][\sl]
% \definestyleinstance[mine][sl][\tt]

% {\bf test \mine test \sl test \mine test \bs oeps \mine oeps {\tt test \mine \bf test}}

\definesystemvariable{sx}

\def\definestylecollection
  {\dosingleargument\dodefinestylecollection}

\def\dodefinestylecollection[#1]%
  {\iffirstargument
     \unexpanded\setvalue{#1}{\styleinstance[#1]}%
     \def\docommand##1%
       {\def\dodocommand####1{\letbeundefined{\??sx##1:####1:\commalistelement}}%
        \processcommacommand[\alternativelist,\s!default]\dodocommand}%
     \processcommacommand[\stylelist,\s!default]\docommand
   \fi}

\def\definestyleinstance
  {\doquadrupleargument\dodefinestyleinstance}

\def\dodefinestyleinstance[#1][#2][#3][#4]% [name] [rm|ss|tt|..] [sl|bf|...] [whatever]
  {\iffirstargument
     \doifundefined{#1}{\definestylecollection[#1]}%
   \fi
   \iffourthargument
     \setvalue{\??sx#1:#2:#3}{#4}%
   \else\ifthirdargument
     \setvalue{\??sx#1::#2}{#3}%
   \else\ifsecondargument
     \letvalue{\??sx#1::#2}\empty
   \fi\fi\fi}

\unexpanded\def\styleinstance[#1]% will be faster
  {%\begingroup\expanded{\infofont[#1:\fontstyle:\fontalternative]}\endgroup
   \executeifdefined{\??sx#1:\fontstyle:\fontalternative}%
  {\executeifdefined{\??sx#1:\fontstyle:\s!default}%
  {\executeifdefined{\??sx#1::\fontalternative}
  {\getvalue        {\??sx#1::\s!default}}}}}

% \beginETEX \ifcsname
%
% \unexpanded\def\styleinstance[#1]%
%   {\csname\??sx#1%
%       \ifcsname:\fontstyle:\fontalternative\endcsname
%         :\fontstyle:\fontalternative
%       \else\ifcsname:\fontstyle:\s!default\endcsname
%         :\fontstyle:\s!default
%       \else\ifcsname::\fontalternative\endcsname
%         ::\fontalternative
%       \else\ifcsname::\s!default\endcsname
%         ::\s!default
%       \else
%         % nothing, \relax
%       \fi\fi\fi\fi
%     \endcsname}
%
% \endETEX

% cleaner
%
% \long\def\doMPTEXcheck#1%
%   {\long\def\dodoMPTEXcheck##1#1##2##3\war{\if##2@\else\@EA\donoMPTEXcheck\fi}%
%    \@EA\dodoMPTEXcheck\MPascii#1@@\war}

% \long\def\donoMPTEXcheck#1\relax
%  {\global\MPTEXgraphictrue}

% \MPTEXgrapicchecks\emptytoks

% \def\forceMPTEXcheck#1%
%   {\convertargument#1\to\ascii
%    \@EA\appendtoks\@EA\doMPTEXcheck\@EA{\ascii}\to\MPTEXgrapicchecks}

% \forceMPTEXcheck{etex}
% \forceMPTEXcheck{textext}
% \forceMPTEXcheck{graphictext}

% \long\def\checkMPTEXgraphic#1%
%   {\ifforceMPTEXgraphic
%      \global\MPTEXgraphictrue
%    \else
%      \global\MPTEXgraphicfalse
%      \expandafter\convertargument#1\to\MPascii
%      \the\MPTEXgrapicchecks\relax % \relax is end condition!
%    \fi}

% no, wrong! never!
%
% \def\tightlayer[#1]%
%   {\begingroup
%    \def\currentlayer{#1}% todo: left/right
%    \setbox\nextbox\emptybox        % hoogte/breedte are \wd\nextbox/\ht\nextbox
%    \hsize\layerparameter\c!width   % \overlaywidth   = \hsize
%    \vsize\layerparameter\c!height  % \overlaywheight = \vsize
%    \hbox to \hsize{\composedlayer{#1}}%
%    \endgroup}

\let\locatedfilepath\empty

\def\locatefilepath#1%
  {\let\locatedfilepath\empty
   \ifx\allinputpaths\empty \else
     \def\docommando##1%
       {\doiffileelse{\pathplusfile{##1}{#1}}{\donetrue\def\locatedfilepath{##1}}\donefalse
        \ifdone\expandafter\quitcommalist\fi}%
     \doifparentfileelse{#1} % new
       {\processcommacommand  [\allinputpaths]\docommando}
       {\processcommacommand[.,\allinputpaths]\docommando}%
   \fi}

% todo : share symbols

% \definecolor[rollover:n][red]
% \definecolor[rollover:r][green]
% \definecolor[rollover:d][blue]

\definepalet
  [rollover]
  [n=red,
   r=green,
   d=blue]

% \newcounter\nofrollovers
%
% \def\dorollbutton[#1][#2]#3[#4]%
%   {\dontleavehmode
%    \bgroup
%    \doglobal\increment\nofrollovers
%    \unexpanded\def\dosetlocationbox[##1]##2[##3]%
%      {\getparameters[##1][##3]%
%       \definecolor[rollover][rollover:##2]%
%       \let\next\hbox
%       \doif{##2}{n}
%         {\doifvalue{##1\c!variant}\v!verborgen{\let\next\phantom}}%
%       \next
%         {\localframed[##1]
%            [\c!framecolor=rollover,\c!backgroundcolor=rollover,\c!color=rollover]%
%            {\dolocationattributes{##1}\c!style\c!color{#3}}}}%
%    \iffirstargument
%      \ifsecondargument
%        \def\setlocationbox##1{\dosetlocationbox[\??am#1]{##1}[#2]}%
%      \else
%        \doifassignmentelse{#1}
%          {\def\setlocationbox##1{\dosetlocationbox[\??bt]{##1}[#1]}}
%          {\def\setlocationbox##1{\dosetlocationbox[\??am#1]{##1}[]}}%
%      \fi
%    \else
%      \def\setlocationbox##1{\dosetlocationbox[\??bt]{##1}[]}%
%    \fi
%    % todo: share symbols
%    \definesymbol[rsym:\nofrollovers:n][\setlocationbox n]%
%    \definesymbol[rsym:\nofrollovers:r][\setlocationbox r]%
%    \definesymbol[rsym:\nofrollovers:d][\setlocationbox d]%
%    \nextsystemfield
%    \setupfield
%      [rollbutton]
%      [\c!frame=\v!off,\c!offset=\v!overlay,\c!klickoff={#4}]%
%    \definefield
%      [\currentsystemfield][push][rollbutton]
%      [rsym:\nofrollovers:n,%
%       rsym:\nofrollovers:r,%
%       rsym:\nofrollovers:d]%
%    \fitfield[\currentsystemfield]%
%    \egroup}

\newcounter\nofrollovers
\newcounter\nofrollbuttons

\def\dorollbutton[#1][#2]#3[#4]%
  {\dontleavehmode
   \bgroup
   \doglobal\increment\nofrollovers
   \doglobal\increment\nofrollbuttons
   \unexpanded\def\dosetlocationbox[##1]##2[##3]%
     {\getparameters[##1][##3]%
      \definecolor[rollover][rollover:##2]%
      \doifelse{##2}{n}{\doifelsevalue{##1\c!alternative}\v!hidden\phantom\hbox}\hbox
        {\localframed[##1]
           [\c!framecolor=rollover,\c!backgroundcolor=rollover,\c!color=rollover]%
           {\dolocationattributes{##1}\c!style\c!color{#3}}}}%
   \iffirstargument
     \ifsecondargument
       \def\setlocationbox##1{\dosetlocationbox[\??am#1]{##1}[#2]}%
     \else
       \doifassignmentelse{#1}
         {\def\setlocationbox##1{\dosetlocationbox[\??bt]{##1}[#1]}}
         {\def\setlocationbox##1{\dosetlocationbox[\??am#1]{##1}[]}}%
     \fi
   \else
     \def\setlocationbox##1{\dosetlocationbox[\??bt]{##1}[]}%
   \fi
   % todo: share symbols, tricky since different dimensions
   \definesymbol[rsym:\nofrollovers:n][\setlocationbox n]%
   \definesymbol[rsym:\nofrollovers:r][\setlocationbox r]%
   \definesymbol[rsym:\nofrollovers:d][\setlocationbox d]%
   \setupfield
     [rollbutton]
     [\c!frame=\v!off,
      \c!offset=\v!overlay,
      \c!clickout={#4}]%
   \definefield
     [roll:\nofrollbuttons][push][rollbutton]
     [rsym:\nofrollovers:n,%
      rsym:\nofrollovers:r,%
      rsym:\nofrollovers:d]%
   \fitfield[roll:\nofrollbuttons]%
   \egroup}

\unexpanded\def\rollbutton
  {\dodoubleempty\dorollbutton}

% \def\do@@amrob[#1]#2\\%
%   {\txt\rollbutton[\currentmenu]{\ignorespaces#2\unskip}[#1]\\}%

% \appendtoks \let\rob\do@@amrob \to \everysetmenucommands

\def\menu@rob[#1]#2\\%
  {\@@amboxcommand\rollbutton[\currentmenu]{\ignorespaces#2\unskip}[#1]\\}%

\appendtoks \let\rob\menu@rob \to \everysetmenucommands

% calls:
%              {..} [JS..]
% [left]       {..} [JS..]
%        [a=b] {..} [JS..]
% [left] [a=b] {..} [JS..]
%
% \setupbuttons[offset=0pt,frame=off] % alternative=hidden
%
% \rollbutton {Manuals}       [JS(Goto_File{show-man.pdf})]
% \rollbutton {Articles}      [JS(Goto_File{show-art.pdf})]
% \rollbutton {Papers}        [JS(Goto_File{show-pap.pdf})]
% \rollbutton {Presentations} [JS(Goto_File{show-pre.pdf})]
% \rollbutton {Resources}     [JS(Goto_File{show-res.pdf})]
%
% \rob [JS(...)] bla bla \\

\unexpanded\def\overlayrollbutton
  {\dodoubleargument\dooverlayrollbutton}

\def\dooverlayrollbutton[#1][#2]%
  {\bgroup
   \nextsystemfield
   \setupfield
     [overlayrollbutton]
     [\c!frame=\v!off,\c!offset=\v!overlay,\c!regionin={#1},\c!regionout={#2}]%
   \definesymbol
     [\currentsystemfield]
     [{\framed[\c!frame=\v!off,\c!width=\overlaywidth,\c!height=\overlayheight]{}}]%
   \definefield
     [\currentsystemfield][push][overlayrollbutton][\currentsystemfield][\currentsystemfield]%
   \fitfield[\currentsystemfield]%
   \egroup}

% \defineoverlay
%   [ShowMenu]
%   [{\overlayrollbutton[VideLayer{navigation}][HideLayer{navigation}]}]

\def\inlinedbox
  {\bgroup
   \dowithnextbox
     {\scratchdimen\nextboxht
      \advance\scratchdimen\nextboxdp
      \advance\scratchdimen-\lineheight
      \divide\scratchdimen\plustwo
      \advance\scratchdimen\strutdepth
      \setbox\nextbox\hbox{\lower\scratchdimen\flushnextbox}%
      \nextboxht\strutht
      \nextboxdp\strutdp
      \flushnextbox
      \egroup}%
     \hbox}

% \readfile{cont-exp}\donothing\donothing % speed up (5-20%)

\def\dimenratio#1#2% etex only
  {\withoutpt\the\dimexpr(2\dimexpr(#1)/(\dimexpr(#2)/32768))}

\def\doxprecurse#1#2%
  {\ifnum#1=\zerocount % no \ifcase
     \expandafter\gobblethreearguments
   \else
     #2\expandafter\expandafter\expandafter\doxprecurse\expandafter
   \fi\expandafter{\the\numexpr(#1-1)}{#2}}

\def\buttonframed{\dodoubleempty\localframed[\??bt]} % goodie

\unexpanded\def\asciistr#1{\convertargument#1\to\ascii{\verbatimfont\ascii}}

\prependtoks \setnormalcatcodes  \to \everyTEXinputmode
\appendtoks  \processingXMLfalse \to \everyTEXinputmode

\let\normalenableXML\enableXML % some day we move the normal \enableXML into the toks

\prependtoks \normalenableXML    \to \everyXMLinputmode
\appendtoks  \processingXMLtrue  \to \everyXMLinputmode

\def\enableXML {\setinputmode[XML]}
\def\disableXML{\setinputmode[TEX]}

\beginTEX

  % else the skip aborts the reshape process

  \def\shapefill{\vskip\onepoint\!!plus\lineheight\!!minus\lineheight\relax}

\endTEX

\beginETEX

  \def\shapefill{\vskip\zeropoint\!!plus\lineheight\!!minus\lineheight\relax}

\endETEX

% Currently there is a bug in \lastnodetype, so we will enable this
% feature when the bugfix is widespread.

% \beginETEX \lastnodetype
%
% \def\dodoreshapebox#1#2#3#4% \shapebox, \shapepenalty, \shapekern, \shapeskip
%   {\ifnum\lastnodetype=\@@gluenode % \ifcase\lastskip % \ifdim\lastskip=\zeropoint\relax
%      \shapeskip\lastskip
%      \global\setbox\tmpshapebox\normalvbox{#4\unvbox\tmpshapebox}%
%      \unskip
%    \else\ifnum\lastnodetype=\@@kernnode % \ifcase\lastkern % \ifdim\lastkern=\zeropoint\relax
%      \shapekern\lastkern
%      \global\setbox\tmpshapebox\normalvbox{#3\unvbox\tmpshapebox}%
%      \unkern
%    \else\ifnum\lastnodetype=\@@penaltynode % \ifcase\lastpenalty % \ifnum\lastpenalty=\zerocount
%      \shapepenalty\lastpenalty
%      \global\setbox\tmpshapebox\normalvbox{#2\unvbox\tmpshapebox}%
%      \unpenalty
%    \else
%      \setbox\shapebox\lastbox
%      \ifvoid\shapebox
%        \unskip\unpenalty\unkern
%      \else
%        \ifdim\wd\shapebox=\shapesignal\relax
%          \exitloop
%        \else
%          \shapecounter\zerocount
%          \global\setbox\tmpshapebox\normalvbox{#1\unvbox\tmpshapebox}%
%        \fi
%      \fi
%    \fi\fi\fi
%    \ifnum\shapecounter>100 % can be less
%      \message{<<forced exit from shapebox>>}%
%      \global\setbox\tmpshapebox\copy\oldshapebox
%      \exitloop
%    \else
%      \advance\shapecounter \plusone
%    \fi}
%
% \endETEX

\let\normaltype\type

\beginTEX

  \unexpanded\def\retype#1{\bgroup\convertargument#1\to\ascii\@EA\normaltype\@EA{\ascii}\egroup}

\endTEX

\beginETEX

  \unexpanded\def\retype#1{\scantokens{\normaltype{#1}\ignorespaces}}

\endETEX

\def\simplifytype{\let\type\retype}

% \ruledhbox
%   {\startignorespaces
%      \def\oeps{a}
%      \startignorespaces
%        \def\oeps{a}
%      \stopignorespaces
%      \def\oeps{a}
%    \stopignorespaces
%    \oeps}

\newsignal\boissignal
\newcount \boislevel

\long\def\startignorespaces
  {\advance\boislevel\plusone
   \ifcase\boislevel\or \ifhmode
     \hskip\boissignal
   \fi \fi
   \ignorespaces}

\long\def\stopignorespaces
  {\ifcase\boislevel\or \ifhmode
    \doloop
      {\ifdim\lastskip=\zeropoint
         \exitloop
       \else\ifdim\lastskip=\boissignal
         \unskip
         \exitloop
       \else
         \unskip
       \fi\fi}%
   \fi \fi
   \advance\boislevel\minusone}

\defineblankmethod [\v!synchronize] {\verticalstrut\vskip-2\lineheight\verticalstrut}

% \vtop{\blank[synchronize]\blank[line]test}

\def\minimalhbox#1#%
  {\dowithnextbox
     {\bgroup
      \setbox\scratchbox\hbox#1{\hss}%
      \ifdim\nextboxwd<\wd\scratchbox\nextboxwd\wd\scratchbox\fi
      \flushnextbox
      \egroup}
     \hbox}

% manual
%
% externfiguur     -> grid        =ja|hoogte|diepte|halveregel|passend -> helemaal in details
% stelplaatsblokin -> zijuitlijnen=hoogte|diepte|regel|halveregel|grid -> halveregel in 'details'

% TODO: TEST FIRST, NO CORRECTION NEEDED IN GRID MODE, EVT OPTION

\def\OTRONEsomeherefloat[#1]% spacing between two successive must be better
  {\baselinecorrection                           % not really needed in grid mode:
  %\ifgridsnapping \else \baselinecorrection \fi % ! ! ! test test test ! ! ! !
   \doplacefloatbox
   \doinsertfloatinfo
   \dochecknextindentation\??bk}

% todo: switch koppelen aan par scheelt pos

% to be documented: \startspread .. \stopspread

% to be documented primarydef p crossed d
% to be documented PlainTextArea

% manual
%
% Sometimes the demands are getting pretty weird:
%
% \startitemize
%   \item test
%   \item test
%   \headsym{xx} test \par test
% \stopitemize

% wait till bugfix in etex is widespead
%
% \beginETEX \lastnodetype
%
% \def\removeunwantedspaces
%   {\ifhmode
%      \doloop{\ifnum\lastnodetype=\@@gluenode\unskip\else\exitloop\fi}%
%    \fi}
%
% \endETEX

% \def\dodimchoice#1#2#3%
%   {\ifx#3\relax
%      #1\@EA\gobbleuntilrelax
%    \else\ifdim#1#2%
%      #3\@EAEAEA\gobbleuntilrelax
%    \else
%      \@EAEAEA\dodimchoice
%    \fi\fi{#1}}

% \def\donumchoice#1#2#3%
%   {\ifx#3\relax
%      #1\@EA\gobbleuntilrelax
%    \else\ifnum#1#2%
%      #3\@EAEAEA\gobbleuntilrelax
%    \else
%      \@EAEAEA\dodimchoice
%    \fi\fi{#1}}

% \def\dimchoice#1#2{\dodimchoice{#1}#2\empty\relax}
% \def\numchoice#1#2{\donumchoice{#1}#2\empty\relax}

\def\gobbleuntilempty#1\empty{}

\def\dodimchoice#1#2#3%
  {\ifdim#1#2%
     #3\@EA\gobbleuntilempty
   \else
     \@EA\dodimchoice
   \fi{#1}}

\def\donumchoice#1#2#3%
  {\ifnum#1#2%
     #3\@EA\gobbleuntilempty
   \else
     \@EA\dodimchoice
   \fi{#1}}

\def\dimchoice#1#2{\dodimchoice{#1}#2{=#1}{#1}\empty}
\def\numchoice#1#2{\donumchoice{#1}#2{=#1}{#1}\empty}

% \the\dimexpr(\dimchoice {7pt}{{<10pt}{8pt}{<12pt}{9pt}{<15pt}{10pt}{=11pt}{12pt}})
% \the\dimexpr(\dimchoice{11pt}{{<10pt}{8pt}{<12pt}{9pt}{<15pt}{10pt}{=11pt}{12pt}})
% \the\dimexpr(\dimchoice{14pt}{{<10pt}{8pt}{<12pt}{9pt}{<15pt}{10pt}{=11pt}{12pt}})

\def\showsetupsdefinition[#1]{\showvalue{\??su:#1}} % temp hack for debugging

% documentation : \setupregister[alternative=a|b|A|B]

\def\pushXMLmeaning#1%
  {\@EA\pushmacro\csname\@@XMLelement:#1/\endcsname
   \@EA\pushmacro\csname\@@XMLelement:#1\endcsname
   \@EA\pushmacro\csname\@@XMLelement:/#1\endcsname}

\def\popXMLmeaning#1%
  {\@EA\popmacro\csname\@@XMLelement:#1/\endcsname
   \@EA\popmacro\csname\@@XMLelement:#1\endcsname
   \@EA\popmacro\csname\@@XMLelement:/#1\endcsname}

\def\defineXMLstore {\doquadrupleargument\dodefineXMLstore[\saveXMLasdata]}
\def\defineXMLgstore{\doquadrupleargument\dodefineXMLstore[\gsaveXMLasdata]}

\def\dodefineXMLstore[#1][#2][#3][#4]% element attribute prefix % will become faster
  {\defineXMLargument[#2][#3=\s!dummy]{#1{#4:\XMLop{#3}}}}

\def\countXMLchildren[#1]#2%
  {\startnointerference
     \doglobal\newcounter\nofXMLchildren
     \defineXMLargument[#1]{\doglobal\increment\nofXMLchildren}%
     \startXMLignore
       #2%
     \stopXMLignore
   \stopnointerference}

\unprotected \def\traceposstring#1#2#3%
  {\iftracepositions
     \smashedhbox%
       {#1{\infofont#2#3}%
        \scratchdimen.5\points
        \kern-2\scratchdimen
        \vrule\!!width4\scratchdimen\!!height\scratchdimen\!!depth\scratchdimen}%
   \fi}

% It took quite a while to figure this out (using the preliminary 1.5
% spec). There are still a lot of things to be implemented. This is
% the third alternative.

% todo: multiple instances, dus indirect

\let\currentrendering\empty

\definereference[StartCurrentRendering] [\v!StartRendering {\currentrendering}]
\definereference[StopCurrentRendering]  [\v!StopRendering  {\currentrendering}]
\definereference[PauseCurrentRendering] [\v!PauseRendering {\currentrendering}]
\definereference[ResumeCurrentRendering][\v!ResumeRendering{\currentrendering}]

\newcounter\nofexternalrenderings

\def\useexternalrendering{\doquadrupleempty\douseexternalrendering}
\def\setinternalrendering{\dodoubleempty   \dosetinternalrendering}

\def\douseexternalrendering[#1][#2][#3][#4]% tag mime file options
  {\setgvalue{\??rd:#1}{\plusone{#1}{#2}{#3}{#4}}}

\def\dosetinternalrendering[#1][#2]% tag options {content}
  {\bgroup
   \dowithnextbox
     {\setgvalue{\??rd:#1}{\plustwo{#1}{IRO}{#1}{#2}}%
      \let\objectoffset\zeropoint
      \setobject{IRO}{#1}\hbox{\box\nextbox}%
      \egroup}%
     \hbox}

\def\checkrendering#1% let's hope that \next is not used
  {\iflocation
    \doifsomething{#1}%
      {\doifdefined{\??rd:#1}%
         {\expanded{\getvalue{\??rd::\number\renderingtype{#1}}%
            {\filterfromvalue{\??rd:#1}52}{\filterfromvalue{\??rd:#1}53}%
            {\filterfromvalue{\??rd:#1}54}{\filterfromvalue{\??rd:#1}55}}}}%
   \fi}

\setvalue{\??rd::1}{\doinsertrendering}
\setvalue{\??rd::2}{\doinsertrenderingobject}

\def\renderingtype   #1{\filterfromvalue{\??rd:#1}51}
\def\renderingoptions#1{\filterfromvalue{\??rd:#1}55}

\setexecutecommandcheck {startrendering}  \checkrendering
\setexecutecommandcheck {stoprendering}   \checkrendering
\setexecutecommandcheck {pauserendering}  \checkrendering
\setexecutecommandcheck {resumerendering} \checkrendering

% by using a nice trick (used in other places of context as well) we
% can easily overload the default size to match the opbject size

\def\renderingwidth {8cm}
\def\renderingheight{6cm}

\def\definerenderingwindow
  {\dodoubleempty\dodefinerenderingwindow}

\def\dodefinerenderingwindow[#1][#2]%
  {\presetlocalframed[\??rw#1]%
   \getparameters%
     [\??rw#1]%
     [\c!openpageaction=,\c!closepageaction=,%
      \c!width=\renderingwidth,\c!height=\renderingheight,%
      #2]}

\def\setuprenderingwindow
  {\dodoubleargument\dosetuprenderingwindow}

\def\dosetuprenderingwindow[#1]%
  {\getparameters[\??rw#1]}

\def\placerenderingwindow
  {\dodoubleempty\doplacerenderingwindow}

\def\doplacerenderingwindow[#1][#2]%
  {\bgroup
   \edef\currentrendering{\ifsecondargument#2\else#1\fi}%
   \ifcase\renderingtype\currentrendering\or
     % a file
   \or
     % an object
     \getobjectdimensions{IRO}\currentrendering
     \scratchdimen\objectheight
     \advance\scratchdimen\objectdepth
     \edef\renderingheight{\the\scratchdimen}%
     \edef\renderingwidth{\objectwidth}%
   \fi
   % create fall back if needed
   \doifdefinedelse{\??rw#1\c!width}
     {\def\currentrenderingwindow{#1}}
     {\let\currentrenderingwindow\s!default
      \definerenderingwindow[\currentrenderingwindow]}%
   \checkrendering\currentrendering
   \handlereferenceactions{\getvalue{\??rw\currentrenderingwindow\c!openpageaction }}\dosetuprenderingopenpageaction
   \handlereferenceactions{\getvalue{\??rw\currentrenderingwindow\c!closepageaction}}\dosetuprenderingclosepageaction
   \localframed
     [\??rw\currentrenderingwindow][\c!offset=\v!overlay]%
     {\expanded{\doinsertrenderingwindow
        \noexpand\currentrendering\hsize\vsize{\renderingoptions\currentrendering}}}%
   \egroup}

% todo:
%
% \setinternalrendering[example-1][options]{}

% test file:
%
% \definerenderingwindow
%   [example]
%   [width=320pt,height=150pt,frame=off,
%    background=color,backgroundcolor=gray,
%    openpageaction=StartCurrentRendering,
%    closepageaction=NextPage]% StopCurrentRendering]
%
% \useexternalrendering[example-1][audio/mpeg]                   [eldorado.mp3]
% \useexternalrendering[example-2][audio/mpeg]                   [myst-12.mp3]
% \useexternalrendering[example-3][application/x-shockwave-flash][http://localhost/mb.swf] [auto]
% \useexternalrendering[example-4][application/x-shockwave-flash][celebration.swf]
% \useexternalrendering[example-5][video/quicktime]              [p1000726.mov]
% \useexternalrendering[example-6][application/smil]             [quadratic_map.smi]
%
% \def\renderingmenu[#1]%
%   {\hbox
%      {\setupbuttons[width=2.5em]%
%       \button{\symbol[StartRendering]} [StartRendering{#1}]\enspace
%       \button{\symbol[StopRendering]}  [StopRendering{#1}]\enspace
%       \button{\symbol[PauseRendering]} [PauseRendering{#1}]\enspace
%       \button{\symbol[ResumeRendering]}[ResumeRendering{#1}]}}
%
% \renderingmenu[example-1]\blank
% \renderingmenu[example-2]\blank
% \renderingmenu[example-3]\blank
% \renderingmenu[example-4] \placefigure{A ShockWave}{\placerenderingwindow[example][example-4]} \page
% \renderingmenu[example-5] \placefigure{A Movie}{\placerenderingwindow[example][example-5]} \page
% \renderingmenu[example-6] \placefigure{A Smile}{\placerenderingwindow[example][example-6]}

% will be a MyWay
%
% \setuplayout[grid=yes] \setupcaption[figure][inbetween=] \useMPlibrary[dum] \setupcolors[state=start]
%
% \starttext \showgrid \showstruts
%
% \input ward \placefigure{}{\externalfigure[dummy][width=.5\hsize,lines=1.4,grid=yes]}
% \input ward \placefigure{}{\externalfigure[dummy][width=.5\hsize,lines=1.4,grid=fit]}
% \input ward \placefigure{}{\externalfigure[dummy][width=.5\hsize,lines=1.4,grid=height]}
% \input ward
% \page
% \input ward \placefigure{}{\externalfigure[dummy][width=.5\hsize,lines=1.5,grid=yes]}
% \input ward \placefigure{}{\externalfigure[dummy][width=.5\hsize,lines=1.5,grid=fit]}
% \input ward \placefigure{}{\externalfigure[dummy][width=.5\hsize,lines=1.5,grid=height]}
% \input ward
% \page
% \input ward \placefigure{}{\externalfigure[dummy][width=.5\hsize,lines=1.6,grid=yes]}
% \input ward \placefigure{}{\externalfigure[dummy][width=.5\hsize,lines=1.6,grid=fit]}
% \input ward \placefigure{}{\externalfigure[dummy][width=.5\hsize,lines=1.6,grid=height]}
% \input ward
% \page
% \input ward \placefigure[none]{}{\externalfigure[dummy][width=.5\hsize,lines=1.4,grid=yes]}
% \input ward \placefigure[none]{}{\externalfigure[dummy][width=.5\hsize,lines=1.4,grid=fit]}
% \input ward \placefigure[none]{}{\externalfigure[dummy][width=.5\hsize,lines=1.4,grid=height]}
% \input ward
% \page
% \input ward \placefigure[none]{}{\externalfigure[dummy][width=.5\hsize,lines=1.5,grid=yes]}
% \input ward \placefigure[none]{}{\externalfigure[dummy][width=.5\hsize,lines=1.5,grid=fit]}
% \input ward \placefigure[none]{}{\externalfigure[dummy][width=.5\hsize,lines=1.5,grid=height]}
% \input ward
% \page
% \input ward \placefigure[none]{}{\externalfigure[dummy][width=.5\hsize,lines=1.6,grid=yes]}
% \input ward \placefigure[none]{}{\externalfigure[dummy][width=.5\hsize,lines=1.6,grid=fit]}
% \input ward \placefigure[none]{}{\externalfigure[dummy][width=.5\hsize,lines=1.6,grid=height]}
% \input ward
%
% \stoptext

% funny, as field action with e.g. dissolve ... only the field dissolves, bug?

\setglobalsystemreference\rt!exec{Transition}{transition}

%def\PDFexecutetransition {/Trans /Trans <</Type /Trans \executeifdefined{PDFpage\argumentA}\PDFpagereplace>>}
\def\PDFexecutetransition {/Trans /Trans <<\executeifdefined{PDFpage\argumentA}\PDFpagereplace>>}

% new, continuous blocks, \som \par \startdoorlopendblok ...

% \startitemize
%   \item                                      bagger
%   \item                                      bagger
%   \item          \startdoorlopendblok        bagger \stopdoorlopendblok
%   \item \endgraf \startdoorlopendblok        bagger \stopdoorlopendblok
%   \item \endgraf \startdoorlopendblok \strut bagger \stopdoorlopendblok
%   \item \startdoorlopendblok
%         \starttabulate
%         \NC test \NC test \NC \NR
%         \NC test \NC test \NC \NR
%         \NC test \NC test \NC \NR
%         \stoptabulate
%         \stopdoorlopendblok
%   \item test
% \stopitemize

\def\startdoorlopendblok % for special cases, don't change it too much and don't rely on it
  {\ifhmode\endgraf\nobreak\fi % don't remove the \nobreak
   \dowithnextboxcontent
     {\setlocalhsize \hsize\localhsize \forgetall}
     {\bgroup
      \forgeteverypar
      \forgetparskip
      \scratchdimen\nextboxht
      \advance\scratchdimen\nextboxdp
      \getnoflines\scratchdimen
      \advance\scratchdimen-\strutheight
      \setbox\nextbox\hbox{\lower\scratchdimen\box\nextbox}%
      \ht\nextbox\strutheight
      \dp\nextbox\strutdepth
      \setbox\nextbox\vbox
        {\indent\box\nextbox
         \endgraf
         \nobreak
         \advance\noflines\minusone
         \dorecurse\noflines{\crlf\nobreak}}%
      \verticalstrut
      \endgraf
      \nobreak
      \offinterlineskip
      \kern-2\lineheight % 2\lineheight when no vertical struts in main \vbox
      \nobreak
      \unvbox\nextbox
      \prevdepth\strutdepth
      % evt (eerst testen) een signal zodat een direct volgend blok goed gaat)
      \egroup}
     \vbox\bgroup
       \vskip-\lineheight \verticalstrut\endgraf
       \insidefloattrue
       \doinhibitblank} % beware, no \inhibitblank ! ! ! ! ! !

\def\stopdoorlopendblok
  {\endgraf\verticalstrut\endgraf\kern-2\lineheight
   \egroup}

\def\definepushbutton % name optional setup
  {\dodoubleempty\dodefinepushbutton}

\def\dodefinepushbutton[#1][#2]% name setup
  {\dododefinepushbutton{#1}{n}{push}%
   \dododefinepushbutton{#1}{r}{\symbol[psym:#1:n]}%
   \dododefinepushbutton{#1}{d}{\symbol[psym:#1:r]}%
   \setvalue{pushbutton:#1}{\dohandlepushbutton{#1}{#2}}}

\def\dododefinepushbutton#1#2#3%
  {\doifsymboldefinedelse{psym:#1:#2}%
     \donothing{\definesymbol[psym:#1:#2][{#3}]}}

\def\definepushsymbol
  {\dotripleargument\dodefinepushsymbol}

\def\dodefinepushsymbol[#1][#2]% [#3]
  {\definesymbol[psym:#1:#2]}

\def\dopushbutton[#1][#2]%
  {\executeifdefined{pushbutton:#1}\gobbleoneargument{#2}}

\def\pushbutton
  {\dodoubleargument\dopushbutton}

\def\dohandlepushbutton#1#2#3% identifier setup script
  {\bgroup
   \nextsystemfield
   \setupfield
     [pushbutton]
     [\c!frame=\v!overlay,
      \c!offset=\v!overlay,
      \c!clickout=#3,#2]%
   \definefield
     [\currentsystemfield]
     [push]
     [pushbutton]
     [psym:#1:n,psym:#1:r,psym:#1:d]%
   \fitfield
     [\currentsystemfield]%
   \egroup}

% \def\do@@ampsh
%   {\dodoubleargument\dodo@@ampsh}
%
% \def\dodo@@ampsh[#1][#2]#3\\%
%   {\txt\pushbutton[#1][#2]\\}%
%
%\appendtoks \let\psh\do@@ampsh \to \everysetmenucommands

\def\@@ampsh{\txt\pushbutton}

\appendtoks \let\psh\@@ampsh \to \everysetmenucommands

% \definepushbutton [reset]
%
% \definepushsymbol [reset] [n] [\uniqueMPgraphic{whatever}{color=green}]
% \definepushsymbol [reset] [r] [\uniqueMPgraphic{whatever}{color=white}]
%
% \startinteractionmenu[bottom]
%   \psh [reset] [JS(reset_something)] \\
% \stopinteractionmenu

\def\tabulaterule % to be redone, not correct
  {\dotabulaterule
     {\hrule\!!height.5\scratchdimen\!!depth.5\scratchdimen\relax
      \doifvalue{\??tt\currenttabulate\c!distance}\v!grid
        {\kern-\scratchdimen}}} % experimental tm-prikkels

% todo: \setupinterlinespace[\c!regel=\v!vast] => ==\the\baselineskip

%%%%%%%% todo: \chardef\snapstruts=1 => d=l-h

\def\useMPvariables
  {\dodoubleargument\douseMPvariables}

\def\douseMPvariables[#1][#2]%
  {\def\@@meta{#1:}%
   \prepareMPvariables{#2}}

\def\processlinetableXMLfile#1%
  {\bgroup
   \let\startlinetable\donothing
   \let\stoplinetable \donothing
   \startlinetableanalysis\processXMLfile{#1}\stoplinetableanalysis
   \startlinetablerun     \processXMLfile{#1}\stoplinetablerun
   \egroup}

% experimental: \synchronizegrid bla bla bla

\newcounter\currentgridsync

\def\gridsynctag{grs:\currentgridsync}

\def\synchronizegrid
  {\doglobal\increment\currentgridsync
   \par\prevdepth\zeropoint
   \nointerlineskip
   \hpos\gridsynctag{\strut}\par
   \vskip-\lineheight
   \nointerlineskip
   % top of text
   \scratchdimen\MPy{\v!text:\MPp\gridsynctag}%
   \advance\scratchdimen\MPh{\v!text:\MPp\gridsynctag}%
   % move to first baseline
   \advance\scratchdimen-\topskip
   % subtract wrong baseline
   \advance\scratchdimen-\MPy\gridsynctag
   % get minimal number of lines
   \advance\scratchdimen\lineheight
   \getnoflines\scratchdimen
   % calculate difference
   \advance\scratchdimen-\noflines\lineheight\relax
   \scratchdimen-\scratchdimen\relax
   \ifdim\scratchdimen>\zeropoint
     \nointerlineskip
     \advance\scratchdimen-\lineheight
     \vskip\scratchdimen \dontleavehmode \quad \strut
     \par
  %\else
  %  \message{no grid correction: \the\scratchdimen}\wait
   \fi}

% needed for extreme

\definesystemvariable{ie}

% \def\definetest[#1]#2%
%   {\long\setvalue{\??ie#1}{#2}}

\def\definetest
  {\dodoubleempty\dodefinetest}

\def\dodefinetest[#1][#2]#3%
  {\setgvalue{\??ie#1}{#3}%
   \ifsecondargument
      \processaction
        [#2]
        [% first test true, rest depends
         \v!next=>\setgvalue{\??ie#1}{\setgvalue{\??ie#1}{#3}\firstoftwoarguments},
         % rest true if first true
         % \v!first=>\setgvalue{\??ie#1}{#3{\letgvalue{\??ie#1}%
         %              \firstoftwoarguments\firstoftwoarguments}%
         %              \secondoftwoarguments},
         % always true
               \v!yes=>\letgvalue{\??ie#1}\firstoftwoarguments,
         % always false
              \v!no=>\letgvalue{\??ie#1}\secondoftwoarguments]%
   \fi}

\def\doperformtest#1%
  {\executeifdefined{\??ie#1}\secondoftwoarguments}

\def\definecolumnsethsize#1#2#3#4% will be improved/speed up
  {\bgroup
   \def\OTRSETidentifier{#1}%
   \ifcase\columnsetlevel\relax
     \mofcolumns\plusone
     \OTRSETinitializecolumns
     \OTRSETassignwidths
     \OTRSETsethsize
   \fi
   \!!counta#2\!!countb#3\docalculatecolumnsetspan
   \expandafter\egroup\expandafter\edef\expandafter
     #4\expandafter{\the\!!widtha}}

% so far

% between alignment lines certain rules apply, and even a
% simple test can mess up a table, which is why we have a
% special test facility
%
% \ruledvbox
%   {\starttabulate[|l|p|]
%    \NC 1test \NC test \NC \NR
%    \tableifelse{\doifelse{a}{a}}{\NC Xtest \NC test \NC \NR}{}%
%    \stoptabulate}

\long \def\tableifelse#1%
  {\TABLEnoalign{#1%
     {\aftergroup \firstoftwoarguments}%
     {\aftergroup\secondoftwoarguments}}}

% \long \def\tableif#1% whow, this is real ugly
%   {\TABLEnoalign{\let\gnext\gobbleoneargument#1%
%      {\let\gnext\firstofoneargument}}\gnext}

\long \def\tableiftextelse#1{\tableifelse{\doiftextelse{#1}}}

\def\overloaded#1#2%
  {\appendtoks
     \writestatus\m!systems{overloaded: \string#2}%
   \to \everybye
   #1#2}

\def\expandifnonempty#1%
  {\@EA\ifx\csname#1\endcsname\empty
     \expandafter\secondoftwoarguments
   \else
     \expandafter\firstoftwoarguments
   \fi
   {\csname#1\endcsname}}

\def\@@sectiekoppeling#1%
  {\expandifnonempty{\??ko#1\c!coupling}{#1}}

\def\@@sectiesectie#1%
  {\expandifnonempty{\??ko#1\c!section}{\@@sectiekoppeling{#1}}}

\def\sectioncountervalue#1%
  {\@@sectionvalue{\@@sectiesectie{#1}}}

% todo namespace \@@meta:#1:... ! ! ! ! ! !

\def\presetMPvariable
  {\dodoubleargument\dopresetMPvariable}

\def\dopresetMPvariable[#1][#2=#3]%
  {\doifundefined{#1:#2}{\setvalue{#1:#2}{#3}}}

% experiment, not yet to be used

\def\displaybreak
  {\ifhmode
     \removeunwantedspaces
     \ifcase\raggedstatus\hfill\fi
     \strut\penalty-9999 % \break fails on case (3)
   \fi}

\def\startdisplay{\displaybreak\ignorespaces\startpacked}
\def\stopdisplay {\stoppacked\displaybreak\ignorespaces}

\def\tightvbox{\dowithnextbox{\nextboxdp\zeropoint\flushnextbox}\vbox}
\def\tightvtop{\dowithnextbox{\nextboxht\zeropoint\flushnextbox}\vtop}

% pretty important (esp since we now ignore shipouts)
%
% actually we should nil all writes, marks, specials

\appendtoks \globallet\popproperties     \relax \to \everylastshipout
\appendtoks \globallet\popsplitproperties\relax \to \everylastshipout

\def\incrementvalue#1{\expandafter\increment\csname#1\endcsname}
\def\decrementvalue#1{\expandafter\decrement\csname#1\endcsname}

% \translateMPinput{il2-pl}
%
% \startMPenvironment[global]
%   \setupbodyfont[plr]
% \stopMPenvironment
%
% \TeX: ± ¶
%
% \startMPcode
% draw btex MetaPost: ± ¶ etex scaled 5 ;
% \stopMPcode

% \startcolumnset[two] \input tufte
% \startcolumnsetspan[two] \input tufte \stopcolumnsetspan
% \input tufte \stopcolumnset

% now in cont-loc.tex, for the sake of testing.
%
% %D When \type {\somecolor} is issued, we can savely assume
% %D grouping. Using \type {\groupedcommand} here (i.e.\ the
% %D definition of \type {\color}) is unsafe because in
% %D interferes with for instance switching attributes.
%
% \def\switchtocolor[#1]%
%   {\bgroup\startcolor[#1]
%    \aftergroup\stopcolor
%    \aftergroup\egroup}

% what is this stupid macro meant for:

\def\hyphenationpoint
  {\hskip\zeropoint}

\def\hyphenated#1%
  {\bgroup
   \!!counta\zerocount
   \def\hyphenated##1{\advance\!!counta\plusone}%
   \handletokens#1\with\hyphenated
   \!!countb\plusone
   \def\hyphenated##1%
     {##1%
      \advance\!!countb\plusone\relax
      \ifnum\!!countb>2 \ifnum\!!countb<\!!counta
        \hyphenationpoint
      \fi\fi}%
   \handletokens#1\with\hyphenated
   \egroup}

\def\obeysupersubletters
  {\let\super\normalsuper
   \let\suber\normalsuber
   \let\normalsuper\letterhat
   \let\normalsuber\letterunderscore
   \enablesupersub}

\def\obeysupersubmath
  {\let\normalsuper\letterhat
   \let\normalsuber\letterunderscore
   \enablesupersub}

%\let\normaltype\type
%
%\def\type#1%
%  {\expanded{\normaltype{\detokenize{#1}}}}

% {x123 \os x123} {\tfa x123 \os x123} {x123 \tx x123 \os x123}
% \definefontsynonym[OldStyle][Serif]
% {x123 \os x123} {\tfa x123 \os x123} {x123 \tx x123 \os x123}

% testen :
%
% \appendtoks
%   \let\registerparoptions\relax
% \to \everyforgetall

\def\startgridcorrection
  {\dosingleempty\dostartgridcorrection}

\def\dostartgridcorrection[#1]%
  {\ifgridsnapping
     \iffirstargument\doifsomething{#1}{\moveongrid[#1]}\fi
     \snaptogrid\vbox\bgroup
   \else
     \startbaselinecorrection
   \fi}

\def\stopgridcorrection
  {\ifgridsnapping
     \egroup
   \else
     \stopbaselinecorrection
   \fi}

\def\checkgridsnapping
  {\lineskip\ifgridsnapping\zeropoint\else\normallineskip\fi}

\def\startplaatsen
  {\dosingleempty\dostartplaatsen}

\def\dostartplaatsen[#1]% tzt n*links etc
  {\endgraf
   \noindent\bgroup
   \setlocalhsize
   \hbox to \localhsize\bgroup
     \doifnot{#1}\v!left\hss
     \def\stopplaatsen
       {\unskip\unskip\unskip
        \doifnot{#1}\v!right\hss
        \egroup
        \egroup
        \endgraf}%
     \gobblespacetokens}

% \startplaatsen[links] bla \stopplaatsen

% we don't register the paragraph characteristics, only the
% width

\appendtoks
  \setinnerparpositions % see "techniek" for application
\to \everytabulate

\appendtoks \checkcurrentlayout \to \everystarttext

\def\flushfootnotes  {\flushnotes}
\def\doflushfootnotes{\doflushnotes}

%D This alternative is slower, since it works on top of the
%D color (stack) mechanism, but it does provide nesting.

\def\dosetrastercolor#1%
  {\edef\@@cl@@s{#1}%
   \ifx\@@cl@@s\empty
     \let\@@cl@@s\@@rsscreen
   \fi
   \let\@@cl@@t\@@cl@@z % else we get rogue
   \let\@@cl@@a\@@cl@@z % transpancies
   \setevalue{\??cr\??rs}{\colorSpattern}}

% beware, don't add extra grouping, else color in tables
% fails

\def\localstartraster[#1]%
  {\ifincolor\dosetrastercolor{#1}\localstartcolor[\??rs]\fi}

\def\startraster[#1]%
  {\ifincolor\dosetrastercolor{#1}\startcolor[\??rs]\fi}

\def\localstopraster{\ifincolor\localstopcolor\fi}
\def\stopraster     {\ifincolor\stopcolor\fi}

\def\fontclassname#1#2%
  {\ifcsname\??ff#1#2\endcsname
     \fontclassname{#1}{\csname\??ff#1#2\endcsname}%
   \else\ifcsname\??ff#2\endcsname
     \fontclassname{#1}{\csname\??ff#2\endcsname}%
   \else
     #2%
   \fi\fi}

\def\defineclassfontsynonym
  {\dotripleargument\dodefineclassfontsynonym}

\def\dodefineclassfontsynonym[#1][#2][#3]%
  {\definefontsynonym[#1][\fontclassname{#2}{#3}]}

%\definefontsynonym [KopFont] [\fontclassname{officina}{SerifBold}]
%
%\defineclassfontsynonym [KopFont] [officina] [SerifBold]

\def\startcolumnmakeup % don't change
  {\bgroup
   \getrawnoflines\textheight % teksthoogte kan topskip hebben, dus raw
   \scratchdimen\noflines\lineheight
   \advance\scratchdimen-\lineheight
   \advance\scratchdimen\topskip
   \setbox\scratchbox
   \ifcase\showgridstate\vbox\else\ruledvbox\fi to \scratchdimen\bgroup
   \forgetall} % ! don't change

\def\stopcolumnmakeup
  {\egroup
   \dp\scratchbox\zeropoint
   \wd\scratchbox\textwidth
   \box\scratchbox
   \egroup
   \synchronizehsize}

% todo : hoe komt box er uit

\long\def\startexternalfigure
  {\dotripleempty\dostartexternalfigure}

\long\def\dostartexternalfigure[#1][#2][#3]#4\stopexternalfigure
  {\gdef\figuredescription{#4}%
   \externalfigure[#1][#2][#3]%
   \globallet\figuredescription\empty}

\let\figuredescription\empty

%% where does this come from, old code probably
%%
%%
%% \newif\ifpagechanged \let\lastchangedpage\empty
%%
%% \def\checkpagechange#1%
%%   {\gettwopassdata\s!paragraph
%%    \pagechangedfalse
%%    \iftwopassdatafound
%%      \ifnum\twopassdata>0\getvalue{\s!paragraph:p:#1}\relax
%%        \pagechangedtrue
%%      \fi
%%    \fi
%%    \ifpagechanged
%%      \letgvalue{\s!paragraph:p:#1}\twopassdata
%%      \globallet\lastchangedpage\twopassdata
%%    \else
%%      \globallet\lastchangedpage\realfolio
%%    \fi
%%    \doparagraphreference}
%%
%% \def\changedpage#1%
%%   {\getvalue{\s!paragraph:p:#1}}

% incomplete, will be a special case of float placement

\def\startfixed{\dosingleempty\dostartfixed}

\def\dostartfixed[#1]%
  {\expanded{\dowithnextbox{\noexpand\dodofixed{\ifhmode0\else1\fi}{#1}}}%
   \vbox\bgroup
   \setlocalhsize}

\def\stopfixed
  {\egroup}

\def\dodofixed#1#2%
  {\ifcase#1\relax
     \processaction
       [#2]
       [   \v!high=>\bbox   {\flushnextbox},
           \v!low=>\tbox   {\flushnextbox},
         \v!middle=>\vcenter{\flushnextbox},
           \v!lohi=>\vcenter{\flushnextbox},
        \s!unknown=>\tbox   {\flushnextbox},
        \s!default=>\tbox   {\flushnextbox}]%
   \else
     \startbaselinecorrection
       \noindent\flushnextbox
     \stopbaselinecorrection
   \fi}

% \startitemize
%
% \item \externalfigure[koe][height=2cm]
% \item \externalfigure[koe][height=2cm]
% \item \externalfigure[koe][height=2cm]
% \item \externalfigure[koe][height=2cm]
%
% \page
%
% \item \startfixed      \externalfigure[koe][height=2cm]\stopfixed
% \item \startfixed[high]\externalfigure[koe][height=2cm]\stopfixed
% \item \startfixed[low] \externalfigure[koe][height=2cm]\stopfixed
% \item \startfixed[lohi]\externalfigure[koe][height=2cm]\stopfixed
%
% \page
%
% \item test \startfixed      \externalfigure[koe][height=2cm]\stopfixed
% \item test \startfixed[high]\externalfigure[koe][height=2cm]\stopfixed
% \item test \startfixed[low] \externalfigure[koe][height=2cm]\stopfixed
% \item test \startfixed[lohi]\externalfigure[koe][height=2cm]\stopfixed
%
% \page
%
% \item test \par \startfixed      \externalfigure[koe][height=2cm]\stopfixed
% \item test \par \startfixed[high]\externalfigure[koe][height=2cm]\stopfixed
% \item test \par \startfixed[low] \externalfigure[koe][height=2cm]\stopfixed
% \item test \par \startfixed[lohi]\externalfigure[koe][height=2cm]\stopfixed
%
% \stopitemize

% still needed for uguide

\let\placefloatlabel          \placefloatcaption
\let\placefloatlabeltext      \placefloatcaptiontext
\let\placefloatlabelreference \placefloatcaptionreference

\def\obeyfollowingtoken{{}}  % end \cs scanning

\def\gobbleparameters{\doquadrupleempty\dogobbleparameters}
\def\dogobbleparameters[#1][#2][#3][#4]{}

% documentation

% \starttable[|||]
% \HL
% \VL test \VS test \VL \FR
% \VL test \VD test \VL \MR
% \VL test \VT test \VL \LR
% \HL
% \stoptable

%D To be documented, \type {\includemenu[menu]}.
%D To be documented, \type {\emphbf} cum suis.

%D A prelude to strategies. Note for myself: overloads
%D previous stuff from local pragma test files.

\def\s!strategy{strategy}

\def\currentstrategypass    {1}
\def\currentstrategyvariable{0}
\def\maximumstrategypass    {8}

\newconditional\strategypassneeded
\newconditional\strategypassforced

\definetwopasslist{\s!strategy}

\def\registerstrategypass%
  {\ifnum\currentstrategypass>\maximumstrategypass \else
     \ifconditional\strategypassforced
       \doglobal\increment\currentstrategypass
     \else%\ifconditional\strategypassneeded
       %\doglobal\increment\currentstrategypass
     \fi%\fi
   \fi
   \savecurrentvalue\currentstrategypass{\currentstrategypass}}

\appendtoks \registerstrategypass \to \everybye % \everylastshipout

\def\setstrategyvariable#1#2% key value
  {%\doifnotstrategyvariable{#1}{\global\settrue\strategypassneeded}%
   \doglobal\increment\currentstrategyvariable
   \expanded{\immediatewriteutilitycommand{\noexpand
     \twopassentry{\s!strategy}{\currentstrategyvariable}{#1::#2}}}}

\def\doifstrategyvariableelse#1#2#3%
  {\getstrategyvariable{#1}\iftwopassdatafound#2\else#3\fi}

\def\getstrategyvariable#1% key
  {\findtwopassdata{\s!strategy}{#1::}%
   \setxvalue{\s!strategy:#1}{\twopassdata}}

\def\retainstrategyvariable#1% key
  {\expanded{\setstrategyvariable{#1}{\strategyvariable{#1}}}}

\def\strategyvariable#1% key
  {\csname\s!strategy:#1\endcsname}

\let\stratvar\strategyvariable

\def\forcestrategy{\global\settrue \strategypassforced}
\def\abortstrategy{\global\setfalse\strategypassforced}

\def\doifstrategyvariableelse#1#2#3%
  {\getstrategyvariable{#1}\iftwopassdatafound#2\else#3\fi}

\def\doifstrategyvariable   #1#2{\doifstrategyvariableelse{#1}{#2}{}}
\def\doifnotstrategyvariable#1#2{\doifstrategyvariableelse{#1}{}{#2}}

%D New: only at start of columns; may change ! Rather
%D interwoven and therefore to be integrated when the multi
%D column modules are merged.

%  already taken care of: \definesystemvariable{ks}

% is buggy now and does not work any longer

\def\setupcolumnspan[#1]%
  {\getparameters[\??ks][#1]}

\presetlocalframed
  [\??ks]

\setupcolumnspan
  [\c!n=2,
   \c!offset=\v!overlay,
   \c!frame=\v!off]

\newbox\columnspanbox \let\postprocesscolumnspanbox\gobbleoneargument

\def\dostartcolumnspan[#1]%
  {\bgroup
   \setupcolumnspan[#1]%
   \forgetall
   \ifinsidecolumns
     \advance\hsize \intercolumnwidth
     \hsize\@@ksn\hsize
     \advance\hsize -\intercolumnwidth
   \fi
   \dowithnextbox
     {\setbox\columnspanbox\flushnextbox
      \ifinsidecolumns\wd\columnspanbox\hsize\fi
      \postprocesscolumnspanbox\columnspanbox
      \scratchdimen\ht\columnspanbox
      \setbox\columnspanbox\hbox % depth to be checked, probably option!
        {\localframed[\??ks][\c!offset=\v!overlay]{\box\columnspanbox}}%
      \ht\columnspanbox\scratchdimen
      \dp\columnspanbox\strutdp
      \wd\columnspanbox\hsize
      \ifinsidecolumns
        \ifnum\@@ksn>1
          \setvsize
          \dohandleallcolumns
            {\ifnum\currentcolumn>\@@ksn\else
               \global\setbox\currenttopcolumnbox=\vbox
                 {\ifnum\currentcolumn=1
                    \snaptogrid\vbox{\copy\columnspanbox}
                  \else
                    \snaptogrid\vbox{\vphantom{\copy\columnspanbox}}
                  \fi}%
               \wd\currenttopcolumnbox\hsize
               \global\advance\vsize -\ht\currenttopcolumnbox
             \fi}
          \global\pagegoal\vsize
        \else
          \snaptogrid\vbox{\box\columnspanbox}
        \fi
      \else
        \snaptogrid\vbox{\box\columnspanbox}
      \fi
      \endgraf
      \prevdepth\strutdp
      \egroup}
     \vbox\bgroup
      %\topskipcorrection % becomes an option !
       \EveryPar{\begstrut\EveryPar{}}} % also !

\def\startcolumnspan
  {\dosingleempty\dostartcolumnspan}

\def\stopcolumnspan
  {\egroup}

%D For Ton. To be documented.

\def\plaatsexterndocument[#1]%
  {\def\doexternaldocument##1##2##3{\readlocfile{##2}\donothing\donothing}%
   \getvalue{\v!file:::#1}}

%D Far from complete.

\def\startgeheel
  {\startlinecorrection
   \insidefloattrue}

\def\stopgeheel
  {\stoplinecorrection}

%D No more news.

\protect

%D Next we load a few local optimizations and new features. They
%D live on on my machine and are not distributed, but they may end
%D up in the distributed files.

\readsysfile {cont-loc} {} {} % local improvements, patches, new features
\readsysfile {cont-exp} {} {} % experimental features (e.g. local speed-ups)

\endinput
