catc-ini.mkxl /size: 13 Kb    last modification: 2024-01-16 09:02
1%D \module
2%D   [       file=catc-ini,
3%D        version=2006.09.18,
4%D          title=\CONTEXT\ System Macros,
5%D       subtitle=Catcode Handling,
6%D         author=Hans Hagen,
7%D           date=\currentdate,
8%D      copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
9%C
10%C This module is part of the \CONTEXT\ macro||package and is
11%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
12%C details.
13
14\registerctxluafile{catc-ini}{autosuffix}
15
16\unprotect
17
18%D A long standing wish has been the availability of catcode arrays. Because
19%D traditional \TEX\ does not provide this we implement a fake method in the \MKII\
20%D file. There is some overlap in code with \MKII\ but we take that for granted.
21%D Also, in \MKIV\ less active characters are used.
22
23% \begingroup
24%     \letcharcode\newlineasciicode\relax \xdef\outputnewlinechar{\tocharacter\newlineasciicode}
25% \endgroup
26
27% \endlinechar = \endoflineasciicode % appended to input lines
28% \newlinechar = \newlineasciicode   % can be used in write
29
30% rather special and used in writing to file: \let\par\outputnewlinechar
31
32% \permanent\protected\def\initializenewlinechar % operating system dependent
33%   {\begingroup
34%    \enforced\letcharcode\newlineasciicode\relax
35%    \newlinechar\newlineasciicode
36%    \xdef\outputnewlinechar{\tocharacter\newlineasciicode}%
37%    \endgroup}
38
39%D We predefine some prefixes ahead of syst-aux and mult-sys. We reserve 8 slots for
40%D catcodes. (This active mess probably needs an update some day.)
41
42% \installsystemnamespace{catcodelet} % let : \let
43% \installsystemnamespace{catcodedef} % def : \def
44% \installsystemnamespace{catcodeued} % ued : \protected\def
45% \installsystemnamespace{catcodeget} %       \meaning
46
47\installsystemnamespace{catcodetablet}
48\installsystemnamespace{catcodetablen}
49
50\newinteger\c_syst_catcodes_n \c_syst_catcodes_n\zerocount % 0 = signal, so advance before allocate
51
52%newinteger\c_syst_catcodes_a
53%newinteger\c_syst_catcodes_b
54%newinteger\c_syst_catcodes_c
55
56\permanent\protected\def\newcatcodetable#1% we could move the cctdefcounter to lua
57  {\global\advanceby\c_syst_catcodes_n\plusone
58   \gdefcsname\??catcodetablen\the\c_syst_catcodes_n\endcsname{\string#1}% logging
59   \immutable\integerdef#1\c_syst_catcodes_n
60   \ctxlua{catcodes.register("\expandafter\gobbleoneargument\string#1",\number#1)}}
61
62\newtoks\everysetdefaultcatcodes
63
64\everysetdefaultcatcodes % this might get dropped
65  {\catcode\backslashasciicode\othercatcode
66   \catcode\endoflineasciicode\othercatcode
67   \catcode\spaceasciicode    \othercatcode
68   \catcode\commentasciicode  \othercatcode
69   \catcode\delasciicode      \othercatcode}
70
71\permanent\protected\def\startcatcodetable#1#2\stopcatcodetable
72  {\begingroup
73   \catcodetable\inicatcodes
74   \expand\everysetdefaultcatcodes
75   #2%
76   \savecatcodetable#1\relax
77   \endgroup}
78
79\permanent\let\stopcatcodetable\relax
80
81\permanent\protected\def\startextendcatcodetable#1#2\stopextendcatcodetable
82  {\begingroup
83   \catcodetable#1\relax
84   \globaldefs\plusone   % a bit hackish
85   #2%
86   \globaldefs\zerocount
87   \endgroup}
88
89% doesn't work these tables are global anyway
90%
91% \permanent\protected\def\startextendcatcodetable#1#2\stopextendcatcodetable
92%   {\begingroup
93%    \c_syst_catcodes_n\catcodetable
94%    \catcodetable#1\relax
95%    #2%
96%    \catcodetable\c_syst_catcodes_n
97%    \endgroup}
98
99\permanent\let\stopextendcatcodetable\relax
100
101\permanent\protected\def\permitcircumflexescape % to be used grouped
102  {\catcode\circumflexasciicode\superscriptcatcode}
103
104\aliased\let\permitcaretescape\permitcircumflexescape
105
106\newconstant\defaultcatcodetable
107
108%D The next command can be defined in a cleaner way in the MkIV way but we want
109%D to have a fast one with a minimal chance for interference. Do we still need
110%D this complex mechanism? Probably not. Future versions of \MKIV\ might only use
111%D active characters for very special cases. Older files demonstrate this old
112%D hackery tilde abuse.
113
114% %D Once a catcode is assigned, the next assignments will happen faster. However,
115% %D redefinitions probably happen seldom so it's sort of overkill. We also need to
116% %D take care of the initial (shared between catcode regimes) binding.
117%
118% \permanent\protected\def\letcatcodecommand{\afterassignment\syst_catcodes_let_a\c_syst_catcodes_a}
119% \permanent\protected\def\defcatcodecommand{\afterassignment\syst_catcodes_def_a\c_syst_catcodes_a} % obsolete
120% \permanent\protected\def\uedcatcodecommand{\afterassignment\syst_catcodes_ued_a\c_syst_catcodes_a} % obsolete
121%
122% \def\syst_catcodes_let_a{\afterassignment\syst_catcodes_let_b\c_syst_catcodes_b}
123% \def\syst_catcodes_def_a{\afterassignment\syst_catcodes_def_b\c_syst_catcodes_b}
124% \def\syst_catcodes_ued_a{\afterassignment\syst_catcodes_ued_b\c_syst_catcodes_b}
125%
126% % The two step definition is used because we need to fetch the third argument.
127%
128% \def\syst_catcodes_let_b % each time
129%   {\ifcsname\??catcodelet\the\c_syst_catcodes_a:\the\c_syst_catcodes_b\endcsname
130%      \expandafter\lastnamedcs
131%    \else
132%      \expandafter\syst_catcodes_let_c
133%    \fi}
134%
135% \def\syst_catcodes_def_b % each time
136%   {\ifcsname\??catcodedef\the\c_syst_catcodes_a:\the\c_syst_catcodes_b\endcsname
137%      \expandafter\lastnamedcs
138%    \else
139%      \expandafter\syst_catcodes_def_c
140%    \fi}
141%
142% \def\syst_catcodes_ued_b % each time
143%   {\ifcsname\??catcodeued\the\c_syst_catcodes_a:\the\c_syst_catcodes_b\endcsname
144%      \expandafter\lastnamedcs
145%    \else
146%      \expandafter\syst_catcodes_ued_c
147%    \fi}
148%
149% \def\syst_catcodes_let_c % only first time
150%   {\frozen\enforced\gdefcsname\??catcodelet\the\c_syst_catcodes_a:\the\c_syst_catcodes_b\expandafter\endcsname\expandafter
151%      {\expandafter\enforced\letcsname\??catcodeget\the\c_syst_catcodes_a:\the\c_syst_catcodes_b\endcsname}%
152%    \syst_catcodes_reinstate_unexpanded
153%    \csname\??catcodelet\the\c_syst_catcodes_a:\the\c_syst_catcodes_b\endcsname}
154%
155% \def\syst_catcodes_def_c % only first time (we could use \normalexpanded here)
156%   {\frozen\enforced\gdefcsname\??catcodedef\the\c_syst_catcodes_a:\the\c_syst_catcodes_b\expandafter\endcsname
157%      \expandafter##\expandafter1\expandafter
158%        {\expandafter\frozen\expandafter\enforced\defcsname\??catcodeget\the\c_syst_catcodes_a:\the\c_syst_catcodes_b\endcsname{##1}}%
159%    \syst_catcodes_reinstate_normal
160%    \csname\??catcodedef\the\c_syst_catcodes_a:\the\c_syst_catcodes_b\endcsname}
161%
162% \def\syst_catcodes_ued_c % only first time
163%   {\frozen\enforced\gdefcsname\??catcodeued\the\c_syst_catcodes_a:\the\c_syst_catcodes_b\expandafter\endcsname
164%      \expandafter##\expandafter1\expandafter
165%        {\expandafter\frozen\expandafter\enforced\expandafter\protected\defcsname\??catcodeget\the\c_syst_catcodes_a:\the\c_syst_catcodes_b\endcsname{##1}}%
166%    \syst_catcodes_reinstate_unexpanded
167%    \csname\??catcodeued\the\c_syst_catcodes_a:\the\c_syst_catcodes_b\endcsname}
168%
169% %D We can simplify this a bit (not that critical):
170%
171% \def\syst_catcodes_let_b
172%   {\afterassignment\syst_catcodes_let_c\let\m_syst_catcodes_temp}
173%
174% \def\syst_catcodes_let_c
175%   {\enforced\letcsname\??catcodeget\the\c_syst_catcodes_a:\the\c_syst_catcodes_b\endcsname\m_syst_catcodes_temp
176%    \protected\edef\m_syst_catcodes_temp{\noexpand\catcodecommand{\the\c_syst_catcodes_b}}%
177%    \letcharcode\c_syst_catcodes_b\m_syst_catcodes_temp}
178%
179% \def\syst_catcodes_let_c
180%   {\letcharcode\c_syst_catcodes_b\m_syst_catcodes_temp}
181%
182% % not that much gain:
183%
184% \def\syst_catcodes_let_c % only first time
185%   {\expandafter\integerdef\csname\??catcodelet\the\c_syst_catcodes_a:\the\c_syst_catcodes_b\endcsname\c_syst_catcodes_b
186%    \letcsname\??catcodeget\the\c_syst_catcodes_a:\the\c_syst_catcodes_b\endcsname\m_syst_catcodes_temp
187%    \protected\edef\m_syst_catcodes_temp{\noexpand\catcodecommand\csname\??catcodelet\the\c_syst_catcodes_a:\the\c_syst_catcodes_b\endcsname}%
188%    \letcharcode\c_syst_catcodes_b\m_syst_catcodes_temp}
189
190%D This can be used when a direct definition has been done and the selector has been
191%D lost. I really need to get rid of this ...
192
193% \permanent\def\reinstatecatcodecommand{\afterassignment\syst_catcodes_reinstate_normal\c_syst_catcodes_b}
194%
195% \let\m_syst_catcodes_temp\relax
196%
197% \def\syst_catcodes_reinstate_normal
198%   {\edef\m_syst_catcodes_temp{\noexpand\catcodecommand{\the\c_syst_catcodes_b}}%
199%    \letcharcode\c_syst_catcodes_b\m_syst_catcodes_temp}
200%
201% \def\syst_catcodes_reinstate_unexpanded
202%   {\protected\edef\m_syst_catcodes_temp{\noexpand\catcodecommand{\the\c_syst_catcodes_b}}%
203%    \letcharcode\c_syst_catcodes_b\m_syst_catcodes_temp}
204%
205% \permanent\def\catcodecommand#1%
206%   {\csname\??catcodeget\number
207%      \ifcsname\??catcodeget\number\currentcatcodetable:\number#1\endcsname
208%        \currentcatcodetable \else \defaultcatcodetable
209%      \fi
210%    :\number#1\endcsname}
211
212%D For now, will become just letcharcode:
213
214\permanent\protected\def\letcatcodecommand{\afterassignment\letcharcode\scratchcounter}
215
216%D \startbuffer
217%D \def\foo{foo}
218%D \start
219%D   \pushactivechar    |   \letcharcode124 \foo test||test\par
220%D   \popactivechar     |                        test||test\par
221%D \stop
222%D \start
223%D   \pushactivecharcode124 \letcharcode124 \foo test||test\par
224%D   \popactivecharcode 124                      test||test\par
225%D \stop
226%D \stopbuffer
227%D
228%D \typebuffer \getbuffer
229
230\permanent\protected\def\pushactivechar#1%
231  {\expandafter\let\expandafter\m_active\csname\csactive#1\endcsname
232  %\expandafter\let\expandafter\m_active\csname\tocharacter"FFFF\tocharacter\expandafter`\string#1\endcsname
233   \pushmacro\m_active}
234
235\permanent\protected\def\popactivechar#1%
236  {\popmacro\m_active
237  %\letcsname\tocharacter"FFFF\tocharacter\expandafter`\string#1\endcsname\m_active
238   \letcsname\csactive#1\endcsname\m_active}
239
240\mutable\integerdef\c_active_char_code\zerocount
241
242\permanent\protected\def\pushactivecharcode{\afterassignment\syst_active_push\integerdef\c_active_char_code}
243\permanent\protected\def\popactivecharcode {\afterassignment\syst_active_pop \integerdef\c_active_char_code}
244
245\permanent\protected\def\syst_active_push
246  {\expandafter\let\expandafter\m_active\csname\csactive\tocharacter\c_active_char_code\endcsname
247  %\expandafter\let\expandafter\m_active\csname\tocharacter"FFFF\tocharacter\c_active_char_code\endcsname
248   \pushmacro\m_active}
249
250\permanent\protected\def\syst_active_pop
251  {\popmacro\m_active
252  %\letcsname\tocharacter"FFFF\tocharacter\c_active_char_code\endcsname\m_active
253   \letcsname\csactive\tocharacter\c_active_char_code\endcsname\m_active}
254
255%D \macros
256%D   {restorecatcodes,pushcatcodetable,popcatcodetable}
257%D
258%D We're not finished dealing \CATCODES\ yet. In \CONTEXT\ we use only one auxiliary
259%D file, which deals with tables of contents, registers, two pass tracking,
260%D references etc. This file, as well as files concerning graphics, is processed
261%D when needed, which can be in the mid of typesetting verbatim. However, when
262%D reading in data in verbatim mode, we should temporary restore the normal
263%D \CATCODES, and that's exactly what the next macros do. Saving the catcodes can be
264%D disabled by saying \type {\localcatcodestrue}. In \MKIV\ instead we can push and
265%D pop catcode tables and as we keep track of used tables users seldom need to deal
266%D with this themselves.
267
268\newinteger\c_syst_catcodes_level
269
270\permanent\protected\def\pushcatcodetable
271  {\advanceby\c_syst_catcodes_level\plusone
272   \syst_catcodes_trace_push
273   \expandafter\integerdef\csname\??catcodetablet\the\c_syst_catcodes_level\endcsname\currentcatcodetable}
274
275\permanent\protected\def\popcatcodetable
276  {\ifcase\c_syst_catcodes_level
277     \syst_catcodes_trace_nesting_error
278   \else
279     \catcodetable\csname\??catcodetablet\the\c_syst_catcodes_level\endcsname
280     \syst_catcodes_trace_pop
281     \advanceby\c_syst_catcodes_level\minusone
282   \fi}
283
284\protected\def\syst_catcodes_trace_nesting_error
285  {\immediate\write\statuswrite{}%
286   \immediate\write\statuswrite{Fatal error: catcode push/pop mismatch. Fix this! (restore level: \the\c_syst_catcodes_level)}\wait\end
287   \immediate\write\statuswrite{}}
288
289\permanent\protected\def\restorecatcodes % takes previous level
290  {\ifnum\c_syst_catcodes_level>\plusone
291     \catcodetable\csname\??catcodetablet\the\numexpr\c_syst_catcodes_level-1\relax\endcsname
292   \fi}
293
294\permanent\protected\def\setcatcodetable#1%
295  {\catcodetable#1%
296   \syst_catcodes_trace_set}
297
298%D Handy for debugging (not that we ever use(d) it):
299%D
300%D \starttyping
301%D \tracecatcodetables
302%D \stoptyping
303
304\permanent\protected\def\tracecatcodetables
305  {\def\syst_catcodes_trace_set {\syst_catcodes_trace{set  \catcodetablename\space                                at \the\c_syst_catcodes_level}}%
306   \def\syst_catcodes_trace_push{\syst_catcodes_trace{push \catcodetablename\space from \syst_catcodes_prev\space at \the\c_syst_catcodes_level}}%
307   \def\syst_catcodes_trace_pop {\syst_catcodes_trace{pop  \catcodetablename\space to   \syst_catcodes_prev\space at \the\c_syst_catcodes_level}}}
308
309\def\syst_catcodes_trace#1{\immediate\write\statuswrite{[#1]}}
310
311\def\syst_catcodes_prev
312  {\ifnum\numexpr\c_syst_catcodes_level-1\relax>\zerocount
313     \csname\??catcodetablen\number\csname\??catcodetablet\the\numexpr\c_syst_catcodes_level-1\relax\endcsname\endcsname
314   \else
315     -%
316   \fi}
317
318\permanent\def\catcodetablename
319  {\ifnum\currentcatcodetable>\zerocount
320     \csname\??catcodetablen\number\currentcatcodetable\endcsname
321   \else
322     -%
323   \fi}
324
325\lettonothing\syst_catcodes_trace_set
326\lettonothing\syst_catcodes_trace_push
327\lettonothing\syst_catcodes_trace_pop
328
329% \tracecatcodetables
330
331\protect
332
333%D We still have to define these so let's do that now:
334
335\newcatcodetable \inicatcodes
336\initcatcodetable\inicatcodes
337
338\mutable\let\currentcatcodetable\catcodetable
339
340\endinput
341