%D \module %D [ file=supp-mis, %D version=1995.10.10, %D title=\CONTEXT\ Support Macros, %D subtitle=Missing, %D author=J. Hagen, %D date=\huidigedatum, %D copyright=J. Hagen / \PRAGMA] % % This module is part of \CONTEXT, a general purpose, % parameter driven, macro package programmed in \TEX. This % module may only be distributed as part of \CONTEXT. %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. %D The next calls prevent reloading or, what's even worse, %D overloading of already defined macros and registers. We do %D so because some definitions are substitutes. Just to be %D sure we test on two macros. \ifx \undefined \writestatus \let\next=\relax \else \ifx \undefined \unprotect \let\next=\relax \else \let\next=\endinput \fi \fi \next %D \macros %D {writestatus} %D {} %D %D We start each module with a message. Normally the output is %D formatted, but here we keep things simple. \def\writestatus#1#2% {\immediate\write16{#1 : #2}} %D Lets see if it works. \writestatus{loading}{Context Support Macros / Missing} %D \macros %D {protect,unprotect} %D {} %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. \ifx \undefined \protect \let\protect=\relax \fi \def\unprotect% {\catcode`@=11 \catcode`!=11 \catcode`?=11 \let\normalprotect=\protect \edef\protect% {\catcode`@=\the\catcode`@\relax \catcode`!=\the\catcode`!\relax \catcode`?=\the\catcode`?\relax \let\protect=\normalprotect}} %D We start using this one it at once. \unprotect %D \macros %D {scratch...,if...,next...} %D {} %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. %D %D These 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} \def\ifnocontextobject#1\do% {\ifx#1\undefined \let\next=\definecontextobject \else \writestatus{system}{beware of conflicting \string#1}% \let\next=\gobblecontextobject \fi \next} \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 \scratchread \fi \ifnocontextobject \nextbox \do \newbox \nextbox \fi \ifnocontextobject \nextdepth \do \newdimen \nextdepth \fi \ifnocontextobject \ifCONTEXTtrue \do \newif\ifCONTEXT \fi \ifnocontextobject \ifdonetrue \do \newif\ifdone \fi \ifnocontextobject \ifeightbitcharacters \do \newif\ifeightbitcharacters \fi %D \macros %D {@@...} %D {} %D %D We use symbolic name for \CATCODES. Thee 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 \@@letter \do \chardef\@@letter = 11 \fi \ifnocontextobject \@@other \do \chardef\@@other = 12 \fi \ifnocontextobject \@@active \do \chardef\@@active = 13 \fi %D \macros %D {everyline,EveryLine,EveryPar} %D {} %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 %D We reserve ourselves some scratch strings (i.e. macros). \ifnocontextobject \!!stringa \do \def\!!stringa {} \fi \ifnocontextobject \!!stringb \do \def\!!stringb {} \fi \ifnocontextobject \!!stringc \do \def\!!stringc {} \fi \ifnocontextobject \!!stringd \do \def\!!stringd {} \fi %D \macros %D {!!...} %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 %D \macros %D {smashbox} %D {} %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 %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 That's it. Please forget this junk and take a look at how %D it should be done. \protect