catc-ini.mkiv /size: 14 Kb    last modification: 2021-10-28 13:50
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%D We've split the functionality of syst-cat.* over more files
15%D now so that we can load more selectively.
16
17\registerctxluafile{catc-ini}{}
18
19\unprotect
20
21%D A long standing wish has been the availability of catcode arrays. Because
22%D traditional \TEX\ does not provide this we implement a fake method in the
23%D \MKII\ file. There is some overlap in code with \MKII\ but we take that
24%D for granted. Also, in \MKIV\ less active characters are used.
25
26% \protected\def\setnewconstantfromchar#1%
27%   {\expandafter\ifdefined\expandafter#1\expandafter
28%         \let\expandafter#1\expandafter\undefined\expandafter\fi\expandafter
29%         \newcount\expandafter#1\expandafter#1\the#1\relax}
30%
31% \protected\def\setnewconstantfromchar#1%
32%   {\begingroup
33%    \scratchcounter#1%
34%    \edef\!!stringa{\meaning#1}%
35%    \chardef#1\scratchcounter
36%    \edef\!!stringb{\meaning#1}%
37%    \normalexpanded{\endgroup
38%      \ifx\!!stringa\!!stringb
39%        \let#1\noexpand\undefined
40%        \newcount#1%
41%      \fi
42%      #1\the\scratchcounter\relax}}
43%
44% \protected\def\setnewconstantfromchar#1%
45%   {\begingroup
46%    \edef\!!stringa{\meaning#1}%
47%    \expandafter\chardef\expandafter#1\the#1%
48%    \edef\!!stringb{\meaning#1}%
49%    \normalexpanded{\endgroup
50%      \ifx\!!stringa\!!stringb
51%        \let#1\noexpand\undefined
52%        \newcount#1%
53%      \fi
54%      #1\the#1\relax}}
55%
56% \protected\def\setnewconstantfromchar#1%
57%   {\scratchcounter#1\let#1\undefined\newcount#1#1\scratchcounter}
58
59\def\promote#1{\scratchcounter#1\let#1\undefined\newcount#1#1\scratchcounter}
60
61\promote\escapecatcode
62\promote\begingroupcatcode
63\promote\endgroupcatcode
64\promote\mathshiftcatcode
65\promote\alignmentcatcode
66\promote\endoflinecatcode
67\promote\parametercatcode
68\promote\superscriptcatcode
69\promote\subscriptcatcode
70\promote\ignorecatcode
71\promote\spacecatcode
72\promote\lettercatcode
73\promote\othercatcode
74\promote\activecatcode
75\promote\commentcatcode
76\promote\invalidcatcode
77
78\promote\tabasciicode
79\promote\newlineasciicode
80\promote\formfeedasciicode
81\promote\endoflineasciicode
82\promote\endoffileasciicode
83\promote\spaceasciicode
84\promote\exclamationmarkasciicode
85\promote\doublequoteasciicode
86\promote\hashasciicode
87\promote\dollarasciicode
88\promote\commentasciicode
89\promote\ampersandasciicode
90\promote\singlequoteasciicode
91\promote\primeasciicode
92\promote\hyphenasciicode
93\promote\forwardslashasciicode
94\promote\colonasciicode
95\promote\lessthanasciicode
96\promote\morethanasciicode
97\promote\questionmarkasciicode
98\promote\atsignasciicode
99\promote\backslashasciicode
100\promote\circumflexasciicode
101\promote\underscoreasciicode
102\promote\leftbraceasciicode
103\promote\barasciicode
104\promote\rightbraceasciicode
105\promote\tildeasciicode
106\promote\delasciicode
107
108\let\promote\undefined
109
110% \begingroup
111%
112%     \catcode\tabasciicode      \activecatcode
113%     \catcode\formfeedasciicode \activecatcode
114%     \catcode\endoflineasciicode\activecatcode
115%
116%     \letcharcode\tabasciicode      \relax
117%     \letcharcode\newlineasciicode  \relax
118%     \letcharcode\formfeedasciicode \relax
119%     \letcharcode\endoflineasciicode\relax
120%
121%     \xdef\activetabtoken      {\Uchar\tabasciicode      } % \gdef\activetabtoken      {^^I}
122%     \xdef\outputnewlinechar   {\Uchar\newlineasciicode  } % \gdef\outputnewlinechar   {^^J}
123%     \xdef\activeformfeedtoken {\Uchar\formfeedasciicode } % \gdef\activeformfeedtoken {^^L}
124%     \xdef\activeendoflinetoken{\Uchar\endoflineasciicode} % \gdef\activeendoflinetoken{^^M}
125%
126% \endgroup
127
128\begingroup
129    \letcharcode\newlineasciicode\relax \xdef\outputnewlinechar{\Uchar\newlineasciicode}
130\endgroup
131
132% \endlinechar = \endoflineasciicode % appended to input lines
133% \newlinechar = \newlineasciicode   % can be used in write
134
135% rather special and used in writing to file: \let\par\outputnewlinechar
136
137% \protected\def\initializenewlinechar % operating system dependent
138%   {\begingroup
139%    \newlinechar\newlineasciicode
140%    \xdef\outputnewlinechar{^^J}%
141%    \endgroup}
142
143\protected\def\initializenewlinechar % operating system dependent
144  {\begingroup
145   \letcharcode\newlineasciicode\relax
146   \newlinechar\newlineasciicode
147   \xdef\outputnewlinechar{\Uchar\newlineasciicode}%
148   \endgroup}
149
150%D We predefine some prefixes ahead of syst-aux and mult-sys.
151
152% We reserve 8 slots for catcodes.
153%
154% \def\??catcodelet   {1>>} % let : \let
155% \def\??catcodedef   {2>>} % def : \def
156% \def\??catcodeued   {3>>} % ued : \protected\def
157% \def\??catcodeget   {4>>} %       \meaning
158%
159% \def\??catcodetablet{5>>}
160% \def\??catcodetablen{6>>}
161
162\installsystemnamespace {catcodelet} % let : \let
163\installsystemnamespace {catcodedef} % def : \def
164\installsystemnamespace {catcodeued} % ued : \protected\def
165\installsystemnamespace {catcodeget} %       \meaning
166
167\installsystemnamespace {catcodetablet}
168\installsystemnamespace {catcodetablen}
169
170\newcount\c_syst_catcodes_n \c_syst_catcodes_n\zerocount % 0 = signal, so advance before allocate
171\newcount\c_syst_catcodes_a
172\newcount\c_syst_catcodes_b
173\newcount\c_syst_catcodes_c
174
175\protected\def\newcatcodetable#1% we could move the cctdefcounter to lua
176  {\global\advance\c_syst_catcodes_n\plusone
177   \expandafter\xdef\csname\??catcodetablen\number\c_syst_catcodes_n\endcsname{\string#1}% logging
178   \newconstant#1%
179   #1\c_syst_catcodes_n
180   \ctxlua{catcodes.register("\expandafter\gobbleoneargument\string#1",\number#1)}}
181
182\newtoks \everysetdefaultcatcodes
183
184\everysetdefaultcatcodes % this might get dropped
185  {\catcode\backslashasciicode\othercatcode
186   \catcode\endoflineasciicode\othercatcode
187   \catcode\spaceasciicode    \othercatcode
188   \catcode\commentasciicode  \othercatcode
189   \catcode\delasciicode      \othercatcode}
190
191\protected\def\startcatcodetable#1#2\stopcatcodetable
192  {\begingroup
193   \catcodetable\inicatcodes
194   \the\everysetdefaultcatcodes
195   #2%
196   \savecatcodetable#1\relax
197   \endgroup}
198
199\let\stopcatcodetable\relax
200
201\protected\def\startextendcatcodetable#1#2\stopextendcatcodetable
202  {\begingroup
203   \catcodetable#1\relax
204   \globaldefs\plusone
205   #2%
206   \globaldefs\zerocount
207   \endgroup}
208
209\let\stopextendcatcodetable\relax
210
211\protected\def\permitcircumflexescape % to be used grouped
212  {\catcode\circumflexasciicode\superscriptcatcode}
213
214\let\permitcaretescape\permitcircumflexescape
215
216% ==
217%
218% \protected\def\startextendcatcodetable#1#2\stopextendcatcodetable
219%   {\bgroup
220%    \scratchcounter\the\catcodetable
221%    \catcodetable #1 #2
222%    \catcodetable\scratchcounter
223%    \egroup}
224
225%D The next command can be defined in a cleaner way in the MkIV way but we want
226%D to have a fast one with a minimal chance for interference. Do we still need
227%D this complex mechanism? Probably not. Future versions of \MKIV\ might only use
228%D active characters for very special cases.
229
230\setnewconstant\c_syst_catcodes_hack\tildeasciicode
231
232%D Once a catcode is assigned, the next assignments will happen faster. However,
233%D redefinitions probably happen seldom so it's sort of overkill.
234
235\def\letcatcodecommand{\afterassignment\syst_catcodes_let_a\c_syst_catcodes_a}
236\def\defcatcodecommand{\afterassignment\syst_catcodes_def_a\c_syst_catcodes_a}
237\def\uedcatcodecommand{\afterassignment\syst_catcodes_ued_a\c_syst_catcodes_a}
238
239\def\syst_catcodes_let_a{\afterassignment\syst_catcodes_let_b\c_syst_catcodes_b}
240\def\syst_catcodes_def_a{\afterassignment\syst_catcodes_def_b\c_syst_catcodes_b}
241\def\syst_catcodes_ued_a{\afterassignment\syst_catcodes_ued_b\c_syst_catcodes_b}
242
243\def\syst_catcodes_let_b % each time
244  {\ifcsname\??catcodelet\number\c_syst_catcodes_a:\number\c_syst_catcodes_b\endcsname
245     \expandafter\lastnamedcs
246   \else
247     \expandafter\syst_catcodes_let_c
248   \fi}
249
250\def\syst_catcodes_def_b % each time
251  {\ifcsname\??catcodedef\number\c_syst_catcodes_a:\number\c_syst_catcodes_b\endcsname
252     \expandafter\lastnamedcs
253   \else
254     \expandafter\syst_catcodes_def_c
255   \fi}
256
257\def\syst_catcodes_ued_b % each time
258  {\ifcsname\??catcodeued\number\c_syst_catcodes_a:\number\c_syst_catcodes_b\endcsname
259     \expandafter\lastnamedcs
260   \else
261     \expandafter\syst_catcodes_ued_c
262   \fi}
263
264\def\syst_catcodes_let_c % only first time
265  {\expandafter\gdef\csname\??catcodelet\number\c_syst_catcodes_a:\number\c_syst_catcodes_b\expandafter\endcsname\expandafter
266     {\expandafter\let\csname\??catcodeget\number\c_syst_catcodes_a:\number\c_syst_catcodes_b\endcsname}%
267   \syst_catcodes_reinstate_unexpanded
268   \csname\??catcodelet\number\c_syst_catcodes_a:\number\c_syst_catcodes_b\endcsname}
269
270\def\syst_catcodes_def_c % only first time (we could use \normalexpanded here)
271  {\expandafter\gdef\csname\??catcodedef\number\c_syst_catcodes_a:\number\c_syst_catcodes_b\expandafter\endcsname
272     \expandafter##\expandafter1\expandafter
273       {\expandafter\def\csname\??catcodeget\number\c_syst_catcodes_a:\number\c_syst_catcodes_b\endcsname{##1}}%
274   \syst_catcodes_reinstate_normal
275   \csname\??catcodedef\number\c_syst_catcodes_a:\number\c_syst_catcodes_b\endcsname}
276
277\def\syst_catcodes_ued_c % only first time
278  {\expandafter\gdef\csname\??catcodeued\number\c_syst_catcodes_a:\number\c_syst_catcodes_b\expandafter\endcsname
279     \expandafter##\expandafter1\expandafter
280       {\expandafter\protected\expandafter\def\csname\??catcodeget\number\c_syst_catcodes_a:\number\c_syst_catcodes_b\endcsname{##1}}%
281   \syst_catcodes_reinstate_unexpanded
282   \csname\??catcodeued\number\c_syst_catcodes_a:\number\c_syst_catcodes_b\endcsname}
283
284\def\reinstatecatcodecommand{\afterassignment\syst_catcodes_reinstate_normal\c_syst_catcodes_b}
285
286\def\syst_catcodes_reinstate_normal % can be used when a direct definition has been done
287  {\begingroup                      % and the selector has been lost
288   \uccode\c_syst_catcodes_hack\c_syst_catcodes_b
289   \catcode\uccode\c_syst_catcodes_hack\activecatcode
290   \uppercase{\xdef~{\noexpand\catcodecommand{\number\c_syst_catcodes_b}}}%
291   \endgroup}
292
293\def\syst_catcodes_reinstate_unexpanded % can be used when a direct definition has been done
294  {\begingroup                          % and the selector has been lost
295   \uccode\c_syst_catcodes_hack\c_syst_catcodes_b
296   \catcode\uccode\c_syst_catcodes_hack\activecatcode
297   \uppercase{\protected\xdef~{\noexpand\catcodecommand{\number\c_syst_catcodes_b}}}%
298   \endgroup}
299
300%D This can be used when a direct definition has been done and the selector has been
301%D lost.
302
303% problem: \next needs to be unique (as it gets bound)
304%
305% \def\syst_catcodes_reinstate_normal
306%   {\begingroup
307%    \edef\next{\noexpand\catcodecommand{\number\c_syst_catcodes_b}}%
308%    \global\letcharcode\c_syst_catcodes_b\next
309%    \endgroup}
310%
311% \def\syst_catcodes_reinstate_unexpanded
312%   {\begingroup
313%    \protected\edef\next{\noexpand\catcodecommand{\number\c_syst_catcodes_b}}%
314%    \global\letcharcode\c_syst_catcodes_b\next
315%    \endgroup}
316
317\newconstant\defaultcatcodetable
318
319\def\catcodecommand#1%
320  {\csname\??catcodeget\number
321     \ifcsname\??catcodeget\number\currentcatcodetable:\number#1\endcsname
322       \currentcatcodetable \else \defaultcatcodetable
323     \fi
324   :\number#1\endcsname}
325
326%D \macros
327%D   {restorecatcodes,pushcatcodetable,popcatcodetable}
328%D
329%D We're not finished dealing \CATCODES\ yet. In \CONTEXT\ we use only one auxiliary
330%D file, which deals with tables of contents, registers, two pass tracking, references
331%D etc. This file, as well as files concerning graphics, is processed when needed,
332%D which can be in the mid of typesetting verbatim. However, when reading in data in
333%D verbatim mode, we should temporary restore the normal \CATCODES, and that's exactly
334%D what the next macros do. Saving the catcodes can be disabled by saying \type
335%D {\localcatcodestrue}. In \MKIV\ instead we can push and pop catcode tables and as
336%D we keep track of used tables users seldom need to deal with this themselves.
337
338\newcount\c_syst_catcodes_level
339
340\protected\def\pushcatcodetable
341  {\advance\c_syst_catcodes_level\plusone
342   \syst_catcodes_trace_push
343   \expandafter\chardef\csname\??catcodetablet\number\c_syst_catcodes_level\endcsname\currentcatcodetable}
344
345\protected\def\popcatcodetable
346  {\ifcase\c_syst_catcodes_level
347     \syst_catcodes_trace_nesting_error
348   \else
349     \expandafter\catcodetable\csname\??catcodetablet\number\c_syst_catcodes_level\endcsname
350     \syst_catcodes_trace_pop
351     \advance\c_syst_catcodes_level\minusone
352   \fi}
353
354\protected\def\syst_catcodes_trace_nesting_error
355  {\immediate\write\statuswrite{}%
356   \immediate\write\statuswrite{Fatal error: catcode push/pop mismatch. Fix this! (restore level: \number\c_syst_catcodes_level)}\wait\end
357   \immediate\write\statuswrite{}}
358
359\protected\def\restorecatcodes % takes previous level
360  {\ifnum\c_syst_catcodes_level>\plusone
361     \expandafter\catcodetable\csname\??catcodetablet\number\numexpr\c_syst_catcodes_level-1\relax\endcsname
362   \fi}
363
364% \newtoks\everycatcodetable
365
366\protected\def\setcatcodetable#1%
367  {\catcodetable#1%
368%  \the\everycatcodetable
369   \syst_catcodes_trace_set}
370
371%D Handy for debugging:
372%D
373%D \starttyping
374%D \tracecatcodetables
375%D \stoptyping
376
377\protected\def\tracecatcodetables
378  {\def\syst_catcodes_trace_set {\syst_catcodes_trace{set  \catcodetablename\space                                at \number\c_syst_catcodes_level}}%
379   \def\syst_catcodes_trace_push{\syst_catcodes_trace{push \catcodetablename\space from \syst_catcodes_prev\space at \number\c_syst_catcodes_level}}%
380   \def\syst_catcodes_trace_pop {\syst_catcodes_trace{pop  \catcodetablename\space to   \syst_catcodes_prev\space at \number\c_syst_catcodes_level}}}
381
382\def\syst_catcodes_trace#1{\immediate\write\statuswrite{[#1]}}
383
384\def\syst_catcodes_prev
385  {\ifnum\numexpr\c_syst_catcodes_level-1\relax>\zerocount
386     \csname\??catcodetablen\number\csname\??catcodetablet\number\numexpr\c_syst_catcodes_level-1\relax\endcsname\endcsname
387   \else
388     -%
389   \fi}
390
391\def\catcodetablename
392  {\ifnum\currentcatcodetable>\zerocount
393     \csname\??catcodetablen\number\currentcatcodetable\endcsname
394   \else
395     -%
396   \fi}
397
398\let\syst_catcodes_trace_set \empty
399\let\syst_catcodes_trace_push\empty
400\let\syst_catcodes_trace_pop \empty
401
402% \tracecatcodetables
403
404\protect
405
406%D We still have to define these so let's do that now:
407
408\newcatcodetable \inicatcodes
409\initcatcodetable\inicatcodes
410
411\let\currentcatcodetable\catcodetable
412
413\endinput
414