%D \module %D [ file=catc-ini, %D version=2006.09.18, %D title=\CONTEXT\ System Macros, %D subtitle=Catcode Handling, %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've split the functionality of syst-cat.* over more files %D now so that we can load more selectively. %D A long standing wish has been the availability of catcode %D arrays. Because traditional \TEX\ does ot provide this we %D implement a fake method in the Mark II file. \ifx\zerocount\undefined \chardef \zerocount= 0 \fi \ifx\plusone \undefined \chardef \plusone = 1 \fi \ifx\minusone \undefined \newcount\minusone \minusone =-1 \fi \chardef\escapecatcode = 0 \chardef\begingroupcatcode = 1 \chardef\endgroupcatcode = 2 \chardef\mathshiftcatcode = 3 \chardef\alignmentcatcode = 4 \chardef\endoflinecatcode = 5 \chardef\parametercatcode = 6 \chardef\superscriptcatcode = 7 \chardef\subscriptcatcode = 8 \chardef\ignorecatcode = 9 \chardef\spacecatcode = 10 \chardef\lettercatcode = 11 \chardef\othercatcode = 12 \chardef\other = 12 \chardef\activecatcode = 13 \chardef\active = 13 \chardef\commentcatcode = 14 \chardef\invalidcatcode = 15 \chardef\tabasciicode = 9 % ^^I \chardef\newlineasciicode = 10 % ^^J don't confuse this one with \endoflineasciicode \chardef\formfeedasciicode = 12 % ^^L \chardef\endoflineasciicode = 13 % ^^M somewhat messy but this can be the active \par \chardef\endoffileasciicode = 26 % ^^Z \chardef\spaceasciicode = 32 \chardef\hashasciicode = 35 \chardef\dollarasciicode = 36 \chardef\commentasciicode = 37 \chardef\ampersandasciicode = 38 \chardef\backslashasciicode = 92 % `\\ \chardef\circumflexasciicode = 94 \chardef\underscoreasciicode = 95 \chardef\leftbraceasciicode = 123 % `\{ \chardef\barasciicode = 124 % `\| \chardef\rightbraceasciicode = 125 % `\} \chardef\tildeasciicode = 126 % `\~ \chardef\delasciicode = 127 \newif \ifrecatcodeuppercharacters % only used in good old tex % \newcount\cctdefcounter \cctdefcounter\plusone % 0 = signal \newcount\cctdefcounter \cctdefcounter\zerocount % 0 = signal, so advance before allocate \newcount\cctcountera \newcount\cctcounterb \newcount\cctcounterc \def\newcatcodetable#1% {\global\advance\cctdefcounter\plusone \global\mathchardef#1\cctdefcounter \expandafter\xdef\csname @@ccn:\number\cctdefcounter\endcsname{\string#1}% logging \expandafter\newtoks\csname @@cct:\number\cctdefcounter\endcsname} \mathchardef\currentcatcodetable\zerocount \newtoks \setdefaultlowercatcodes \newtoks \setdefaultuppercatcodes \def\next#1% we don't have a proper loop defined yet {\edef\nextnext{#1{\the#1\catcode\the\cctcountera\space \ifnum\catcode\cctcountera=\lettercatcode \lettercatcode\else\othercatcode\fi}}% \nextnext\ifnum\cctcountera<\cctcounterb \advance\cctcountera\plusone \expandafter\next\expandafter#1\fi} \cctcountera 0 \cctcounterb 127 \next\setdefaultlowercatcodes \cctcountera 128 \cctcounterb 255 \next\setdefaultuppercatcodes \recatcodeuppercharactersfalse \def\catcodetable#1% {\mathchardef\currentcatcodetable#1% \the\setdefaultlowercatcodes \ifrecatcodeuppercharacters\the\setdefaultuppercatcodes\fi \the\csname @@cct:\number#1\endcsname} \long\def\startcatcodetable#1#2\stopcatcodetable {\global\csname @@cct:\number#1\endcsname{#2}} \long\def\startextendcatcodetable#1#2\stopextendcatcodetable {\global\csname @@cct:\number#1\endcsname\expandafter{\the\csname @@cct:\number#1\endcsname#2}} %D The next command can be defined in a cleaner way in the %D Mk IV file but we want to have a fast one with a minimal %D chance for interference. \chardef\activehackcode=`\~ %D Once a catcode is assigned, the next assignments will happen faster. % (expandable) let \def\letcatcodecommand {\afterassignment\letcatcodecommanda\cctcountera} \def\letcatcodecommanda{\afterassignment\letcatcodecommandb\cctcounterb} \def\letcatcodecommandb % each time {\ifcsname CCL:\number\cctcountera:\number\cctcounterb\endcsname \csname CCL:\number\cctcountera:\number\cctcounterb\expandafter\endcsname \else \expandafter\letcatcodecommandc \fi} \def\letcatcodecommandc % only first time {\expandafter\gdef\csname CCL:\number\cctcountera:\number\cctcounterb\expandafter\endcsname\expandafter {\expandafter\let\csname CCC:\number\cctcountera:\number\cctcounterb\endcsname}% \reinstatecatcodecommanda \csname CCL:\number\cctcountera:\number\cctcounterb\endcsname} % expandable def \def\defcatcodecommand {\afterassignment\defcatcodecommanda\cctcountera} \def\defcatcodecommanda{\afterassignment\defcatcodecommandb\cctcounterb} \def\defcatcodecommandb % each time {\ifcsname CCD:\number\cctcountera:\number\cctcounterb\endcsname \csname CCD:\number\cctcountera:\number\cctcounterb\expandafter\endcsname \else \expandafter\defcatcodecommandc \fi} \def\defcatcodecommandc % only first time {\expandafter\gdef\csname CCD:\number\cctcountera:\number\cctcounterb\expandafter\endcsname \expandafter##\expandafter1\expandafter {\expandafter\def\csname CCC:\number\cctcountera:\number\cctcounterb\endcsname{##1}}% \reinstatecatcodecommanda \csname CCD:\number\cctcountera:\number\cctcounterb\endcsname} % un expandable def (e.g. used for discretionaries) \def\uedcatcodecommand {\afterassignment\uedcatcodecommanda\cctcountera} \def\uedcatcodecommanda{\afterassignment\uedcatcodecommandb\cctcounterb} \def\uedcatcodecommandb % each time {\ifcsname CCU:\number\cctcountera:\number\cctcounterb\endcsname \csname CCU:\number\cctcountera:\number\cctcounterb\expandafter\endcsname \else \expandafter\uedcatcodecommandc \fi} \def\uedcatcodecommandc % only first time {\expandafter\gdef\csname CCU:\number\cctcountera:\number\cctcounterb\expandafter\endcsname \expandafter##\expandafter1\expandafter {\expandafter\unexpanded\expandafter\def\csname CCC:\number\cctcountera:\number\cctcounterb\endcsname{##1}}% \reinstatecatcodecommanda \csname CCU:\number\cctcountera:\number\cctcounterb\endcsname} \def\reinstatecatcodecommand{\afterassignment\reinstatecatcodecommanda\cctcounterb} \def\reinstatecatcodecommanda % can be used when a direct definition has been done {\bgroup % and the selector has been lost \uccode\activehackcode\cctcounterb \catcode\uccode\activehackcode\activecatcode \uppercase{\xdef~{\noexpand\catcodecommand{\number\cctcounterb}}}% \egroup} \chardef\defaultcatcodetable\zerocount \def\catcodecommand#1% {\csname CCC:\number \ifcsname CCC:\number\currentcatcodetable:\number#1\endcsname \currentcatcodetable \else \defaultcatcodetable \fi :\number#1\endcsname} %D \macros %D {restorecatcodes, %D beginrestorecatcodes,endrestorecatcodes} %D %D We're not finished dealing \CATCODES\ yet. In \CONTEXT\ we %D use only one auxiliary file, which deals with tables of %D contents, registers, two pass tracking, references etc. This %D file, as well as files concerning graphics, is processed when %D needed, which can be in the mid of typesetting verbatim. %D However, when reading in data in verbatim mode, we should %D temporary restore the normal \CATCODES, and that's exactly %D what the next macros do. Saving the catcodes can be %D disabled by saying \type{\localcatcodestrue}. \let\savedcatcodetable\relax \newcount\catcoderestorelevel \def\pushcatcodetable {\advance\catcoderestorelevel\plusone \tracepushcatcodetable \expandafter\mathchardef\csname scct:\number\catcoderestorelevel\endcsname\currentcatcodetable} \def\popcatcodetable {\ifcase\catcoderestorelevel \showcatcodenestingerror \else \expandafter\catcodetable\csname scct:\number\catcoderestorelevel\endcsname \tracepopcatcodetable \advance\catcoderestorelevel\minusone \fi} \def\showcatcodenestingerror % can be overloaded {\immediate\write16{}% \immediate\write16{Fatal error: catcode push/pop mismatch. Fix this!}\wait\end \immediate\write16{}} \def\restorecatcodes % takes previous level {\ifnum\catcoderestorelevel>\plusone \expandafter\catcodetable\csname scct:\number\numexpr\catcoderestorelevel-1\relax\endcsname \fi} \newtoks\everycatcodetable \def\setcatcodetable#1% {\catcodetable#1% \the\everycatcodetable \tracesetcatcodetable} \def\dotracecatcodetable#1{\immediate\write16{[#1]}} \def\tracecatcodetables {\def\tracesetcatcodetable {\dotracecatcodetable{set \catcodetablename\space at \number\catcoderestorelevel}}% \def\tracepushcatcodetable{\dotracecatcodetable{push \catcodetablename\space from \catcodetableprev\space at \number\catcoderestorelevel}}% \def\tracepopcatcodetable {\dotracecatcodetable{pop \catcodetablename\space to \catcodetableprev\space at \number\catcoderestorelevel}}} \def\catcodetableprev {\ifnum\numexpr\catcoderestorelevel-1\relax>\zerocount \csname @@ccn:\number\csname scct:\number\numexpr\catcoderestorelevel-1\relax\endcsname\endcsname \else -% \fi} \def\catcodetablename {\ifnum\currentcatcodetable>\zerocount \csname @@ccn:\number\currentcatcodetable\endcsname \else -% \fi} \ifx\empty\undefined \def\empty{} \fi \let\tracesetcatcodetable \empty \let\tracepushcatcodetable\empty \let\tracepopcatcodetable \empty \def\beginrestorecatcodes{\pushcatcodetable} \def\endrestorecatcodes {\popcatcodetable} %D Handy for debugging: % \tracecatcodetables \endinput