summaryrefslogtreecommitdiff
path: root/tex/context/base/mkii/syst-new.mkii
diff options
context:
space:
mode:
authorContext Git Mirror Bot <phg42.2a@gmail.com>2016-01-12 17:15:07 +0100
committerContext Git Mirror Bot <phg42.2a@gmail.com>2016-01-12 17:15:07 +0100
commit8d8d528d2ad52599f11250cfc567fea4f37f2a8b (patch)
tree94286bc131ef7d994f9432febaf03fe23d10eef8 /tex/context/base/mkii/syst-new.mkii
parentf5aed2e51223c36c84c5f25a6cad238b2af59087 (diff)
downloadcontext-8d8d528d2ad52599f11250cfc567fea4f37f2a8b.tar.gz
2016-01-12 16:26:00
Diffstat (limited to 'tex/context/base/mkii/syst-new.mkii')
-rw-r--r--tex/context/base/mkii/syst-new.mkii868
1 files changed, 868 insertions, 0 deletions
diff --git a/tex/context/base/mkii/syst-new.mkii b/tex/context/base/mkii/syst-new.mkii
new file mode 100644
index 000000000..34b535b90
--- /dev/null
+++ b/tex/context/base/mkii/syst-new.mkii
@@ -0,0 +1,868 @@
+%D \module
+%D [ file=syst-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 ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D Code from this module will move. For instance to
+%D syst-dat.tex (datastructures).
+
+\unprotect
+
+% 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
+
+\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%
+ {\defconvertedargument#2{#1}%
+ \@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}}
+
+% sometimes handy:
+
+\def\doifhasspaceelse#1%
+ {\edef\!!stringa{#1}%
+ \expanded{\dodoifhasspaceelse#1\space}\empty\relax}
+
+\def\dodoifhasspaceelse#1 #2#3\relax % \space\empty\relax
+ {\ifx\!!stringa\space
+ \@EA\firstoftwoarguments
+ \else\ifx#2\empty
+ \@EAEAEA\secondoftwoarguments
+ \else
+ \@EAEAEA\firstoftwoarguments
+ \fi\fi}
+
+% 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\docommand##1%
+% {\advance\scratchcounter by 1
+% \setvalue{@@aa#1\the\scratchcounter}{##1}}%
+% \processcommalist[#2]\docommand
+% \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
+ \@EAEAEA\secondoftwoarguments
+ \else
+ \endgroup
+ \@EAEAEA\firstoftwoarguments
+ \fi
+ \else
+ \endgroup
+ \@EA\secondoftwoarguments
+ \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\DOSPLITSKIP#1 #2 #3
+ {\dimen0=#1\onepoint
+ \dimen2=\dimexpr#2\onepoint-\onepoint\relax
+ \dimen4=\dimexpr#3\onepoint-\onepoint\relax}
+
+% \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\interwordspace\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
+ \writestatus\m!systems{feature test done (\elapsedseconds s)}%
+ \wait
+ \egroup}
+
+\def\elapsedseconds{\expandafter\withoutpt\the\dimexpr\elapsedtime sp\relax}
+
+\def\showtimer#1%
+ {\writestatus{runtime}{\elapsedseconds\space s / #1}}
+
+% \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\docommand%
+% {\advance#2 \dimentoaddto
+% \futurelet\next\dodocommand}%
+% \def\dodocommand%
+% {\ifx\next\relax
+% \expanded{\endgroup#2=\the#2}%
+% \else
+% \@EA\afterassignment\@EA\docommand\@EA\dimentoaddto
+% \fi}%
+% \docommand#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}}
+
+\def\freezedimenmacro#1%
+ {\edef#1{\the\dimexpr#1}}
+
+%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\@do@the@number@#1\relax#2\end{#1}
+
+\def\@the@number@#1{\@EA\@do@the@number@\number#1\relax\end}
+
+\def\doifnum#1#2%
+ {\ifnum#1=\@the@number@{#2} % space needed
+ \expandafter\firstofoneargument
+ \else
+ \expandafter\gobbleoneargument
+ \fi}
+
+\def\doifnotnum#1#2%
+ {\ifnum#1=\@the@number@{#2} % space needed
+ \expandafter\gobbleoneargument
+ \else
+ \expandafter\firstofoneargument
+ \fi}
+
+\def\doifelsenum#1#2%
+ {\ifnum#1=\@the@number@{#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]\defconvertedcommand\ascii\compressedlist\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]\defconvertedcommand\ascii\compressedlist\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]\defconvertedcommand\ascii\reversedlist\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
+ \defconvertedcommand\ascii{#1}%
+ \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}}}
+
+%D \macros {uncompresslist}
+%D
+%D When given a list like \type{1,4-7,9} as argument, this macro
+%D will store the expanded commalist in \type{\uncompressedlist}.
+%D
+%D \startbuffer
+%D \def\MojcaHasToDoTheTasks[#1]#2%
+%D {{\uncompresslist[#1]%
+%D \def\processitem##1{I have to do ##1 #2\par}%
+%D \processcommacommand[\uncompressedlist]\processitem}}
+%D
+%D \MojcaHasToDoTheTasks [1-4,7,9-11] {until tomorrow}
+%D \stopbuffer
+%D
+%D Here is an example of how to use \type {\uncompresslist}:
+%D \typebuffer
+%D
+%D The output of this is:
+%D
+%D \getbuffer
+
+\beginETEX \numexpr
+
+\def\uncompresslist[#1]% by TH
+ {\let\uncompressedlist\empty
+ \def\docompressedlistitem##1-##2-%
+ {\@EA\dorecurse\@EA
+ {\the\numexpr1+##2-##1\relax}%
+ {\@EA\appendtocommalist\@EA{\the\numexpr##1-1+####1\relax}\uncompressedlist}}%
+ \def\douncompresslist##1%
+ {\doifinstringelse{-}{##1}
+ {\docompressedlistitem##1-}
+ {\appendtocommalist{##1}\uncompressedlist}}%
+ \processcommalist[#1]\douncompresslist}
+
+\endETEX
+
+\beginTEX
+
+\def\uncompresslist[#1]%
+ {\def\uncompressedlist{#1}}
+
+\endTEX
+
+%D \macros
+%D {ignoreimplicitspaces}
+%D
+%D \startbuffer
+%D \def\whatever[#1]{\expanded{\definedfont[#1 at 12pt]}\ignorespaces}
+%D {a\whatever[Serif]b a\whatever[Serif] b a\whatever[Serif]\space b}
+%D \def\whatever[#1]{\expanded{\definedfont[#1 at 12pt]}\ignoreimplicitspaces}
+%D {a\whatever[Serif]b a\whatever[Serif] b a\whatever[Serif]\space b}
+%D \stopbuffer
+%D
+%D \typebuffer \getbuffer
+
+\def\ignoreimplicitspaces
+ {\doifnextcharelse\relax\relax\relax}
+
+% new
+%
+% \startnointerference
+% all kind of code
+% \stopnointerference
+
+\newbox\nointerferencebox
+
+\def\startnointerference
+ {\setbox\nointerferencebox\vbox
+ \bgroup}
+
+\def\stopnointerference
+ {\egroup
+ \setbox\nointerferencebox\emptybox}
+
+\protect \endinput
+
+
+% \def\appendtovaluelist#1#2%
+% {\ifcsname#1\endcsname
+% \expandafter\ifx\csname#1\endcsname\empty
+% \expandafter\def\csname#1\endcsname{#2}%
+% \else
+% \expandafter\def\csname#1\expandafter\expandafter\expandafter\endcsname
+% \expandafter\expandafter\expandafter{\csname#1\endcsname,#2}%
+% \fi
+% \else
+% \expandafter\def\csname#1\endcsname{#2}%
+% \fi}
+%
+% or
+%
+% \def\appendtovaluelist#1%
+% {\ifcsname#1\endcsname
+% \expandafter\ifx\csname#1\endcsname\empty
+% \expandafter\noappendtovaluelist\csname#1\expandafter\expandafter\expandafter\endcsname
+% \else
+% \expandafter\doappendtovaluelist\csname#1\expandafter\expandafter\expandafter\endcsname
+% \fi
+% \else
+% \expandafter\noappendtovaluelist\csname#1\expandafter\endcsname
+% \fi}
+
+% \def\doappendtovaluelist#1#2{\expandafter\def\expandafter#1\expandafter{#1,#2}}
+% \def\noappendtovaluelist#1#2{\def#1{#2}}
+
+% \appendtovaluelist{mylist}{aap}
+% \appendtovaluelist{mylist}{noot}
+% \appendtovaluelist{mylist}{mies}
+
+% \showvalue{mylist}