%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!oneven\else\v!even\fi}

% For myself

\newcount\nofprofiled

\def\profilemacro#1%
  {\nofprofiled\zerocount
   \letvalue{\string#1\string#1}#1%
   \appendtoks
     \writestatus\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
  {\let\withcharacter\setownlccode 
   \the\withlowercharacters
   \let\withcharacter\setobeyedlccode
   \the\withminorcharacters
   \ifeightbitcharacters\the\withuppercharacters\fi}

\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 1pt \!!minus 1pt
   \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 -1pt%
   \advance\dimen4 -1pt}

% \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\blankoskipamount
%    \maximizeskip\parskip
%    \maximizeskip\tussenwit
%    \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}}

\newcount\featuretest

\def\testfeature#1#2%
  {\def\dotestfeature
     {\advance\featuretest \plusone
      \ifnum\featuretest<#1\relax#2\expandafter\dotestfeature\fi}%
   \retestfeature}

\def\retestfeature
  {\bgroup
   \ifcase\interactionmode\let\wait\relax\fi
   \message{starting feature test}\wait
   \featuretest=-1 \dotestfeature
   \message{feature test done}\wait
   \egroup}

\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 \starttypen 
%D \adddimenregister 10pt 5pt \papierbreedte \to \somedimen
%D \adddimenmacro    10pt 5pt \papierbreedte \to \bagger
%D \stoptypen

\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 \starttypen 
%D \freezedimenmacro\linkermargeafstand
%D \stoptypen 

\def\freezedimenmacro#1%
  {\scratchdimen#1\edef#1{\the\scratchdimen}}

%D The next one is slower: 
%D
%D \starttypen
%D \def\freezedimenmacro#1{\edef#1{\the\dimexpr(#1)}} 
%D \stoptypen 

% \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}

% 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\unstringnothing}

\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}}

\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}

\protect \endinput
