%D \module
%D   [       file=supp-mis,
%D        version=1997.01.04,
%D          title=\CONTEXT\ Support Macros,
%D       subtitle=Missing (For Generic Use),
%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. Non||commercial use is
%C granted.

%D Some support modules are more or less independant. This
%D module, which is not part of plain \CONTEXT, provides the
%D missing macros and declarations of registers.

\ifx \undefined \writestatus \else \expandafter \endinput \fi

%D \macros
%D   {ifnocontextobject}
%D
%D First we take care of redundant defining. The next set of
%D macros are a bit complicated by the fact that Plain
%D \TEX\ defines the \type{\new}||macros as being outer.
%D Furthermore nested \type{\if}'s can get us into
%D trouble.

\def\definecontextobject%
  {\iftrue}

\def\gobblecontextobject%
  {\setbox0=\hbox
     \bgroup
     \long\def\gobblecontextobject##1\fi{\egroup}%
     \expandafter\gobblecontextobject\string}

\long\def\ifnocontextobject#1\do%
  {\ifx#1\undefined
     \let\next=\definecontextobject
   \else
     %\writestatus{system}{beware of conflicting \string#1}%
     \let\next=\gobblecontextobject
   \fi
   \next}

%D \macros 
%D   {beginETEX,beginTEX}
%D
%D Outside \CONTEXT\ we will not be \ETEX||aware.

\long\def\beginETEX#1\endETEX{}

\let\beginTEX\relax \let\endTEX\relax

%D \macros
%D   {writestatus}
%D
%D We start each module with a message. Normally the output is
%D formatted, but here we keep things simple.

\ifnocontextobject \writestatus \do

  \def\writestatus#1#2%
    {\immediate\write16{#1 : #2}}

\fi

%D Lets see if it works.

\writestatus{loading}{Context Support Macros / Missing}

%D \macros
%D   {protect,unprotect}
%D
%D Next we present a poor mans alternative for \type{\protect}
%D and \type{\unprotect}, two commands that enable us to use
%D the characters \type{@}, \type{!} and \type{?} in macro
%D names.

\ifnocontextobject \protect \do

  \let\protect=\relax

\fi

\newcount\protectiondepth

\ifnocontextobject \unprotect \do

  \def\unprotect%
    {\advance\protectiondepth 1
     \ifnum\protectiondepth=1
       \let\normalprotect=\protect
       \def\protect%
         {\ifnum\protectiondepth>0
            \advance\protectiondepth -1
            \ifnum\protectiondepth=0
              \doprotect
              \let\protect=\normalprotect
            \fi
          \fi}
       \edef\doprotect%
         {\catcode`\noexpand @=\the\catcode`@\relax
          \catcode`\noexpand !=\the\catcode`!\relax
          \catcode`\noexpand ?=\the\catcode`?\relax}
       \catcode`@=11
       \catcode`!=11
       \catcode`?=11
     \fi}

\fi

%D We start using this one it at once.

\unprotect

%D \macros
%D   {scratch...,if...,next...}
%D
%D We need some scratch registers. Users are free to use them,
%D but can never be sure of their value once another macro is
%D called. We only allocate things when they are yet
%D undefined. This way we can't mess up other macro packages,
%D but of course previous definitions can mess up our modules.

\ifnocontextobject \scratchcounter         \do \newcount  \scratchcounter  \fi
\ifnocontextobject \scratchdimen           \do \newdimen  \scratchdimen    \fi
\ifnocontextobject \scratchskip            \do \newskip   \scratchskip     \fi
\ifnocontextobject \scratchmuskip          \do \newmuskip \scratchmuskip   \fi
\ifnocontextobject \scratchbox             \do \newbox    \scratchbox      \fi
\ifnocontextobject \scratchread            \do \newread   \scratchread     \fi
\ifnocontextobject \scratchwrite           \do \newwrite  \scratchwrite    \fi
 
\ifnocontextobject \nextbox                \do \newbox    \nextbox         \fi

\ifnocontextobject \nextdepth              \do \newdimen  \nextdepth       \fi

\ifnocontextobject \CONTEXTtrue            \do \newif\ifCONTEXT            \fi
\ifnocontextobject \donetrue               \do \newif\ifdone               \fi
\ifnocontextobject \eightbitcharacterstrue \do \newif\ifeightbitcharacters \fi
\ifnocontextobject \MPdrawingdonetrue      \do \newif\ifMPdrawingdone      \fi

%D \macros
%D   {@@...}
%D
%D We use symbolic name for \CATCODES. They can only be used
%D when we are in unprotected state.

\ifnocontextobject \@@escape     \do \chardef\@@escape     =  0 \fi
\ifnocontextobject \@@begingroup \do \chardef\@@begingroup =  1 \fi
\ifnocontextobject \@@endgroup   \do \chardef\@@endgroup   =  2 \fi
\ifnocontextobject \@@endofline  \do \chardef\@@endofline  =  5 \fi
\ifnocontextobject \@@ignore     \do \chardef\@@ignore     =  9 \fi
\ifnocontextobject \@@space      \do \chardef\@@space      = 10 \fi
\ifnocontextobject \@@letter     \do \chardef\@@letter     = 11 \fi
\ifnocontextobject \@@other      \do \chardef\@@other      = 12 \fi
\ifnocontextobject \@@active     \do \chardef\@@active     = 13 \fi
\ifnocontextobject \@@comment    \do \chardef\@@comment    = 14 \fi

%D \macros
%D   {everyline,EveryLine,EveryPar}
%D
%D In \CONTEXT\ we use \type{\everypar} for special purposes
%D and provide \type{\EveryPar} as an alternative. The same
%D goes for \type{\everyline} and \type{\EveryLine}.

\ifnocontextobject \everyline \do \newtoks\everyline        \fi
\ifnocontextobject \EveryPar  \do \let\EveryPar =\everypar  \fi
\ifnocontextobject \EveryLine \do \let\EveryLine=\everyline \fi

%D \macros
%D   {!!...}
%D
%D We reserve ourselves some scratch strings (i.e. macros)
%D and some more counters.

\ifnocontextobject \!!stringa \do \def\!!stringa {} \fi
\ifnocontextobject \!!stringb \do \def\!!stringb {} \fi
\ifnocontextobject \!!stringc \do \def\!!stringc {} \fi
\ifnocontextobject \!!stringd \do \def\!!stringd {} \fi

\ifnocontextobject \!!counta \do \newcount\!!counta {} \fi
\ifnocontextobject \!!countb \do \newcount\!!countb {} \fi

%D \macros
%D   {!!...}
%D
%D The next set of definitions speed up processing a bit.
%D Furthermore it saves memory.

\ifnocontextobject \!!zeropoint   \do \def\!!zeropoint   {0pt}    \fi
\ifnocontextobject \!!tenthousand \do \def\!!tenthousand {10000}  \fi

\ifnocontextobject \!!width       \do \def\!!width       {width}  \fi
\ifnocontextobject \!!height      \do \def\!!height      {height} \fi
\ifnocontextobject \!!depth       \do \def\!!depth       {depth}  \fi

\ifnocontextobject \!!plus        \do \def\!!plus        {plus}   \fi
\ifnocontextobject \!!minus       \do \def\!!minus       {minus}  \fi
\ifnocontextobject \!!to          \do \def\!!to          {to}     \fi

%D \macros
%D   {smashbox}
%D
%D The system modules offer a range of smashing macros, of
%D which we only copied \type{\smashbox}.

\ifnocontextobject \smashbox \do

  \def\smashbox#1%
    {\wd#1=\!!zeropoint
     \ht#1=\!!zeropoint
     \dp#1=\!!zeropoint}

\fi

%D \macros
%D   {dowithnextbox}
%D
%D Also without further comment, we introduce a macro that
%D gets the next box and does something usefull with it.
%D Because the \type{\afterassignment} is executed inside the
%D box, we have to use a \type{\aftergroup} too.

\ifnocontextobject \dowithnextbox \do

  \def\dowithnextbox#1%
    {\def\dodowithnextbox{#1}%
     \afterassignment\dododowithnextbox
     \setbox\nextbox}

  \def\dododowithnextbox%
    {\aftergroup\dodowithnextbox}

\fi

%D \macros
%D   {setvalue,getvalue,letvalue,setgvalue}
%D
%D The next two macros expand their argument to
%D \type{\argument}. The first one is used to define macro's
%D the second one executes them.

\ifnocontextobject \setvalue \do

  \def\setvalue #1{\expandafter\def\csname#1\endcsname}
  \def\getvalue #1{\csname#1\endcsname}
  \def\letvalue #1{\expandafter\let\csname#1\endcsname}
  \def\setgvalue#1{\expandafter\gdef\csname#1\endcsname}

\fi

%D \macros
%D   {unexpanded}
%D
%D The next command can be used as prefixed for commands that
%D need protection during tests and writing to files. This
%D is a very \CONTEXT\ specific one.

\ifnocontextobject \unexpanded \do

  \let\unexpanded=\relax

\fi

%D \macros
%D   {convertargument}
%D
%D The original one offers a bit more, like global assignment, the
%D the next implementation is however a bit more byte saving.

\ifnocontextobject \convertargument \do

  \def\doconvertargument#1>{}

  \long\def\convertargument#1\to#2%
    {\long\def\convertedargument{#1}%
     \edef#2{\expandafter\doconvertargument\meaning\convertedargument}}

\fi

%D \macros
%D   {forgetall}
%D
%D Sometimes we have to disable interference of whatever kind
%D of skips and mechanisms. The next macro resets some.

\ifnocontextobject \forgetall \do

  \def\forgetall%
    {\parskip\!!zeropoint
     \leftskip\!!zeropoint
     \parindent\!!zeropoint
     \everypar{}}

\fi

%D \macros
%D   {withoutpt}
%D
%D \TEX\ lacks some real datastructure. We can however use
%D \DIMENSIONS. This kind of trickery is needed when we want
%D \TEX\ to communicate with the outside world (by means of
%D \type{\specials}).

\ifnocontextobject \withoutpt \do

  {\catcode`\.=\@@other
   \catcode`\p=\@@other
   \catcode`\t=\@@other
   \gdef\WITHOUTPT#1pt{#1}}

  \def\withoutpt#1%
    {\expandafter\WITHOUTPT#1}

  \def\ScaledPointsToBigPoints#1#2%
    {\scratchdimen=#1sp\relax
     \scratchdimen=.996264\scratchdimen
     \edef#2{\withoutpt{\the\scratchdimen}}}

\fi

%D \macros
%D   {doprocessfile}
%D
%D This macro takes three arguments: the file number, the
%D filename and a macro that handles the content of a read
%D line.

\newif\iffileprocessed

\ifnocontextobject \doprocessfile \do

  \def\doprocessfile#1#2#3%
    {\openin#1=#2\relax
     \ifeof#1%
       \fileprocessedfalse
       \closein#1\relax
     \else
       \fileprocessedtrue
       \gdef\dofinishfile% 
         {\closein#1\relax
          \global\let\doprocessline=\relax}%
       \gdef\doprocessline%
         {\ifeof#1%
            \dofinishfile
          \else
            \global\read#1 to \fileline
            #3\relax
            \expandafter\doprocessline
          \fi}%
       \expandafter\doprocessline
     \fi}

\fi

%D \macros
%D   {uncatcodespecials}
%D
%D This one is taken from the \TEX\ book. The \CONTEXT\
%D alternative is a bit different, but we hope this one works
%D here.

\ifnocontextobject \uncatcodespecials \do

  \def\uncatcodespecials%
    {\def\do##1{\catcode`##1=12 }\dospecials}

\fi

\ifnocontextobject \setnaturalcatcodes \do

\def\setnaturalcatcodes%
  {\catcode`\!=\@@other \catcode`\?=\@@other \catcode`\@=\@@other
   \catcode`\#=\@@other \catcode`\&=\@@other \catcode`\|=\@@other
   \catcode`\$=\@@other \catcode`\^=\@@other \catcode`\_=\@@other
   \catcode`\*=\@@other \catcode`\/=\@@other
   \catcode`\-=\@@other \catcode`+=\@@other
   \catcode`\==\@@other \catcode`\<=\@@other \catcode`\>=\@@other
   \catcode`\"=\@@other \catcode`\'=\@@other \catcode`\`=\@@other
   \catcode`\:=\@@other \catcode`\;=\@@other
   \catcode`\,=\@@other \catcode`\.=\@@other \catcode`\~=\@@other 
   \catcode`\(=\@@other \catcode`\)=\@@other 
   \catcode`\{=\@@other \catcode`\}=\@@other}

\fi

%D \macros
%D   {doglobal}
%D
%D Some \CONTEXT\ low level macros can have a \type{\doglobal}
%D prefix. Let's just forget about that here:

\ifnocontextobject \doglobal \do \let\doglobal=\relax  \fi

%D The next obscure one is needed in the generic verbatim
%D environment. When we end up with more of these, it's time
%D to load the module \type{syst-gen}.

\ifnocontextobject \doifincsnameelse \do

  \def\dodoifincsnameelse#1#2%
    {\def\dododoifincsnameelse##1#1##2##3\war%
       {\csname\if##2@iffalse\else iftrue\fi\endcsname}%
     \expandafter\dododoifincsnameelse#2#1@@\war}

  \long\def\doifincsnameelse#1#2#3#4%
    {\edef\@@instring{#1}%
     \expandafter\dodoifincsnameelse\expandafter{\@@instring}{#2}%
       #3%
     \else
       #4%
     \fi}

\fi

%D \macros
%D   {dostepwiserecurse}
%D 
%D The next loop macro is a real weak one, and does not offer 
%D the full \CONTEXT\ functionality, let alone nesting, but 
%D for simple purposes, its behaviour is acceptable.  

\newcount\recursecounter

\def\dostepwiserecurse#1#2#3#4% very weak and rubishly version 
  {\ifnum#2<#1\relax\else\dodostepwiserecurse{#1}{#2}{#3}{#4}\fi}

\def\dodostepwiserecurse#1#2#3#4% very weak and rubishly version 
  {\recursecounter=#1\relax
   \loop 
     \edef\recurselevel{\the\recursecounter}%
     #4\relax
   \ifnum\recursecounter<#2\relax
     \advance\recursecounter by #3\relax
   \repeat}

%D \macros
%D   {twodigitrounding}
%D
%D We don't support rounding outside \CONTEXT. Sorry. 

\def\twodigitrounding#1{#1}

%D That's it. Please forget this junk and take a look at how
%D it should be done.

\protect

\endinput
