summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/context/base/syst-new.tex
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/tex/context/base/syst-new.tex')
-rw-r--r--Master/texmf-dist/tex/context/base/syst-new.tex823
1 files changed, 823 insertions, 0 deletions
diff --git a/Master/texmf-dist/tex/context/base/syst-new.tex b/Master/texmf-dist/tex/context/base/syst-new.tex
new file mode 100644
index 00000000000..0172745bf4b
--- /dev/null
+++ b/Master/texmf-dist/tex/context/base/syst-new.tex
@@ -0,0 +1,823 @@
+%D \module
+%D [ file=supp-new,
+%D version=1997.01.03,
+%D title=\CONTEXT\ Support Macros,
+%D subtitle=New Ones,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D Code from this module will move. For instance to
+%D syst-dat.tex (datastructures).
+
+\unprotect
+
+% moved from core-ntb
+
+\def\v!oddeven#1{\ifodd#1\v!odd\else\v!even\fi}
+
+% For myself
+
+\newcount\nofprofiled
+
+\def\profilemacro#1%
+ {\nofprofiled\zerocount
+ \letvalue{\string#1\string#1}#1%
+ \appendtoks
+ \normalwritestatus\m!systems{profile \string#1: \number\nofprofiled}%
+ \to \everystoptext
+ \unexpanded\def#1%
+ {\global\advance\nofprofiled\plusone
+ \csname\string#1\string#1\endcsname}}
+
+% pretty ugly but fast
+
+% \copycsname xxx\endcsname\csname ..\endcsname
+
+\def\copycsname{\@EA\@EA\@EA\let\@EA\@EA\csname}
+
+% \letcscsname \crap \csname ..\endcsname
+% \letcsnamecs \csname ..\endcsname\crap
+% \letcsnamecsname\csname ..\endcsname\csname ..\endcsname
+
+\def\letcscsname {\@EA\let\@EA}
+\def\letcsnamecs {\@EA\let}
+\def\letcsnamecsname{\@EA\@EA\@EA\let\@EA\@EA}
+
+% another one, add an item to a commalist
+
+\def\addvalue#1#2% cs item
+ {\ifundefined{#1}\@EA\let\csname#1\endcsname\empty\fi
+ \expanded{\addtocommalist{#2}\@EA\noexpand\csname#1\endcsname}}
+
+% faster, and looks okay
+
+\dostepwiserecurse{0}{255}{1}
+ {\@EA\chardef\csname-\recurselevel\endcsname\recurselevel}
+
+\newtoks\withminorcharacters
+\newtoks\withlowercharacters
+\newtoks\withuppercharacters
+
+% \thewithcharacter#1 % self
+
+\dostepwiserecurse{0}{31}{1}
+ {\expanded
+ {\appendtoks\noexpand\withcharacter\csname-\recurselevel\endcsname
+ \noexpand\to\withminorcharacters}}
+
+\dostepwiserecurse{32}{127}{1}
+ {\expanded
+ {\appendtoks\noexpand\withcharacter\csname-\recurselevel\endcsname
+ \noexpand\to\withlowercharacters}}
+
+\dostepwiserecurse{128}{255}{1}
+ {\expanded
+ {\appendtoks\noexpand\withcharacter\csname-\recurselevel\endcsname
+ \noexpand\to\withuppercharacters}}
+
+\def\doassigncatcodes#1%
+ {\def\withcharacter##1{\catcode##1#1}%
+ \the\withminorcharacters
+ \the\withlowercharacters
+ \ifeightbitcharacters\the\withuppercharacters\fi}
+
+\def\makeallother
+ {\doassigncatcodes\@@other}
+
+\chardef\obeyedlccode=`. % so <32 and >127 chars become .
+
+% \def\obeylccodes
+% {\def\withcharacter##1{\lccode##1##1}%
+% \the\withlowercharacters
+% \def\withcharacter##1{\lccode##1\obeyedlccode}%
+% \the\withminorcharacters
+% \ifeightbitcharacters\the\withuppercharacters\fi}
+
+\def\setownlccode #1{\lccode#1#1}
+\def\setobeyedlccode#1{\lccode#1\obeyedlccode}
+
+\def\obeylccodes % also eightbitcharacters
+ {\let\withcharacter\setownlccode
+ \the\withlowercharacters
+ \let\withcharacter\setobeyedlccode
+ \the\withminorcharacters
+ \the\withuppercharacters
+ \relax}
+
+\def\retainlccodes % also eightbitcharacters
+ {\let\withcharacter\setownlccode
+ \the\withlowercharacters
+ \the\withminorcharacters
+ \the\withuppercharacters
+ \relax}
+
+% not faster
+%
+% \newtoks \retainedlccodes
+% \dostepwiserecurse{0}{255}{1}
+% {\appendetoks\lccode\recurselevel=\recurselevel\to\retainedlccodes}
+% \appendetoks\relax\to\retainedlccodes
+
+%D This one is much faster in \ETEX. Hm, I misinterpreted
+%D the specs; it does not work.
+%
+% \ifx\normallanguage\undefined \let\normallanguage\language \fi
+% \let\doobeylccodes\obeylccodes
+%
+% \beginETEX \lccode
+% \begingroup
+% \normallanguage\zerocount
+% \doobeylccodes
+% \patterns{dummy}
+% \endgroup
+% \def\obeylccodes{\normallanguage\zerocount}
+% \endETEX
+
+\def\unspaced#1%
+ {\dounspaced#1\end}
+
+\def\dounspaced#1%
+ {\ifx#1\end
+ \@EA\gobbleoneargument
+ \else
+ \ifx#1\blankspace\else#1\fi
+ \fi
+ \dounspaced}
+
+\def\unspaceargument#1\to#2%
+ {\convertargument#1\to#2%
+ \@EA\edef\@EA#2\@EA{\@EA\unspaced\@EA{#2}}}
+
+\def\unspaceafter#1#2%
+ {\edef\ascii{\dounspaced#2\end}\@EA#1\@EA{\ascii}}
+
+% etex, much faster
+%
+% \def\unspaceargument#1\to#2%
+% {\scratchcounter\catcode'32\catcode32=\@@ignore
+% \scantokens{\edef#2{#1}}%
+% \catcode32=\scratchcounter}
+
+\def\unspaceafter#1#2%
+ {\edef\ascii{\dounspaced#2\end}\@EA#1\@EA{\ascii}}
+
+% this will replace loadfile once and alike !!! todo
+
+\def\@flg@{@flg@}
+
+\def\setflag#1%
+ {\@EA\dodoglobal\@EA\chardef\csname\@flg@#1\endcsname\zerocount}
+
+\def\resetflag#1%
+ {\@EA\dodoglobal\@EA\chardef\csname\@flg@#1\endcsname\plusone}
+
+\let\ifflagged\ifcase
+
+\def\flag#1{\csname\@flg@#1\endcsname}
+
+\def\doifelseflagged#1%
+ {\@EA\ifx\csname\@flg@#1\endcsname\relax
+ \@EA\secondoftwoarguments
+ \else\ifcase\csname\@flg@#1\endcsname
+ \@EAEAEA\firstoftwoarguments
+ \else
+ \@EAEAEA\secondoftwoarguments
+ \fi\fi}
+
+\def\doifnotflagged#1%
+ {\@EA\ifx\csname\@flg@#1\endcsname\relax
+ \@EA\firstofoneargument
+ \else\ifcase\csname\@flg@#1\endcsname
+ \@EAEAEA\gobbleoneargument
+ \else
+ \@EAEAEA\firstofoneargument
+ \fi\fi}
+
+\def\inheritparameter[#1]#2[#3]#4[#5]% tag tokey fromkey % [bypasses k!prefix]
+ {\@EAEAEA\def\@EA\csname\@EA#1\@EA#3\@EA\endcsname\@EA
+ {\csname#1#5\endcsname}}
+
+% \buildarray[test][aa,bb,cc,dd,ee,ff]
+% \setarrayelement{test}{1}{qq}
+% \arrayelement{test}{1}
+% \arraylength{test}
+%
+% \def\buildarray[#1][#2]%
+% {\scratchcounter=0
+% \def\docommando##1%
+% {\advance\scratchcounter by 1
+% \setvalue{@@aa#1\the\scratchcounter}{##1}}%
+% \processcommalist[#2]\docommando
+% \setevalue{@@aa#1}{\the\scratchcounter}}%
+%
+% \def\setarrayelement#1#2{\setvalue{@@aa#1#2}}
+% \def\arrayelement #1#2{\getvalue{@@aa#1#2}}
+% \def\arraylength #1{\getvalue{@@aa#1}}
+
+% \newsignal\junksignal
+%
+% \def\setjunksignal%
+% {\ifhmode
+% \hskip\junksignal
+% \let\removejunkspaces\doremovejunkspaces
+% \else
+% \let\removejunkspaces\relax
+% \fi}
+%
+% \def\doremovejunkspaces%
+% {\doloop{\ifdim\lastskip=\junksignal\unskip\else\exitloop\fi}}
+
+% \def\doifnonzeropositiveelse#1#2#3%
+% {\bgroup
+% \setbox\scratchbox=\hbox{\scratchcounter=0#1}%
+% \ifdim\wd\scratchbox=\!!zeropoint\egroup#2\else\egroup#3\fi}
+%
+% \def\dodoifnonzeropositiveelse#1#2\end#3#4%
+% {\egroup
+% \ifx#1\relax#3\else#4\fi}
+%
+% \def\doifnonzeropositiveelse#1%
+% {\bgroup
+% \afterassignment\dodoifnonzeropositiveelse\scratchcounter=0#1\relax\empty\end}
+
+\def\dodoifnonzeropositiveelse#1#2\end#3#4%
+ {\ifx#1\relax
+ \ifcase\scratchcounter\endgroup#4\else\endgroup#3\fi\else\endgroup#4%
+ \fi}
+
+\def\doifnonzeropositiveelse#1%
+ {\begingroup\afterassignment\dodoifnonzeropositiveelse\scratchcounter=0#1\relax\empty\end}
+
+% here ?
+
+\def\dosetrawvalue #1#2#3{\@EA \def\csname#1#2\endcsname{#3}}
+\def\dosetrawevalue#1#2#3{\@EA\edef\csname#1#2\endcsname{#3}}
+\def\dosetrawgvalue#1#2#3{\@EA\gdef\csname#1#2\endcsname{#3}}
+\def\dosetrawxvalue#1#2#3{\@EA\xdef\csname#1#2\endcsname{#3}}
+
+\def\getrawparameters {\dogetparameters\dosetrawvalue }
+\def\getraweparameters {\dogetparameters\dosetrawevalue}
+\def\getrawgparameters {\dogetparameters\dosetrawgvalue}
+\def\getrawxparameters {\dogetparameters\dosetrawxvalue}
+
+\def\globalgetrawparameters{\dogetparameters\dosetrawgvalue} % obsolete
+
+\def\splitskip#1%
+ {\scratchskip\zeropoint \!!plus \onepoint \!!minus \onepoint
+ \advance\scratchskip#1\relax % \relax is realy needed here
+ \expandafter\SPLITSKIP\the\scratchskip}
+
+{\catcode`\.=\@@other
+ \catcode`\p=\@@other
+ \catcode`\l=\@@other
+ \catcode`\u=\@@other
+ \catcode`\s=\@@other
+ \catcode`\m=\@@other
+ \catcode`\i=\@@other
+ \catcode`\n=\@@other
+ \catcode`\t=\@@other
+ \gdef\SPLITSKIP#1pt plus #2pt minus #3pt%
+ {\DOSPLITSKIP#1 #2 #3 }}
+
+\def\DOSPLITSKIP#1 #2 #3
+ {\dimen0=#1pt\dimen2=#2pt\dimen4=#3pt
+ \advance\dimen2 -\onepoint
+ \advance\dimen4 -\onepoint}
+
+% \def\minimaxskip#1#2%
+% {\splitskip#2\relax
+% \scratchdimen=#2\relax
+% #2=\scratchdimen
+% \advance#2 by #1\relax}
+%
+% \def\maximizeskip%
+% {\minimaxskip{-\dimen4}}
+%
+% \def\maximizeskip%
+% {\minimaxskip{\dimen2}}
+%
+% \def\maximizespacing%
+% {\maximizeskip\blankskipamount
+% \maximizeskip\parskip
+% \maximizeskip\ctxparskip
+% \maximizeskip\baselineskip
+% \maximizeskip\bigskipamount
+% \maximizeskip\medskipamount
+% \maximizeskip\smallskipamount}
+
+\newcount\modcounter
+
+%\def\DoMod #1by#2to#3%
+% {\modcounter#1\divide\modcounter#2\multiply\modcounter#2%
+% #3#1\advance#3 -\modcounter}
+%
+%\def\DoDiv #1by#2to#3%
+% {#3#1\divide#3 #2\relax}
+
+\def\dosetmodulo#1#2#3%
+ {\modcounter#1\divide\modcounter#2\multiply\modcounter#2%
+ #3#1\advance#3-\modcounter}
+
+\def\dosetdivision#1#2#3%
+ {#3#1\divide#3 #2\relax}
+
+\def\DoMod#1by#2to#3{\dosetmodulo {#1}{#2}{#3}}
+\def\DoDiv#1by#2to#3{\dosetdivision{#1}{#2}{#3}}
+
+\def\dounprotected#1\par
+ {#1\protect}
+
+\def\unprotected
+ {\unprotect\dounprotected}
+
+%D Standaard kan een spatie (zoals ~) uitrekken. Dit is in
+%D overzichten niet altijd de bedoeling, vandaar:
+
+%\def\fixedspace%
+% {\hskip\fontdimen2\font\relax}
+
+%\def\ExpandSecondAfter#1#2#3%
+% {\!!toksa={#2}%
+% \edef\!!stringa{#3}%
+% \edef\expanded%
+% {\noexpand#1{\the\!!toksa}{\!!stringa}}%
+% \expanded}
+%
+%\def\ExpandThirdAfter#1#2#3#4%
+% {\!!toksa={#2}%
+% \!!toksb={#3}%
+% \edef\!!stringa{#4}%
+% \edef\expanded%
+% {\noexpand#1{\the\!!toksa}{\the\!!toksb}{\!!stringa}}%
+% \expanded}
+
+%\def\indirect#1#2#3%
+% {\@EA#1\@EA#2\@EA{\@EA#3\csname\s!do\string#2\endcsname}%
+% \@EA#1\csname\s!do\string#2\endcsname}
+%
+%\def\doubleemptied#1#2#3%
+% {\indirect#1#2\dodoublempty}
+%
+%\indirect\def\stelietsin\dodoubleempty[#1][#2]%
+% {...}
+%
+%\doubleemptied\def\stelietsin[#1][#2]%
+% {...}
+
+% in mult-set
+%
+%\def\defaultsetup{def}
+%
+%\def\selectdefaultsetup#1#2%
+% {\writestatus{setup}{choose #1 setupfile}%
+% \bgroup
+% \endlinechar=-1
+% \global\read16 to \usersetup
+% \egroup
+% \ifx\usersetup\empty
+% \let\usersetup=\defaultsetup
+% \fi
+% \readfile{#2\usersetup}{}{}%
+% \writestatus{setup}{loading #1 setupfile #2\usersetup}}
+
+% awaiting the definitive implementation
+
+\ifx\resettimer\undefined
+ \let\resettimer \relax
+ \newcount\elapsedtime
+\fi
+
+\newcount\featuretest
+
+\def\testfeature#1#2%
+ {\def\dotestfeature
+ {\advance\featuretest \plusone
+ \ifnum\featuretest>#1\else#2\expandafter\dotestfeature\fi}%
+ \retestfeature}
+
+\def\retestfeature % timer support is new per 10/5/2005
+ {\bgroup
+ \ifcase\interactionmode\let\wait\relax\fi
+ \writestatus\m!systems{starting feature test}\wait
+ \resettimer
+ \featuretest\zerocount \dotestfeature
+ \scratchdimen\elapsedtime\s!sp
+ \writestatus\m!systems{feature test done (\expandafter\withoutpt\the\scratchdimen s)}%
+ \wait
+ \egroup}
+
+% \edef\elapsedtime{\expandafter\withoutpt\the\dimexpr\elapsedtime\relax s}%
+% \writestatus\m!systems{feature test done (\elapsedtime)}%
+
+\def\testfeatureonce#1#2%
+ {\let\wait\relax\testfeature{#1}{#2}\end}
+
+%D \macros
+%D {adddimenregister,adddimenmacro}
+%D
+%D Instead of using numerous \type {\advance}'s, one can use
+%D the next macros to add|/|subtract a series of dimensions
+%D to a register or macro.
+%D
+%D \starttyping
+%D \adddimenregister 10pt 5pt \paperwidth \to \somedimen
+%D \adddimenmacro 10pt 5pt \paperwidth \to \bagger
+%D \stoptyping
+
+\newdimen\dimentoaddto
+
+\def\adddimenregister#1\to#2% will be obsolete once full etex
+ {\begingroup
+ #2=\zeropoint
+ \dimentoaddto\zeropoint
+ \def\docommando%
+ {\advance#2 \dimentoaddto
+ \futurelet\next\dodocommando}%
+ \def\dodocommando%
+ {\ifx\next\relax
+ \expanded{\endgroup#2=\the#2}%
+ \else
+ \@EA\afterassignment\@EA\docommando\@EA\dimentoaddto
+ \fi}%
+ \docommando#1\relax}
+
+\def\adddimenmacro#1\to#2%
+ {\adddimenregister#1\to\scratchdimen
+ \edef#2{\the\scratchdimen}}
+
+%D \macros
+%D {freezedimenmacro}
+%D
+%D This macro is use as:
+%D
+%D \starttyping
+%D \freezedimenmacro\leftmargindistance
+%D \stoptyping
+
+\def\freezedimenmacro#1%
+ {\scratchdimen#1\edef#1{\the\scratchdimen}}
+
+%D The next one is slower:
+%D
+%D \starttyping
+%D \def\freezedimenmacro#1{\edef#1{\the\dimexpr(#1)}}
+%D \stoptyping
+
+% \newcount\rawrecursecounter
+%
+% \def\rawrecurselevel{\the\rawrecursecounter}%
+%
+% \def\dorawrecurse#1#2%
+% {\rawrecursecounter\plusone
+% \let\oldrecurselevel\recurselevel
+% \let\recurselevel\rawrecurselevel
+% \def\dodorawrecurse
+% {\ifnum\rawrecursecounter>#1\relax
+% \let\recurselevel\oldrecurselevel
+% \else
+% #2\advance\rawrecursecounter \plusone
+% \expandafter\dodorawrecurse
+% \fi}%
+% \dodorawrecurse}
+
+%D The next macro negates a macro (dimension or number, or actually, whatever.
+%D It's a typical example of \type {\if} usage:
+%D
+%D \starttyping
+%D \if-\whatever \else-\whatever\fi => else => -whatever
+%D \if--\whatever\else-\whatever\fi => then => whatever
+%D \stoptyping
+
+\def\negated#1{\if-#1\else-#1\fi} % does only work in macros or text
+
+% This permits things like ^\index{hans}^, where hans is
+% duplicated in the text.
+
+\newif\ifduplicate
+
+\bgroup
+
+\gdef\checkduplication % in line with Knuth
+ {\ifmmode\expandafter^\else\expandafter\startduplication\fi}
+
+\gdef\insideduplication
+ {\ifmmode\expandafter^\else\expandafter\egroup\fi}
+
+\catcode`\^=\@@active
+
+\gdef\enableduplication
+ {\catcode`\^=\@@active \let^\checkduplication}
+
+\gdef\disableduplication
+ {\catcode`\^=\@@superscript}
+
+\gdef\startduplication
+ {\bgroup \duplicatetrue \let^\insideduplication}
+
+\egroup
+
+\def\gobbleassigndimen#1\\{}
+
+\def\assigndimen#1#2%
+ {\afterassignment\gobbleassigndimen#1=#2\!!zeropoint\\}
+
+\def\setusage#1%
+ {\@EA\let\csname#1\endcsname\iftrue}
+
+\def\resetusage#1%
+ {\@EA\let\csname#1\endcsname\iffalse}
+
+\beginTEX
+
+\def\ifusage#1%
+ {\@EA\ifx\csname#1\endcsname\relax
+ \resetusage{#1}%
+ \fi
+ \csname#1\endcsname}
+
+\endTEX
+
+\beginETEX \ifcsname
+
+\def\ifusage#1%
+ {\ifcsname#1\endcsname\else
+ \resetusage{#1}%
+ \fi
+ \csname#1\endcsname}
+
+\endETEX
+
+%D Very handy, more efficient than \type{{}}, and more readable
+%D than \type {\empty}.
+
+\let\donothing\empty
+
+% The following macros are used in XML handling.
+
+% \long\def\dowithstringed#1#2#3#4% " ' space
+% {\if#4"\@EA#1\else\if#4'\@EAEAEA#2\else\@EAEAEA#3\fi\fi#4}
+%
+% \def\unstringed
+% {\dowithstringed\unstringdouble\unstringsingle\unstringspaced}
+%
+% \long\def\unstringdouble"#1"{#1}
+% \long\def\unstringsingle'#1'{#1}
+% \long\def\unstringspaced #1 {#1}
+%
+% \def\grabstring
+% {\dowithstringed\grabstringdouble\grabstringsingle\grabstringspaced}
+%
+% \def\dowithgrabbedstring#1%
+% {\def\@@dowithgrabbedstring{#1}%
+% \afterassignment\@@dowithgrabbedstring\grabstring}
+%
+% \long\def\grabstringdouble"#1"{\scratchtoks{#1}}
+% \long\def\grabstringsingle'#1'{\scratchtoks{#1}}
+% \long\def\grabstringspaced #1 {\scratchtoks{#1}}
+
+\long\setvalue{@u@s@"}#1#2"{#2} \long\setvalue{@g@s@"}#1#2"{\scratchtoks{#2}}
+\long\setvalue{@u@s@'}#1#2'{#2} \long\setvalue{@g@s@'}#1#2'{\scratchtoks{#2}}
+\long\setvalue{@u@s@ }#1#2 {#2} \long\setvalue{@g@s@ }#1#2 {\scratchtoks{#2}}
+
+\long\def\unstringed#1{\csname\ifcsname @u@s@#1\endcsname @u@s@#1\else\s!empty\fi\endcsname#1}
+\long\def\grabstring#1{\csname\ifcsname @g@s@#1\endcsname @g@s@#1\else\s!empty\fi\endcsname#1}
+
+\def\dowithgrabbedstring#1%
+ {\def\@@dowithgrabbedstring{#1}%
+ \afterassignment\@@dowithgrabbedstring\grabstring}
+
+\def\expifequalelse#1#2%
+ {\@@ifequal#1\relax\relax\@@and#2\relax\relax\@@then}
+
+\def\@@ifequal#1#2\@@and#3%
+ {\ifx#1\relax
+ \ifx#3\relax
+ \@EAEAEA\@@if@@equal@@true
+ \else
+ \@EAEAEA\@@if@@equal@@false
+ \fi
+ \else
+ \ifx#3\relax
+ \@EAEAEAEAEAEA\@@if@@equal@@false
+ \else\ifx#1#3%
+ % go on
+ \else
+ \@EAEAEAEAEAEA\@@if@@equal@@false
+ \fi\fi
+ \fi
+ \@@ifequal#2\@@and}
+
+\long\def\@@if@@equal@@true #1\@@then#2#3{#2}
+\long\def\@@if@@equal@@false#1\@@then#2#3{#3}
+
+%D new stuff :
+
+\def\partialexpanded#1%
+ {\let\notexpanded\noexpand
+ \long\xdef\@@expanded{\noexpand#1}%
+ \let\notexpanded\empty
+ \@@expanded}
+
+% for Simon ; watch how we make them fully expandable (i.e.
+% no \type {\relax}es) popping up
+
+\def\@@dothenumber#1\relax#2\end{#1}
+
+\def\@@thenumber#1{\@EA\@@dothenumber\number#1\relax\end}
+
+\def\doifnum#1#2%
+ {\ifnum#1=\@@thenumber{#2} % space needed
+ \expandafter\firstofoneargument
+ \else
+ \expandafter\gobbleoneargument
+ \fi}
+
+\def\doifnotnum#1#2%
+ {\ifnum#1=\@@thenumber{#2} % space needed
+ \expandafter\gobbleoneargument
+ \else
+ \expandafter\firstofoneargument
+ \fi}
+
+\def\doifelsenum#1#2%
+ {\ifnum#1=\@@thenumber{#2} % space needed
+ \expandafter\firstoftwoarguments
+ \else
+ \expandafter\secondoftwoarguments
+ \fi}
+
+% \edef\xxxx{\doifnum{1}{2}{no}} \show \xxxx
+% \edef\xxxx{\doifnum{2}{2}{yes}} \show \xxxx
+% \scratchcounter0 \edef\xxxx{\doifnum{1}{\scratchcounter}{no}} \show \xxxx
+% \scratchcounter1 \edef\xxxx{\doifnum{1}{\scratchcounter}{yes}} \show \xxxx
+
+\def\appended#1#2#3{\@EA#1\@EA#2\@EA{#2#3}}
+\def\appendvalue #1{\@EA\appended\@EA \def\csname#1\endcsname}
+\def\appendgvalue#1{\@EA\appended\@EA\gdef\csname#1\endcsname}
+
+\def\prepended#1#2#3{\scratchtoks{#3}\@EA\@EA\@EA#1\@EA\@EA\@EA#2\@EA\@EA\@EA{\@EA\the\@EA\scratchtoks#2}}
+\def\prependvalue #1{\@EA\prepended\@EA \def\csname#1\endcsname}
+\def\prependgvalue#1{\@EA\prepended\@EA\gdef\csname#1\endcsname}
+
+%D \macros
+%D {compresscommacommandnrs,compresscommalistnrs,compressedcommalistnrs,
+%D compresscommacommand,compresscommalist,compressedcommalist,
+%D reversecommacommand,reversecommalist,reversedcommalist}
+%D
+%D The following two list processing macros are needed by Taco's
+%D bibliography module. The numbers compressor converts the
+%D list in a list of ranges. The normal compressor remove duplicate
+%D and empty entries.
+
+\def\compresscommalistnrs[#1]%
+ {\let\compressedlist\empty
+ \!!counta\maxdimen
+ \!!countb\maxdimen
+ \processcommalist[#1]\docompresslistnrs
+ \ifnum\!!counta=\maxdimen\else\dodocompresslistnrs\fi}
+
+\def\compresscommacommandnrs[#1]%
+ {\expanded{\compresscommalistnrs[#1]}}
+
+\def\docompresslistnrs#1%
+ {\edef\commalistelement{#1}%
+ \ifx\commalistelement\empty\else
+ \ifnum\!!counta=\maxdimen
+ \!!counta\commalistelement\relax
+ \!!countb\!!counta
+ \else
+ \advance\!!countb\plusone
+ \ifnum\commalistelement>\!!countb
+ \advance\!!countb\minusone
+ \dodocompresslistnrs
+ \!!counta\commalistelement\relax
+ \!!countb\!!counta
+ \fi
+ \fi
+ \fi}
+
+\def\dodocompresslistnrs
+ {\edef\compressedlist
+ {\ifx\compressedlist\empty\else\compressedlist,\fi
+ {\the\!!counta}{\ifnum\!!countb>\!!counta\the\!!countb\fi}}}
+
+%D \def\test#1{{\tttf#1->\compresscommalistnrs[#1]\convertcommand\compressedlist\to\ascii\ascii}}
+%D \startlines
+%D \test{}
+%D \test{1}
+%D \test{1,3}
+%D \test{1,3,4}
+%D \test{1,3,3,4,5}
+%D \test{1,3,3,4,5,8}
+%D \test{1,3,3,4,5,5,8,10}
+%D \test{1,3,4,5,8,10,11}
+%D \test{1,,3,,4,,5,,8,,10,,11,}
+%D \stoplines
+
+\def\compresscommalist[#1]%
+ {\let\compressedlist\empty
+ \let\!!stringa\empty
+ \processcommalist[#1]\docompresslist}
+
+\def\compresscommacommand[#1]%
+ {\expanded{\compresscommalist[#1]}}
+
+\def\docompresslist#1%
+ {\edef\commalistelement{#1}%
+ \ifx\commalistelement\empty \else
+ \ifx\!!stringa\commalistelement \else
+ \ifx\compressedlist\empty
+ \def\compressedlist{#1}%
+ \else
+ \appended\def\compressedlist{,#1}%
+ \fi
+ \let\!!stringa\commalistelement
+ \fi
+ \fi}
+
+%D \def\test#1{{\tttf#1->\compresscommalist[#1]\convertcommand\compressedlist\to\ascii\ascii}}
+%D \startlines
+%D \test{}
+%D \test{1}
+%D \test{1,3}
+%D \test{1,3,4}
+%D \test{1,3,3,4,5}
+%D \test{1,3,3,4,5,8}
+%D \test{1,3,3,4,5,5,8,10}
+%D \test{1,3,4,5,8,10,11}
+%D \test{1,,3,,4,,5,,8,,10,,11,}
+%D \stoplines
+
+\def\reversecommalist[#1]%
+ {\let\reversedlist\empty
+ \processcommalist[#1]\doreverselist}
+
+\def\doreverselist#1%
+ {\ifx\reversedlist\empty
+ \def\reversedlist{#1}%
+ \else
+ \prepended\def\reversedlist{#1,}%
+ \fi}
+
+\def\reversecommacommand[#1]%
+ {\expanded{\reversecommalist[#1]}}
+
+%D \def\test#1{{\tttf#1->\reversecommalist[#1]\convertcommand\reversedlist\to\ascii\ascii}}
+%D \startlines
+%D \test{}
+%D \test{1}
+%D \test{1,3}
+%D \test{1,3,4}
+%D \test{1,3,3,4,5}
+%D \test{1,3,3,4,5,8}
+%D \test{1,3,3,4,5,5,8,10}
+%D \test{1,3,4,5,8,10,11}
+%D \test{1,,3,,4,,5,,8,,10,,11,}
+%D \stoplines
+
+%D \macros
+%D {stripstring}
+%D
+%D Needed in bookmarks:
+%D
+%D \starttyping
+%D {\sanitizePDFdocencoding test \CONTEXT\ test \to\oeps\stripstring\oeps\tttf[\oeps]}
+%D \stoptyping
+
+\def\stripstring#1% #1 is \cs
+ {\bgroup
+ \convertcommand#1\to\ascii
+ \global\let\globalascii\empty
+ \donefalse
+ \expandafter\handletokens\ascii\with\dostripstring
+ \egroup
+ \let#1\globalascii}
+
+\def\dostripstring#1%
+ {\ifx#1\blankspace
+ \donetrue
+ \else
+ \ifdone\ifx\globalascii\empty\else
+ \xdef\globalascii{\globalascii\space}%
+ \donefalse
+ \fi\fi
+ \xdef\globalascii{\globalascii#1}%
+ \fi}
+
+%D \macros
+%D {dowithrange}
+%D
+%D This one is for Mojca Miklavec, who made me aware of the fact that
+%D \type {page-imp.tex} was not the best place to hide it.
+
+\def\dowithrange#1#2% #2 takes number
+ {\splitstring#1\at:\to\fromrange\and\torange
+ \ifx\torange\empty\let\torange\fromrange\fi
+ \dostepwiserecurse\fromrange\torange1{#2{\recurselevel}}}
+
+\protect \endinput