catc-sym.mkiv / last modification: 2020-01-30 14:16
%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<E
.catcode `.> 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