catc-sym.mkii / last modification: 2020-01-30 14:15
%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.

% we now have loaded syst-* so we have all @@catcode constants

%D We want to have access to the raw alternatives of the
%D special characters. We use a \type {\xdef} instead of
%D \type {\let} because we need an expandable token in a
%D \type {\write}.

\bgroup

\catcode`B=\begingroupcatcode
\catcode`E=\endgroupcatcode
\catcode`.=\escapecatcode

.catcode `.{ 12 .xdef .letteropenbrace       B.string{E
.catcode `.} 12 .xdef .letterclosebrace      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

         .global .let .letterescape     .letterbackslash
         .global .let .letterbgroup     .letteropenbrace
         .global .let .letteregroup     .letterclosebrace
         .global .let .letterleftbrace  .letteropenbrace
         .global .let .letterrightbrace .letterclosebrace

.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.

\def\uncatcodespecials     {\setcatcodetable\nilcatcodes \uncatcodespacetokens}
\def\setnaturalcatcodes    {\setcatcodetable\nilcatcodes}
\def\setnormalcatcodes     {\setcatcodetable\ctxcatcodes} % maybe \texcatcodes
\def\uncatcodecharacters   {\setcatcodetable\nilcatcodes} % was fast version, gone now
\def\uncatcodeallcharacters{\setcatcodetable\nilcatcodes} % was slow one, with restore

\def\uncatcodespacetokens
  {\catcode\spaceasciicode    \spacecatcode
   \catcode\formfeedasciicode \ignorecatcode
   \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

\def\setverbosecscharacter#1%
  {\edef#1{\string#1}}

\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]

\long\def\rescan#1{\scantokens{#1\ignorespaces}}
\long\def\rescanwithsetup#1#2{\begingroup\directsetup{#1}\scantokens{#2\ignorespaces}\endgroup}

\ifx\scantextokens\undefined \else
  \long\def\rescan#1{\scantextokens{#1}}
  \long\def\rescanwithsetup#1#2{\begingroup\directsetup{#1}\scantextokens{#2}\endgroup}
\fi

\endinput