%D \module %D [ file=catc-sym, %D version=1997.01.03, % moved code %D title=\CONTEXT\ Catcode Macros, %D subtitle=Some Handy Constants, %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 We want to have access to the raw alternatives of the special characters. We %D use a \type {\xdef} instead of \type {\let} because we need an expandable token %D in a \type {\write}. \bgroup \catcode`B=\begingroupcatcode \catcode`E=\endgroupcatcode \catcode`.=\escapecatcode .catcode `.{ 12 .xdef .letterleftbrace B.string{E .catcode `.} 12 .xdef .letterrightbrace B.string}E .catcode `.& 12 .xdef .letterampersand B.string&E .catcode `.< 12 .xdef .letterless B.string 12 .xdef .lettermore B.string>E .catcode `.# 12 .xdef .letterhash B.string#E .catcode `." 12 .xdef .letterdoublequote B.string"E .catcode `.' 12 .xdef .lettersinglequote B.string'E .catcode `.$ 12 .xdef .letterdollar B.string$E .catcode `.% 12 .xdef .letterpercent B.string%E .catcode `.^ 12 .xdef .letterhat B.string^E .catcode `._ 12 .xdef .letterunderscore B.string_E .catcode `.| 12 .xdef .letterbar B.string|E .catcode `.~ 12 .xdef .lettertilde B.string~E .catcode `.\ 12 .xdef .letterbackslash B.string\E .catcode `./ 12 .xdef .letterslash B.string/E .catcode `.? 12 .xdef .letterquestionmark B.string?E .catcode `.! 12 .xdef .letterexclamationmark B.string!E .catcode `.@ 12 .xdef .letterat B.string@E .catcode `.: 12 .xdef .lettercolon B.string:E .catcode `.( 12 .xdef .letterleftparenthesis B.string(E .catcode `.) 12 .xdef .letterrightparenthesis B.string)E .catcode `.[ 12 .xdef .letterleftbracket B.string[E .catcode `.] 12 .xdef .letterrightbracket B.string]E .global .let .letterescape .letterbackslash .global .let .letterbgroup .letterleftbrace .global .let .letteregroup .letterrightbrace .global .let .letteropenbrace .letterleftbrace .global .let .letterclosebrace .letterrightbrace .egroup \bgroup \catcode`_=\lettercatcode %xdef\_n_u_l_{\expandafter\string\Uchar1} % nul(l) %xdef\_s_o_h_{\expandafter\string\Uchar1} % start of header ^^^^0001 \xdef\_s_t_x_{\expandafter\string\Uchar2} % start of text ^^^^0002 \xdef\_e_t_x_{\expandafter\string\Uchar3} % end of text ^^^^0003 \xdef\_e_o_t_{\expandafter\string\Uchar4} % end of transmission ^^^^0004 %xdef\_e_n_q_{\expandafter\string\Uchar5} % enquiry %xdef\_a_c_k_{\expandafter\string\Uchar6} % aknowledgement \egroup %D \macros %D {uncatcodespecials,setnaturalcatcodes,setnormalcatcodes, %D uncatcodecharacters,uncatcodeallcharacters, %D uncatcodespacetokens} %D %D The following macros are more or less replaced by switching %D to a catcode table (which we simulate in \MKII) but we keep %D them for convenience and compatibility. Some old engine code %D has been removed. \normalprotected\def\uncatcodespecials {\setcatcodetable\nilcatcodes \uncatcodespacetokens} \normalprotected\def\setnaturalcatcodes {\setcatcodetable\nilcatcodes} \normalprotected\def\setnormalcatcodes {\setcatcodetable\ctxcatcodes} % maybe \texcatcodes \normalprotected\def\uncatcodecharacters {\setcatcodetable\nilcatcodes} % was fast version, gone now \normalprotected\def\uncatcodeallcharacters{\setcatcodetable\nilcatcodes} % was slow one, with restore \normalprotected\def\uncatcodespacetokens {\catcode\spaceasciicode \spacecatcode \catcode\tabasciicode \spacecatcode \catcode\formfeedasciicode \endoflinecatcode \catcode\endoflineasciicode\endoflinecatcode \catcode\delasciicode \ignorecatcode} %D \macros %D {setverbosecharacter,setverbosecscharacters} %D %D Next follows a definition that lets some shortcuts expand to %D themselves. This macro is meant for \POSTSCRIPT\ and \PDF\ %D code passed on to the backend. \newtoks\everyverbosechacters \normalprotected\def\setverbosecscharacter#1% {\edef#1{\string#1}} \normalprotected\def\setverbosecscharacters {\the\everyverbosechacters} \bgroup % if used often we can move the code inline \catcode\barasciicode \activecatcode \catcode\tildeasciicode\activecatcode \global \everyverbosechacters = {\setverbosecscharacter |\setverbosecscharacter ~% context specific \setverbosecscharacter\|\setverbosecscharacter\~% \setverbosecscharacter\:\setverbosecscharacter\;% \setverbosecscharacter\+\setverbosecscharacter\-% \setverbosecscharacter\[\setverbosecscharacter\]% \setverbosecscharacter\.\setverbosecscharacter\\% \setverbosecscharacter\)\setverbosecscharacter\(% \setverbosecscharacter\0\setverbosecscharacter\1% \setverbosecscharacter\2\setverbosecscharacter\3% \setverbosecscharacter\4\setverbosecscharacter\5% \setverbosecscharacter\6\setverbosecscharacter\7% \setverbosecscharacter\8\setverbosecscharacter\9% \setverbosecscharacter\n\setverbosecscharacter\s% \setverbosecscharacter\/} \egroup %D (Inspired by a discussion on the \CONTEXT\ mailing list) %D %D In \TEX\ each character can have one of 16 catcodes. This way the %D backslash, dollar, ampersand, hash and some more characters get %D their special meaning. If you want to process tokens under a %D certain catcode regime, passing arguments can interfere badly. %D %D \startbuffer[a] %D \def\whatever#1{[#1]} %D \whatever{whatever \type {\whatever{you want}} $or$ not!} %D \stopbuffer %D %D \typebuffer[a] %D %D Here we pass an argument to \type {\whatever} but part of that %D argument is to be processed under a different catcode regime, i.e.\ %D all characters that need to be typeset verbatim need to get %D the catcode that makes it a letter. This is what we get when we typeset %D the text verbatim: %D %D \starttyping %D whatever \type {\whatever{you want}} $or$ not! %D \stoptyping %D %D However, when passed to \type {\whatever} we get: %D %D \getbuffer[a] %D %D In \ETEX\ one can use \type {\scantokens} to circumvent this problem. %D %D \startbuffer[b] %D \def\rescan#1{\scantokens{#1}} %D \def\whatever#1{[\rescan{#1}]} %D \whatever{whatever \type {\whatever{you want}} $or$ not!} %D \stopbuffer %D %D \getbuffer[b] \typebuffer[b] %D %D This time the \type {\whatever} call gives: %D %D \getbuffer[b] %D %D In this example, two spaces have crept in. The first one, after the %D macro name, is inserted by \TEX\ and cannot be avoided. The last space %D is inserted by \type {\scantokens}, and is the consequence of the fact %D that this macro mimics reading from a file. You can avoid the last %D space by a slightly different definition: %D %D \startbuffer[c] %D \def\rescan#1{\scantokens{#1\ignorespaces}} %D \def\whatever#1{[\rescan{#1}]} %D \whatever{whatever \type {\whatever{you want}} $or$ not!} %D \stopbuffer %D %D \typebuffer[c] %D %D Unfortunately we still keep the first space, but at least it's better than %D a failure: %D %D \getbuffer[c] \def\rescan #1{\scantokens{#1\ignorespaces}} \def\rescanwithsetup#1#2{\begingroup\directsetup{#1}\scantokens{#2\ignorespaces}\endgroup} \ifx\scantextokens\undefined \else \def\rescan #1{\scantextokens{#1}} \def\rescanwithsetup#1#2{\begingroup\directsetup{#1}\scantextokens{#2}\endgroup} \fi \endinput