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

\writestatus{loading}{Context Core Macros / Misc Commands}

% todo: kleur in legenda + letter

% Obsolete
%
% \startmessages  dutch  library: systems
%   title: systeem
%       3: probeer LaTeX eens
% \stopmessages
%
% \startmessages  english  library: systems
%   title: system
%       3: try LaTeX
% \stopmessages
%
% \startmessages  german  library: systems
%   title: system
%       3: Versuche LaTeX
% \stopmessages
%
% \startmessages  czech  library: systems
%   title: system
%       3: zkuste LaTeX
% \stopmessages
%
% \startmessages  italian  library: systems
%   title: sistema
%       3: provare LaTeX
% \stopmessages
%
% \startmessages  norwegian  library: systems
%   title: system
%       3: forsøker LaTeX
% \stopmessages
%
% \startmessages  romanian  library: systems
%   title: sistem
%       3: incercati LaTeX
% \stopmessages
%
% %D You would not expect the next macro in \CONTEXT,
% %D wouldn't you? It's there to warn \LATEX\ users that
% %D something is wrong.
% %D
% %D Obsolete now:
% %
% % \def\documentstyle{\showmessage\m!systems3\empty\stoptekst}
% %
% % \let\documentclass=\documentstyle
% %D \macros
% %D   {simplifiedcommands, simplifycommands}
% %D
% %D I first needed this simplification in bookmarks. Users can
% %D add their own if needed.

\unprotect

%D Sometimes (for instance in bookmarks) we need to simplify macro
%D behaviour, so here is the hook.

\ifx\simplifiedcommands\undefined \newtoks\simplifiedcommands \fi

\def\simplifycommands{\the\simplifiedcommands}

%D A possibly growing list:

%appendtoks        \def\executesynonym#1#2#3#4{#3}\to\simplifiedcommands
%appendtoks             \def\executesort#1#2#3{#3}\to\simplifiedcommands

\appendtoks                                \def\ { }\to\simplifiedcommands
\appendtoks  \def\type#1{\string\\\strippedcsname#1}\to\simplifiedcommands
\appendtoks                            \def\TeX{TeX}\to\simplifiedcommands
\appendtoks                    \def\ConTeXt{ConTeXt}\to\simplifiedcommands
\appendtoks                  \def\MetaPost{MetaPost}\to\simplifiedcommands
\appendtoks                  \def\MetaFont{MetaFont}\to\simplifiedcommands
\appendtoks                    \def\MetaFun{MetaFun}\to\simplifiedcommands
\appendtoks                                \def||{-}\to\simplifiedcommands

\appendtoks\let\buildtextaccent\secondoftwoarguments\to\simplifiedcommands

% THIS WAS MAIN-002.TEX

%\def\checkinterlineskip
%  {\ifvmode
%     \ifdim\lastskip>\zeropoint
%       \nointerlineskip
%     \else\ifdim\lastkern>\zeropoint
%       \nointerlineskip
%     \fi\fi
%   \fi}

\def\horitems#1#2% #1=breedte #2=commandos
  {\scratchdimen#1%
   \divide\scratchdimen \nofitems
   \!!counta\zerocount
   \def\docommando##1%
     {\advance\!!counta \plusone
      \processaction
        [\@@isalign]
        [   \v!left=>\hbox to \scratchdimen{\strut##1\hss},
           \v!right=>\hbox to \scratchdimen{\hss\strut##1},
          \v!middle=>\hbox to \scratchdimen{\hss\strut##1\hss},
          \v!margin=>\ifnum\!!counta=\plusone\hss\else\hfill\fi
                     \strut##1%
                     \ifnum\!!counta=\nofitems\hss\else\hfill\fi,
         \s!default=>\hbox to \scratchdimen{\hss\strut##1\hss}, % midden
         \s!unknown=>\hbox to \scratchdimen{\strut##1\hss}]}%   % links
   \hbox to #1{\hss#2\hss}}

\def\veritems#1#2% #1=breedte #2=commandos
  {\scratchdimen#1%
   \def\docommando##1%
     {\ifdim\scratchdimen<\zeropoint % the - was a signal
        \hbox to -\scratchdimen{\hss\strut##1}%
      \else\ifdim\scratchdimen>\zeropoint
        \hbox to \scratchdimen{\strut##1\hss}%
      \else
        \hbox{\strut##1}%
      \fi\fi}%
   \vbox{#2}}

\def\dosetupitems[#1]%
  {\getparameters[\??is][#1]%
   \doif\@@iswidth\v!unknown
     {\def\@@iswidth{\hsize}}%
   \doifconversiondefinedelse\@@issymbol
     {\def\doitembullet##1{\convertnumber{\@@issymbol}{##1}}}
     {\doifsymboldefinedelse\@@issymbol
        {\def\doitembullet##1{\symbol[\@@issymbol]}}{}}}

\def\makeitemsandbullets#1%
  {\doifelse\@@isn\v!unknown
     {\getcommalistsize[#1]%
      \edef\nofitems{\commalistsize}}
     {\edef\nofitems{\@@isn}}%
   \setbox0\hbox
     {\doitems \@@iswidth
        {\processcommalist[#1]\docommando}}%
   \setbox2\hbox
     {\doitems \@@isbulletbreedte
        {\dorecurse\nofitems
           {\docommando{\strut\doitembullet\recurselevel}}}}}

\def\dostartitems#1#2#3%
  {\let\doitems#2%
   \def\@@isbulletbreedte{#3}%
   \makeitemsandbullets{#1}%
   \@@isbefore}

\def\dostopitems
  {\@@isafter
   \egroup}

\setvalue{doitems\v!top}#1%
  {\dostartitems{#1}\horitems\@@iswidth
   \noindent\vbox
     {\forgetall
      \doifsomething\@@issymbol
        {\doifnot\@@issymbol\v!none
           {\box2
            \@@isinbetween
            \nointerlineskip}}%
      \box0}%
   \dostopitems}

\setvalue{doitems\v!bottom}#1%
  {\dostartitems{#1}\horitems\@@iswidth
   \noindent\vbox
     {\forgetall
      \box0
      \doifsomething\@@issymbol
        {\@@isinbetween
         \nointerlineskip
         \box2}}%
   \dostopitems}

\setvalue{doitems\v!inmargin}#1%
  {\dostartitems{#1}\veritems{-1.5em}%  - is a signal
   \noindent\hbox{\llap{\box2\hskip\leftmargindistance}\box0}%
   \dostopitems}

\setvalue{doitems\v!left}#1%
  {\advance\hsize -1.5em%
   \dostartitems{#1}\veritems{1.5em}%
   \noindent\hbox{\box2\box0}%
   \dostopitems}

\setvalue{doitems\v!right}#1%
  {\dostartitems{#1}\veritems{0em}%
   \noindent\hbox{\box0\hskip-\wd2\box2}%
   \dostopitems}

\def\setupitems
  {\dosingleargument\dosetupitems}

\def\complexitems[#1]%
  {\bgroup
   \setupitems[#1]%
   \parindent\zeropoint
   \setlocalhsize
   \hsize\localhsize
   \dontcomplain
  %\doifundefined{doitems\@@islocation}%
  %  {\let\@@islocation\v!left}%
  %\getvalue{doitems\@@islocation}}
   \executeifdefined{doitems\@@islocation}{\let\@@islocation\v!left}}

\definecomplexorsimpleempty\items

\setupitems
  [\c!location=\v!left,
   \c!symbol=5,
   \c!width=\hsize,
   \c!align=\v!middle,
   \c!n=\v!unknown,
   \c!before=\blank,
   \c!inbetween={\blank[\v!medium]},
   \c!after=\blank]

% Te zijner tijd [plaats=boven,onder,midden] implementeren,
% in dat geval moet eerst de maximale hoogte worden bepaald.
%
% Overigens kan een en ander mooier met \halign.

\def\dodefineparagraphs[#1][#2]%
  {\setvalue{\s!do\s!next#1}%
     {\def\\{\getvalue{#1}}}%
   \setvalue{#1}%
     {\getvalue{\s!do\s!next#1}%
      \dostartalineas{#1}}%
   \setvalue{\e!next#1}%
     {\getvalue{#1}}%
   \setvalue{\e!start#1}%
     {\bgroup
      \letvalue{\s!do\s!next#1}\empty
      \setvalue{\e!stop#1}%
        {\getvalue{#1}%
         \egroup}%
      \getvalue{#1}}%
   \getparameters[\??al#1]%
     [\c!n=3,
      \c!before=\blank,
      \c!after=\blank,
      \c!distance=1em,
      \c!height=\v!fit,
      \c!rule=\v!off,
      \c!command=,
      \c!align=,
      \c!tolerance=\v!tolerant,
      \c!style=,
      \c!color=,
      \c!top=,
      \c!top=\vss,
      \c!bottom=\vfill,
      #2]%
   \setvalue{\e!setup#1\e!endsetup}%
     {\setupparagraphs[#1]}%
   \dorecurse
      {\getvalue{\??al#1\c!n}}
      {\setupparagraphs[#1][\recurselevel]
         [\c!width=,
          \c!bottom=\getvalue{\??al#1\c!bottom},
          \c!top=\getvalue{\??al#1\c!top},
          \c!height=\getvalue{\??al#1\c!height},
          \c!style=\getvalue{\??al#1\c!style},
          \c!color=\getvalue{\??al#1\c!color},
          \c!rule=\getvalue{\??al#1\c!rule},
          \c!align=\getvalue{\??al#1\c!align},
          \c!tolerance=\getvalue{\??al#1\c!tolerance},
          \c!distance=\getvalue{\??al#1\c!distance}]}%
   \setupparagraphs[#1][1][\c!distance=0em]}

\def\defineparagraphs
  {\dodoubleargument\dodefineparagraphs}

\def\dosetupparagraphs[#1][#2][#3]%
  {\doifelse{#2}\v!each
     {\dorecurse
        {\getvalue{\??al#1\c!n}}
        {\getparameters[\??al#1\recurselevel][#3]}}
     {\ConvertToConstant\doifelse{#3}{}
        {\getparameters[\??al#1][#2]}
        {\def\docommando##1%
           {\getparameters[\??al#1##1][#3]}%
         \processcommalist[#2]\docommando}}}

\def\setupparagraphs
  {\dotripleempty\dosetupparagraphs}

\newcount\alteller
\newcount\alnsize
\newdimen\alhsize

\def\doalinealijn#1#2%
  {\doifelsevalue{\??al#2\the\alteller\c!rule}\v!on
     {\dimen2=#1\relax
      \hskip.5\dimen2
      \hskip-\linewidth
      \vrule\!!width\linewidth
      \hskip.5\dimen2}
     {\hskip#1}}

\def\dostartalinea#1%
  {\doifelsevaluenothing{\??al#1\the\alteller\c!width}
     {\!!widtha\alhsize
      \divide\!!widtha \alnsize}
     {\!!widtha\getvalue{\??al#1\the\alteller\c!width}}%
   \dostartattributes
     {\??al#1\the\alteller}\c!style\c!color
     \empty
   \doifelsevalue{\??al#1\the\alteller\c!height}\v!fit
     {\setbox0\vtop}
     {\setbox0\vtop to \getvalue{\??al#1\the\alteller\c!height}}%
   \bgroup
   \blank[\v!disable]%
   \forgetall
   \getvalue{\??al#1\the\alteller\c!top}%
   \getvalue{\??al#1\c!inner}%
   \hsize\!!widtha  % setting \wd afterwards removed
   \getvalue{\??al#1\the\alteller\c!inner}%
   \edef\!!stringa{\getvalue{\??al#1\the\alteller\c!align}}%  nodig?
   \expandafter\setupalign\expandafter[\!!stringa]%
   \edef\!!stringa{\getvalue{\??al#1\the\alteller\c!tolerance}}% nodig?
   \expandafter\setuptolerance\expandafter[\!!stringa]%
   \ignorespaces
   \endgraf
   \ignorespaces
   %
   % Nadeel van de onderstaande constructie is dat \everypar
   % binnen een groep kan staan en zo steeds \begstruts
   % worden geplaatst. Mooi is anders dus moet het anders!
   %
   % Hier is \Everypar niet nodig.
   %
   \everypar{\begstrut\everypar\emptytoks}%
   %
   \ignorespaces\geenspatie % dubbel: \ignorespaces
   \getvalue{\??al#1\the\alteller\c!command}}

\def\dostopalinea#1%
  {\ifvmode
     \removelastskip
   \else
     \unskip\endstrut\endgraf
   \fi
   \getvalue{\??al#1\the\alteller\c!bottom}%
   \egroup
   \ifdim\wd0=\zeropoint % no data
     \wd0\!!widtha
   \fi
   \box0
   \dostopattributes
   %\ifnum\alteller<\getvalue{\??al#1\c!n}\relax
   %  \def\next{\doalinea{#1}}%
   %\else
   %  \def\next{\dostopalineas{#1}}%
   %\fi
   %\next}
   \ifnum\alteller<\getvalue{\??al#1\c!n}\relax
     \@EA\doalinea
   \else
     \@EA\dostopalineas
   \fi{#1}}

\def\doalinea#1%
  {\global\advance\alteller \plusone
   \doifelsevaluenothing{\??al#1\the\alteller\c!distance}
     {\doifnot{\the\alteller}{1}
        {\hskip\getvalue{\??al#1\c!distance}}}
     {\doifelse{\the\alteller}{1}%
        {\hskip\getvalue{\??al#1\the\alteller\c!distance}}
        {\doalinealijn{\getvalue{\??al#1\the\alteller\c!distance}}{#1}}}%
   \setvalue{#1}{\dostopalinea{#1}}%
   \dostartalinea{#1}}

\def\dostartalineas#1%
  {\global\alteller\zerocount
   \parindent\zeropoint
   \setlocalhsize
   \alhsize\localhsize
   \alnsize\getvalue{\??al#1\c!n}\relax
   \dorecurse
     {\getvalue{\??al#1\c!n}}
     {\doifelsevaluenothing{\??al#1\recurselevel\c!distance}
        {\doifnot{\recurselevel}{1}
           {\global\advance\alhsize -\getvalue{\??al#1\c!distance}\relax}}
        {\global\advance\alhsize -\getvalue{\??al#1\recurselevel\c!distance}\relax}%
      \doifvaluesomething{\??al#1\recurselevel\c!width}
        {\global\advance\alnsize \minusone
         \global\advance\alhsize -\getvalue{\??al#1\recurselevel\c!width}\relax}}%
   %\whitespace                 % gaat fout bij \framed
   \getvalue{\??al#1\c!before}%
   \leavevmode                 % gaat wel goed bij \framed
   \vbox\bgroup\hbox\bgroup\doalinea{#1}}

\def\dostopalineas#1%
  {\egroup
   \egroup
   \par
   \getvalue{\??al#1\c!after}}%

\def\dosetuptab[#1]%
  {\getparameters[\??ta]
     [\c!headstyle=\v!normal,
      \c!headcolor=,
      \c!style=\v!normal,
      \c!color=,
      \c!width=\v!broad,
      \c!sample={\hskip4em},
      \c!before=,
      \c!after=,
      #1]%
   \definedescription
     [tab]
     [\c!headstyle=\@@taheadstyle,
      \c!headcolor=\@@tacolor,
      \c!sample=\@@tasample,
      \c!width=\@@tawidth,
      \c!before=\@@tabefore,
      \c!after=\@@taafter]}

\def\setuptab
  {\dosingleargument\dosetuptab}

\setuptab
  [\c!location=\v!left]

% The following macro's are derived from PPCHTEX and
% therefore take some LaTeX font-switching into account.

\newif\ifloweredsubscripts

% Due to some upward incompatibality of LaTeX to LaTeX2.09
% and/or LaTeX2e we had to force \@@chemieletter. Otherwise
% some weird \nullfont error comes up.

\doifundefined{@@chemieletter}{\def\@@chemieletter{\rm}}

\def\beginlatexmathmodehack
  {\ifmmode
     \let\endlatexmathmodehack\relax
   \else
     \def\endlatexmathmodehack{$}$\@@chemieletter
   \fi}

\def\setsubscripts
  {\beginlatexmathmodehack
   \def\dosetsubscript##1##2##3%
     {\dimen0=##3\fontdimen5##2%
      \setxvalue{@@\string##1\string##2}{\the##1##2\relax}%
      ##1##2=\dimen0\relax}%
   \def\dodosetsubscript##1##2%
     {\dosetsubscript{##1}{\textfont2}{##2}%
      \dosetsubscript{##1}{\scriptfont2}{##2}%
      \dosetsubscript{##1}{\scriptscriptfont2}{##2}}%
  %\dodosetsubscript{\fontdimen14}{?}%
   \dodosetsubscript{\fontdimen16}{.7}%
   \dodosetsubscript{\fontdimen17}{.7}%
   \global\loweredsubscriptstrue
   \endlatexmathmodehack}

\def\resetsubscripts
  {\ifloweredsubscripts
     \beginlatexmathmodehack
     \def\doresetsubscript##1##2%
       {\dimen0=\getvalue{@@\string##1\string##2}\relax
        ##1##2=\dimen0}%
     \def\dodoresetsubscript##1%
       {\doresetsubscript{##1}{\textfont2}%
        \doresetsubscript{##1}{\scriptfont2}%
        \doresetsubscript{##1}{\scriptscriptfont2}}%
    %\dodoresetsubscript{\fontdimen14}%
     \dodoresetsubscript{\fontdimen16}%
     \dodoresetsubscript{\fontdimen17}%
     \global\loweredsubscriptsfalse
     \endlatexmathmodehack
   \fi}

\let\beginlatexmathmodehack = \relax
\let\endlatexmathmodehack   = \relax

\def\chem#1#2#3%
  {\bgroup
   \setsubscripts
   \mathematics{\hbox{#1}_{#2}^{#3}}%
   \resetsubscripts
   \egroup}

\def\celsius#1{#1\mathematics{^\circ}C}
\def\graden   {\mathematics{^\circ}}
\def\inch     {\hbox{\rm\char125\relax}}
\def\fraction#1#2{\mathematics{#1\over#2}}

\def\bedragprefix {\euro\normalfixedspace}
\def\bedragsuffix {}
\def\bedragempty  {\euro}

\unexpanded\def\bedrag#1%
  {\strut\hbox\bgroup
   \let\normalfixedspace~%
   \doifelsenothing{#1}
     {\bedragempty}
     {\bedragprefix\digits{#1}\bedragsuffix}%
   \egroup}

% \definieeralineas[test][n=3]
%
% \stelalineasin[test][3][breedte=4cm,uitlijnen=links]
%
% \startopelkaar
% \test hans \\ ton \\ \bedrag{1.000,--} \\
% \test hans \\ ton \\ \bedrag{~.~~1,--} \\
% \test hans \\ ton \\ \bedrag{~.~~1,~~} \\
% \test hans \\ ton \\ \bedrag{~.100,--} \\
% \test hans \\ ton \\ \subtot{1.000,--} \\
% \test hans \\ ton \\ \bedrag{1.000,--} \\
% \test hans \\ ton \\ \bedrag{1.000,--} \\
% \test hans \\ ton \\ \totaal{1.000,--} \\
% \test hans \\ ton \\ \bedrag{nihil,--} \\
% \test hans \\ ton \\ \totaal{nihil,--} \\
% \test hans \\ ton \\ \subtot{nihil,--} \\
% \stopopelkaar

\def\periodswidth  {.5em}
\def\periodsdefault{3}    % was 5, but now it's like \unknown

\unexpanded\def\periods
  {\dosingleempty\doperiods}

\def\doperiods[#1]%
  {\dontleavehmode
   \begingroup
   \scratchdimen\periodswidth
   \hbox to \iffirstargument#1\else\periodsdefault\fi \scratchdimen
     {\leaders\hbox to \scratchdimen{\hss.\hss}\hss}%
   \endgroup}

\unexpanded\def\unknown
  {\periods\relax} % relax prevents lookahead for []

% compatibility macros

\def\doorsnede
  {\hbox{\rlap/$\circ$} }

\unexpanded\def\ongeveer
  {\mathematics\pm}

\def\midboundarycharacter#1#2%
  {%\nobreak
   \hskip\hspaceamount\currentlanguage{#2}%
   \languageparameter#1%
   %\nobreak
   \hskip\hspaceamount\currentlanguage{#2}}

\def\leftboundarycharacter#1#2%
  {\languageparameter#1%
   \nobreak
   \hskip\hspaceamount\currentlanguage{#2}}

% \def\rightboundarycharacter#1#2%
%   {\nobreak
%    \hskip\hspaceamount\currentlanguage{#2}%
%    \languageparameter#1}

\def\rightboundarycharacter#1#2%
  {\prewordbreak %\nobreak
   \hskip\hspaceamount\currentlanguage{#2}%
   \languageparameter#1}

% actually this is pretty old, but temporary moved here
%
% obsolete:

\def\setuphyphenmark
  {\dodoubleargument\getparameters[\??kp]}

\setuphyphenmark
  [\c!sign=\composedhyphen]

\installdiscretionaries || \@@kpsign

% will become:
%
% \installdiscretionaries || \composedhyphen

\def\composedhyphen
  {\discretionary
     {\hbox{\directsymbol\empty\c!leftcompoundhyphen}}
     {\hbox{\directsymbol\empty\c!rightcompoundhyphen}}
     {\hbox{\directsymbol\empty\c!compoundhyphen}}}

\definesymbol[\c!leftcompoundhyphen]  [\languageparameter\c!leftcompoundhyphen]
\definesymbol[\c!rightcompoundhyphen] [\languageparameter\c!rightcompoundhyphen]
\definesymbol[\c!compoundhyphen]      [\languageparameter\c!compoundhyphen]

\definehspace [sentence]      [\zeropoint]
\definehspace [intersentence] [.250em]

\definesymbol
  [\c!midsentence]
  [\midboundarycharacter\c!midsentence{sentence}]

\definesymbol
  [\c!leftsentence]
  [\leftboundarycharacter\c!leftsentence{sentence}]

\definesymbol
  [\c!rightsentence]
  [\rightboundarycharacter\c!rightsentence{sentence}]

\definesymbol
  [\c!leftsubsentence]
  [\leftboundarycharacter\c!leftsubsentence{sentence}]

\definesymbol
  [\c!rightsubsentence]
  [\rightboundarycharacter\c!rightsubsentence{sentence}]

\newsignal \subsentencesignal
\newcounter\subsentencelevel

\def\midsentence
  {\symbol[\c!midsentence]}

\def\beginofsubsentence
  {\ifdim\lastkern=\subsentencesignal
     \unskip
     \kern\hspaceamount\currentlanguage{intersentence}%
   \fi
   \doglobal\increment\subsentencelevel
   \ifnum\subsentencelevel=\plusone
     \leaveoutervmode
   \fi
   \symbol[\ifodd\subsentencelevel\c!leftsentence   \else
                                  \c!leftsubsentence\fi]%
   \ignorespaces}

\def\beginofsubsentencespacing
  {\kern\subsentencesignal\ignorespaces}

\def\endofsubsentence
  {\symbol[\ifodd\subsentencelevel\c!rightsentence   \else
                                  \c!rightsubsentence\fi]%
   \doglobal\decrement\subsentencelevel
   \unskip
   \kern\subsentencesignal}

\def\endofsubsentencespacing
  {\ifdim\lastkern=\subsentencesignal
     \unskip
     \hskip\hspaceamount\currentlanguage{intersentence}%
     \ignorespaces
   \else
     \unskip
   \fi}

% test |<|test |<|test|>| test|>| test \par
% test|<|test|<|test|>|test|>|test     \par
% test |<||<|test|>||>| test           \par

\enableactivediscretionaries

\definehspace [quotation]      [\zeropoint]
\definehspace [interquotation] [.125em]

%definehspace [quote]  [\zeropoint]
%definehspace [speech] [\zeropoint]

\definehspace [quote]  [\hspaceamount\currentlanguage{quotation}]
\definehspace [speech] [\hspaceamount\currentlanguage{quotation}]

\definesymbol
  [\c!leftquotation]
  [\leftboundarycharacter\c!leftquotation{quotation}]

\definesymbol
  [\c!rightquotation]
  [\rightboundarycharacter\c!rightquotation{quotation}]

\definesymbol
  [\c!leftquote]
  [\leftboundarycharacter\c!leftquote{quote}]

\definesymbol
  [\c!rightquote]
  [\rightboundarycharacter\c!rightquote{quote}]

\definesymbol
  [\c!leftspeech]
  [\leftboundarycharacter\c!leftspeech{speech}]

\definesymbol
  [\c!rightspeech]
  [\rightboundarycharacter\c!rightspeech{speech}]

\definesymbol
  [\c!middlespeech]
  [\leftboundarycharacter\c!middlespeech{speech}]

%%%%% will be replaced by delimitedtext %%%%%

\def\leftquotationmark
  {\setbox\scratchbox\hbox{\symbol[\c!leftquotation]}%
   \doif\@@cilocation\v!margin{\hskip-\wd\scratchbox}%
   \box\scratchbox}

\def\rightquotationmark
  {\hsmash{\symbol[\c!rightquotation]}}

\newsignal\quotationsignal

\def\setupquote
  {\dodoubleargument\getparameters[\??ci]}

% \def\setuoquotation
%   {\setupquote}

\def\startquotation
  {\bgroup\dosingleempty\dostartquotation}

\def\dostartquotation[#1]%
  {\@@cibefore
   \doifelsenothing{#1}
     {\let\dostopquotation\relax}
     {\startnarrower[#1]%
      \let\dostopquotation\stopnarrower}%
   \dostartattributes\??ci\c!style\c!color\empty
   \leftquotationmark
   \ignorespaces}

\def\stopquotation
  {\removeunwantedspaces
   \removelastskip
   \rightquotationmark
   \dostopattributes
   \dostopquotation
   \@@ciafter
   \egroup}

\def\dohandlequotation#1#2%
  {\ifdim\lastskip=\quotationsignal
     \unskip\hskip\hspaceamount\currentlanguage{interquotation}%
   \else
     #2%
   \fi
   \ifhmode % else funny pagebeaks
     \penalty\!!tenthousand\hskip\zeropoint      % == \prewordbreak
   \fi
   \strut % new, needed below
   \symbol[#1]%
   \penalty\!!tenthousand\hskip\quotationsignal} % +- \prewordbreak

\def\handlequotation#1%
  {\dohandlequotation{#1}\relax}

\unexpanded\def\quotation
  {\groupedcommand
     {\dohandlequotation\c!leftquotation \relax}
     {\dohandlequotation\c!rightquotation\removelastskip}}

\unexpanded\def\quote
  {\doifelse\@@cistyle\v!normal\doquotedcite\doattributedcite}

\def\doquotedcite
  {\groupedcommand
     {\dohandlequotation\c!leftquote \relax}
     {\dohandlequotation\c!rightquote\removelastskip}}

\def\doattributedcite
  {\groupedcommand
     {\dostartattributes\??ci\c!style\c!color}
     {\dostopattributes}}

%D The previous one fails in \placefloat[left]{}{}, so instead
%D we use the next alternative, where the first one is handled
%D outside group. Watch the strut.

\unexpanded\def\quotation
  {\dohandlequotation\c!leftquotation\relax
   \groupedcommand \donothing
     {\dohandlequotation\c!rightquotation\removelastskip}}

\def\doquotedcite
  {\dohandlequotation\c!leftquote\relax
   \groupedcommand \donothing
     {\dohandlequotation\c!rightquote\removelastskip}}

\setupquote
  [\c!location=\v!margin,
   \c!style=\v!normal,
   \c!color=,
   \c!before=\startnarrower,
   \c!after=\stopnarrower]

\appendtoks\def\quotation#1{"#1"}\to\simplifiedcommands
\appendtoks\def\quote    #1{'#1'}\to\simplifiedcommands

%D The next features was so desperately needed by Giuseppe
%D Bilotta that he made a module for it. Since this is a
%D typical example of core functionality, I decided to extend
%D the low level quotation macros in such a way that a speech
%D feature could be build on top of it. The speech opening and
%D closing symbols are defined per language. Italian is an
%D example of a language that has them set.

%%%%% will be replaced by delimitedtext %%%%%

\newcounter\speechlevel \newconditional\insidespeech

\def\startspeech
  {\doglobal\increment\speechlevel\relax
   \dohandlequotation\c!leftspeech\relax
   \global\settrue\insidespeech
   \ignorespaces}

\def\stopspeech
  {\dohandlequotation\c!rightspeech\removelastskip
   \doglobal\decrement\speechlevel\relax
   \ifcase\speechlevel\relax \global\setfalse\insidespeech \fi}

\def\dohandlespeech % indirect since called in everypar
  {\relax % still needed?
   \ifcase\speechlevel\or\dodohandlespeech\fi}

\def\dodohandlespeech
  {\ifconditional\insidespeech
     \dohandlequotation\c!middlespeech\relax
   \else
     \global\settrue\insidespeech
   \fi}

\unexpanded\def\speech
  {\doglobal\increment\speechlevel\relax
   \dohandlequotation\c!leftspeech\relax
   \groupedcommand \ignorespaces
     {\dohandlequotation\c!rightspeech\removelastskip
      \doglobal\decrement\speechlevel\relax}}

% \appendtoks \dohandlespeech \to \everypar

% this will replace the quotation and speed definitions

\newsignal\delimitedtextsignal

\def\delimitedtextparameter#1%
  {\csname\??ci
     \ifundefined{\??ci\currentdelimitedtext#1}\else\currentdelimitedtext\fi
   #1\endcsname}

\def\definedelimitedtext
  {\dodoubleempty\dodefinedelimitedtext}

\def\dodefinedelimitedtext[#1][#2]%
  {\doifassignmentelse{#2}
     {\getparameters
        [\??ci#1]
        [\c!location=\v!margin, % \v!text \v!paragraph
         \c!spacebefore=,
         \c!spaceafter=\delimitedtextparameter\c!spacebefore,
         \c!style=\v!normal,
         \c!color=,
         \c!leftmargin=\zeropoint,
         \c!rightmargin=\delimitedtextparameter\c!leftmargin,
         \c!indentnext=\v!yes,
         \c!before=,
         \c!after=,
         \c!left=,
         \c!right=,
         \c!level=0,
         \c!repeat=\v!no,
        #2]}%
     {\doifdefined{#2}
        {\copyparameters[\??ci#1][\??ci#2]
           [\c!location,\c!spacebefore,\c!spaceafter,\c!style,\c!color,
            \c!leftmargin,\c!rightmargin,\c!indentnext,
            \c!before,\c!after,\c!left,\c!right]}}%
   \doifsomething{#1}
     {\unexpanded\setvalue{#1}{\delimitedtext[#1]}%
      \setvalue{\e!start#1}{\startdelimitedtext[#1]}%
      \setvalue{\e!stop#1}{\stopdelimitedtext}}}

\def\setupdelimitedtext
  {\dodoubleargument\dosetupdelimitedtext}

\def\dosetupdelimitedtext[#1][#2]%
  {\ifsecondargument
     \getparameters[\??ci#1][#2]%
   \else
     \getparameters[\??ci][#1]%
   \fi}

\def\dorepeatdelimitedtext
  {\relax\ifcase\delimitedtextparameter\c!level\else
     \dohandledelimitedtext\c!middle
   \fi}

\def\startdelimitedtext[#1]%
  {\bgroup
   \def\currentdelimitedtext{#1}%
   \doif{\delimitedtextparameter\c!repeat}\v!yes
     {\appendtoks \dorepeatdelimitedtext \to \everypar}%
   \doifinsetelse{\delimitedtextparameter\c!location}{\v!paragraph,\v!margin}%
     {\dosingleempty\dostartdelimitedtextpar}\dostartdelimitedtexttxt}

\def\dostartdelimitedtextpar[#1]%
  {\let\dostopdelimitedtext\dostopdelimitedtextpar
   \doifsomething{\delimitedtextparameter\c!spacebefore}
     {\blank[\delimitedtextparameter\c!spacebefore]}%
   \delimitedtextparameter\c!before
   % nicer:
   % \doadaptleftskip {\delimitedtextparameter\c!leftmargin}%
   % \doadaptrightskip{\delimitedtextparameter\c!rightmargin}%
   % backward compatible:
   \doifelsenothing{#1}
     {\doadaptleftskip {\delimitedtextparameter\c!leftmargin}%
      \doadaptrightskip{\delimitedtextparameter\c!rightmargin}%
      \let\dodostopdelimitedtextpar\endgraf}
     {\startnarrower[#1]\let\dodostopdelimitedtextpar\stopnarrower}%
   % so far
   \dochecknextindentation{\??ci\currentdelimitedtext}%
   \dostartattributes{\??ci\currentdelimitedtext}\c!style\c!color\empty
   \leftdelimitedtextmark
   \doglobal\incrementvalue{\??ci\currentdelimitedtext\c!level}%
   \ignorespaces}

\def\dostopdelimitedtextpar
  {\removeunwantedspaces
   \removelastskip
   \rightdelimitedtextmark
   \dostopattributes
   \dodostopdelimitedtextpar
   \delimitedtextparameter\c!after
   \doifsomething{\delimitedtextparameter\c!spaceafter}
     {\blank[\delimitedtextparameter\c!spaceafter]}}

\def\dostartdelimitedtexttxt
  {\let\dostopdelimitedtext\dostopdelimitedtexttxt
   \dostartattributes{\??ci\currentdelimitedtext}\c!style\c!color\empty
   \dohandledelimitedtext\c!left
   \ignorespaces}

\def\dostopdelimitedtexttxt
  {\removeunwantedspaces
   \dohandledelimitedtext\c!right
   \dostopattributes}

\def\stopdelimitedtext
  {\dostopdelimitedtext
   \doglobal\decrementvalue{\??ci\currentdelimitedtext\c!level}%
   \egroup}

\def\delimitedtext[#1]%
  {\pushmacro\currentdelimitedtext
   \def\currentdelimitedtext{#1}%
   \doifinsetelse{\delimitedtextparameter\c!location}{\v!paragraph,\v!margin}%
     \dodelimitedtextpar\dodelimitedtexttxt}

% shortcuts

\def\startdelimited{\startdelimitedtext}
\def\stopdelimited {\stopdelimitedtext}  % no let, dynamically assigned
\def\delimited     {\delimitedtext}

\def\leftdelimitedtextmark
  {\dontleavehmode
   \setbox\scratchbox\hbox{\delimitedtextparameter\c!left}%
   \doif{\delimitedtextparameter\c!location}\v!margin{\hskip-\wd\scratchbox}%
   \box\scratchbox}

\def\rightdelimitedtextmark
  {\hsmash{\delimitedtextparameter\c!right}}

\def\dohandledelimitedtext#1#2%
  {\bgroup
   \setbox\scratchbox\hbox{#1}%
   \ifdim\wd\scratchbox>\zeropoint
     \ifdim\lastskip=\delimitedtextsignal
       \unskip\hskip\hspaceamount\currentlanguage{interquotation}%
     \else
       #2%
     \fi
     \ifhmode % else funny pagebeaks
       \penalty\!!tenthousand\hskip\zeropoint % == \prewordbreak
     \fi
     \strut % new, needed below
     \delimitedtextparameter#1%
     \penalty\!!tenthousand\hskip\delimitedtextsignal % +- \prewordbreak
   \fi
   \egroup}

\def\handledelimitedtext#1%
  {\dohandledelimitedtext{#1}\relax}

\unexpanded\def\dodelimitedtextpar
  {\dohandledelimitedtext\c!left\relax
   \groupedcommand
     \donothing
     {\dohandledelimitedtext\c!right\removelastskip}}

\unexpanded\def\dodelimitedtexttxt
  {\doifelse{\delimitedtextparameter\c!style}\v!normal
     \doquoteddelimited\doattributeddelimited}

\def\doquoteddelimited
  {\dohandledelimitedtext\c!left\relax
   \groupedcommand
     \donothing
     {\dohandledelimitedtext\c!right
      \removelastskip
      \popmacro\currentdelimitedtext}}

\def\doattributeddelimited
  {\groupedcommand
     {\dostartattributes{\??ci\currentdelimitedtext}\c!style\c!color}
     {\dostopattributes
      \popmacro\currentdelimitedtext}}

% \definedelimitedtext
%   [\v!quotation]
%   [\c!left={\symbol[\c!leftquotation]},
%    \c!right={\symbol[\c!rightquotation]},
%    \c!leftmargin=\v!standard]
%
% \definedelimitedtext
%   [\v!quote][\v!quotation]
%
% \setupdelimitedtext
%   [\v!quote]
%   [\c!location=\v!text,
%    \c!left={\symbol[\c!leftquote]},
%    \c!right={\symbol[\c!rightquote]}]
%
% \definedelimitedtext
%   [\v!speech][\v!quotation]
%
% \setupdelimitedtext
%   [\v!speech]
%   [\c!repeat=\v!yes,
%    \c!left={\symbol[\c!leftspeech]},
%    \c!middle={\symbol[\c!middlespeech]},
%    \c!right={\symbol[\c!rightspeech]}]
%
% how do we call an tight quote
%
% \definedelimitedtext
%    [\v!quotation][\v!quotation]
%
% \setupdelimitedtext
%   [\v!quotation]
%   [\c!indentnext=\v!no,
%    \c!spacebefore=\v!nowhite]
%
% \def\setupquotation{\setupdelimitedtext[\v!quotation]}
% \def\setupquote    {\setupdelimitedtext[\v!quote]}

% seldom used, move from kernel to run time module

\def\basegrid
  {\dosingleempty\dobasegrid}

\def\dobasegrid[#1]%
  {\begingroup
   \getparameters[\??rt]
     [\c!x=0,\c!y=0,
      \c!nx=10,\c!ny=10,
      \c!dx=.5,\c!dy=.5,
      \c!xstep=0,\c!ystep=0,
      \c!unit=\s!cm,
      \c!scale=1,
      \c!factor=1,
      \c!offset=\v!yes,
      \c!location=\v!left,
      #1]%
   \startpositioning
     \dimen0=\@@rtdx\@@rtunit\relax
     \dimen0=\@@rtscale\dimen0\relax
     \dimen0=\@@rtfactor\dimen0\relax
     \multiply\dimen0 \@@rtnx\relax
     \dimen2=\@@rtdy\@@rtunit\relax
     \dimen2=\@@rtscale\dimen2\relax
     \dimen2=\@@rtfactor\dimen2\relax
     \multiply\dimen2 \@@rtny\relax
     \def\horline
       {\vbox
          {\hrule
             \!!width \dimen0
             \!!height \linewidth
             \!!depth \!!zeropoint}}%
     \def\verline%
       {\vrule
          \!!width \linewidth
          \!!height \dimen2
          \!!depth \!!zeropoint}%
     \doglobal\newcounter\@@gridc
     \doglobal\newcounter\@@gridd
     \doglobal\newcounter\@@gride
     \def\setlegend##1##2##3%
       {\gdef\@@gridc{0}%
        \dimen0=2em\relax
        \dimen2=##2\@@rtunit\relax
        \dimen2=\@@rtscale\dimen2\relax
        \dimen2=\@@rtfactor\dimen2\relax
        \divide\dimen0 \dimen2\relax
        \xdef\@@gride{\number\dimen0}%
        \ifnum\@@gride>50
          \gdef\@@gride{100}%
        \else\ifnum\@@gride>10
          \gdef\@@gride{50}%
        \else\ifnum\@@gride>5
          \gdef\@@gride{10}%
        \else\ifnum\@@gride>1
          \gdef\@@gride{5}%
        \else
          \gdef\@@gride{1}%
        \fi\fi\fi\fi
        \gdef\@@gridd{0}%
        \def\legend
          {\ifnum\@@gridd=\zerocount
             \vbox
               {\increment(\@@gridc,##1)%
                \hbox to 2em{\hss\@@gridc\hss}}%
             \global\let\@@gridd=\@@gride
           \fi
             \doglobal\decrement\@@gridd
             \doglobal\increment(\@@gridc,##1)}}%
     \def\draw##1##2##3##4##5##6##7##8##9%
       {\setuppositioning
          [\c!state=##8,
           \c!xstep=\v!absolute,
           \c!ystep=\v!absolute,
           \c!unit=\@@rtunit,
           \c!scale=\@@rtscale,
           \c!factor=\@@rtfactor,
           \c!offset=\@@rtoffset,
           \c!xoffset=##6,
           \c!yoffset=##7]%
        \doifelse{##9}\v!middle
          {\scratchdimen##3pt\scratchdimen.5\scratchdimen
           \edef\@@psxx{\withoutpt\the\scratchdimen}%
           \scratchdimen##4pt\scratchdimen.5\scratchdimen
           \edef\@@psyy{\withoutpt\the\scratchdimen}%
           \scratchcounter##2\advance\scratchcounter -1
           \edef\@@pszz{\the\scratchcounter}}
          {\edef\@@psxx{0}\edef\@@psyy{0}\edef\@@pszz{##2}}%
        \position(\@@psxx,\@@psyy){##1}%
        \setuppositioning
          [\c!state=##8,
           \c!xstep=\v!relative,
           \c!ystep=\v!relative,
           \c!scale=\@@rtscale,
           \c!factor=\@@rtfactor,
           \c!offset=\@@rtoffset,
           \c!unit=\@@rtunit]%
        \dorecurse\@@pszz{\position(##3,##4){##5}}}%
     \draw
       \verline\@@rtnx\@@rtdx0\verline\!!zeropoint\!!zeropoint\v!start\empty
     \draw
       \horline\@@rtny0\@@rtdy\horline\!!zeropoint\!!zeropoint\v!start\empty
     \tfx
     \doifnot\@@rtxstep{0}
       {\setlegend\@@rtxstep\@@rtdx\@@rtx
        \draw\legend\@@rtnx\@@rtdx0\legend{-1em}{-1.5em}\v!overlay\@@rtlocation}%
     \doifnot\@@rtystep{0}
       {\setlegend\@@rtystep\@@rtdy\@@rty
        \draw\legend\@@rtny0\@@rtdy\legend{-2em}{-.75ex}\v!overlay\@@rtlocation}%
  \stoppositioning
  \endgroup}

\let\grid\basegrid

% Dit wordt:
%
%   \doorverwijzen[naam][instellingen] enz.
%
% waarbij <naam> bijvoorbeeld publicatie is. Dit levert:
%
%   \start<naam>
%   \stop<naam>
%
%   \beginvan<naam>
%   \eindvan<naam>
%
%   \publicatie
%
%   \volledigelijstmetpublicaties
%
% eigenlijk kan ook door... zo worden uitgebreid!

% old, will become obsolete or module, replace by bib module

\defineenumeration
  [@publicatie]
  [\c!location=\v!left,
   \c!width=\@@pbwidth,\c!hang=,\c!sample=,
   \c!before=\@@pbbefore,\c!after=\@@pbafter,\c!inbetween=,
   \c!headstyle=\@@pbheadstyle,\c!style=,
   \c!headcolor=\@@pbheadcolor,\c!color=,
   \c!way=\@@pbway,\c!blockway=\@@pbblockway,
   \c!text=,\c!left=\@@pbleft,\c!right=\@@pbright]

\def\dosetuppublications[#1]%
  {\getparameters[\??pb][#1]}

\def\setuppublications%
  {\dosingleargument\dosetuppublications}

\def\apa@publicatie
  {\doifsomething\@@pb@naam    {\@@pb@naam,\space}%
   \doifsomething\@@pb@titel   {{\sl\@@pb@titel}.\space}%
   \doifsomething\@@pb@jaar    {(\@@pb@jaar).\space}%
   \doifsomething\@@pb@plaats  {\@@pb@plaats\doifelsenothing\@@pb@uitgever{.}{:\space}}%
   \doifsomething\@@pb@uitgever{\@@pb@uitgever.}}

\def\normaal@publicatie
  {\@@pb@naam, \@@pb@titel, \@@pb@jaar, \@@pb@pagina, \@@pb@plaats, \@@pb@uitgever.}

\def\complexstartpublicatie[#1]#2\stoppublicatie
  {\bgroup
   \def\dosetpublicatie
     {\processcommalist
        [naam,titel,jaar,plaats,pagina,uitgever]
        \setpublicatie
      \ignorespaces}%
   \def\setpublicatie##1%
      {\letvalue{\??pb @##1}\empty
       \setvalue{##1}####1{\setvalue{\??pb @##1}{####1}\ignorespaces}}%
   \def\getpublicatie%
     {\doifsomething\@@pbalternative{\getvalue{\@@pbalternative @publicatie}}}%
   \doifelse\@@pbnumbering\v!yes
      {\@publicatie[#1]\dosetpublicatie#2\getpublicatie\par}%
      {\@@pbbefore
       \dosetpublicatie\ignorespaces#2\getpublicatie
       \@@pbafter}%
   \egroup}

\definecomplexorsimpleempty\startpublicatie

\def\publication#1[#2]%
  {\@@pbleft\in{#1}[#2]\@@pbright}

\setuppublications
  [\c!numbering=\v!yes,
   \c!alternative=\c!apa,
   \c!width=2em,
   \c!hang=,
   \c!sample=,
   \c!before=,
   \c!after=,
   \c!inbetween=,
   \c!headstyle=,
   \c!headcolor=,
   \c!style=,
   \c!color=,
   \c!blockway=\v!by\v!text,
   \c!way=\v!by\v!text,
   \c!text=,
   \c!left={[},
   \c!right={]}]

% only used at pragma, move from kernel to run time module

\def\referraldate
  {\currentdate[\v!referral]}

\def\doreferral[#1]%
   {\noheaderandfooterlines
    \bgroup
    \getparameters
      [\??km]
      [\c!bet=\unknown,\c!dat=\unknown,\c!ken=\unknown,
       \c!from=,\c!to=,\c!ref=,#1]%
    % moet anders, hoort niet in 01b
    \assigntranslation[\s!nl=referentie,\s!en=reference,\s!de=Referenz,\s!sp=referencia]\to\@@@kmref
    \assigntranslation[\s!nl=van,\s!en=from,\s!de=Von,\s!sp=de]\to\@@@kmvan
    \assigntranslation[\s!nl=aan,\s!en=to,\s!de=An,\s!sp=a]\to\@@@kmaan
    \assigntranslation[\s!nl=betreft,\s!en=concerns,\s!de=Betreff,\s!sp=]\to\@@@kmbet
    \assigntranslation[\s!nl=datum,\s!en=date,\s!de=Datum,\s!sp=fecha]\to\@@@kmdat
    \assigntranslation[\s!nl=kenmerk,\s!en=mark,\s!de=Kennzeichen,\s!sp=]\to\@@@kmken
    %
    \definetabulate[\s!dummy][|l|p|]
    \startdummy
      \NC\@@@kmbet\EQ\@@kmbet\NC\NR
      \NC\@@@kmdat\EQ\@@kmdat\NC\NR
      \NC\@@@kmken\EQ\expanded{\smallcapped{\@@kmken}}\NC\NR
      \doifsomething{\@@kmfrom\@@kmto}{\NC\NC\NC\NR}%
      \doifsomething \@@kmfrom         {\NC\@@@kmvan\EQ\@@kmfrom\NC\NR}%
      \doifsomething \@@kmto         {\NC\@@@kmaan\EQ\@@kmto\NC\NR}%
      \doifsomething \@@kmref         {\NC\NC\NC\NR\NC\@@@kmref\EQ\@@kmref\NC\NR}%
    \stopdummy
    \egroup}

\def\referral
  {\dosingleargument\doreferral}

% FUZZY OLD STUFF: will be removed when not used in some manual;
% rows instead of columns, i'd forgotten that this code exist
%
% \definesystemvariable{ri}
%
% \def\setuprows
%   {\dodoubleargument\getparameters[\??ri]}
%
% \definecomplexorsimpleempty\startrows
%
% \def\complexstartrows[#1]%
%   {\bgroup
%    \setuprows[#1]%
%    \let\do@@ribottom\relax
%    \def\row
%      {\do@@ribottom
%       \egroup
%       \dimen0\vsize
%       \divide\dimen0 \@@rin
%       \advance\dimen0 -\lineskip
%       \vbox to \dimen0
%         \bgroup
%         \@@ritop
%         \let\do@@ribottom\@@ribottom
%         \ignorespaces}%
%    \bgroup
%    \row}
%
% \def\stoprows
%   {\do@@ribottom
%    \egroup
%    \egroup}
%
% \setuprows
%   [\c!n=2,
%    \c!top=,
%    \c!bottom=\vfill]

% THIS WAS MAIN-003.TEX

\startmessages  dutch  library: systems
     41: externe file -- in groep -- bestaat niet
\stopmessages

\startmessages  english  library: systems
     41: external file -- in group -- does not exist
\stopmessages

\startmessages  german  library: systems
     41: Externe Datei -- in Gruppe -- existiert nicht
\stopmessages

\startmessages  czech  library: systems
     41: externi soubor -- ve skupine -- neexistuje
\stopmessages

\startmessages  italian  library: systems
     41: il file esterno -- del gruppo -- non esiste
\stopmessages

\startmessages  norwegian  library: systems
     41: ekstern fil -- i gruppe -- eksisterer ikke
\stopmessages

\startmessages  romanian  library: systems
     41: fisierul extern -- din grupul -- nu exista
\stopmessages

\definetabulate
  [\v!legend]
  [|emj1|i1|mR|]

\setuptabulate
  [\v!legend]
  [\c!unit=.75em,\c!inner=\setquicktabulate\leg,EQ={=}]

\definetabulate
  [\v!legend][\v!two]
  [|emj1|emk1|i1|mR|]

\definetabulate
  [\v!fact]
  [|R|ecmj1|i1mR|]

\setuptabulate
  [\v!fact]
  [\c!unit=.75em,\c!inner=\setquicktabulate\fact,EQ={=}]

\unexpanded\def\xbox
  {\bgroup\aftergroup\egroup\hbox\bgroup\tx\let\next=}

\unexpanded\def\xxbox
  {\bgroup\aftergroup\egroup\hbox\bgroup\txx\let\next=}

% \def\mrm#1%
%   {$\rm#1$}

%D \macros
%D   {definepairedbox, setuppairedbox, placepairedbox}
%D
%D Paired boxes, formally called legends, but from now on a
%D legend is just an instance, are primarily meant for
%D typesetting some text alongside an illustration. Although
%D there is quite some variation possible, the functionality is
%D kept simple, if only because in most cases such pairs are
%D typeset sober.
%D
%D The location specification accepts a pair, where the first
%D keyword specifies the arrangement, and the second one the
%D alignment. The first key of the location pair is one of
%D \type {left}, \type {right}, \type {top} or \type {bottom},
%D while the second key can also be \type {middle}.
%D
%D The first box is just collected in an horizontal box, but
%D the second one is a vertical box that gets passed the
%D bodyfont and alignment settings.

%D Today we would implement this using layers .... but for the
%D moment we keep it this way.

%  \startbuffer[test]
%  \test left   \test left,top    \test left,bottom  \test left,middle
%  \test right  \test right,top   \test right,bottom \test right,middle
%  \test top    \test top,left    \test top,right    \test top,middle
%  \test bottom \test bottom,left \test bottom,right \test bottom,middle
%  \stopbuffer
%
%  \def\showtest#1%
%    {\pagina
%     \typebuffer[demo]
%     \def\test##1
%       {\startlinecorrection[blank]
%        \getbuffer[demo]%
%        \ruledhbox\placelegend
%          [bodyfont=6pt,location={##1}]
%          {\framed[width=.25\textwidth]{\tttf##1}}
%          {#1}
%        \stoplinecorrection}
%     \getbuffer[test]}
%
%  \startbuffer[demo]
%  \setuplegend
%    [width=\hsize,maxwidth=\makeupwidth,
%     height=\vsize,maxheight=\makeupheight]
%  \stopbuffer
%
%  \showtest{These examples demonstrate the default settings.}
%
%  \startbuffer[demo]
%  \setuplegend
%    [width=\textwidth,
%     maxwidth=\textwidth]
%  \stopbuffer
%
%  \showtest{\input tufte }
%
%  \startbuffer[demo]
%  \setuplegend
%    [width=.65\textwidth]
%  \stopbuffer
%
%  \showtest{\input knuth }
%
%  \startbuffer[demo]
%  \setuplegend
%    [height=2cm]
%  \stopbuffer
%
%  \showtest{These examples demonstrate some other settings.}
%
%  \startbuffer[demo]
%  \setuplegend
%    [width=.65\textwidth,
%     height=2cm]
%  \stopbuffer
%
%  \showtest{These examples demonstrate some other settings.}
%
%  \startbuffer[demo]
%  \setuplegend
%    [n=2,align=right,width=.5\textwidth]
%  \stopbuffer
%
%  \showtest{\input zapf }

%D \macros
%D   {setuplegend, placelegend}
%D
%D It makes sense to typeset a legend to a figure in \TEX\
%D and not in a drawing package. The macro \type {\placelegend}
%D combines a figure (or something else) and its legend. This
%D command is just a paired box.
%D
%D The legend is placed according to \type {location}, being
%D \type {bottom} or \type {right}. The macro macro is used as
%D follows.
%D
%D \starttyping
%D \placefigure
%D   {whow}
%D   {\placelegend
%D      {\externalfigure[cow]}
%D      {\starttabulation
%D       \NC 1 \NC head \NC \NR
%D       \NC 2 \NC legs \NC \NR
%D       \NC 3 \NC tail \NC \NR
%D       \stoptabulation}}
%D
%D \placefigure
%D   {whow}
%D   {\placelegend
%D      {\externalfigure[cow]}
%D      {\starttabulation[|l|l|l|l|]
%D       \NC 1 \NC head \NC 3 \NC tail \NC \NR
%D       \NC 2 \NC legs \NC   \NC      \NC \NR
%D       \stoptabulation}}
%D
%D \placefigure
%D   {whow}
%D   {\placelegend[n=2]
%D      {\externalfigure[cow]}
%D      {\starttabulation
%D       \NC 1 \NC head \NC \NR
%D       \NC 2 \NC legs \NC \NR
%D       \NC 3 \NC tail \NC \NR
%D       \stoptabulation}}
%D
%D \placefigure
%D   {whow}
%D   {\placelegend[n=2]
%D      {\externalfigure[cow]}
%D      {head \par legs \par tail}}
%D
%D \placefigure
%D   {whow}
%D   {\placelegend[n=2]
%D      {\externalfigure[cow]}
%D      {\startitemize[packed]
%D       \item head \item legs \item  tail \item belly \item horns
%D       \stopitemize}}
%D
%D \placefigure
%D   {whow}
%D   {\placelegend[n=2,width=.8\hsize]
%D      {\externalfigure[cow]}
%D      {\startitemize[packed]
%D       \item head \item legs \item  tail \item belly \item horns
%D       \stopitemize}}
%D \stoptyping

\newbox\firstpairedbox
\newbox\secondpairedbox

\def\definepairedbox
  {\dodoubleempty\dodefinepairedbox}

\def\dodefinepairedbox[#1][#2]%
  {\getparameters
     [\??ld#1]
     [\c!n=1,
      \c!distance=\bodyfontsize,
      \c!before=,
      \c!after=,
      \c!color=,
      \c!style=,
      \c!inbetween={\blank[\v!medium]},
      \c!width=\hsize,
      \c!height=\vsize,
      \c!maxwidth=\textwidth,   % \makeupwidth,
      \c!maxheight=\textheight, % \makeupheight,
      \c!bodyfont=,
      \c!align=,
      \c!location=\v!bottom,
      #2]%
   \setvalue{\e!setup#1\e!endsetup}{\setuppairedbox[#1]}%
   \setvalue{\e!place#1}{\placepairedbox[#1]}}

\def\setuppairedbox
  {\dodoubleempty\dosetuppairedbox}

\def\dosetuppairedbox[#1]%
  {\getparameters[\??ld#1]}

\def\placepairedbox
  {\bgroup\dodoubleempty\doplacepairedbox}

\def\doplacepairedbox[#1][#2]% watch the hsize/vsize tricks
  {\setuppairedbox[#1][#2]%     % and don't change them
   \copyparameters % brrr
     [\??ld][\??ld#1]
     [\c!n,\c!distance,\c!inbetween,\c!before,\c!after,
      \c!width,\c!height,\c!maxwidth,\c!maxheight,
      \c!color,\c!style,\c!bodyfont,\c!align,\c!location]%
   \@@ldbefore\bgroup
   \global\setsystemmode{pairedbox}%
   \beforefirstpairedbox
   \dowithnextbox
     {\betweenbothpairedboxes
      \dowithnextbox
        {\afterbothpairedboxes
         \egroup\@@ldafter
         \egroup}
      \vbox\bgroup
        \insidesecondpairedbox
        \let\next=}
   \hbox}

\def\beforefirstpairedbox
  {\chardef\pairedlocationa1 % left
   \chardef\pairedlocationb4 % middle
   \getfromcommacommand[\@@ldlocation][1]%
   \processaction
     [\commalistelement]
     [  \v!left=>\chardef\pairedlocationa0,
       \v!right=>\chardef\pairedlocationa1,
         \v!top=>\chardef\pairedlocationa2,
      \v!bottom=>\chardef\pairedlocationa3]%
   \getfromcommacommand[\@@ldlocation][2]%
   \processaction
     [\commalistelement]
     [  \v!left=>\chardef\pairedlocationb0,
       \v!right=>\chardef\pairedlocationb1,
        \v!high=>\chardef\pairedlocationb2,
         \v!top=>\chardef\pairedlocationb2,
         \v!low=>\chardef\pairedlocationb3,
      \v!bottom=>\chardef\pairedlocationb3,
      \v!middle=>\chardef\pairedlocationb4]}

\def\betweenbothpairedboxes
  {\switchtobodyfont[\@@ldbodyfont]% split under same regime
   \setbox\firstpairedbox\flushnextbox
   \ifnum\pairedlocationa<2
     \hsize\wd\firstpairedbox % trick
     \hsize\@@ldwidth
     \scratchdimen\wd\firstpairedbox
     \advance\scratchdimen \@@lddistance
     \bgroup\advance\scratchdimen \hsize
     \ifdim\scratchdimen>\@@ldmaxwidth\relax
       \egroup
       \hsize\@@ldmaxwidth
       \advance\hsize -\scratchdimen
     \else
       \egroup
     \fi
   \else
     \hsize\wd\firstpairedbox
     \hsize\@@ldwidth % can be \hsize
     \ifdim\hsize>\@@ldmaxwidth\relax \hsize\@@ldmaxwidth \fi % can be \hsize
   \fi
   \ifnum\@@ldn>\plusone
     \setrigidcolumnhsize\hsize\@@lddistance\@@ldn
   \fi}

\def\afterbothpairedboxes
  {\setbox\secondpairedbox\vbox
     {% \localstartcolor[\@@ldcolor]% does not work yet
        \ifnum\@@ldn>1
          \rigidcolumnbalance\nextbox
        \else
          \flushnextbox
        \fi
      }% \localstopcolor}%
   \ifnum\pairedlocationa<2\hbox\else\vbox\fi\bgroup % hide vsize
   \forgetall
   \ifnum\pairedlocationa<2
     \scratchdimen\maxoftwoboxdimens\ht\firstpairedbox\secondpairedbox
     \vsize\scratchdimen
     \ifdim\scratchdimen<\@@ldheight\relax % can be \vsize
       \scratchdimen\@@ldheight
     \fi
     \ifdim\scratchdimen>\@@ldmaxheight\relax
       \scratchdimen\@@ldmaxheight
     \fi
     \valignpairedbox\firstpairedbox \scratchdimen
     \valignpairedbox\secondpairedbox\scratchdimen
   \else
     \scratchdimen\maxoftwoboxdimens\wd\firstpairedbox\secondpairedbox
     \halignpairedbox\firstpairedbox \scratchdimen
     \halignpairedbox\secondpairedbox\scratchdimen
     \scratchdimen\ht\secondpairedbox
     \vsize\scratchdimen
     \ifdim\ht\secondpairedbox<\@@ldheight\relax % can be \vsize
       \scratchdimen\@@ldheight\relax % \relax needed
     \fi
     \ifdim\scratchdimen>\@@ldmaxheight\relax % todo: totale hoogte
       \scratchdimen\@@ldmaxheight\relax % \relax needed
     \fi
     \ifdim\scratchdimen>\ht\secondpairedbox
       \setbox\secondpairedbox\vbox to \scratchdimen
         {\ifnum\pairedlocationa=3 \vss\fi %
          \box\secondpairedbox
          \ifnum\pairedlocationa=2 \vss\fi}% \kern\zeropoint
     \fi
   \fi
   \ifcase\pairedlocationa
     \box\secondpairedbox\hskip\@@lddistance\box\firstpairedbox \or
     \box\firstpairedbox \hskip\@@lddistance\box\secondpairedbox\or
     \box\secondpairedbox\endgraf \nointerlineskip \@@ldinbetween \box\firstpairedbox \or
     \box\firstpairedbox \endgraf \nointerlineskip \@@ldinbetween \box\secondpairedbox\else
   \fi
   \egroup}

\def\insidesecondpairedbox
  {\forgetall
   \setupalign[\@@ldalign]%
   \tolerantTABLEbreaktrue % hm.
   \blank[\v!disable]%
   \everypar{\begstrut}}

\def\maxoftwoboxdimens#1#2#3%
  {#1\ifdim#1#2>#1#3 #2\else#3\fi}

\def\valignpairedbox#1#2%
  {\setbox#1\vbox to #2
     {\ifcase\pairedlocationb\or\or\or\vss\or\vss\fi
      \box#1\relax
      \ifcase\pairedlocationb\or\or\vss\or\or\vss\fi}}

\def\halignpairedbox#1#2%
  {\setbox#1\hbox to #2
     {\ifcase\pairedlocationb\or\hss\or\or\or\hss\fi
      \box#1\relax
      \ifcase\pairedlocationb\hss\or\or\or\or\hss\fi}}

\definepairedbox[\v!legend]

%D Goody:

\newevery \everyinsidefloat \relax

\appendtoks
  \global\resetsystemmode{combination}%
  \global\resetsystemmode{pairedbox}%
\to \everyinsidefloat

\newcount\horcombination  % counter
\newcount\totcombination

\def\definecombination
  {\dodoubleempty\dodefinecombination}

\def\dodefinecombination[#1][#2]%
  {\copyparameters
     [\??co#1][\??co]
     [\c!width,\c!height,\c!distance,\c!location,%
      \c!before,\c!inbetween,\c!after,\c!align,%
      \c!style,\c!color]%
   \getparameters
     [\??co#1][#2]}

\def\setupcombinations
  {\dodoubleempty\dosetupcombinations}

\def\dosetupcombinations[#1][#2]%
  {\ifsecondargument
     \getparameters[\??co#1][#2]%
   \else
     \getparameters[\??co][#1]%
   \fi}

\def\startcombination
  {\dodoubleempty\dostartcombination}

\def\combinationparameter#1%
  {\csname\??co\currentcombination#1\endcsname}%

\def\dostartcombination[#1][#2]%
  {\bgroup
   \global\setsystemmode{combination}%
   \ifsecondargument
     \def\currentcombination{#1}%
   \else
     \let\currentcombination\empty
   \fi
   \forgetall
   \doifelse{\combinationparameter\c!height}\v!fit
     \vbox {\vbox to \combinationparameter\c!height}%
   \bgroup
  %\doifelsenothing{#1}
  %  {\dodostartcombination[2*1*]}
  %  {\doifelsenothing{#2}
  %     {\dodostartcombination[#1*1*]}
  %     {\dodostartcombination[#2*1*]}}}
   \expanded{\dodostartcombination
     [\ifsecondargument#2\else\iffirstargument#1\else2\fi\fi*1*]}}

\long\def\dodostartcombination[#1*#2*#3]%
  {\setuphorizontaldivision
     [\c!n=\v!fit,\c!distance=\combinationparameter\c!distance]%
   \global\horcombination#1%
   \global\totcombination#2%
   \global\setbox\combinationstack\emptybox
   \xdef\maxhorcombination{\the\horcombination}%
   \multiply\totcombination\horcombination
   \tabskip\zeropoint
   \doifelse{\combinationparameter\c!width}\v!fit
     {\halign}{\halign to \combinationparameter\c!width}%
   \bgroup&%
   %\hfil##\hfil% now : location={left,top}
   \ExpandBothAfter\doifnotinset\v!left{\combinationparameter\c!location}\hfil
   ##%
   \ExpandBothAfter\doifnotinset\v!right{\combinationparameter\c!location}\hfil
   &\tabskip\zeropoint \!!plus 1fill##\cr
   \docombination}

\def\docombination % we want to add struts but still ignore an empty box
  {\dowithnextbox
     {\setbox0\flushnextbox
      \dowithnextbox
        {\setbox2\flushnextbox
         \dodocombination}%
      \vtop\bgroup
        \def\next
          {\futurelet\nexttoken\nextnext}%
        \def\nextnext
          {\ifx\nexttoken\egroup \else % the next box is empty
             \hsize\wd0
             \setupalign[\combinationparameter\c!align]%
             \dostartattributes{\??co\currentcombination}\c!style\c!color\empty
             \bgroup
             \aftergroup\endstrut
             \aftergroup\dostopattributes
             \aftergroup\egroup
             \begstrut
           \fi}%
        \afterassignment\next\let\nexttoken=}
  \hbox}

% stupid version, does not align top stuff when captions,
% keep as example
%
% \def\dodocombination
%   {\vbox
%      {\forgetall % \setupwhitespace[\v!none]%
%       \let\next\vbox
%       \ExpandFirstAfter\processallactionsinset
%         [\combinationparameter\c!location]
%         [   \v!top=>\let\next\tbox,
%          \v!middle=>\let\next\halfwaybox]%
%       \next{\copy0}%
%       \ifdim\ht2>\zeropoint % beter dan \wd2, nu \strut mogelijk
%         \combinationparameter\c!inbetween
%         %\vtop % wrong code
%         %  {\nointerlineskip  % recently added
%         %   \hsize\wd0
%         %   \setupalign[\combinationparameter\c!align]%  % \raggedcenter
%         %   \begstrut\unhbox2\endstrut}%
%         \box2
%       \fi}%
%    \ifnum\totcombination>\plusone
%      \global\advance\totcombination\minusone
%      \global\advance\horcombination\minusone
%      \ifnum\horcombination=\zerocount
%        \def\next
%          {\cr\noalign
%             {\forgetall % \setupwhitespace[\v!geen]% no
%              \nointerlineskip
%              \combinationparameter\c!before
%              \combinationparameter\c!after
%              \vss
%              \nointerlineskip}%
%           \global\horcombination\maxhorcombination\relax
%           \docombination}%
%      \else
%        \def\next
%          {&&&\hskip\combinationparameter\c!distance&\docombination}%
%      \fi
%    \else
%      \def\next
%        {\cr\egroup}%
%    \fi
%    \next}

% \def\dodocombination
%   {\vbox
%      {\forgetall % \setupwhitespace[\v!none]%
%       \let\next\vbox
%       \ExpandFirstAfter\processallactionsinset
%         [\combinationparameter\c!plaats]
%         [   \v!top=>\let\next\tbox,
%          \v!middle=>\let\next\halfwaybox]%
%       \next{\copy0}%
%       % we need to save the caption for a next alignment line
%       \saveoncombinationstack2}%
%    \ifnum\totcombination>\plusone
%      \global\advance\totcombination\minusone
%      \global\advance\horcombination\minusone
%      \ifnum\horcombination=\zerocount
%        \def\next
%          {\cr
%           \flushcombinationstack
%           \noalign
%             {\forgetall % \setupwhitespace[\v!none]% no
%              \global\setbox\combinationstack\emptybox
%              \nointerlineskip
%              \combinationparameter\c!after
%              \combinationparameter\c!before
%              \vss
%              \nointerlineskip}%
%           \global\horcombination\maxhorcombination\relax
%           \docombination}%
%      \else
%        \def\next
%          {&&&\hskip\combinationparameter\c!distance&\docombination}%
%      \fi
%    \else
%      \def\next
%        {\cr
%         \flushcombinationstack
%         \egroup}%
%    \fi
%    \next}

\def\depthonlybox
  {\dowithnextbox{\vtop{\hsize\wd\nextbox\kern\zeropoint\box\nextbox}}\vbox}

% \def\boxwithstrutheight
%   {\dowithnextbox
%      {\scratchdimen\strutheight
%       \advance\scratchdimen-\nextboxht
%       \hbox{\raise\scratchdimen\box\nextbox}}%
%      \vbox}

\def\dodocombination
  {\vbox
     {\forgetall % \setupwhitespace[\v!none]%
      \let\next\vbox
      \ExpandFirstAfter\processallactionsinset
        [\combinationparameter\c!location]
        [  \v!top=>\let\next\depthonlybox, % \tbox,
          \v!middle=>\let\next\halfwaybox]%
      \next{\copy0}%
      % we need to save the caption for a next alignment line
      \saveoncombinationstack2}%
   \ifnum\totcombination>\plusone
     \global\advance\totcombination\minusone
     \global\advance\horcombination\minusone
     \ifnum\horcombination=\zerocount
       \def\next
         {\cr
          \flushcombinationstack
          \noalign
            {\forgetall % \setupwhitespace[\v!none]% no
             \global\setbox\combinationstack\emptybox
             \nointerlineskip
             \combinationparameter\c!after
             \combinationparameter\c!before
             \vss
             \nointerlineskip}%
          \global\horcombination\maxhorcombination\relax
          \docombination}%
     \else
       \def\next
         {&&&\hskip\combinationparameter\c!distance&\docombination}%
     \fi
   \else
     \def\next
       {\cr
        \flushcombinationstack
        \egroup}%
   \fi
   \next}

\def\stopcombination
  {\egroup
   \egroup}

\newbox\combinationstack

\def\saveoncombinationstack#1%
  {\global\setbox\combinationstack\hbox
     {\hbox{\box#1}\unhbox\combinationstack}}

\def\flushcombinationstack
  {\noalign
     {\ifdim\ht\combinationstack>\zeropoint
\nointerlineskip % nieuw
        \combinationparameter\c!inbetween
        \global\horcombination\maxhorcombination
        \globallet\doflushcombinationstack\dodoflushcombinationstack
      \else
        \global\setbox\combinationstack\emptybox
        \globallet\doflushcombinationstack\donothing
      \fi}%
   \doflushcombinationstack\crcr}

\gdef\dodoflushcombinationstack
  {\global\setbox\combinationstack\hbox
     {\unhbox\combinationstack
      \global\setbox1\lastbox}%
   \box1% \ruledhbox{\box1}%
   \global\advance\horcombination\minusone\relax
   \ifnum\horcombination>\zerocount
     \def\next{&&&&\doflushcombinationstack}%
   \else
     \global\setbox\combinationstack\emptybox
    %\let\next\relax
     \@EA\gobbleoneargument
   \fi
   \next}

\setupcombinations
  [\c!width=\v!fit,
   \c!height=\v!fit,
   \c!distance=1em,
   \c!location=\v!bottom, % can be something {top,left}
   \c!before=\blank,
   \c!inbetween={\blank[\v!medium]},
   \c!style=,
   \c!color=,
   \c!after=,
   \c!align=\v!middle]

% does not work
%
% \def\plaatsondernaastelkaar#1#2%
%   {\bgroup
%    \def\doplaatsondernaastelkaar%
%      {#2\cr\omit\bgroup#2%
%       \aftergroup#2%
%       \aftergroup\cr
%       \aftergroup\egroup
%       \aftergroup\egroup
%       \let\next=}%
%    #1\bgroup##\cr
%    \omit\bgroup#2%
%    \aftergroup\doplaatsondernaastelkaar
%    \let\next=}

\def\plaatsondernaastelkaar#1#2%
  {\bgroup
   \dowithnextbox
     {\bgroup
      \setbox0\box\nextbox
      \dowithnextbox
        {\setbox2\box\nextbox
         #1{#2#########2\cr\box0\cr\box2\cr}
         \egroup
         \egroup}
        \hbox}
     \hbox}

\def\placeontopofeachother
  {\plaatsondernaastelkaar\halign\hss}

\def\placesidebyside
  {\plaatsondernaastelkaar\valign\vss}

\def\douseexternalfiles[#1][#2]%
  {\getparameters
     [\??fi#1]
     [\c!file=,
      \c!bodyfont=,
      \c!option=,
      #2]}

\def\useexternalfiles
  {\dodoubleargument\douseexternalfiles}

\def\dostelexternefilesin[#1][#2]%
  {\doifundefinedelse{\??fi#1\c!file}
     {\useexternalfiles[#1][#2]}
     {\getparameters[\??fi#1][#2]}}

\def\stelexternefilesin
  {\dodoubleargument\dostelexternefilesin}

\def\verwerkexternefile#1#2#3%
  {\bgroup
   \getparameters[\??fi#1][\c!file=,#3]%
   \doinputonce{\getvalue{\??fi#1\c!file}}%
   \ExpandFirstAfter\switchtobodyfont[\getvalue{\??fi#1\c!bodyfont}]%
   \readsysfile{#2}  % beter: loc of fix gebied
     \donothing
     {\showmessage\m!systems{41}{#2,#1}}%
   \egroup}

\def\douseexternalfile[#1][#2][#3][#4]%
  {\stelexternefilesin[#1][]%
   \doinputonce{\getvalue{\??fi#1\c!file}}%
   \doifelsenothing{#2}
     {\setvalue{#3}{\verwerkexternefile{#1}{#3}{#4}}}
     {\setvalue{#2}{\verwerkexternefile{#1}{#3}{#4}}}}

\def\useexternalfile
  {\doquadrupleargument\douseexternalfile}

\useexternalfiles
  [pictex]
  [\c!bodyfont=\v!small,
   \c!file=pictex]

\useexternalfiles
  [table]
  [\c!file=table]

%D A couple of examples, demonstrating how the depth is
%D taken care of:
%D
%D \startbuffer
%D test\rotate[frame=on, rotation=0]  {gans}%
%D test\rotate[frame=on, rotation=90] {gans}%
%D test\rotate[frame=on, rotation=180]{gans}%
%D test\rotate[frame=on, rotation=270]{gans}%
%D test
%D \stopbuffer
%D
%D \typebuffer \getbuffer

% \presetlocalframed[\??ro]
%
% \def\setuprotate
%   {\dodoubleargument\getparameters[\??ro]}
%
% \def\dorotatebox#1% {angle} \hbox/\vbox/\vtop
%   {\bgroup
%    \hbox\bgroup % compatibility hack
%    \dowithnextbox
%      {\edef\@@rorotation{#1}%
%       \setbox\nextbox\vbox{\flushnextbox}%
%       \dostoprotate
%       \egroup}}
%
% \def\dodostoprotate#1#2#3#4#5#6%
%   {\dontshowcomposition
%    \scratchdimen\nextboxht\advance\scratchdimen\nextboxdp
%    \doif\@@rolocation\v!high
%      {\setbox\nextbox\vbox{\hbox{\raise\nextboxdp\flushnextbox}}}%
%    \setbox\nextbox\vbox to #1
%      {#2\relax
%       \hbox to #4
%         {#5\relax % \number removes leading spaces too
%          \edef\@@rorotation{\number\@@rorotation}%
%          \doifelsenothing\@@rorotation
%            {\dostartrotation{90}}
%            {\dostartrotation{\@@rorotation}}%
%          \nextboxwd\zeropoint
%          \nextboxht\zeropoint
%         %\nextboxdp\zeropoint
%          \flushnextbox
%          \dostoprotation
%          #6}
%       #3}%
%    \nextboxdp\zeropoint
%    \flushnextbox
%    \egroup}
%
% \def\dostoprotate
%   {\!!counta\@@rorotation
%    \divide\!!counta 90
%    \ifcase\!!counta
%      \dodostoprotate\nextboxht\relax\vfill\nextboxwd\relax\hfill
%    \or
%     %\dodostoprotate\nextboxwd\vfill\relax\nextboxht\relax\hfill
%      \dodostoprotate\nextboxwd\vfill\relax\scratchdimen\relax\hfill
%    \or
%      \dodostoprotate\nextboxht\vfill\relax\nextboxwd\hfill\relax
%    \or
%     %\dodostoprotate\nextboxwd\relax\vfill\nextboxht\hfill\relax
%      \dodostoprotate\nextboxwd\relax\vfill\scratchdimen\hfill\relax
%    \or
%      \dodostoprotate\nextboxht\relax\vfill\nextboxwd\relax\hfill
%    \else
%      \def\@@rotation{90}%
%      \dodostoprotate\nextboxht\relax\vfill\nextboxwd\relax\hfill
%    \fi}
%
% \def\complexrotate[#1]%
%   {\dowithnextbox
%      {\getparameters[\??ro][#1]%
%       \dostoprotate}%
%    \vbox\localframed[\??ro][#1]}
%
% \unexpanded\def\rotate % \bgroup: \rotate kan argument zijn
%   {\bgroup\complexorsimpleempty\rotate}
%
% \setuprotate
%   [\c!rotation=90,
%    \c!width=\v!fit,
%    \c!height=\v!fit,
%    \c!offset=\v!overlay,
%    \c!frame=\v!off]

% The previous implementation is replaced by one that supports
% rotation over arbitrary angles.
%
% When we rotate over arbitrary angles, we need to relocate the
% resulting box because rotation brings that box onto the negative
% axis. The calculations (mostly sin and cosine) need to be tuned for
% the way a box is packages (i.e. the refence point). A typical example
% of drawing, scribbling, and going back to the days of school math.
%
% We do a bit more calculations than needed, simply because that way
% it's easier to debug the code.

\def\dododorotatenextbox
  {\setbox\nextbox\vbox to \@@layerysiz
     {\vfill
      \hbox to \@@layerxsiz
        {\dostartrotation\@@rorotation
           \nextboxwd\zeropoint
           \nextboxht\zeropoint
           \flushnextbox
         \dostoprotation
         \hfill}%
      \kern\@@layerypos}%
  \setbox\nextbox\hbox
    {\kern\@@layerxpos
     \kern\@@layerxoff
     \lower\@@layeryoff\flushnextbox}}

\def\dodorotatenextbox#1#2% quite some trial and error -)
  {\dontshowcomposition
   \dontcomplain
   \ifnum#2=\plusfour
     % new, location=middle
     \!!widthb \nextboxwd
     \!!heightb\nextboxht
     \!!depthb \nextboxdp
     \setbox\nextbox\vbox{\vskip.5\nextboxht\hskip-.5\nextboxwd\flushnextbox}%
     \smashbox\nextbox
   \fi
   \!!widtha \nextboxwd
   \!!heighta\nextboxht
   \!!deptha \nextboxdp
   \!!doneafalse
   \!!donebfalse
   \ifcase#2\or
     % 1: fit
   \or
     % 2: depth, not fit
     \!!doneatrue
     \!!donebtrue
   \or
     % 3: depth, fit
     \!!donebtrue
   \fi
   \setbox\nextbox\vbox{\hbox{\raise\nextboxdp\flushnextbox}}%
   \!!dimena \nextboxht
   \calculatecos\@@rorotation\edef\cos{\calculatedcos\@@rorotation}%
   \calculatesin\@@rorotation\edef\sin{\calculatedsin\@@rorotation}%
   \@@layerxpos\zeropoint
   \@@layerypos\zeropoint
   \@@layerxoff\zeropoint
   \@@layeryoff\zeropoint
   \ifdim\sin\points>\zeropoint
     \ifdim\cos\points>\zeropoint
       \@@layerxsiz                    \cos\!!widtha
       \@@layerysiz                    \sin\!!widtha
       \advance\@@layerxsiz            \sin\!!dimena
       \advance\@@layerysiz            \cos\!!dimena
       \@@layerypos                    \cos\!!dimena
       \if!!donea
         \@@layerxoff          \negated\sin\!!dimena
         \advance\@@layerxoff          \sin\!!deptha
       \fi
       \if!!doneb
         \@@layeryoff                  \cos\!!deptha
       \fi
       \dododorotatenextbox
     \else
       \@@layerxsiz            \negated\cos\!!widtha
       \@@layerysiz                    \sin\!!widtha
       \advance\@@layerxsiz            \sin\!!dimena
       \advance\@@layerysiz    \negated\cos\!!dimena
       \@@layerxpos            \negated\cos\!!widtha
       \if!!donea
         \@@layerxoff                     -\@@layerxsiz
         \advance\@@layerxoff          \sin\!!deptha
       \fi
       \if!!doneb
         \@@layeryoff          \negated\cos\!!heighta
       \fi
       \dododorotatenextbox
       \wd\nextbox\if!!donea\sin\!!deptha\else\@@layerxsiz\fi
     \fi
   \else
     \ifdim\cos\points<\zeropoint
       \@@layerxsiz           \negated\cos\!!widtha
       \@@layerysiz           \negated\sin\!!widtha
       \advance\@@layerxsiz   \negated\sin\!!dimena
       \advance\@@layerysiz   \negated\cos\!!dimena
       \@@layerxpos                        \@@layerxsiz
       \@@layerypos            \negated\sin\!!widtha
       \if!!donea
         \@@layerxoff                     -\@@layerxsiz
         \advance\@@layerxoff  \negated\sin\!!heighta
       \fi
       \if!!doneb
         \@@layeryoff                      \@@layerysiz
         \advance\@@layeryoff          \cos\!!deptha
       \fi
       \dododorotatenextbox
       \wd\nextbox\if!!donea\negated\sin\!!heighta\else\@@layerxsiz\fi
     \else
       \@@layerxsiz                    \cos\!!widtha
       \@@layerysiz            \negated\sin\!!widtha
       \advance\@@layerxsiz    \negated\sin\!!dimena
       \advance\@@layerysiz            \cos\!!dimena
       \ifdim\sin\points=\zeropoint
         \@@layerxpos                       \zeropoint
         \@@layerxoff                       \zeropoint
         \@@layerypos                      \@@layerysiz
         \if!!doneb
           \@@layeryoff                     \!!deptha
         \fi
       \else
         \@@layerypos                       \@@layerysiz
         \@@layerxpos           \negated\sin\!!dimena
         \if!!donea
           \@@layerxoff                    -\@@layerxsiz
           \advance\@@layerxoff \negated\sin\!!heighta
         \fi
         \if!!doneb
           \@@layeryoff          \negated\sin\!!deptha
         \fi
       \fi
       \dododorotatenextbox
       \ifdim\sin\points=\zeropoint
       \else
         \wd\nextbox\if!!donea\negated\sin\!!heighta\else\@@layerxsiz\fi
       \fi
     \fi
   \fi
   % new, location=middle
   \ifnum#2=\plusfour
     \setbox\nextbox\vbox{\vskip-.5\!!heightb\hskip.5\!!heightb\flushnextbox}%
     \nextboxwd\!!widthb
     \nextboxht\!!heightb
     \nextboxdp\!!depthb
   \fi}

\def\dorotatenextbox#1#2%
  {\doifsomething{#1}
     {\edef\@@rorotation{\number#1}% get rid of leading zeros and spaces
      \setbox\nextbox\vbox{\flushnextbox}% not really needed
      \dodorotatenextbox\@@rorotation#2}%
   \hbox{\boxcursor\flushnextbox}}

\def\dodorotatebox#1% {angle} \hbox/\vbox/\vtop
  {\bgroup\hbox\bgroup % compatibility hack
     \dowithnextbox
       {\dorotatenextbox{#1}\plusone
        \egroup\egroup}}

\def\dorotatebox#1% {angle} \hbox/\vbox/\vtop
  {\ifcase#1\relax
     \expandafter\gobbleoneargument
   \else
     \expandafter\dodorotatebox
   \fi{#1}}

\unexpanded\def\rotate % \bgroup: \rotate kan argument zijn
  {\bgroup\complexorsimpleempty\rotate}

\def\complexrotate[#1]% framed met diepte !
  {\getparameters[\??ro][#1]%
   \processaction
     [\@@rolocation]
     [  \v!depth=>\!!counta\plusthree\donefalse,% depth   fit   - raw box
          \v!fit=>\!!counta\plustwo  \donefalse,% depth   tight - raw box
        \v!broad=>\!!counta\plusone  \donefalse,% nodepth fit   - raw box
         \v!high=>\!!counta\plusone  \donetrue ,% nodepth fit   - framed
       \v!middle=>\!!counta\plusfour \donefalse,% centered, keep dimensions
      \s!default=>\!!counta\plusthree\donetrue ,% depth   fit   - framed
      \s!unknown=>\!!counta\plusthree\donetrue ]% depth   fit   - framed
   \ifdone
     \def\docommand{\localframed[\??ro][#1,\c!location=]}%
   \else
     \let\docommand\relax
   \fi
   \dowithnextbox{\dorotatenextbox\@@rorotation\!!counta\egroup}\vbox\docommand}

\presetlocalframed[\??ro]

\def\setuprotate
  {\dodoubleargument\getparameters[\??ro]}

\setuprotate
  [\c!rotation=90,
   \c!location=\v!normal,
   \c!width=\v!fit,
   \c!height=\v!fit,
   \c!offset=\v!overlay,
   \c!frame=\v!off]

% \dostepwiserecurse{0}{360}{10}
%   {\startlinecorrection[blank]
%    \hbox
%      {\expanded{\setuprotate[rotation=\recurselevel]}%
%       \traceboxplacementtrue
%       \hbox to .2\hsize{\hss\ruledhbox{\rotate[location=depth] {\ruledhbox{\bfb  (depth)}}}}%
%       \hbox to .2\hsize{\hss\ruledhbox{\rotate[location=fit]   {\ruledhbox{\bfb    (fit)}}}}%
%       \hbox to .2\hsize{\hss\ruledhbox{\rotate[location=broad] {\ruledhbox{\bfb  (broad)}}}}%
%       \hbox to .2\hsize{\hss\ruledhbox{\rotate[location=normal]{\ruledhbox{\bfb (normal)}}}}%
%       \hbox to .2\hsize{\hss\ruledhbox{\rotate[location=high]  {\ruledhbox{\bfb   (high)}}}}}
%    \stoplinecorrection}

% scale

\def\doscalelikeafigure % quite dirty and potential interference possible
  {\doifsomething{\@@xyfactor\@@xyhfactor\@@xywfactor\@@xyscale
                  \@@xywidth\@@xyheight\@@xylines}
     {\let \@@efscale \@@xyscale
      \let \@@effactor \@@xyfactor
      \let \@@efwfactor\@@xywfactor
      \let \@@efhfactor\@@xyhfactor
      \let \@@efwidth\@@xywidth
      \let \@@efheight \@@xyheight
      \let \@@eflines \@@xylines
      \let \@@efgrid   \@@xygrid
      \let \@@epx      \!!zeropoint
      \let \@@epy      \!!zeropoint
      \edef\@@epw     {\the\nextboxwd}%
      \edef\@@eph     {\the\nextboxht}%
      \figwid\zeropoint \figxsca\plusone % see note * (core-fig)
      \fighei\zeropoint \figysca\plusone % see note * (core-fig)
      \checkfiguresettings
      \setfactorfiguresize
      \setscalefiguresize
      \setdimensionfiguresize
      \convertfigureinsertscale\@@epx\figx\figxsca\scax
      \convertfigureinsertscale\@@epy\figy\figysca\scay
      \scratchdimen\scax\points \divide\scratchdimen \plushundred
      \edef\@@xysx{\withoutpt\the\scratchdimen}%
      \scratchdimen\scay\points \divide\scratchdimen \plushundred
      \edef\@@xysy{\withoutpt\the\scratchdimen}}}

\def\doscale[#1]%
  {\bgroup
   \forgetall
   \getparameters
     [\??xy]
     [\c!scale=,\c!width=,\c!height=,\c!lines=,
      \c!factor=,\c!hfactor=,\c!wfactor=,\c!grid=,
      \c!sx=1,\c!sy=1,#1]%
   \dowithnextbox
     {\dontshowcomposition
      \ifdim\nextboxht>\zeropoint \ifdim\nextboxwd>\zeropoint
        \doscalelikeafigure
        \dimen0=\@@xysy\nextboxht
        \dimen2=\@@xysy\nextboxdp
        \dimen4=\@@xysx\nextboxwd
        \dimen6=\dimen0\advance\dimen6 \dimen2
%        \setbox\nextbox\vbox to \dimen6
%          {\nextboxht\zeropoint
%           \nextboxdp\zeropoint
%           \vfill % erbij
%           \dostartscaling\@@xysx\@@xysy\flushnextbox\dostopscaling}%
        \setbox\nextbox\hbox
          {\smashbox\nextbox
           \dostartscaling\@@xysx\@@xysy\flushnextbox\dostopscaling}%
        \nextboxht\dimen0
        \nextboxdp\dimen2
        \nextboxwd\dimen4
      \fi \fi
      \flushnextbox
      \egroup}
   \hbox}

\def\scale
  {\dosingleempty\doscale}

% mirror

\def\domirrorbox % \hbox/\vbox/\vtop
  {\bgroup
   \dowithnextbox
     {\dontshowcomposition
      \scratchdimen\nextboxwd
      % better use an hbox (if no \forgetall, leftskip etc may creep in)
     %\setbox\nextbox\vbox{\forgetall\dostartmirroring\hskip-\nextboxwd\flushnextbox\dostopmirroring}%
      \setbox\nextbox\hbox{\dostartmirroring\hskip-\nextboxwd\flushnextbox\dostopmirroring}%
      \nextboxwd\scratchdimen
      \flushnextbox
      \egroup}}

\def\mirror
  {\domirrorbox\hbox}

%\setbox0=\hbox{gans}
%
%\ruledhbox{\copy0 \schaal[sx=2,sy=2]{\copy0}}
%
%\spiegel{\ruledhbox{\copy0 \schaal{\box0}}}

% to be used in some other places! todo!
%
% divides \hsize in fractions, will be made a bit more
% clever and advanced when needed
%
% \horizontaldivision[n/m,elements,distance]
%
% \horizontaldivision[2/5,3,1em]
% \horizontaldivision[2/5,3,1em]
% \horizontaldivision[1/5,3,1em]
%
% \setuphorizontaldivision[afstand=,aantal=]  (passend,passend)

\def\??fr{@@fr}

\def\setuphorizontaldivision
  {\dodoubleargument\getparameters[\??fr]}

\def\horizontaldivision
  {\dosingleargument\dohorizontaldivision}

\def\dohorizontaldivision[#1]%
  {\dodohorizontaldivision[#1,,,,,,]}

\def\dodohorizontaldivision[#1/#2,#3,#4,#5]%
  {\doifelsenothing{#3}
     {\doifelse\@@frn\v!fit
        {\!!counta#2\relax}
        {\!!counta\@@frn\relax}}
     {\!!counta#3\relax}%
   \doifelsenothing{#4}
     {\doifelse\@@frdistance\v!fit
        {\!!widtha\zeropoint}
        {\!!widtha\@@frdistance}}
     {\!!widtha#4}%
   \advance\!!counta \minusone
   \multiply\!!widtha \!!counta
   \advance\hsize -\!!widtha
   \divide\hsize #2\relax
   \hsize#1\hsize}

\setuphorizontaldivision
  [\c!distance=\tfskipsize,
   \c!n=\v!fit]

%D This one is for Daniel Pittman, who wanted tight
%D fractions. We show three versions. First the simple
%D one using \type {\low} and \type {high}:
%D
%D \startbuffer
%D \def\vfrac#1#2%
%D   {\hbox{\high{\tx#1\kern-.25em}/\low{\kern-.25em\tx#2}}}
%D
%D test \vfrac{1}{2} test \vfrac{123}{456} test
%D \stopbuffer
%D
%D \typebuffer {\showmakeup\getbuffer}
%D
%D A better way to handle the kerning is the following, here
%D we kind of assume that tye slash is symmetrical and has
%D nearly zero width.
%D
%D \startbuffer
%D \def\vfract#1#2%
%D   {\hbox{\high{\tx#1}\hbox to \zeropoint{\hss/\hss}\low{\tx#2}}}
%D \stopbuffer
%D
%D \typebuffer {\showmakeup\getbuffer}
%D
%D The third and best alternative is the following:
%D
%D {\showmakeup\getbuffer}\crlf\getbuffer
%D
%D This time we measure the height of the \type {/} and
%D shift over the maximum height and depths of this
%D character and the fractional digits (we use 57 as
%D sample). Here we combine all methods in one macros.

\chardef\vulgarfractionmethod=3

\definehspace[vulgarfraction][.25em] % [.15em]
\definesymbol[vulgarfraction][/]     % [\raise.2ex\hbox{/}]

\unexpanded\def\vulgarfraction#1#2%
  {\dontleavehmode
   \hbox
     {\def\vulgarfraction{vulgarfraction}%
      \ifcase\vulgarfractionmethod
        #1\symbol[\vulgarfraction]#2%
      \or
        \high{\tx#1\kern-\hspaceamount\empty\vulgarfraction}%
        \symbol[\vulgarfraction]%
        \low {\kern-\hspaceamount\empty\vulgarfraction\tx#2}%
      \or
        \high{\tx#1}%
        \hbox to \zeropoint{\hss\symbol[\vulgarfraction]\hss}%
        \low{\tx#2}%
      \or
        \setbox0\hbox{\symbol[\vulgarfraction]}%
        \setbox2\hbox{\txx57}%
        \raise\ht0\hbox{\lower\ht2\hbox{\txx#1}}%
        \hbox to \zeropoint{\hss\symbol[\vulgarfraction]\hss}%
        \lower\dp0\hbox{\raise\dp2\hbox{\txx#2}}%
      \fi}}

\ifx\vfrac\undefined \let\vfrac\vulgarfraction \fi

%D \starttabulate
%D \HL
%D \NC \bf method \NC \bf visualization \NC\NR
%D \HL
%D \NC 0 \NC \chardef\vulgarfractionmethod0\vulgarfraction{1}{2} \NC\NR
%D \NC 1 \NC \chardef\vulgarfractionmethod1\vulgarfraction{1}{2} \NC\NR
%D \NC 2 \NC \chardef\vulgarfractionmethod2\vulgarfraction{1}{2} \NC\NR
%D \NC 3 \NC \chardef\vulgarfractionmethod3\vulgarfraction{1}{2} \NC\NR
%D \HL
%D \stoptabulate

%D Under construction:
%D
%D \starttyping
%D \commalistsentence[aap,noot,mies]
%D \commalistsentence[aap,noot]
%D \commalistsentence[aap]
%D \stoptyping

\let\handlecommalistsentence\firstofoneargument

\def\commalistsentence[#1]%
  {\bgroup
   \getcommalistsize[#1]%
   \ifcase\commalistsize\relax
     \def\serializedcommalist{#1}%
   \else
     \let\serializedcommalist\empty
     \scratchcounter\zerocount
     \def\docommando##1%
       {\advance\scratchcounter \plusone
        \ifnum\scratchcounter=\plusone
          \scratchtoks{\handlecommalistsentence{##1}}%
        \else
          \ifnum\scratchcounter=\commalistsize
            \appendtoks\labeltext{and-2}\handlecommalistsentence{##1}\to\scratchtoks
          \else
            \appendtoks\labeltext{and-1}\handlecommalistsentence{##1}\to\scratchtoks
          \fi
        \fi}%
     \processcommacommand[#1]\docommando
     \edef\serializedcommalist{\the\scratchtoks}%
   \fi
   \serializedcommalist
   \egroup}

\ifx\textcomma\undefined \def\textcomma{,} \fi

\setuplabeltext [\s!nl] [and-1=\textcomma\ , and-2= en ]
\setuplabeltext [\s!en] [and-1=\textcomma\ , and-2=\textcomma\ and ]
\setuplabeltext [\s!de] [and-1=\textcomma\ , and-2= und ]

\protect \endinput
