syst-ini.mkxl /size: 68 Kb    last modification: 2024-01-16 09:03
1%D \module
2%D   [       file=syst-ini,
3%D        version=2008.11.04, % 2001.11.16, % 1999.03.17,  % an oldie: 1995.10.10
4%D          title=\CONTEXT\ System Macros,
5%D       subtitle=Bootstrapping \TEX,
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 used to load plain \TEX\ in a special way, but redefining a couple of
15%D primitives so that for instance font loading was ignored. For those interested,
16%D this loader is found in \type {syst-tex.tex}. Some of the comment's are Don
17%D Knuths and more of it can be found in the plain \TEX\ format.
18%D
19%D Successive versions will be adapted to \LUAMETATEX. That also means that we
20%D define things a bit differently than in \MKII\ and \MKIV. This is party due to
21%D the fact that in this engine we removed some side effects or added features. The
22%D original \TEX\ program is well defined and documented and is still the benchmark.
23%D The \ETEX\ extensions originally were meant as systematic follow up but that
24%D never went beyond a first upgrade. It had a dual mode: compatible or extensible.
25%D We always used the second mode. The \LUATEX\ engines don't have that.
26%D
27%D There are some hard coded properties that relate to for instance node types but
28%D we always used abstraction. There are also side effects that (probably) originate
29%D in the fact that \ETEX\ had to stay compatible with the dominant set of macros
30%D using the original \TEX\ ones (either or not wrapped). Even unwanted side effects
31%D eventually become features. In\LUATEX\ and even more in \LUAMETATEX\ we get
32%D around that by additional mode variables that you can find below.
33%D
34%D Side note: those who complain about \TEX\ as rather special language, \ETEX\
35%D extensions that should have been or be different, should really look into how
36%D \TEX\ and friends evolved, and not come to quick and wrong conclusions. There are
37%D only a very few languages that evolve this way. As a comparison one can wonder
38%D why \CCODE\ never had proper strings like \PASCAL\ bit it's just hindsight and
39%D discussing it has no use. In a similar fashion one should keep in mind that what
40%D you see here is just a logical follow up in \MKII\ where we had to bend the rules
41%D and \MKIV\ where we had a bit more available. Not many who look at the latest
42%D engines had to jump though all the hoops.
43%D
44%D This is for instance noticeable in the names of some primitvies: \CONTEXT\ has a
45%D concept of protection before \type {\protected} showed up, and similarly had
46%D expansion helpers. This is why in \MKII\ you find \type {\protected}, \type
47%D {\expanded}, and \type {\unexpanded} commands with different meanings than the
48%D later \ETEX\ primitives. In \MKIV\ we stuck to the \CONTEXT\ originals and use
49%D \type {\normal...} ones when needed (so \type {\normal...} is there for a
50%D reason!). In \LMTX\ we made the transition from \type {\unexpanded} to \type
51%D {\protected} so again this file looks different than the \MKIV\ ancestor.
52%D
53%D When primitives get initialized they come from the \TEX\ namespace (the
54%D originals), the \ETEX\ extensions (although we dropped some) and \LUATEX\ which
55%D includes the \LUAMETATEX\ ones. The most noticeable \ETEX\ extensions we kept are
56%D those that relate to expansion and the expression scanners. The last group has
57%D always been somewhat special because (we were told) it was modelled after a macro
58%D set so it had to be compatible. It is tempting to replace it (and eventually I
59%D might do that) but for now we stick to them (although with an integer divide
60%D extension (like the \LUA\ \type {//} and the source has commented binary
61%D operators but I haven't yet decided on the symbols to use because we need to
62%D avoid expansion issues). For the record: the more extensive, related to \ETEX\
63%D follow up \NTS\ never took of, probably because of the implementation language
64%D and because performance made it unuseable. This is also why \LUATEX\ took a
65%D different route: extending by an extension language. Of course in the end some
66%D core functionality got added too.
67%D
68%D The most noticeable \LUAMETATEX\ specific code here has to do with additional
69%D data types (integer and dimension constants) and macro argument extensions. We
70%D also set up some defaults in handling math, languages, etc. Elsewhere in the
71%D \CONTEXT\ source the real configuration and usage happens so don't consider this
72%D an tutorial (as the plain format is).
73%D
74%D Category codes are another areas where subtle changed happened. You might not
75%D grasp it (maybe because \CONTEXT\ is alien to you) but whenever you see something
76%D that looks weird keep in mind that there is a valid reason for it.
77%D
78%D In due time I will add some more comments here, also because some \CONTEXT\
79%D users might be interested in the hostiry. Now to the code!
80
81%D Characters can have special states, that can be triggered by setting their
82%D category coded. Some are preset, others are to be set as soon as possible,
83%D otherwise we cannot define any useful macros.
84%D
85%D First we define a bunch of constants. Normally we would \type {\setconstant}
86%D but we're prestine and have no macros defined yet. Abstraction also makes it
87%D possible to avoid the \type {^^} in the input. We no longer define the \ETEX\
88%D nodes here (we have not only more, but also different numbers) so we do it
89%D elsewhere.
90
91% cheatsheet
92%
93% # : 0--9
94% * : ignore spaces
95% + : keep the braces
96% - : discard and don't count the argument
97% . : ignore pars and spaces
98% , : push back space when no match
99% / : remove leading and trailing spaces and pars
100% : : pick up scanning here
101% ; : quit scanning
102% = : braces are mandate
103% ^ : keep leading spaces
104% _ : braces are mandate and kept
105
106\immutable\integerdef\escapecatcode             0
107\immutable\integerdef\begingroupcatcode         1
108\immutable\integerdef\endgroupcatcode           2
109\immutable\integerdef\mathshiftcatcode          3
110\immutable\integerdef\alignmentcatcode          4
111\immutable\integerdef\endoflinecatcode          5
112\immutable\integerdef\parametercatcode          6
113\immutable\integerdef\superscriptcatcode        7
114\immutable\integerdef\subscriptcatcode          8
115\immutable\integerdef\ignorecatcode             9
116\immutable\integerdef\spacecatcode             10
117\immutable\integerdef\lettercatcode            11
118\immutable\integerdef\othercatcode             12  % finally obsolete: \let\other \othercatcode
119\immutable\integerdef\activecatcode            13  % finally obsolete: \let\active\activecatcode
120\immutable\integerdef\commentcatcode           14
121\immutable\integerdef\invalidcatcode           15
122
123%immutable\integerdef\zeroasciicode             0
124\immutable\integerdef\tabasciicode              9
125\immutable\integerdef\newlineasciicode         10  % don't confuse this one with \endoflineasciicode
126\immutable\integerdef\formfeedasciicode        12
127\immutable\integerdef\endoflineasciicode       13  % somewhat messy but this can be the active \par
128\immutable\integerdef\endoffileasciicode       26
129\immutable\integerdef\spaceasciicode           32
130\immutable\integerdef\exclamationmarkasciicode 33 % ! used in namespace protection
131\immutable\integerdef\doublequoteasciicode     34 % "
132\immutable\integerdef\hashasciicode            35
133\immutable\integerdef\dollarasciicode          36
134\immutable\integerdef\commentasciicode         37
135\immutable\integerdef\ampersandasciicode       38
136\immutable\integerdef\singlequoteasciicode     39 % '
137\immutable\integerdef\primeasciicode           39 % '
138\immutable\integerdef\leftparentasciicode      40
139\immutable\integerdef\rightparentasciicode     41
140\immutable\integerdef\commaasciicode           44
141\immutable\integerdef\hyphenasciicode          45
142\immutable\integerdef\periodasciicode          46
143\immutable\integerdef\forwardslashasciicode    47 % /
144\immutable\integerdef\zeroasciicode            48
145\immutable\integerdef\nineasciicode            57
146\immutable\integerdef\colonasciicode           58
147\immutable\integerdef\semicolonasciicode       59
148\immutable\integerdef\lessthanasciicode        60 % < used as alternative verbatim {
149\immutable\integerdef\morethanasciicode        62 % > used as alternative verbatim }
150\immutable\integerdef\questionmarkasciicode    63 % ? used in namespace protection
151\immutable\integerdef\atsignasciicode          64 % @ used in namespace protection
152\immutable\integerdef\leftbracketasciicode     91
153\immutable\integerdef\backslashasciicode       92 % `\\
154\immutable\integerdef\rightbracketasciicode    93
155\immutable\integerdef\circumflexasciicode      94
156\immutable\integerdef\underscoreasciicode      95
157\immutable\integerdef\alowercaseasciicode      97
158\immutable\integerdef\zlowercaseasciicode     122
159\immutable\integerdef\leftbraceasciicode      123 % `\{
160\immutable\integerdef\barasciicode            124 % `\|
161\immutable\integerdef\rightbraceasciicode     125 % `\}
162\immutable\integerdef\tildeasciicode          126 % `\~
163\immutable\integerdef\delasciicode            127
164
165\aliased\let\percentasciicode\commentasciicode
166
167%catcode\zeroasciicode           \ignorecatcode      % `\^^@   ascii null is ignored
168\catcode\tabasciicode            \spacecatcode       % `\^^I   ascii tab is a blank space
169\catcode\formfeedasciicode       \activecatcode      % `\^^L   ascii form-feed (active, set later)
170%catcode\endoflineasciicode      \endoflinecatcode   % `\^^M   ascii return is end-line
171\catcode\endoffileasciicode      \ignorecatcode      % `\^^Z   endoffile (ignored in ConTeXt)
172%catcode\spaceasciicode          \spacecatcode       % `\      ascii space is blank space
173\catcode\hashasciicode           \parametercatcode   % `\#     hash mark is macro parameter character
174\catcode\dollarasciicode         \mathshiftcatcode   % `\$     dollar sign is math shift
175%catcode\commentasciicode        \commentcatcode     % `\%     percent sign is comment character
176\catcode\ampersandasciicode      \alignmentcatcode   % `\&     ampersand is alignment tab
177%catcode\backslashasciicode      \escapecatcode      % `\\     backslash is TeX escape character
178\catcode\circumflexasciicode     \superscriptcatcode % `\^     circumflex and uparrow are for superscripts
179\catcode\underscoreasciicode     \subscriptcatcode   % `\_     underline and downarrow are for subscripts
180\catcode\leftbraceasciicode      \begingroupcatcode  % `\{     left brace is begin-group character
181\catcode\rightbraceasciicode     \endgroupcatcode    % `\}     right brace is end-group character
182\catcode\tildeasciicode          \activecatcode      % `\~     tilde is active
183%catcode\delasciicode            \invalidcatcode     % `\^^?   ascii delete is invalid
184
185%D First we need to initialization the primitives. Because \CONTEXT\ is already a
186%D pretty old macro package, we have a couple of issues with respect to primitives.
187%D The \ETEX\ engine added a few as did \PDFTEX. The \LUATEX\ engine added even
188%D more. This means that there can be a potential clash between primitives and
189%D existing macros. The most noticeable ones are:
190%D
191%D \starttyping
192%D \protected
193%D \expanded
194%D \unexpanded
195%D \stoptyping
196%D
197%D Because we had macros like that before the primitives showed up. The protection
198%D related macros were there before we even knew about extensions to the engine.
199%D When the expansion related ones were introduced, we originally came up with
200%D different names but due to requests we used the current names, somethng that in
201%D retrospect was a bad idea: they should have gotten different names in \LUATEX, if
202%D only because at that time only \CONTEXT\ was using them in rolling releases.
203%D Anyway, we're now stuck with this situation, and it means that one should use the
204%D \type {\normal...} variants in low level code:
205%D
206%D \starttyping
207%D \normalexpanded
208%D \normalprotected
209%D \normalunexpanded
210%D \stoptyping
211%D
212%D In the end not using different names in \LUATEX\ for these kind of backfires. It
213%D makes not much sense to fix this in \LUAMETATEX\ because we're now to long on the
214%D road. It is actually the reason why we have the option in \LUATEX\ to alias all
215%D primitives in one go using a prefix. Actually this trick could be used to recover
216%D a primitive meaning: just enable it with some prefix and \type {\let} the
217%D original to that. But \unknown\ we prevent that trick below.
218%D
219%D The code below differs from \LUATEX: in \LUAMETATEX\ all primitives are already
220%D available; it cannot limit itself to being \TEX\ or \ETEX. It could not do that
221%D anyway because there are differences (no backend, to mention one).
222
223\directlua {
224    tex.enableprimitives("normal",true) % we default to everything
225    function tex.enableprimitives() end % so we kind of protect what's there
226}
227
228\untraced\permanent\let\undefined\undefined
229
230\immutable\def\space{ }
231\immutable\def\empty{}
232\mutable  \def\temp {}
233
234\immutable\letcharcode \formfeedasciicode \par    % \def ^^L{\par}  formfeed
235\immutable\letcharcode \tildeasciicode    \       %                 tilde
236\immutable\letcharcode \spaceasciicode    \space  %                 space
237
238\immutable\defcsname\tocharacter\tabasciicode      \endcsname {\ }   % \def\^^I{\ }    tab
239\immutable\defcsname\tocharacter\formfeedasciicode \endcsname {\par} % \def\^^L{\par}  formfeed
240\immutable\defcsname\tocharacter\endoflineasciicode\endcsname {\ }   % \def\^^M{\ }    return
241
242%D For now:
243
244\permanent\def\gobbleoneargument#-{} % will be defined later on anyway
245
246%D First we define a simplified version of the \CONTEXT\ protection mechanism. Later
247%D we will implement a better variant.
248
249\def\unprotect
250  {\edef\protect
251     {\catcode\atsignasciicode         \the\catcode\atsignasciicode         \relax
252      \catcode\exclamationmarkasciicode\the\catcode\exclamationmarkasciicode\relax
253      \catcode\questionmarkasciicode   \the\catcode\questionmarkasciicode   \relax
254      \catcode\underscoreasciicode     \the\catcode\underscoreasciicode     \relax
255      \let\protect\relax}%
256   \catcode\atsignasciicode         \lettercatcode
257   \catcode\exclamationmarkasciicode\lettercatcode
258   \catcode\questionmarkasciicode   \lettercatcode
259   \catcode\underscoreasciicode     \lettercatcode}
260
261\let\protect\relax
262
263\unprotect
264
265%D Some pretty important definitions:
266
267\immutable\let\bgroup={
268\immutable\let\egroup=}
269
270%D \macros
271%D   {normalbgroup,normalgroup}
272%D
273%D No comment.
274
275%D Allocation of registers is done slightly different than in plain \TEX. First of
276%D all we use different reserved counters. We also don't implement a family handler
277%D because users are not supposed to implement their own math. We reserve the lowest
278%D 31 registers for scratch purposes. Keep in mind that in the core engine some
279%D registers are reserved: counters 0 upto 9, and counter 255.
280%D
281%D As with plain \TEX\ we recommend that macro designers always use \type {\global}
282%D assignments with respect to registers numbered 1, 3, 5 \unknown\ 31, and always
283%D non||\type {\global} assignments with respect to registers 0, 2, 4, \unknown\ 30.
284%D This will prevent \quote {save stack buildup} that might otherwise occur.
285%D
286%D We reserve some registers for special (management) purposes. In the mkiv file you
287%D can see how we also (even if we don't use it) deal with families and languages
288%D and distinguish read and write ranges. There we also use a more traditional
289%D insert allocator that operates in its own range. In \MKIV\ the ranges are:
290
291%   0 -  20 : scratch
292%  21 - 127 : internal
293% 128 - 254 : inserts   (no longer)
294% 255       : page
295% 256 -     : user defined
296
297%D However, in \LMTX\ we have:
298
299%   0 - 199 : scratch
300% 200 - 254 : internal
301% 255       : page
302% 256 -     : user defined
303
304%D Later on, the \type {\c_syst_max_allocated_*} variables will be halfed so that
305%D while local allocators will use the 23* range. So we have plenty of room reserved
306%D for more private ones.
307
308\directlua {tex.magicconstants = status.getconstants()} % this will be reset later on
309
310\permanent\countdef\c_syst_min_allocated_register  = 201 \c_syst_min_allocated_register  =   256 % can change
311
312\permanent\countdef\c_syst_min_allocated_iohandle  = 203 \c_syst_min_allocated_iohandle  =     0
313\permanent\countdef\c_syst_max_allocated_iohandle  = 204 \c_syst_max_allocated_iohandle  =  1023
314
315\permanent\countdef\c_syst_min_allocated_mark      = 205 \c_syst_min_allocated_mark      =    16 % a few scratch ones
316\permanent\countdef\c_syst_max_allocated_mark      = 206 \c_syst_max_allocated_mark      =  1024 % max 10K in luametatex anyway
317
318\permanent\countdef\c_syst_min_allocated_attribute = 207 \c_syst_min_allocated_attribute =  1024 % 0-1023 : private
319\permanent\countdef\c_syst_max_allocated_attribute = 208 \c_syst_min_allocated_attribute = \directlua{tex.write(tex.magicconstants.max_attribute_register_index)} % 65535 % no allocator, managed differently
320
321\permanent\countdef\c_syst_max_allocated_count     = 211 \c_syst_max_allocated_count     = \directlua{tex.write(tex.magicconstants.max_integer_register_index)}   % 65535 % is adapted later on
322\permanent\countdef\c_syst_max_allocated_dimen     = 212 \c_syst_max_allocated_dimen     = \directlua{tex.write(tex.magicconstants.max_dimension_register_index)} % idem
323\permanent\countdef\c_syst_max_allocated_skip      = 213 \c_syst_max_allocated_skip      = \directlua{tex.write(tex.magicconstants.max_glue_register_index)}      % idem
324\permanent\countdef\c_syst_max_allocated_muskip    = 214 \c_syst_max_allocated_muskip    = \directlua{tex.write(tex.magicconstants.max_muglue_register_index)}    % idem
325\permanent\countdef\c_syst_max_allocated_box       = 215 \c_syst_max_allocated_box       = \directlua{tex.write(tex.magicconstants.max_box_register_index)}       % idem
326\permanent\countdef\c_syst_max_allocated_toks      = 216 \c_syst_max_allocated_toks      = \directlua{tex.write(tex.magicconstants.max_toks_register_index)}      % idem
327\permanent\countdef\c_syst_max_allocated_read      = 217 \c_syst_max_allocated_read      = \c_syst_max_allocated_iohandle
328\permanent\countdef\c_syst_max_allocated_write     = 218 \c_syst_max_allocated_write     = \c_syst_max_allocated_iohandle
329\permanent\countdef\c_syst_max_allocated_float     = 220 \c_syst_max_allocated_float     = \directlua{tex.write(tex.magicconstants.max_float_register_index or 0)}     % idem
330
331\permanent\countdef\c_syst_last_allocated_count    = 221 \c_syst_last_allocated_count    = \c_syst_min_allocated_register
332\permanent\countdef\c_syst_last_allocated_dimen    = 222 \c_syst_last_allocated_dimen    = \c_syst_min_allocated_register
333\permanent\countdef\c_syst_last_allocated_skip     = 223 \c_syst_last_allocated_skip     = \c_syst_min_allocated_register
334\permanent\countdef\c_syst_last_allocated_muskip   = 224 \c_syst_last_allocated_muskip   = \c_syst_min_allocated_register
335\permanent\countdef\c_syst_last_allocated_box      = 225 \c_syst_last_allocated_box      = \c_syst_min_allocated_register
336\permanent\countdef\c_syst_last_allocated_toks     = 226 \c_syst_last_allocated_toks     = \c_syst_min_allocated_register
337\permanent\countdef\c_syst_last_allocated_read     = 227 \c_syst_last_allocated_read     = \c_syst_min_allocated_iohandle
338\permanent\countdef\c_syst_last_allocated_write    = 228 \c_syst_last_allocated_write    = \c_syst_min_allocated_iohandle
339\permanent\countdef\c_syst_last_allocated_marks    = 229 \c_syst_last_allocated_marks    = \c_syst_min_allocated_mark
340\permanent\countdef\c_syst_last_allocated_float    = 230 \c_syst_last_allocated_float    = \c_syst_min_allocated_register
341
342\permanent\countdef\c_syst_min_counter_value       = 253 \c_syst_min_counter_value       = -"7FFFFFFF
343\permanent\countdef\c_syst_max_counter_value       = 254 \c_syst_max_counter_value       =  "7FFFFFFF
344
345\immutable\integerdef\zerocount       0
346\immutable\integerdef\plusone         1
347\immutable\integerdef\minusone       -1
348
349\immutable\integerdef\normalpagebox 255  % hardcoded in pdftex/xetex
350
351\immutable\integerdef\statuswrite \minusone
352
353\immutable\dimensiondef\zeropoint 0pt
354
355\immutable\positdef\zerofloat 0
356
357%D These alternatives avoid the indirect references. Don't use these for generic
358%D code because one never knows what happens elsewhere.
359
360% \permanent\protected\def\newinteger   #1{\ifdefined#1\else\integerdef   #1\fi\zerocount} % can be relax
361% \permanent\protected\def\newdimension #1{\ifdefined#1\else\dimensiondef #1\fi\zeropoint}
362% \permanent\protected\def\newgluespec  #1{\ifdefined#1\else\gluespecdef  #1\fi\zeropoint}
363% \permanent\protected\def\newmugluespec#1{\ifdefined#1\else\mugluespecdef#1\fi\zeropoint}
364
365\permanent\protected\def\newinteger   #1{\integerdef   #1\zerocount}
366\permanent\protected\def\newdimension #1{\dimensiondef #1\zeropoint}
367\permanent\protected\def\newgluespec  #1{\gluespecdef  #1\zeropoint}
368\permanent\protected\def\newmugluespec#1{\mugluespecdef#1\zeropoint}
369\permanent\protected\def\newposit     #1{\positdef     #1\zerocount}
370
371%D The aliasing here is tricky: we need to make sure the alias is not let to the
372%D current value but behaves dynamic. Instead we can use just \newcount, unless of
373%D course I introduce a reference in the engine which is not more efficient so then
374%D one can as well use registers.
375
376\protected\def\aliasinteger  #1#2{\untraced\protected\def#1{#2}}% name parent
377\protected\def\aliasdimension#1#2{\untraced\protected\def#1{#2}}% name parent
378\protected\def\aliasposit    #1#2{\untraced\protected\def#1{#2}}% name parent
379
380%D So, effectively we start allocating from 256 and upwards. The inserts sit in the
381%D range 128 upto 254. Page numbers use the counters 0 upto 9 and the pagebox is
382%D 255. Users can use the scratch registers upto 31 without problem but all others
383%D are reserved.
384
385\permanent\let\wlog\gobbleoneargument % Let's get rid of this one.
386
387%D The allocators share a common helper macro. Marks might be changed to work in lower
388%D regions and we always assumes allocation.
389
390\permanent\protected\def\newcount {\syst_basics_allocate\c_syst_last_allocated_count \count \countdef  \c_syst_max_allocated_count}
391\permanent\protected\def\newdimen {\syst_basics_allocate\c_syst_last_allocated_dimen \dimen \dimendef  \c_syst_max_allocated_dimen}
392\permanent\protected\def\newskip  {\syst_basics_allocate\c_syst_last_allocated_skip  \skip  \skipdef   \c_syst_max_allocated_skip}
393\permanent\protected\def\newmuskip{\syst_basics_allocate\c_syst_last_allocated_muskip\muskip\muskipdef \c_syst_max_allocated_muskip}
394\permanent\protected\def\newbox   {\syst_basics_allocate\c_syst_last_allocated_box   \box   \integerdef\c_syst_max_allocated_box}
395\permanent\protected\def\newtoks  {\syst_basics_allocate\c_syst_last_allocated_toks  \toks  \toksdef   \c_syst_max_allocated_toks}
396\permanent\protected\def\newread  {\syst_basics_allocate\c_syst_last_allocated_read  \read  \integerdef\c_syst_max_allocated_read}
397\permanent\protected\def\newwrite {\syst_basics_allocate\c_syst_last_allocated_write \write \integerdef\c_syst_max_allocated_write}
398\permanent\protected\def\newmarks {\syst_basics_allocate\c_syst_last_allocated_marks \marks \integerdef\c_syst_max_allocated_mark}
399\permanent\protected\def\newfloat {\syst_basics_allocate\c_syst_last_allocated_float \float \floatdef  \c_syst_max_allocated_float}
400
401\firstvalidlanguage \plusone % so zero is ignored in hyphenation, this might become the default
402
403%D Watch out, for the moment we disable the check for already being defined later we
404%D will revert this but first all chardefs must be replaced.
405
406\permanent\protected\def\setconstant         {}
407\permanent\protected\def\setconstantvalue#1#2{\csname#1\endcsname\numexpr#2\relax}
408
409\permanent\protected\def\newconstant#1%
410  {\ifrelax#1%
411    %\writestatus{!!!!!!!!!!}{\string #1 => RELAX}%
412     \unletfrozen#1%
413   % \newcount#1%
414     \newinteger#1%
415   \orelse\ifdefined#1%
416    %\writestatus{!!!!!!!!!!}{\string #1 => DEFINED}%
417   \else
418   % \newcount#1%
419     \newinteger#1%
420   \fi}
421
422\permanent\protected\def\setnewconstant#1{\newconstant#1#1}
423
424% %D The next definitions are really needed (in \CONTEXT):
425
426\newlinechar\newlineasciicode  \permanent\edef\outputnewlinechar{\tocharacter\newlineasciicode} % {^^J}
427
428%D One reason to start high with allocation is that it permits us to allocate
429%D consecutive ranges more easily, for instance if for \MPLIB\ we want to allocate a
430%D continuous range of boxes. It also permits us to do a proper upward allocation
431%D for inserts. The current code evolved from code that dealt with older engines but
432%D as all engines now provide many registers we removed all traces. If you ever run
433%D into the \MKII\ \type {mptopdf} code, you'll notice that some register magic was
434%D needed to fit into existing macro packages. The same is true for \PICTEX\ that we
435%D used in (generic) \PPCHTEX.
436
437\ifdefined\writestatus \else
438   %\protected\def\writestatus#1#2{\immediate\write\statuswrite{#1: #2}}
439    \frozen\protected\def\writestatus#1#2{\message{#1: #2}}
440\fi
441
442%D The above command will normally hook into the interface commands and is a
443%D protected command. We also have an \type {\diagnostic} predefined which is an
444%D expandable command:
445%D
446%D \starttyping
447%D test \diagnostic     {here 1} test
448%D test \diagnostic[2]  {here 2} test
449%D test \diagnostic[.05]{here 3} test
450%D \stoptyping
451%D
452%D The optional argument triggers a sleep in seconds.
453
454\def\syst_basics_allocate_yes#1#2#3#4#5% last class method max name
455  {\ifnum#1<#4\relax
456     \global\advanceby#1\plusone
457     \permanent\global#3#5=#1\relax
458   \else
459     \writestatus{warning}{no room for \string#2\space \string#5\space (max: \number#4)}%
460   \fi}
461
462\def\syst_basics_allocate_nop#1#2#3#4#5% last class method max name
463  {\writestatus{warning}{\string#2 \string#5 is already defined (\string\relax\space it first)}}
464
465\def\syst_basics_allocate#1#2#3#4#5% last class method max name
466  {\ifrelax#5%
467     \expandafter\syst_basics_allocate_yes
468   \orelse\ifdefined#5%
469     \expandafter\syst_basics_allocate_nop
470   \else
471     \expandafter\syst_basics_allocate_yes
472   \fi
473   #1#2#3#4#5}
474
475%D Since the number of chars exceed 256 now, we can use \type {\chardef} instead of
476%D the more limited \type {\mathchardef}.
477
478%D Attributes are something very \LUATEX. In \CONTEXT\ you are not supposed to use
479%D the attributes directly but always allocate then first. For instance attribute~0
480%D is reserved for special purposes (this might change). Attributes in the range
481%D 128-1023 are private and should not be touched.
482
483\immutable\integerdef\attributeunsetvalue\c_syst_min_counter_value % used to be \minusone
484
485% \permanent\protected\def\newattribute{\syst_basics_allocate\c_syst_last_allocated_attribute\attribute\attributedef\c_syst_max_allocated_attribute}
486
487% %D Not used by \CONTEXT\ but for instance \PICTEX\ needs it. It's a trick to force
488% %D strings instead of tokens that take more memory.
489%
490% \permanent\protected\def\newhelp#1#2{\newtoks#1#1\expandafter{\detokenize{#2}}}
491
492%D \macros
493%D   {scratchcounter,
494%D    scratchdimen,scratchskip,scratchmuskip,
495%D    scratchbox,
496%D    scratchtoks}
497%D
498%D We now define a few scratch registers, so that successive loads at least have
499%D some available. The private ones are used in cases where we don't want to
500%D intrude on normal scratch ones.
501
502\newinteger  \scratchcounter    \newinteger  \globalscratchcounter \newinteger  \privatescratchcounter
503\newposit    \scratchfloat      \newposit    \globalscratchfloat   \newposit    \privatescratchfloat
504\newdimension\scratchdimen      \newdimension\globalscratchdimen   \newdimension\privatescratchdimen
505\newgluespec \scratchskip       \newgluespec \globalscratchskip    \newgluespec \privatescratchskip
506\newmuskip   \scratchmuskip     \newmuskip   \globalscratchmuskip  \newmuskip   \privatescratchmuskip
507\newtoks     \scratchtoks       \newtoks     \globalscratchtoks    \newtoks     \privatescratchtoks
508\newbox      \scratchbox        \newbox      \globalscratchbox     \newbox      \privatescratchbox
509
510\newinteger  \scratchcounterone \newinteger  \scratchcountertwo    \newinteger  \scratchcounterthree
511\newposit    \scratchfloatone   \newposit    \scratchfloattwo      \newposit    \scratchfloatthree
512\newdimension\scratchdimenone   \newdimension\scratchdimentwo      \newdimension\scratchdimenthree
513\newgluespec \scratchskipone    \newgluespec \scratchskiptwo       \newgluespec \scratchskipthree
514\newmuskip   \scratchmuskipone  \newmuskip   \scratchmuskiptwo     \newmuskip   \scratchmuskipthree
515\newtoks     \scratchtoksone    \newtoks     \scratchtokstwo       \newtoks     \scratchtoksthree
516\newbox      \scratchboxone     \newbox      \scratchboxtwo        \newbox      \scratchboxthree
517
518\newinteger  \scratchcounterfour\newinteger  \scratchcounterfive   \newinteger  \scratchcountersix
519\newposit    \scratchfloatfour  \newposit    \scratchfloatfive     \newposit    \scratchfloatsix
520\newdimension\scratchdimenfour  \newdimension\scratchdimenfive     \newdimension\scratchdimensix
521\newgluespec \scratchskipfour   \newgluespec \scratchskipfive      \newgluespec \scratchskipsix
522\newmuskip   \scratchmuskipfour \newmuskip   \scratchmuskipfive    \newmuskip   \scratchmuskipsix
523\newtoks     \scratchtoksfour   \newtoks     \scratchtoksfive      \newtoks     \scratchtokssix
524\newbox      \scratchboxfour    \newbox       \scratchboxfive      \newbox      \scratchboxsix
525
526\newinteger\globalscratchcounterone
527\newinteger\globalscratchcountertwo
528\newinteger\globalscratchcounterthree
529
530\mutable\let\scratchmacro   \relax
531\mutable\let\scratchmacroone\relax
532\mutable\let\scratchmacrotwo\relax
533
534%D \macros
535%D   {tempstring, scratchstring*}
536
537\mutable\lettonothing\tempstring
538
539\mutable\lettonothing\scratchstring
540\mutable\lettonothing\scratchstringone
541\mutable\lettonothing\scratchstringtwo
542
543%D \macros
544%D   {scratchwidth, scratchheight, scratchdepth, scratchoffset, scratchdistance}
545%D
546%D A few more scratch dimensions:
547
548\newdimension\scratchwidth
549\newdimension\scratchheight
550\newdimension\scratchdepth
551\newdimension\scratchitalic
552\newdimension\scratchtotal
553
554\newdimension\scratchoffset
555\newdimension\scratchleftoffset
556\newdimension\scratchrightoffset
557\newdimension\scratchtopoffset
558\newdimension\scratchbottomoffset
559
560\newdimension\scratchdistance
561
562\newdimension\scratchhsize
563\newdimension\scratchvsize
564
565\newdimension\scratchxoffset
566\newdimension\scratchyoffset
567\newdimension\scratchhoffset
568\newdimension\scratchvoffset
569
570\newdimension\scratchxposition
571\newdimension\scratchyposition
572
573\newinteger\scratchnx
574\newinteger\scratchny
575
576\newinteger\scratchmx
577\newinteger\scratchmy
578
579\newinteger\scratchmin
580\newinteger\scratchmax
581
582\newinteger\scratchunicode
583\newinteger\scratchunicodeone
584\newinteger\scratchunicodetwo
585\newinteger\scratchunicodethree
586
587\newdimension\scratchleftskip
588\newdimension\scratchrightskip
589\newdimension\scratchtopskip
590\newdimension\scratchbottomskip
591
592%D More allocations:
593
594% \newcount \maxcount      \immutable\maxcount      2147483647
595
596% \newdimen \zeropoint     \immutable\zeropoint     0pt
597% \newdimen \onepoint      \immutable\onepoint      1pt
598% \newdimen \halfapoint    \immutable\halfapoint    0.5pt
599% \newdimen \maxdimen      \immutable\maxdimen      16383.99999pt % 1073741823sp
600% \newdimen \onebasepoint  \immutable\onebasepoint  1bp
601% \newdimen \scaledpoint   \immutable\scaledpoint   1sp
602% \newdimen \thousandpoint \immutable\thousandpoint 1000pt
603
604\immutable\integerdef    \maxcount 2147483647
605
606%immutable\dimensiondef  \zeropoint     0pt
607\immutable\dimensiondef  \onepoint      1pt
608\immutable\dimensiondef  \halfapoint    0.5pt
609\immutable\dimensiondef  \maxdimen      16383.99999pt % 1073741823sp
610\immutable\dimensiondef  \onebasepoint  1bp
611\immutable\dimensiondef  \scaledpoint   1sp
612\immutable\dimensiondef  \thousandpoint 1000pt
613
614\immutable\gluespecdef   \zeroskip            \zeropoint plus \zeropoint     minus \zeropoint
615\immutable\gluespecdef   \centeringskip       \zeropoint plus \thousandpoint minus \thousandpoint
616\immutable\gluespecdef   \stretchingskip      \zeropoint plus \thousandpoint
617\immutable\gluespecdef   \shrinkingskip       \zeropoint                     minus \thousandpoint
618\immutable\gluespecdef   \centeringfillskip   \zeropoint plus 1fill          minus 1fill
619\immutable\gluespecdef   \stretchingfillskip  \zeropoint plus 1fill
620\immutable\gluespecdef   \shrinkingfillskip   \zeropoint                     minus 1fill
621\immutable\gluespecdef   \centeringfilllskip  \zeropoint plus 1filll         minus 1filll
622\immutable\gluespecdef   \stretchingfilllskip \zeropoint plus 1filll
623\immutable\gluespecdef   \shrinkingfilllskip  \zeropoint                     minus 1filll
624
625\immutable\mugluespecdef \zeromuskip 0mu
626\immutable\mugluespecdef \onemuskip  1mu
627\immutable\mugluespecdef \muquad     18mu
628
629\aliased\let\points   \onepoint
630\aliased\let\halfpoint\halfapoint
631
632\newtoks \emptytoks
633
634%D And even more: (todo: countdefs 60+). Watch out, we need a count for a negative constant
635%D but can use chardefs for positive ones. Actually, because we have plenty of counters we
636%D can also use counts for those.
637
638%immutable\integerdef\minusone              -1
639\immutable\integerdef\minustwo              -2
640%immutable\integerdef\zerocount              0
641%immutable\integerdef\plusone                1
642\immutable\integerdef\plustwo                2
643\immutable\integerdef\plusthree              3
644\immutable\integerdef\plusfour               4
645\immutable\integerdef\plusfive               5
646\immutable\integerdef\plussix                6
647\immutable\integerdef\plusseven              7
648\immutable\integerdef\pluseight              8
649\immutable\integerdef\plusnine               9
650\immutable\integerdef\plusten               10
651\immutable\integerdef\pluseleven            11
652\immutable\integerdef\plustwelve            12
653\immutable\integerdef\plussixteen           16
654\immutable\integerdef\plusfifty             50
655\immutable\integerdef\plushundred          100
656\immutable\integerdef\plusonehundred       100
657\immutable\integerdef\plustwohundred       200
658\immutable\integerdef\plusfivehundred      500
659\immutable\integerdef\pluscxxvii           127
660\immutable\integerdef\pluscxxviii          128
661\immutable\integerdef\pluscclv             255
662\immutable\integerdef\pluscclvi            256
663\immutable\integerdef\plusthousand        1000
664\immutable\integerdef\plustenthousand    10000
665\immutable\integerdef\plustwentythousand 20000
666\immutable\integerdef\medcard            32768
667\immutable\integerdef\maxcard            65536 % pdftex has less mathchars
668\immutable\integerdef\maxcardminusone    65535
669\immutable\integerdef\maxiterator       "FFFFF
670
671\immutable\integerdef\binaryshiftedten          1024
672\immutable\integerdef\binaryshiftedtwenty    1048576
673\immutable\integerdef\binaryshiftedthirty 1073741824
674
675%D \macros
676%D   {doubleexpandafter,tripleexpandafter,expanded,startexpanded}
677%D
678%D A few handy shortcuts
679
680\permanent\let\singleexpandafter \expandafter
681\permanent\def\doubleexpandafter{\expandafter\expandafter\expandafter}
682\permanent\def\tripleexpandafter{\expandafter\doubleexpandafter\expandafter}
683
684%D We prefer the more readable variant than in plain \TEX. User should only
685%D use \type {\emptybox}:
686
687\newbox\voidbox  % public
688
689\permanent\def\unvoidbox{\unhbox\voidbox}
690\permanent\def\emptybox {\box   \voidbox}  % used in initializations so no attributes
691\permanent\def\emptyvbox{\normalvpack{}}   % no copy as we need to set attributes
692\permanent\def\emptyhbox{\normalhpack{}}   % no copy as we need to set attributes
693
694\aliased\let\leavevmode\unvoidbox % we prefer to use \dontleavehmode
695
696%D \macros
697%D   {dontcomplain,lessboxtracing}
698%D
699%D We need this one soon. The second one shows less box details (because that actually
700%D slows down noticeably due to the more extensive details in node content.
701
702% With \showboxdepth\maxcount and \showboxbreadth\maxcount the second one is way slower:
703%
704% \testfeatureonce{10}{\setbox\scratchbox\vbox        {\samplefile{tufte}}} \elapsedtime\par
705% \testfeatureonce{10}{\setbox\scratchbox\vbox to 10cm{\samplefile{tufte}}} \elapsedtime\par
706
707\permanent\protected\def\dontcomplain
708  {\hbadness\plustenthousand
709   \vbadness\plustenthousand
710   \hfuzz   \maxdimen
711   \vfuzz   \maxdimen}
712
713\permanent\protected\def\noboxtracing
714  {\showboxdepth  \zerocount
715   \showboxbreadth\zerocount}
716
717\permanent\protected\def\lessboxtracing
718  {\showboxdepth  \plusfive
719   \showboxbreadth\plusten}
720
721\permanent\protected\def\moreboxtracing
722  {\showboxbreadth\maxcount
723   \showboxdepth  \maxcount}
724
725%D Some expected plain variants follow. We don't reuse registers because we don't
726%D want clashes. These will go away and packages that need them have to define them.
727
728\aliased\let\p@     \onepoint
729\aliased\let\m@ne   \minusone
730\aliased\let\z@     \zeropoint
731\aliased\let\@ne    \plusone
732\aliased\let\tw@    \plustwo
733\aliased\let\thr@@  \plusthree
734\aliased\let\sixt@@n\plussixteen
735\aliased\let\@cclv  \pluscclv
736\aliased\let\@cclvi \pluscclvi
737\aliased\let\voidb@x\voidbox
738
739\newtoks    \toks@  %scratchtoks
740
741%D We define \type {\newif} a la plain \TEX, but will redefine it later. As Knuth
742%D says:
743%D
744%D \startnarrower
745%D And here's a different sort of allocation: for example,
746%D
747%D \starttyping
748%D \newif\iffoo
749%D \stoptyping
750%D
751%D creates \type {\footrue}, \type {\foofalse} to go with \type {\iffoo}.
752%D \stopnarrower
753
754% \protected\def\newif#1%
755%   {\count@\escapechar
756%    \escapechar\minusone
757%    \expandafter\expandafter\expandafter\def\new_if #1{true}{\let#1\iftrue }%
758%    \expandafter\expandafter\expandafter\def\new_if#1{false}{\let#1\iffalse}%
759%    \new_if#1{false}% the condition starts out false
760%    \escapechar\count@}
761%
762% \def\new_if#1#2%
763%   {\csname\expandafter\if@\string#1#2\endcsname}
764%
765% \bgroup % `if' is required
766%   \uccode`1=`i \uccode`2=`f \uppercase{\gdef\if@12{}}
767% \egroup
768
769% We use \csstring so there is no need to push/pop escapechar.
770% We use different names so that we get a better error message.
771%
772% \protected\def\newif#1%
773%   {\let\new_if_saved\newif
774%    \let\newif\new_if_check
775%    \expandafter\expandafter\expandafter\def\new_if_cs #1{true}{\let#1\iftrue }%
776%    \expandafter\expandafter\expandafter\def\new_if_cs#1{false}{\let#1\iffalse}%
777%    \new_if_cs#1{false}%
778%    \let\newif\new_if_saved}
779%
780% \protected\def\new_if_cs#1#2%
781%   {\csname\expandafter\newif\csstring#1#2\endcsname}
782%
783% We wrap all into one macro (the frozen stuff adds 10% runtime):
784
785\permanent\protected\def\new_if_define#1#2%
786  {\permanent\protected\gdefcsname\expandafter\new_if_check\csstring#2true\endcsname {\enforced#1#2\iftrue }%
787   \permanent\protected\gdefcsname\expandafter\new_if_check\csstring#2false\endcsname{\enforced#1#2\iffalse}%
788   \csname\expandafter\new_if_check\csstring#2false\endcsname}
789
790\normalexpanded{\gdef\noexpand\new_if_check\string i\string f{}}
791
792\permanent\protected\def\newif      {\new_if_define\let }
793\permanent\protected\def\globalnewif{\new_if_define\glet}
794
795%D Let's test this one:
796
797\newif\ifdone  \globalnewif\ifglobaldone
798\newif\iffound \globalnewif\ifglobalfound
799
800\newif\ifscratchcondition
801\newif\ifscratchconditionone
802\newif\ifscratchconditiontwo
803
804%D This used to be a protected definition with a \type {dimexpr} but now we have
805%D it natively (less tracking noise).
806
807\aliased\let\htdp\boxtotal
808
809%D A few shortcuts (gone by now):
810
811% \permanent\protected\def\udef {\protected\def }
812% \permanent\protected\def\ugdef{\protected\gdef}
813% \permanent\protected\def\uedef{\protected\edef}
814% \permanent\protected\def\uxdef{\protected\xdef}
815
816%D For a while we keep the following, as systems like tikz need it. Best not use
817%D that one \CONTEXT. It will probably move to the tikz loader.
818
819\aliased\let\active\activecatcode
820
821%D Constants to be used with \type {\interactionmode}.
822
823% \immutable\integerdef\batchmodecode     \zerocount
824% \immutable\integerdef\nonstopmodecode   \plusone
825% \immutable\integerdef\scrollmodecode    \plustwo
826% \immutable\integerdef\errorstopmodecode \plusthree
827
828%D Of course we want even bigger log files, so we copied this from the \ETEX\
829%D source files.
830%D
831%D When watching such logs, beware of nasty side effects of \type {\scantokens},
832%D as in:
833%D
834%D \starttyping
835%D \bgroup
836%D   \lccode`a=12\lowercase{\xdef\whatever{a}}\egroup
837%D   \def\whatever{test \whatever test}
838%D   \scantokens\expandafter{\whatever}
839%D \egroup
840%D \stoptyping
841%D
842%D In \LUATEX\ we have ways around this.
843
844% no longer \errorstopmode cf. plain tex 3.141592653
845
846\permanent\protected\def\tracingall
847  {\tracingcommands  \plusfour  % > 3: show mode change independent
848   \tracingmacros    \plusthree % > 2: obey \untraced
849   \tracingoutput    \plusone
850   \tracingpages     \plusone
851   \tracingparagraphs\plustwo
852   \tracingrestores  \plusone
853   \tracinggroups    \plusone
854   \tracingifs       \plusone
855   \tracingnesting   \plusthree
856   \tracingassigns   \plustwo
857   \tracingmath      \plusone
858   \tracingalignments\plustwo   % > 1: also show preamble
859   \showboxbreadth   \maxcount
860   \showboxdepth     \maxcount
861   \tracingonline    \plusone}
862
863\permanent\protected\def\tracingless
864  {\tracingall
865   \tracingoutput    \zerocount
866   \showboxbreadth   \maxcount
867   \showboxdepth     \plusten}
868
869\permanent\protected\def\loggingall
870  {\tracingall
871   \tracingonline    \zerocount}
872
873\permanent\protected\def\tracingnone
874  {\tracingonline    \zerocount
875   \showboxdepth     \plusfive % lessboxtracing
876   \showboxbreadth   \plusten
877   \tracingalignments\zerocount
878   \tracingmath      \zerocount
879   \tracingassigns   \zerocount
880   \tracingnesting   \zerocount
881   \tracingifs       \zerocount
882   \tracinggroups    \zerocount
883   \tracingrestores  \zerocount
884   \tracingparagraphs\zerocount
885   \tracingpages     \zerocount
886   \tracingoutput    \zerocount
887   \tracingmacros    \zerocount
888   \tracingcommands  \zerocount
889   \tracingonline    \zerocount}
890
891%D When we want to see a box we can as well show all of it.
892
893% \showboxdepth  \maxcount
894% \showboxbreadth\maxcount
895
896\lessboxtracing
897
898%D Just for tracing purposes we set:
899
900\tracingstats\plusone
901
902%D This is only used when we load \CONTEXT. Nesting is not supported here.
903
904\permanent\def\pushoverloadmode
905  {\enforced\permanent\protected\edef\popoverloadmode{\normaloverloadmode\the\normaloverloadmode\enforced\let\popoverloadmode\relax}%
906   \normaloverloadmode\zerocount}
907
908\aliased\let\popoverloadmode\relax
909
910\let\pushrunstate\relax % will be defined later
911\let\poprunstate \relax % will be defined later
912
913\newtoks\everydump
914
915\pushoverloadmode
916
917\permanent\protected\def\dump
918  {\the\everydump
919   \global\everydump\emptytoks
920   \pushoverloadmode
921   \enforced\glet\dump\relax
922   \popoverloadmode
923   %let\pushoverloadmode\relax
924   %let\popoverloadmode\relax
925 % \tracingall
926   \normaldump}
927
928\permanent\protected\def\input
929  {\normalinput}
930
931\popoverloadmode
932
933%D \macros
934%D   {newconditional,
935%D    settrue, setfalse,
936%D    ifconditional,then}
937%D
938%D \TEX's lacks boolean variables, although the \PLAIN\ format implements \type
939%D {\newif}. The main disadvantage of this scheme is that it takes three hash table
940%D entries. A more memory saving alternative is presented here. A conditional is
941%D defined by:
942%D
943%D \starttyping
944%D \newconditional\doublesided
945%D \setfalse
946%D \stoptyping
947%D Setting a conditional is done by \type{\settrue} and
948%D \type{\setfalse}:
949%D
950%D \starttyping
951%D \doublesided\conditionaltrue
952%D \setfalse
953%D \stoptyping
954%D while testing is accomplished by:
955%D
956%D \starttyping
957%D \ifconditional\doublesided  ... \else ... \fi
958%D \setfalse
959%D \stoptyping
960%D We cannot use the simple scheme:
961%D
962%D \starttyping
963%D \def\settrue #1{\let#1=\iftrue}
964%D \def\setfalse#1{\let#1=\iffalse}
965%D \stoptyping
966%D
967%D Such an implementation gives problems with nested conditionals. The next
968%D implementation is about as fast and just as straightforward:
969
970\aliased\let\conditionalfalse\plusone    % maybe we will have a dedicated count/chardef
971\aliased\let\conditionaltrue \zerocount  % maybe we will have a dedicated count/chardef
972
973% \permanent\protected\def\settrue #1{\integerdef#1\conditionaltrue }
974% \permanent\protected\def\setfalse#1{\integerdef#1\conditionalfalse}
975%
976% \permanent\protected\def\settruevalue #1{\expandafter\integerdef\csname#1\endcsname\conditionaltrue }
977% \permanent\protected\def\setfalsevalue#1{\expandafter\integerdef\csname#1\endcsname\conditionalfalse}
978
979\permanent\protected\def\settrue       #1{\enforced\let#1\conditionaltrue }
980\permanent\protected\def\setfalse      #1{\enforced\let#1\conditionalfalse}
981\permanent\protected\def\setconditional#1{\enforced\let#1}
982
983\permanent\protected\def\settruevalue #1{\enforced\letcsname#1\endcsname\conditionaltrue }
984\permanent\protected\def\setfalsevalue#1{\enforced\letcsname#1\endcsname\conditionalfalse}
985
986
987\aliased\let\newconditional\setfalse
988\aliased\let\ifconditional \ifcase
989
990\permanent\protected\lettonothing\then % so that we can say: \ifnum1>2\then -)
991
992\permanent\def\truecondition {\iftrue}
993\permanent\def\falsecondition{\iffalse}
994
995% This one has to be unprotected otherwise we get a files-ends-to-soon but it's ok
996% as conditions expand anyway.
997
998\permanent\def\quitcondition{\orelse\iffalse}
999
1000%D \macros
1001%D   {newmacro,setnewmacro,newfraction}
1002%D
1003%D Let's be complete and also introduce some definers. These are not mandate
1004%D but handy for grepping. We make these mutable because they are \type
1005%D {\let} (the only advantage is that we often give them names with some
1006%D prefix.
1007
1008\permanent\protected\def\newmacro   #1{\mutable\lettonothing#1}
1009\permanent\protected\def\setnewmacro#1{\mutable\let#1}
1010
1011\permanent\protected\def\newfraction#1{\mutable\let#1\!!plusone}
1012
1013\def\!!zerocount{0} % later redefined
1014\def\!!plusone  {1} % later redefined
1015
1016%D It would be handy to have a primitive \type {\unless\ifcase} because then we
1017%D could use nicer values. Anyhow, this conditional code used to be in the \type
1018%D {syst-aux} module but is now promoted to here.
1019
1020%D \macros
1021%D   {ifzeropt}
1022%D
1023%D The next macro is both cosmetic and byte saving. It is pretty \type
1024%D {\if}||safe too. It can be used in cases like:
1025%D
1026%D \starttyping
1027%D \ifzeropt \somedimen ... \else ... \fi
1028%D \stoptyping
1029
1030\aliased\let\ifzeropt\ifzerodim % was \let\ifzeropt\ifcase
1031\aliased\let\ifzero  \ifzeronum % was \let\ifzeropt\ifcase
1032
1033% these token list helpers might move to syst-aux.mkiv
1034%
1035% we assume a \cs. not toks0 or so
1036%
1037% \protected\def\appendtotoks #1#{\def\temp{#1}\afterassignment\doappendtotoks \scratchtoks=}
1038% \protected\def\prependtotoks#1#{\def\temp{#1}\afterassignment\doprependtotoks\scratchtoks=}
1039
1040\newtoks\t_syst_toks_temp \let\m_syst_toks_temp\t_syst_toks_temp
1041
1042\permanent\protected\def\appendtotoks #1{\let\m_syst_toks_temp#1\afterassignment\syst_toks_append_l \t_syst_toks_temp=}
1043\permanent\protected\def\prependtotoks#1{\let\m_syst_toks_temp#1\afterassignment\syst_toks_prepend_l\t_syst_toks_temp=}
1044
1045% \def\syst_toks_append {\m_syst_toks_temp\expandafter\expandafter\expandafter{\expandafter\the\expandafter\m_syst_toks_temp\the\t_syst_toks_temp}}}
1046% \def\syst_toks_prepend{\m_syst_toks_temp\expandafter\expandafter\expandafter{\expandafter\the\expandafter\t_syst_toks_temp\the\m_syst_toks_temp}}}
1047
1048\permanent\protected\def\globalappendtotoks #1{\let\m_syst_toks_temp#1\afterassignment\syst_toks_append_g \t_syst_toks_temp=}
1049\permanent\protected\def\globalprependtotoks#1{\let\m_syst_toks_temp#1\afterassignment\syst_toks_prepend_g\t_syst_toks_temp=}
1050
1051\def\syst_toks_append_l {\normalexpanded{\m_syst_toks_temp{\the\m_syst_toks_temp\the\t_syst_toks_temp}}}
1052\def\syst_toks_prepend_l{\normalexpanded{\m_syst_toks_temp{\the\t_syst_toks_temp\the\m_syst_toks_temp}}}
1053
1054\def\syst_toks_append_g {\global\syst_toks_append_l }
1055\def\syst_toks_prepend_g{\global\syst_toks_prepend_l}
1056
1057\permanent\protected\def\addtotoks      #1{\let\m_syst_toks_temp#1\afterassignment\syst_toks_add_l\let\next}
1058\permanent\protected\def\globaladdtotoks#1{\let\m_syst_toks_temp#1\afterassignment\syst_toks_add_g\let\next}
1059
1060\def\syst_toks_add_l{\m_syst_toks_temp\expandafter\bgroup\the\m_syst_toks_temp}
1061\def\syst_toks_add_g{\global\syst_toks_add_l}
1062
1063\permanent\protected\def\addtotokscs      #1#2{#1{\the#1#2}}        % saves a few bytes
1064\permanent\protected\def\globaladdtotokscs#1#2{\global#1{\the#1#2}} % saves a few bytes
1065
1066%D \macros
1067%D   {begcsname}
1068%D
1069%D Handy for \ETEX-only usage (avoids making \type {\relax}'s:
1070
1071% \def\begcsname#1\endcsname{\ifcsname#1\endcsname\csname#1\endcsname\fi}
1072
1073\aliased\let\begcsname\begincsname
1074
1075%D Now come a few macros that might be needed in successive loading. We redefine the
1076%D \type {\par} primitive pretty soon so that we get the equivalents right.
1077
1078% too tricky: \par is use more often than a par starts so we have too much change
1079% that we get assymetrical behaviour
1080%
1081% \newtoks\everyendpar
1082%
1083% \protected\def\endpar{\the\everyendpar\normalpar}
1084% \protected\def\par   {\endpar}
1085%
1086% \protected\def\reseteverypar
1087%   {\everypar   \emptytoks
1088%    \everyendpar\emptytoks}
1089
1090\permanent\protected\def\reseteverypar
1091  {\everypar\emptytoks}
1092
1093\aliased\let\endgraf\par % plain, a kind of funny name
1094%aliased\let\endline\cr  % plain, not needed and probably also confusing
1095
1096\permanent\protected\def\null{\hpack{}}
1097
1098%D The following two might be overloaded later on but some modules need then
1099%D earlier. These functionality is reflected in the name and will not change.
1100
1101% \bgroup
1102%     \catcode`\^^M=\activecatcode%
1103%     \gdef\obeylines{\catcode`\^^M\activecatcode \let^^M\par}%
1104%     \glet^^M\par%
1105% \egroup
1106%
1107% \bgroup
1108%     \gdef\obeyspaces{\catcode`\ \activecatcode}%
1109%     \obeyspaces\glet =\space%
1110% \egroup
1111
1112\def\obeylines {\catcode\endoflineasciicode\activecatcode\letcharcode\endoflineasciicode\par  } % check if these can be \permanent
1113\def\obeyspaces{\catcode\spaceasciicode    \activecatcode\letcharcode\spaceasciicode    \space} % check if these can be \permanent
1114
1115% %D A constant:
1116%
1117% \let\endoflinetoken=^^M
1118
1119%D Also needed might be a simple loop structure and we borrow plain \TEX's one
1120%D as it is often expected to be present and it is about the fastest you can
1121%D get. Beware: this macro does not support nested loops. We use a namespace
1122%D prefix \type {@@pln}.
1123
1124\let\syst_plain_body\relax
1125
1126\permanent\def\loop#1\repeat{\def\syst_plain_body{#1}\syst_plain_iterate} % might go
1127
1128%D The following makes \type {\loop} \unknown\ \type {\if} \unknown\ \type
1129%D {\repeat} skippable (clever trick):
1130
1131\permanent\let\repeat\fi % so both \loop and \repeat are reserved words!
1132
1133%D The original (no \type {syst_plain_} there):
1134%D
1135%D \starttyping
1136%D \def\syst_plain_iterate
1137%D   {\syst_plain_body
1138%D    \let\next\syst_plain_iterate
1139%D    \else
1140%D      \let\next\relax
1141%D    \fi
1142%D    \next}
1143%D \stoptyping
1144%D
1145%D A more efficient alternative:
1146%D
1147%D \starttyping
1148%D \def\syst_plain_iterate
1149%D   {\syst_plain_body
1150%D    \expandafter\syst_plain_iterate
1151%D    \else\expandafter\relax\fi}
1152%D \stoptyping
1153%D
1154%D An even more efficient one:
1155
1156\def\syst_plain_iterate
1157  {\syst_plain_body
1158   \expandafter\syst_plain_iterate\else\fi}
1159
1160%D We don't define a real output routine yet but at least get rid of pages:
1161
1162\output{\shipout\box\normalpagebox}
1163
1164%D Although we don't add pagenumbers yet we alias the default register used
1165%D for counting pages:
1166
1167\permanent\countdef\pageno\zerocount \pageno\plusone % first page is number 1
1168
1169%D Beside the raw counter \type {\pageno} the \type {\folio} macro provides
1170%D the value.
1171
1172\permanent\def\folio{\the\pageno} % kind of expected and therefore reserved
1173
1174%D The following registers are kind of standard and (for the moment) we define
1175%D them here. This might change.
1176
1177\newgluespec \bigskipamount    \bigskipamount   = 12pt plus 4pt minus 4pt
1178\newgluespec \medskipamount    \medskipamount   =  6pt plus 2pt minus 2pt
1179\newgluespec \smallskipamount  \smallskipamount =  3pt plus 1pt minus 1pt
1180
1181\baselineskip  = 12pt
1182\lineskip      =  1pt
1183\lineskiplimit =  0pt
1184
1185%D Sometimes kerns make more sense than glue but we need to be in the right mode:
1186
1187\ifdefined\vkern    \else \permanent\protected\def\vkern   {\ifhmode\par           \fi\kern}    \fi
1188\ifdefined\hkern    \else \permanent\protected\def\hkern   {\ifvmode\dontleavehmode\fi\kern}    \fi
1189
1190\ifdefined\vpenalty \else \permanent\protected\def\vpenalty{\ifhmode\par           \fi\penalty} \fi
1191\ifdefined\hpenalty \else \permanent\protected\def\hpenalty{\ifvmode\dontleavehmode\fi\penalty} \fi
1192
1193%D Again a few kind-of-extensions the core. These come from plain \TEX\ but are
1194%D probably not used in \CONTEXT.
1195
1196\newgluespec \hideskip   \hideskip  = -1000pt plus 1fill           % obsolete
1197\newgluespec \centering  \centering = 0pt plus 1000pt minus 1000pt % obsolete
1198
1199% \permanent\def\hidewidth % for alignment entries that can stick out
1200%   {\hskip\hideskip}
1201%
1202% \permanent\def\ialign % initialized \halign, to be used grouped!
1203%   {\everycr\emptytoks
1204%    \tabskip\zeroskip
1205%    \halign}
1206
1207\newcount \mscount
1208
1209\permanent\def\spanomit{\span\omit} % bypass error message
1210
1211\permanent\def\multispan#1%
1212  {\omit
1213   \mscount#1\relax
1214   \loop
1215     \ifnum\mscount>\plusone
1216       \spanomit \advanceby\mscount\minusone
1217   \repeat}
1218
1219\let\nopdfcompression        \relax % later
1220\let\onlypdfobjectcompression\relax % later
1221\let\maximumpdfcompression   \relax % later
1222\let\normalpdfcompression    \relax % later
1223
1224%D Basic status stuff.
1225
1226% \newif\ifproductionrun % already defined
1227
1228%D For those who expect this \unknown
1229
1230\ifdefined\fmtname    \else \immutable\def\fmtname   {ConTeXt Initial TeX} \fi
1231\ifdefined\fmtversion \else \immutable\def\fmtversion{3.1415926}           \fi
1232
1233%D A few bonus macros:
1234
1235%permanent\def\modulonumber#1#2{\the\numexpr#2-((((#2+(#1/2))/#1)-1)*#1)\relax}
1236\permanent\def\modulonumber#1#2{\the\numexpr#2-(#2:#1)*#1\relax}
1237\permanent\def\dividenumber#1#2{\the\numexpr(#2-(#1/2))/#1\relax}
1238
1239%D These could be set at the \LUA\ end instead:
1240
1241\immutable\edef\texenginename         {\directlua{tex.print(LUATEXENGINE)}}
1242\immutable\edef\texengineversion      {\directlua{tex.print(LUATEXVERSION)}}
1243\immutable\edef\texenginefunctionality{\directlua{tex.print(LUATEXFUNCTIONALITY)}}
1244
1245%D We have no reason not to enable this:
1246
1247\savingvdiscards\plusone
1248
1249%D We only can set this one via directives (system.synctex) and we only support
1250%D the context variant. This will go away completely.
1251
1252\newcount\synctex % \let\normalsynctex\synctex
1253
1254%D We get rid of the funny \TEX\ offset defaults of one inch by setting them to zero.
1255
1256% \voffset\zeropoint \overloaded\let\voffset\relax \newdimen\voffset \let\normalvoffset\voffset
1257% \hoffset\zeropoint \overloaded\let\hoffset\relax \newdimen\hoffset \let\normalhoffset\hoffset
1258
1259\matheqnogapstep\zerocount % for now
1260
1261%D Now we define a few helpers that we need in a very early stage. We have no
1262%D message system yet but redundant definitions are fatal anyway.
1263
1264\newcount\c_syst_helpers_n_of_namespaces \c_syst_helpers_n_of_namespaces\pluseight % 1-8 reserved for catcodes
1265
1266\def\v_interfaces_prefix_template_system{\the       \c_syst_helpers_n_of_namespaces>>}
1267%def\v_interfaces_prefix_template_system{\characters\c_syst_helpers_n_of_namespaces>>} % no \characters yet
1268
1269\protected\def\installsystemnamespace#1% will be redefined
1270  {\ifcsname ??#1\endcsname
1271     \immediate\write\statuswrite{fatal error: duplicate system namespace '#1'}%
1272   \else
1273     \global\advanceby\c_syst_helpers_n_of_namespaces\plusone
1274     \immutable\cdefcsname ??#1\endcsname{\v_interfaces_prefix_template_system}%
1275   \fi}
1276
1277%D It makes more sense to have these here:
1278
1279\aliased\let\normalstartimath  \Ustartmath
1280\aliased\let\normalstopimath   \Ustopmath
1281\aliased\let\normalstartdmath  \Ustartdisplaymath
1282\aliased\let\normalstopdmath   \Ustopdisplaymath
1283
1284\aliased\let\normalUchar       \tocharacter
1285
1286% These are the old U* commands:
1287
1288\aliased\let\Usuperscript      \superscript
1289\aliased\let\Usubscript        \subscript
1290\aliased\let\Uprimescript      \primescript
1291\aliased\let\Unosuperscript    \nosuperscript
1292\aliased\let\Unosubscript      \nosubscript
1293\aliased\let\Usuperprescript   \superprescript
1294\aliased\let\Usubprescript     \subprescript
1295\aliased\let\Unosuperprescript \nosuperprescript
1296\aliased\let\Unosubprescript   \nosubprescript
1297
1298\aliased\let\Ustack            \mathstack
1299\aliased\let\Umathdict         \mathdictionary
1300\aliased\let\Umathclass        \mathclass
1301
1302\aliased\let\Ustyle            \givenmathstyle
1303
1304\aliased\let\Uchar             \tocharacter
1305
1306% Todo:
1307
1308% \aliased\let\Umathchar            \mathcharacter
1309% \aliased\let\Umathchardef         \mathcharacterdef
1310% \aliased\let\Umathdictdef         \mathdictionarydef
1311% \aliased\let\Umathchardef         \mathcharacterdef
1312
1313% \aliased\let\Udelimited           \mathdelimited           % left right math
1314% \aliased\let\Udelimiterover       \mathdelimiterover       % top math
1315% \aliased\let\Udelimiterunder      \mathdelimiterunder      % bottom math
1316
1317% \aliased\let\Uhextensible         \mathhextensible         % middle
1318% \aliased\let\Uoverdelimiter       \mathoverdelimiter       % top math
1319% \aliased\let\Uunderdelimiter      \mathunderdelimiter      % bottom math
1320
1321% \aliased\let\Uradical             \mathdelimitedradical    % left math
1322% \aliased\let\Uroot                \mathdelimitedroot       % left degree math
1323% \aliased\let\Urooted              \mathdelimitedrooted     % left right degree math
1324
1325% \aliased\let\Uabove               \mathabove
1326% \aliased\let\Uabovewithdelims     \mathabovewithdelims
1327% \aliased\let\Uatop                \mathatop
1328% \aliased\let\Uatopwithdelims      \mathatopwithdelims
1329% \aliased\let\Uover                \mathover
1330% \aliased\let\Uoverwithdelims      \mathoverwithdelims
1331% \aliased\let\Uskewed              \mathskewed
1332% \aliased\let\Uskewedwithdelims    \mathskewedwithdelims
1333% \aliased\let\Ustretched           \mathstretched
1334% \aliased\let\Ustretchedwithdelims \mathstretchedwithdelims
1335
1336% \aliased\let\Uleft                \mathleftfence
1337% \aliased\let\Umiddle              \mathmiddlefence
1338% \aliased\let\Uoperator            \mathoperator
1339% \aliased\let\Uright               \mathrightfence
1340% \aliased\let\Uvextensible         \mathvextensible
1341
1342% \aliased\let\overline             \mathoverline
1343% \aliased\let\underline            \mathunderline
1344
1345% \aliased\let\Udelimiter           \Umathdelimiter
1346% \aliased\let\Umathaccent          \Umathaccented
1347% \aliased\let\Udelcode             \mathdelimitercode
1348% \aliased\let\Umathcode            \mathcharactercode
1349
1350% \aliased\let\Umathadapttoleft     \mathadapttoleft
1351% \aliased\let\Umathadapttoright    \mathadapttoright
1352% \aliased\let\Umathlimits          \mathlimits
1353% \aliased\let\Umathnoaxis          \mathnoaxis
1354% \aliased\let\Umathnolimits        \mathnolimits
1355% \aliased\let\Umathopenupdepth     \mathopenupdepth
1356% \aliased\let\Umathopenupheight    \mathopenupheight
1357% \aliased\let\Umathphantom         \mathphantom
1358% \aliased\let\Umathsource          \mathsource
1359% \aliased\let\Umathuseaxis         \mathuseaxis
1360% \aliased\let\Umathvoid            \mathvoid
1361
1362% \aliased\let\Ustartdisplaymath    \mathstartdisplaymath % otherwise conflict
1363% \aliased\let\Ustartmath           \mathstartmath        % idem
1364% \aliased\let\Ustartmathmode       \mathstartmathmode    % idem
1365% \aliased\let\Ustopdisplaymath     \mathstopdisplaymath  % idem
1366% \aliased\let\Ustopmath            \mathstopmath         % idem
1367% \aliased\let\Ustopmathmode        \mathstopmathmode     % idem
1368
1369%D Also better here:
1370
1371\immutable\def\wildcardsymbol{*}
1372
1373%D For a while we will keep these useless numbers as for instance tikz checks for them:
1374
1375\immutable\integerdef\eTeXversion    2
1376\immutable\def       \eTeXrevision {.2} % there is a funny period here
1377
1378% %D Just in case users use this (or some styles still have it):
1379
1380\aliased\let\immediateassigned\localcontrolled
1381
1382%D Needed (maybe no longer the multiple next ones):
1383
1384\mutable\let\nexttoken   \relax
1385\mutable\let\next        \relax
1386\mutable\let\nextnext    \relax
1387\mutable\let\nextnextnext\relax
1388
1389%D For now here: will get a proper solution
1390
1391% \pushoverloadmode
1392% \mutable\let\par\par
1393% \popoverloadmode
1394
1395%D Often used as cs key:
1396
1397\mutable\let\on  \relax % \empty
1398\mutable\let\of  \relax % \empty
1399\mutable\let\and \relax % \empty
1400\mutable\let\with\relax % \empty
1401
1402\mutable\lettonothing\nop % used often
1403\mutable\lettonothing\yes % used often
1404
1405%D Another experiment:
1406
1407\def\syst_suggested_alias#1#2% expandable
1408  {\beginlocalcontrol
1409   \writestatus{suggestion}{use \string#2 instead of \string#1}%
1410   \enforced\glet#1#2%
1411   \endlocalcontrol
1412   #2}
1413
1414\permanent\protected\def\suggestedalias#1#2% old new
1415  {\ifflags#2\permanent\permanent\fi % the rest is taken with the copy
1416   \def#1{\syst_suggested_alias#1#2}}
1417
1418% A few traditional allocations (these might go too):
1419
1420% \countdef \count@   255 % hm, used in \newif .. todo: replace it there
1421% \dimendef \dimen@     0
1422% \dimendef \dimen@i    1 % global only
1423% \dimendef \dimen@ii   2
1424
1425\suggestedalias \count@   \scratchcounter
1426\suggestedalias \dimen@   \scratchdimen
1427\suggestedalias \dimen@i  \scratchdimenone
1428\suggestedalias \dimen@ii \scratchdimentwo
1429
1430%D The next feature is experimental and could go into another system module, but it
1431%D feels more natural to have it here.
1432%D
1433%D \starttyping
1434%D \begingroup
1435%D   \newlocaldimen\mydimena % \mydimena1\onepoint
1436%D   \newlocaldimen\mydimenb % \mydimenb2\onepoint
1437%D   \begingroup
1438%D     \newlocaldimen\mydimena % \mydimena3\onepoint
1439%D     \newlocaldimen\mydimenb % \mydimenb4\onepoint
1440%D     \newlocaldimen\mydimenc % \mydimenc5\onepoint
1441%D   \endgroup
1442%D \endgroup
1443%D
1444%D \begingroup
1445%D   \setlocaldimen\mydimena 1\onepoint
1446%D   \setlocaldimen\mydimenb 2\onepoint
1447%D   \begingrou
1448%D     \setlocaldimen\mydimena 3\onepoint
1449%D     \setlocaldimen\mydimenb 4\onepoint
1450%D     \setlocaldimen\mydimenc 5\onepoint
1451%D   \endgroup
1452%D \endgroup
1453%D \stoptyping
1454%D
1455%D There is a little extra overhead in the overload protection but not that much.
1456
1457% integerdef is local
1458
1459\permanent\countdef\c_syst_local_count  = 231 \c_syst_local_count  = \c_syst_max_allocated_count
1460\permanent\countdef\c_syst_local_dimen  = 232 \c_syst_local_dimen  = \c_syst_max_allocated_dimen
1461\permanent\countdef\c_syst_local_skip   = 233 \c_syst_local_skip   = \c_syst_max_allocated_skip
1462\permanent\countdef\c_syst_local_muskip = 234 \c_syst_local_muskip = \c_syst_max_allocated_muskip
1463\permanent\countdef\c_syst_local_box    = 235 \c_syst_local_box    = \c_syst_max_allocated_box
1464\permanent\countdef\c_syst_local_toks   = 236 \c_syst_local_toks   = \c_syst_max_allocated_toks
1465\permanent\countdef\c_syst_local_read   = 237 \c_syst_local_read   = \c_syst_max_allocated_read
1466\permanent\countdef\c_syst_local_write  = 238 \c_syst_local_write  = \c_syst_max_allocated_write
1467
1468\c_syst_max_allocated_count    \numexpr\c_syst_max_allocated_count   :2\relax % floor
1469\c_syst_max_allocated_dimen    \numexpr\c_syst_max_allocated_dimen   :2\relax % floor
1470\c_syst_max_allocated_skip     \numexpr\c_syst_max_allocated_skip    :2\relax % floor
1471\c_syst_max_allocated_muskip   \numexpr\c_syst_max_allocated_muskip  :2\relax % floor
1472\c_syst_max_allocated_toks     \numexpr\c_syst_max_allocated_toks    :2\relax % floor
1473\c_syst_max_allocated_box      \numexpr\c_syst_max_allocated_box     :2\relax % floor
1474\c_syst_max_allocated_read     \numexpr\c_syst_max_allocated_read    :2\relax % floor
1475\c_syst_max_allocated_write    \numexpr\c_syst_max_allocated_write   :2\relax % floor
1476
1477\permanent\protected\def\syst_local_overflow#1#2{\writestatus\m!system{no room for local #1 \string#2}\wait}
1478
1479\permanent\protected\def\setnewlocalcount#1%
1480  {\ifnum\c_syst_local_count>\c_syst_max_allocated_count
1481     \advanceby\c_syst_local_count\minusone
1482     \overloaded\frozen\countdef#1\c_syst_local_count
1483   \else
1484     \syst_local_overflow_count#1%
1485   \fi
1486   #1}
1487
1488\permanent\protected\def\setnewlocaldimen#1%
1489  {\ifnum\c_syst_local_dimen>\c_syst_max_allocated_dimen
1490     \advanceby\c_syst_local_dimen\minusone\dimendef#1\c_syst_local_dimen
1491   \else
1492     \syst_local_overflow_dimen#1%
1493   \fi
1494   #1}
1495
1496\permanent\protected\def\setnewlocalskip#1%
1497  {\ifnum\c_syst_local_skip>\c_syst_max_allocated_skip
1498     \advanceby\c_syst_local_skip\minusone
1499     \overloaded\frozen\skipdef#1\c_syst_local_skip
1500   \else
1501     \syst_local_overflow_skip#1%
1502   \fi
1503   #1}
1504
1505\permanent\protected\def\setnewlocalmuskip#1%
1506  {\ifnum\c_syst_local_muskip>\c_syst_max_allocated_muskip
1507     \advanceby\c_syst_local_muskip\minusone
1508     \overloaded\frozen\muskipdef#1\c_syst_local_muskip
1509   \else
1510     \syst_local_overflow_muskip#1%
1511   \fi
1512   #1}
1513
1514\permanent\protected\def\setnewlocaltoks#1%
1515  {\ifnum\c_syst_local_toks>\c_syst_max_allocated_toks
1516     \advanceby\c_syst_local_toks\minusone
1517     \overloaded\frozen\toksdef#1\c_syst_local_toks
1518   \else
1519     \syst_local_overflow_toks#1%
1520   \fi
1521   #1}
1522
1523\permanent\protected\def\setnewlocalbox#1%
1524  {\ifnum\c_syst_local_box>\c_syst_max_allocated_box
1525     \advanceby\c_syst_local_box\minusone
1526     \overloaded\frozen\integerdef#1\c_syst_local_box
1527   \else
1528     \syst_local_overflow_box#1%
1529   \fi
1530   \setbox#1}
1531
1532\permanent\protected\def\newlocalread#1% so no set
1533  {\ifnum\c_syst_local_read>\c_syst_max_allocated_read
1534     \advanceby\c_syst_local_read\minusone
1535     \overloaded\frozen\integerdef#1\c_syst_local_read
1536   \else
1537     \syst_local_overflow_read#1%
1538   \fi}
1539
1540\permanent\protected\def\newlocalwrite#1% so no set
1541  {\ifnum\c_syst_local_write>\c_syst_max_allocated_write
1542     \advanceby\c_syst_local_write\minusone
1543     \overloaded\frozen\integerdef#1\c_syst_local_write
1544   \else
1545     \syst_local_overflow_write#1%
1546   \fi}
1547
1548%D The error handlers:
1549
1550\permanent\protected\def\syst_local_overflow_count {\syst_local_overflow {count}}
1551\permanent\protected\def\syst_local_overflow_dimen {\syst_local_overflow {dimen}}
1552\permanent\protected\def\syst_local_overflow_skip  {\syst_local_overflow  {skip}}
1553\permanent\protected\def\syst_local_overflow_muskip{\syst_local_overflow{muskip}}
1554\permanent\protected\def\syst_local_overflow_toks  {\syst_local_overflow  {toks}}
1555\permanent\protected\def\syst_local_overflow_box   {\syst_local_overflow   {box}}
1556\permanent\protected\def\syst_local_overflow_read  {\syst_local_overflow  {read}}
1557\permanent\protected\def\syst_local_overflow_write {\syst_local_overflow {write}}
1558
1559%D We sacrifice a little performance but save some tokens by not defining these
1560%D completely:
1561
1562\permanent\protected\def\newlocalcount #1{\setnewlocalcount #1\zerocount }
1563\permanent\protected\def\newlocaldimen #1{\setnewlocaldimen #1\zeropoint }
1564\permanent\protected\def\newlocalskip  #1{\setnewlocalskip  #1\zeroskip  }
1565\permanent\protected\def\newlocalmuskip#1{\setnewlocalmuskip#1\zeromuskip}
1566\permanent\protected\def\newlocaltoks  #1{\setnewlocaltoks  #1\emptytoks }
1567\permanent\protected\def\newlocalbox   #1{\setnewlocalbox   #1\emptybox  }
1568
1569%D Let's be detailed: grouplevel:inputlevel:catcodetable (bits 1 2 4)
1570
1571\tracinglevels\plusthree
1572
1573\permanent\protected\def\tracingcatcodes{\tracinglevels\plusseven}
1574
1575%D We just report duplicate patterns being ignored:
1576
1577\tracinghyphenation\plusone
1578
1579%D Sometimes nicer:
1580
1581\let\ifexpression\ifnumexpression
1582
1583%D So we register implicit (newline) pars. When we set bit 2 and define a macro
1584%D with \type {\par} as delimiter, an explicit \par is expected and newline pars
1585%D are then part of the argument.
1586
1587% newline :
1588%     bit 1: text
1589%         set  : <end_paragraph_cmd,new_line_end_paragraph_code>
1590%         unset: par_loc
1591%     bit 2: macro
1592%         set  : par_command_match
1593%         unset: use token
1594%     bit 3: go on
1595%         set  : don't increment loc
1596%         unset: increment loc
1597%
1598%     default:
1599%         inject : par_loc
1600%         macro  : use token
1601%         input  : increment loc
1602%
1603%     only      bit 1 set: macros work with \par as normal
1604%     when also bit 2 set: embedded empty lines grabbed too
1605
1606\autoparagraphmode\plusone
1607
1608%D The same values apply as \type {\shownodedetails}. When set the box is shown in
1609%D the the log file but that is pretty slow when we have much detail.
1610
1611\tracingfullboxes\zerocount
1612
1613%D We don't do this:
1614
1615% \setdefaultmathcodes % initializes traditional codes
1616
1617%D Catch
1618
1619\ifdefined\mathpunctuation \else \let\mathpunctuation\mathpunct \fi % fixed in 2.10.06
1620
1621%D We keep this for a while (suggested correction by KB):
1622
1623\ifdefined\linebreakcriterion   \aliased\let\linebreakcriterium  \linebreakcriterion   \fi
1624\ifdefined\ignoredepthcriterion \aliased\let\ignoredepthcriterium\ignoredepthcriterion \fi
1625
1626%D Special purpose:
1627
1628\permanent\protected\def\if_false{\iffalse}
1629\permanent\protected\def\if_true {\iftrue}
1630
1631%D Pseudo primitives:
1632
1633\permanent\untraced\def\localcontrolledrepeating{\localcontrolledrepeat\maxcount}
1634\permanent\untraced\def\expandedrepeating       {\expandedrepeat       \maxcount}
1635\permanent\untraced\def\unexpandedrepeating     {\unexpandedrepeat     \maxcount}
1636
1637\aliased\let\lastchkinteger\lastchknumber
1638\aliased\let\ifchkinteger  \ifchknumber
1639
1640%D Let's be neat:
1641
1642\permanent\untraced\def\userunitcode#1#2%
1643  {\numexpr(`#1-\alowercaseasciicode)*26+(`#2-\alowercaseasciicode)\relax}
1644
1645\permanent\protected\def\newuserunit#1#2#3%
1646  {\associateunit#1=\numexpr(`#2-\alowercaseasciicode)*26+(`#3-\alowercaseasciicode)\relax}
1647
1648\newdimension\piunit \piunit 3.1415926535898pt % 205887sp % for Mikael
1649\newdimension\ftunit \ftunit 12in              % foot     % for Alan
1650\newdimension\uunit  \uunit  1cm
1651
1652\newuserunit \piunit pi
1653\newuserunit \ftunit ft
1654\newuserunit \uunit  uu
1655
1656%D We enable special escapes:
1657
1658\parametermode \plusone
1659
1660%D While the buildbot is down:
1661
1662\ifdefined\protecteddetokenize\else
1663    \aliased\let\protecteddetokenize\detokenize
1664\fi
1665
1666%D Consistency:
1667
1668\let\boxwidth \wd
1669\let\boxheight\ht
1670\let\boxdepth \dp
1671
1672\protect \endinput
1673
1674% performance experiment:
1675%
1676% \def\footest
1677%   {\iftrue
1678%      \relax\relax\relax\relax\relax\relax\relax\relax\relax\relax
1679%      \relax\relax\relax\relax\relax\relax\relax\relax\relax\relax
1680%    % \quitfinow\ignorerest % n=11000000 : 0.304 -> 0.224
1681%    \else
1682%      \relax\relax\relax\relax\relax\relax\relax\relax\relax\relax
1683%      \relax\relax\relax\relax\relax\relax\relax\relax\relax\relax
1684%    \fi}
1685