cont-new.tex / last modification: 2008-08-27 11:47
%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.

\newcontextversion{2008.08.27 11:47}

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

\unprotect

% it's about time to clean up this file ...

\writestatus{\m!systems}{beware: some patches loaded from cont-new.tex}

% \ifx\pdfmapfile \undefined \else \pdfmapfile{ } \fi

% \font\f=dummyfont  \rpcode\f0=500 \hbox{..}\char0
% todo: mp-new
% caption: grid=top|bottom in xml defs

\let\then\relax % \ifnum1>2\then -)

\def\TransparencyHack %  png: /CS /DeviceRGB /I true
  {\appendtoks
     \doPDFpageattribute{/Group << /S /Transparency /I true /K true>>}%
   \to \everyPDFxform
   \appendtoks
     \doPDFpageattribute{/Group << /S /Transparency /I true /K true>>}%
   \to \everyshipout}

% \setupcaption [figure]   [align=flushleft]
% \setupcaption [figure-1] [align=flushleft,leftmargin=10mm]
% \setupcaption [figure-2] [align=flushleft,leftmargin=10mm,rightmargin=-10mm,width=\textwidth]
%
% \startsetups somefigure
%     \ifdim\floatsetupwidth>\textwidth
%         \placesetupfloat[figure-2]
%     \else
%         \placesetupfloat[figure-1]
%     \fi
% \stopsetups
%
% \placefloatwithsetups[somefigure]{}{\externalfigure[dummy][width=5cm,height=2cm]}

\def\placefloatwithsetups
  {\dotripleempty\doplacefloatwithsetups}

\long\def\doplacefloatwithsetups[#1][#2][#3]#4%
  {\def\floatsetupcaption   {#4}%
   \def\floatsetupcontent   {\copy\nextbox}%
   \def\floatsetupwidth     {\wd\nextbox}%
   \def\floatsetupheight    {\ht\nextbox}%
   \def\placesetupfloat[##1]{\placefloat[##1][#2][#3]{#4}{\floatsetupcontent}}% #4 and not \floatsetupcaption (unexpanded)
   \dowithnextbox{\setups[#1]}\vbox}

\def\dividedsize#1#2#3% size gap n
  {\dimexpr
     \ifnum\dimexpr#1\relax>\plusone
       (\dimexpr#1\relax-\numexpr#3-1\relax\dimexpr#2\relax)/#3\else#1%
     \fi
   \relax}

% maybe to be integrated (option=...)

\def\directexternalfigure
  {\dodoubleempty\dodirectexternalfigure}

\def\dodirectexternalfigure[#1][#2]%
  {\bgroup
   \getparameters[\??ef][\c!type=\splitofftype,\c!page=1,#2]%
   \sanitizefilename#1\to\expandedfigurename
   \splitfilename\expandedfigurename
   \let\@@DriverImageWidth  \!!zeropoint
   \let\@@DriverImageHeight \!!zeropoint
   \let\@@DriverImageFile   \splitofffull
   \let\@@DriverImageType   \@@eftype
   \let\@@DriverImageMethod \@@eftype
   \let\@@DriverImageLabel  \empty
   \let\@@DriverImagePage   \@@efpage
   \doinsertfile
   \egroup}

% \directexternalfigure[cow.pdf]

% normally one does not want this to happen nested, maybe there
% is more; non public vars btw, will become conditionals

\appendtoks \writetoregisterfalse \to \everybeforeutilityread
\appendtoks \writetolistfalse     \to \everybeforeutilityread
\appendtoks \notesenabledfalse    \to \everybeforeutilityread

% \setuplabeltext[\s!itemcount1={{I(},{)}}]
% \def\labeledcountervalue#1{\labeltexts{#1}{\countervalue{#1}}}

\def\singlewidened     #1{\hbox spread 1em{\hss#1\hss}}
\def\complexwidened[#1]#2{\hbox spread  #1{\hss#2\hss}}

\definecomplexorsimple\widened

% todo
%
% \def\definelocation{\dodoubleargument\dodefinelocation}
% \def\dodefinelocation[#1][#2]{\setvalue{loc:#1}{#2}}
%
% \definelocation[lt]           [\v!left\v!top]
% \definelocation[tl]           [\v!left\v!top]
% \definelocation[\v!top\v!left][\v!left\v!top]
%
% \def\getlocation#1{\executeifdefined{loc:#1}{#1}}

% just in case we load something from a file (pdfr-ec for instance)

\prependtoks \restoreendofline \to \everybeforeshipout

\let\cs\getvalue

% 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}

% \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}

%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{\begingroup\directsetup{#1}\scantokens{#2\ignorespaces}\endgroup}

\ifx\scantextokens\undefined \else
  \long\def\rescan#1{\scantextokens{#1}}
  \long\def\rescanwithsetup#1#2{\begingroup\directsetup{#1}\scantextokens{#2}\endgroup}
\fi

% 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
%
% IS THIS STILL OK? TO BE CHECKED (UTF AND SUCH) ! ! ! !

\def\XMLexpanded#1%
  {\bgroup
   \honorunexpanded
%    \dontexpandencoding
%    \dontexpandutf
   \chardef\activecharactermode\zerocount
   \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}}}

% \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}

\newcounter\nofmarkedpages

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

\def\markpage[#1]% looks very much like domarginreference
  {\iftrialtypesetting\else
     \doglobal\increment\nofmarkedpages\relax
     \lazysavetwopassdata{\v!page:#1}{\nofmarkedpages}{\noexpand\realfolio}%
   \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\relax\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

% 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

% 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}

% 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\dimexpr2\dimexpr(#1)/\dimexpr(#2)/32768\relax\relax}

\def\doxprecurse#1#2%
  {\ifnum#1=\zerocount % no \ifcase
     \expandafter\gobblethreearguments
   \else
     #2\expandafter\expandafter\expandafter\doxprecurse\expandafter
   \fi\expandafter{\the\numexpr#1-1\relax}{#2}}

\def\buttonframed{\dodoubleempty\localframed[\??bt]} % goodie

\unexpanded\def\asciistr#1{\dontleavehmode{\defconvertedargument\ascii{#1}\verbatimfont\ascii}}

% messy, will be improved:

\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

\unexpanded\def\enableXML {\setinputmode[XML]} % \enableXML is used in edef's and marks
\unexpanded\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

\let\normaltype\type

\ifx\scantextokens\undefined
    \ifx\scantokens\undefined
        \unexpanded\def\retype#1{\dontleavehmode{\defconvertedargument\ascii{#1}\@EA\normaltype\@EA{\ascii}}}
    \else
        \unexpanded\def\retype#1{\dontleavehmode\scantokens{\normaltype{#1}\ignorespaces}\relax}
    \fi
\else
  \unexpanded\def\retype#1{\dontleavehmode\scantextokens{\normaltype{#1}}}
\fi

\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#%
  {\dowi