syst-ini.mkxl /size: 71 Kb    last modification: 2025-02-21 11: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_max_allocated_attribute = \directlua{tex.write(tex.magicconstants.max_attribute_register_index)}
320
321\permanent\countdef\c_syst_max_allocated_count     = 211 \c_syst_max_allocated_count     = \directlua{tex.write(tex.magicconstants.max_integer_register_index)}
322\permanent\countdef\c_syst_max_allocated_dimen     = 212 \c_syst_max_allocated_dimen     = \directlua{tex.write(tex.magicconstants.max_dimension_register_index)}
323\permanent\countdef\c_syst_max_allocated_skip      = 213 \c_syst_max_allocated_skip      = \directlua{tex.write(tex.magicconstants.max_glue_register_index)}
324\permanent\countdef\c_syst_max_allocated_muskip    = 214 \c_syst_max_allocated_muskip    = \directlua{tex.write(tex.magicconstants.max_muglue_register_index)}
325\permanent\countdef\c_syst_max_allocated_box       = 215 \c_syst_max_allocated_box       = \directlua{tex.write(tex.magicconstants.max_box_register_index)}
326\permanent\countdef\c_syst_max_allocated_toks      = 216 \c_syst_max_allocated_toks      = \directlua{tex.write(tex.magicconstants.max_toks_register_index)}
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_allocated_mvl       = 231 \c_syst_min_allocated_mvl       = \directlua{tex.write(tex.magicconstants.min_mvl_index)}
343\permanent\countdef\c_syst_max_allocated_mvl       = 232 \c_syst_max_allocated_mvl       = \directlua{tex.write(tex.magicconstants.max_mvl_index)}
344\permanent\countdef\c_syst_last_allocated_mvl      = 233 \c_syst_last_allocated_mvl      = \c_syst_min_allocated_mvl
345
346\permanent\countdef\c_syst_min_counter_value       = 253 \c_syst_min_counter_value       = -"7FFFFFFF
347\permanent\countdef\c_syst_max_counter_value       = 254 \c_syst_max_counter_value       =  "7FFFFFFF
348
349\immutable\integerdef\zerocount       0
350\immutable\integerdef\plusone         1
351\immutable\integerdef\minusone       -1
352
353\immutable\integerdef\normalpagebox  255
354\immutable\integerdef\delayedpagebox 254
355
356\immutable\integerdef\statuswrite \minusone
357
358\immutable\dimensiondef\zeropoint 0pt
359
360\immutable\positdef\zerofloat 0
361
362%D These alternatives avoid the indirect references. Don't use these for generic
363%D code because one never knows what happens elsewhere.
364
365% \permanent\protected\def\newinteger   #1{\ifdefined#1\else\integerdef   #1\fi\zerocount} % can be relax
366% \permanent\protected\def\newdimension #1{\ifdefined#1\else\dimensiondef #1\fi\zeropoint}
367% \permanent\protected\def\newgluespec  #1{\ifdefined#1\else\gluespecdef  #1\fi\zeropoint}
368% \permanent\protected\def\newmugluespec#1{\ifdefined#1\else\mugluespecdef#1\fi\zeropoint}
369
370\permanent\protected\def\newinteger   #1{\integerdef   #1\zerocount}
371\permanent\protected\def\newdimension #1{\dimensiondef #1\zeropoint}
372\permanent\protected\def\newgluespec  #1{\gluespecdef  #1\zeropoint}
373\permanent\protected\def\newmugluespec#1{\mugluespecdef#1\zeropoint}
374\permanent\protected\def\newposit     #1{\positdef     #1\zerocount}
375
376%D The aliasing here is tricky: we need to make sure the alias is not let to the
377%D current value but behaves dynamic. Instead we can use just \newcount, unless of
378%D course I introduce a reference in the engine which is not more efficient so then
379%D one can as well use registers.
380
381\protected\def\aliasinteger  #1#2{\untraced\protected\def#1{#2}}% name parent
382\protected\def\aliasdimension#1#2{\untraced\protected\def#1{#2}}% name parent
383\protected\def\aliasposit    #1#2{\untraced\protected\def#1{#2}}% name parent
384
385%D So, effectively we start allocating from 256 and upwards. The inserts sit in the
386%D range 128 upto 254. Page numbers use the counters 0 upto 9 and the pagebox is
387%D 255. Users can use the scratch registers upto 31 without problem but all others
388%D are reserved.
389
390\permanent\let\wlog\gobbleoneargument % Let's get rid of this one.
391
392%D The allocators share a common helper macro. Marks might be changed to work in lower
393%D regions and we always assumes allocation.
394
395\permanent\protected\def\newcount {\syst_basics_allocate\c_syst_last_allocated_count \count   \countdef  \c_syst_max_allocated_count}
396\permanent\protected\def\newdimen {\syst_basics_allocate\c_syst_last_allocated_dimen \dimen   \dimendef  \c_syst_max_allocated_dimen}
397\permanent\protected\def\newskip  {\syst_basics_allocate\c_syst_last_allocated_skip  \skip    \skipdef   \c_syst_max_allocated_skip}
398\permanent\protected\def\newmuskip{\syst_basics_allocate\c_syst_last_allocated_muskip\muskip  \muskipdef \c_syst_max_allocated_muskip}
399\permanent\protected\def\newbox   {\syst_basics_allocate\c_syst_last_allocated_box   \box     \integerdef\c_syst_max_allocated_box}
400\permanent\protected\def\newtoks  {\syst_basics_allocate\c_syst_last_allocated_toks  \toks    \toksdef   \c_syst_max_allocated_toks}
401\permanent\protected\def\newread  {\syst_basics_allocate\c_syst_last_allocated_read  \read    \integerdef\c_syst_max_allocated_read}
402\permanent\protected\def\newwrite {\syst_basics_allocate\c_syst_last_allocated_write \write   \integerdef\c_syst_max_allocated_write}
403\permanent\protected\def\newmarks {\syst_basics_allocate\c_syst_last_allocated_marks \marks   \integerdef\c_syst_max_allocated_mark}
404\permanent\protected\def\newfloat {\syst_basics_allocate\c_syst_last_allocated_float \float   \floatdef  \c_syst_max_allocated_float}
405\permanent\protected\def\newmvl   {\syst_basics_allocate\c_syst_last_allocated_mvl   \flushmvl\integerdef\c_syst_max_allocated_mvl}
406
407\firstvalidlanguage \plusone % so zero is ignored in hyphenation, this might become the default
408
409%D Watch out, for the moment we disable the check for already being defined later we
410%D will revert this but first all chardefs must be replaced.
411
412\permanent\protected\def\setconstant         {}
413\permanent\protected\def\setconstantvalue#1#2{\csname#1\endcsname\numexpr#2\relax}
414
415\permanent\protected\def\newconstant#1%
416  {\ifrelax#1%
417    %\writestatus{!!!!!!!!!!}{\string #1 => RELAX}%
418     \unletfrozen#1%
419   % \newcount#1%
420     \newinteger#1%
421   \orelse\ifdefined#1%
422    %\writestatus{!!!!!!!!!!}{\string #1 => DEFINED}%
423   \else
424   % \newcount#1%
425     \newinteger#1%
426   \fi}
427
428\permanent\protected\def\setnewconstant#1{\newconstant#1#1}
429
430% %D The next definitions are really needed (in \CONTEXT):
431
432\newlinechar\newlineasciicode  \permanent\edef\outputnewlinechar{\tocharacter\newlineasciicode} % {^^J}
433
434%D One reason to start high with allocation is that it permits us to allocate
435%D consecutive ranges more easily, for instance if for \MPLIB\ we want to allocate a
436%D continuous range of boxes. It also permits us to do a proper upward allocation
437%D for inserts. The current code evolved from code that dealt with older engines but
438%D as all engines now provide many registers we removed all traces. If you ever run
439%D into the \MKII\ \type {mptopdf} code, you'll notice that some register magic was
440%D needed to fit into existing macro packages. The same is true for \PICTEX\ that we
441%D used in (generic) \PPCHTEX.
442
443\ifdefined\writestatus \else
444   %\protected\def\writestatus#1#2{\immediate\write\statuswrite{#1: #2}}
445    \frozen\protected\def\writestatus#1#2{\message{#1: #2}}
446\fi
447
448%D The above command will normally hook into the interface commands and is a
449%D protected command. We also have an \type {\diagnostic} predefined which is an
450%D expandable command:
451%D
452%D \starttyping
453%D test \diagnostic     {here 1} test
454%D test \diagnostic[2]  {here 2} test
455%D test \diagnostic[.05]{here 3} test
456%D \stoptyping
457%D
458%D The optional argument triggers a sleep in seconds.
459
460\def\syst_basics_allocate_yes#1#2#3#4#5% last class method max name
461  {\ifnum#1<#4\relax
462     \global\advanceby#1\plusone
463     \permanent\global#3#5=#1\relax
464   \else
465     \writestatus{warning}{no room for \string#2\space \string#5\space (max: \number#4)}%
466   \fi}
467
468\def\syst_basics_allocate_nop#1#2#3#4#5% last class method max name
469  {\writestatus{warning}{\string#2 \string#5 is already defined (\string\relax\space it first)}}
470
471\def\syst_basics_allocate#1#2#3#4#5% last class method max name
472  {\ifrelax#5%
473     \expandafter\syst_basics_allocate_yes
474   \orelse\ifdefined#5%
475     \expandafter\syst_basics_allocate_nop
476   \else
477     \expandafter\syst_basics_allocate_yes
478   \fi
479   #1#2#3#4#5}
480
481%D Since the number of chars exceed 256 now, we can use \type {\chardef} instead of
482%D the more limited \type {\mathchardef}.
483
484%D Attributes are something very \LUATEX. In \CONTEXT\ you are not supposed to use
485%D the attributes directly but always allocate then first. For instance attribute~0
486%D is reserved for special purposes (this might change). Attributes in the range
487%D 128-1023 are private and should not be touched.
488
489\immutable\integerdef\attributeunsetvalue\c_syst_min_counter_value % used to be \minusone
490
491% \permanent\protected\def\newattribute{\syst_basics_allocate\c_syst_last_allocated_attribute\attribute\attributedef\c_syst_max_allocated_attribute}
492
493% %D Not used by \CONTEXT\ but for instance \PICTEX\ needs it. It's a trick to force
494% %D strings instead of tokens that take more memory.
495%
496% \permanent\protected\def\newhelp#1#2{\newtoks#1#1\expandafter{\detokenize{#2}}}
497
498%D \macros
499%D   {scratchcounter,
500%D    scratchdimen,scratchskip,scratchmuskip,
501%D    scratchbox,
502%D    scratchtoks}
503%D
504%D We now define a few scratch registers, so that successive loads at least have
505%D some available. The private ones are used in cases where we don't want to
506%D intrude on normal scratch ones.
507
508\newinteger  \scratchcounter    \newinteger  \globalscratchcounter \newinteger  \privatescratchcounter
509\newposit    \scratchfloat      \newposit    \globalscratchfloat   \newposit    \privatescratchfloat
510\newdimension\scratchdimen      \newdimension\globalscratchdimen   \newdimension\privatescratchdimen
511\newgluespec \scratchskip       \newgluespec \globalscratchskip    \newgluespec \privatescratchskip
512\newmuskip   \scratchmuskip     \newmuskip   \globalscratchmuskip  \newmuskip   \privatescratchmuskip
513\newtoks     \scratchtoks       \newtoks     \globalscratchtoks    \newtoks     \privatescratchtoks
514\newbox      \scratchbox        \newbox      \globalscratchbox     \newbox      \privatescratchbox
515
516\newinteger  \scratchcounterone \newinteger  \scratchcountertwo    \newinteger  \scratchcounterthree
517\newposit    \scratchfloatone   \newposit    \scratchfloattwo      \newposit    \scratchfloatthree
518\newdimension\scratchdimenone   \newdimension\scratchdimentwo      \newdimension\scratchdimenthree
519\newgluespec \scratchskipone    \newgluespec \scratchskiptwo       \newgluespec \scratchskipthree
520\newmuskip   \scratchmuskipone  \newmuskip   \scratchmuskiptwo     \newmuskip   \scratchmuskipthree
521\newtoks     \scratchtoksone    \newtoks     \scratchtokstwo       \newtoks     \scratchtoksthree
522\newbox      \scratchboxone     \newbox      \scratchboxtwo        \newbox      \scratchboxthree
523
524\newinteger  \scratchcounterfour\newinteger  \scratchcounterfive   \newinteger  \scratchcountersix
525\newposit    \scratchfloatfour  \newposit    \scratchfloatfive     \newposit    \scratchfloatsix
526\newdimension\scratchdimenfour  \newdimension\scratchdimenfive     \newdimension\scratchdimensix
527\newgluespec \scratchskipfour   \newgluespec \scratchskipfive      \newgluespec \scratchskipsix
528\newmuskip   \scratchmuskipfour \newmuskip   \scratchmuskipfive    \newmuskip   \scratchmuskipsix
529\newtoks     \scratchtoksfour   \newtoks     \scratchtoksfive      \newtoks     \scratchtokssix
530\newbox      \scratchboxfour    \newbox       \scratchboxfive      \newbox      \scratchboxsix
531
532\newinteger\globalscratchcounterone
533\newinteger\globalscratchcountertwo
534\newinteger\globalscratchcounterthree
535
536\mutable\let\scratchmacro   \relax
537\mutable\let\scratchmacroone\relax
538\mutable\let\scratchmacrotwo\relax
539
540%D \macros
541%D   {tempstring, scratchstring*}
542
543\mutable\lettonothing\tempstring
544
545\mutable\lettonothing\scratchstring
546\mutable\lettonothing\scratchstringone
547\mutable\lettonothing\scratchstringtwo
548
549%D \macros
550%D   {scratchwidth, scratchheight, scratchdepth, scratchoffset, scratchdistance}
551%D
552%D A few more scratch dimensions:
553
554\newdimension\scratchwidth
555\newdimension\scratchheight
556\newdimension\scratchdepth
557\newdimension\scratchitalic
558\newdimension\scratchtotal
559
560\newdimension\scratchoffset
561\newdimension\scratchleftoffset
562\newdimension\scratchrightoffset
563\newdimension\scratchtopoffset
564\newdimension\scratchbottomoffset
565
566\newdimension\scratchdistance
567
568\newdimension\scratchhsize
569\newdimension\scratchvsize
570
571\newdimension\scratchxoffset
572\newdimension\scratchyoffset
573\newdimension\scratchhoffset
574\newdimension\scratchvoffset
575
576\newdimension\scratchxposition
577\newdimension\scratchyposition
578
579\newinteger\scratchnx
580\newinteger\scratchny
581
582\newinteger\scratchmx
583\newinteger\scratchmy
584
585\newinteger\scratchsx
586\newinteger\scratchsy
587
588\newinteger\scratchmin
589\newinteger\scratchmax
590
591\newinteger\scratchunicode
592\newinteger\scratchunicodeone
593\newinteger\scratchunicodetwo
594\newinteger\scratchunicodethree
595
596\newinteger\scratchclass
597
598\newdimension\scratchleftskip
599\newdimension\scratchrightskip
600\newdimension\scratchtopskip
601\newdimension\scratchbottomskip
602
603%D More allocations:
604
605% \newcount \maxcount      \immutable\maxcount      2147483647
606
607% \newdimen \zeropoint     \immutable\zeropoint     0pt
608% \newdimen \onepoint      \immutable\onepoint      1pt
609% \newdimen \halfapoint    \immutable\halfapoint    0.5pt
610% \newdimen \maxdimen      \immutable\maxdimen      16383.99999pt % 1073741823sp
611% \newdimen \onebasepoint  \immutable\onebasepoint  1bp
612% \newdimen \scaledpoint   \immutable\scaledpoint   1sp
613% \newdimen \thousandpoint \immutable\thousandpoint 1000pt
614
615\immutable\integerdef    \maxcount 2147483647
616
617%immutable\dimensiondef  \zeropoint     0pt
618\immutable\dimensiondef  \onepoint      1pt
619\immutable\dimensiondef  \twopoints     2pt
620\immutable\dimensiondef  \threepoints   3pt
621\immutable\dimensiondef  \halfapoint    0.5pt
622\immutable\dimensiondef  \maxdimen      16383.99999pt % 1073741823sp
623\immutable\dimensiondef  \onebasepoint  1bp
624\immutable\dimensiondef  \scaledpoint   1sp
625\immutable\dimensiondef  \thousandpoint 1000pt
626
627\immutable\gluespecdef   \zeroskip            \zeropoint plus \zeropoint     minus \zeropoint
628\immutable\gluespecdef   \centeringskip       \zeropoint plus \thousandpoint minus \thousandpoint
629\immutable\gluespecdef   \stretchingskip      \zeropoint plus \thousandpoint
630\immutable\gluespecdef   \shrinkingskip       \zeropoint                     minus \thousandpoint
631\immutable\gluespecdef   \centeringfillskip   \zeropoint plus 1fill          minus 1fill
632\immutable\gluespecdef   \stretchingfillskip  \zeropoint plus 1fill
633\immutable\gluespecdef   \shrinkingfillskip   \zeropoint                     minus 1fill
634\immutable\gluespecdef   \centeringfilllskip  \zeropoint plus 1filll         minus 1filll
635\immutable\gluespecdef   \stretchingfilllskip \zeropoint plus 1filll
636\immutable\gluespecdef   \shrinkingfilllskip  \zeropoint                     minus 1filll
637
638\immutable\mugluespecdef \zeromuskip 0mu
639\immutable\mugluespecdef \onemuskip  1mu
640\immutable\mugluespecdef \muquad     18mu
641
642\aliased\let\points   \onepoint
643\aliased\let\halfpoint\halfapoint
644
645\newtoks \emptytoks
646
647%D And even more: (todo: countdefs 60+). Watch out, we need a count for a negative constant
648%D but can use chardefs for positive ones. Actually, because we have plenty of counters we
649%D can also use counts for those.
650
651%immutable\integerdef\minusone                  -1
652\immutable\integerdef\minustwo                  -2
653%immutable\integerdef\zerocount                  0
654%immutable\integerdef\plusone                    1
655\immutable\integerdef\plustwo                    2  % also fitness value
656\immutable\integerdef\plusthree                  3
657\immutable\integerdef\plusfour                   4
658\immutable\integerdef\plusfive                   5
659\immutable\integerdef\plussix                    6
660\immutable\integerdef\plusseven                  7
661\immutable\integerdef\pluseight                  8
662\immutable\integerdef\plusnine                   9
663\immutable\integerdef\plusten                   10
664\immutable\integerdef\pluseleven                11
665\immutable\integerdef\plustwelve                12  % also fitness value
666\immutable\integerdef\plusthirteen              13
667\immutable\integerdef\plusfourteen              14
668\immutable\integerdef\plusfifteen               15
669\immutable\integerdef\plussixteen               16
670\immutable\integerdef\plustwentyfive            25
671\immutable\integerdef\plusfourtytwo             42  % also fitness value
672\immutable\integerdef\plusfifty                 50
673\immutable\integerdef\plusninetynine            99  % also fitness value
674\immutable\integerdef\plushundred              100
675\immutable\integerdef\plusonehundred           100
676\immutable\integerdef\plusonehundredtwentyfive 125
677\immutable\integerdef\plustwohundred           200
678\immutable\integerdef\plustwohundredfifty      250
679\immutable\integerdef\plusfivehundred          500
680\immutable\integerdef\pluscxxvii               127
681\immutable\integerdef\pluscxxviii              128
682\immutable\integerdef\pluscclv                 255
683\immutable\integerdef\pluscclvi                256
684\immutable\integerdef\plusthousand            1000
685\immutable\integerdef\plusonethousand         1000
686\immutable\integerdef\plustwothousand         2000
687\immutable\integerdef\plusthreethousand       3000
688\immutable\integerdef\plusfourthousand        4000
689\immutable\integerdef\plusfivethousand        5000
690\immutable\integerdef\plussixthousand         6000
691\immutable\integerdef\plusseventhousand       7000
692\immutable\integerdef\pluseightthousand       8000
693\immutable\integerdef\plusninethousand        9000
694\immutable\integerdef\plustenthousand        10000
695\immutable\integerdef\plustwentythousand     20000
696\immutable\integerdef\plusfifteenhundred      1500
697\immutable\integerdef\plustwentyfivehundred   2500
698\immutable\integerdef\plusfortyfivehundred    4500
699\immutable\integerdef\plusseventyfivehundred  7500
700
701\immutable\integerdef\medcard          32768
702\immutable\integerdef\maxcard          65536 % pdftex has less mathchars
703\immutable\integerdef\maxcardminusone  65535
704\immutable\integerdef\maxiterator     "FFFFF
705
706\immutable\integerdef\binaryshiftedten          1024
707\immutable\integerdef\binaryshiftedtwenty    1048576
708\immutable\integerdef\binaryshiftedthirty 1073741824
709
710%D \macros
711%D   {doubleexpandafter,tripleexpandafter,expanded,startexpanded}
712%D
713%D A few handy shortcuts
714
715\permanent\let\singleexpandafter \expandafter
716\permanent\def\doubleexpandafter{\expandafter\expandafter\expandafter}
717\permanent\def\tripleexpandafter{\expandafter\doubleexpandafter\expandafter}
718
719%D We prefer the more readable variant than in plain \TEX. User should only
720%D use \type {\emptybox}:
721
722\newbox\voidbox  % public
723
724\permanent\def\unvoidbox{\unhbox\voidbox}
725\permanent\def\emptybox {\box   \voidbox}  % used in initializations so no attributes
726\permanent\def\emptyvbox{\normalvpack{}}   % no copy as we need to set attributes
727\permanent\def\emptyhbox{\normalhpack{}}   % no copy as we need to set attributes
728
729\aliased\let\dontleavehmode\quitvmode
730
731\aliased\let\leavevmode\unvoidbox % we prefer to use \dontleavehmode and never use this one
732
733%D \macros
734%D   {dontcomplain,lessboxtracing}
735%D
736%D We need this one soon. The second one shows less box details (because that actually
737%D slows down noticeably due to the more extensive details in node content.
738
739% With \showboxdepth\maxcount and \showboxbreadth\maxcount the second one is way slower:
740%
741% \testfeatureonce{10}{\setbox\scratchbox\vbox        {\samplefile{tufte}}} \elapsedtime\par
742% \testfeatureonce{10}{\setbox\scratchbox\vbox to 10cm{\samplefile{tufte}}} \elapsedtime\par
743
744\permanent\protected\def\dontcomplain
745  {\hbadness\plustenthousand
746   \vbadness\plustenthousand
747   \hfuzz   \maxdimen
748   \vfuzz   \maxdimen}
749
750\permanent\protected\def\noboxtracing
751  {\showboxdepth  \zerocount
752   \showboxbreadth\zerocount}
753
754\permanent\protected\def\lessboxtracing
755  {\showboxdepth  \plusfive
756   \showboxbreadth\plusten}
757
758\permanent\protected\def\moreboxtracing
759  {\showboxbreadth\maxcount
760   \showboxdepth  \maxcount}
761
762%D Some expected plain variants follow. We don't reuse registers because we don't
763%D want clashes. These will go away and packages that need them have to define them.
764
765\aliased\let\p@     \onepoint
766\aliased\let\m@ne   \minusone
767\aliased\let\z@     \zeropoint
768\aliased\let\@ne    \plusone
769\aliased\let\tw@    \plustwo
770\aliased\let\thr@@  \plusthree
771\aliased\let\sixt@@n\plussixteen
772\aliased\let\@cclv  \pluscclv
773\aliased\let\@cclvi \pluscclvi
774\aliased\let\voidb@x\voidbox
775
776\newtoks    \toks@  %scratchtoks
777
778%D We define \type {\newif} a la plain \TEX, but will redefine it later. As Knuth
779%D says:
780%D
781%D \startnarrower
782%D And here's a different sort of allocation: for example,
783%D
784%D \starttyping
785%D \newif\iffoo
786%D \stoptyping
787%D
788%D creates \type {\footrue}, \type {\foofalse} to go with \type {\iffoo}.
789%D \stopnarrower
790
791% \protected\def\newif#1%
792%   {\count@\escapechar
793%    \escapechar\minusone
794%    \expandafter\expandafter\expandafter\def\new_if #1{true}{\let#1\iftrue }%
795%    \expandafter\expandafter\expandafter\def\new_if#1{false}{\let#1\iffalse}%
796%    \new_if#1{false}% the condition starts out false
797%    \escapechar\count@}
798%
799% \def\new_if#1#2%
800%   {\csname\expandafter\if@\string#1#2\endcsname}
801%
802% \bgroup % `if' is required
803%   \uccode`1=`i \uccode`2=`f \uppercase{\gdef\if@12{}}
804% \egroup
805
806% We use \csstring so there is no need to push/pop escapechar.
807% We use different names so that we get a better error message.
808%
809% \protected\def\newif#1%
810%   {\let\new_if_saved\newif
811%    \let\newif\new_if_check
812%    \expandafter\expandafter\expandafter\def\new_if_cs #1{true}{\let#1\iftrue }%
813%    \expandafter\expandafter\expandafter\def\new_if_cs#1{false}{\let#1\iffalse}%
814%    \new_if_cs#1{false}%
815%    \let\newif\new_if_saved}
816%
817% \protected\def\new_if_cs#1#2%
818%   {\csname\expandafter\newif\csstring#1#2\endcsname}
819%
820% We wrap all into one macro (the frozen stuff adds 10% runtime):
821
822\permanent\protected\def\new_if_define#1#2%
823  {\permanent\protected\gdefcsname\expandafter\new_if_check\csstring#2true\endcsname {\enforced#1#2\iftrue }%
824   \permanent\protected\gdefcsname\expandafter\new_if_check\csstring#2false\endcsname{\enforced#1#2\iffalse}%
825   \csname\expandafter\new_if_check\csstring#2false\endcsname}
826
827\normalexpanded{\gdef\noexpand\new_if_check\string i\string f{}}
828
829\permanent\protected\def\newif      {\new_if_define\let }
830\permanent\protected\def\globalnewif{\new_if_define\glet}
831
832%D Let's test this one:
833
834\newif\ifdone  \globalnewif\ifglobaldone
835\newif\iffound \globalnewif\ifglobalfound
836
837\newif\ifscratchcondition
838\newif\ifscratchconditionone
839\newif\ifscratchconditiontwo
840
841%D This used to be a protected definition with a \type {dimexpr} but now we have
842%D it natively (less tracking noise).
843
844\aliased\let\htdp\boxtotal
845
846%D A few shortcuts (gone by now):
847
848% \permanent\protected\def\udef {\protected\def }
849% \permanent\protected\def\ugdef{\protected\gdef}
850% \permanent\protected\def\uedef{\protected\edef}
851% \permanent\protected\def\uxdef{\protected\xdef}
852
853%D For a while we keep the following, as systems like tikz need it. Best not use
854%D that one \CONTEXT. It will probably move to the tikz loader.
855
856\aliased\let\active\activecatcode
857
858%D Constants to be used with \type {\interactionmode}.
859
860% \immutable\integerdef\batchmodecode     \zerocount
861% \immutable\integerdef\nonstopmodecode   \plusone
862% \immutable\integerdef\scrollmodecode    \plustwo
863% \immutable\integerdef\errorstopmodecode \plusthree
864
865%D Of course we want even bigger log files, so we copied this from the \ETEX\
866%D source files.
867%D
868%D When watching such logs, beware of nasty side effects of \type {\scantokens},
869%D as in:
870%D
871%D \starttyping
872%D \bgroup
873%D   \lccode`a=12\lowercase{\xdef\whatever{a}}\egroup
874%D   \def\whatever{test \whatever test}
875%D   \scantokens\expandafter{\whatever}
876%D \egroup
877%D \stoptyping
878%D
879%D In \LUATEX\ we have ways around this.
880
881% no longer \errorstopmode cf. plain tex 3.141592653
882
883\permanent\protected\def\tracingall
884  {\tracingcommands  \plusfour  % > 3: show mode change independent
885   \tracingmacros    \plusthree % > 2: obey \untraced
886   \tracingoutput    \plusone
887   \tracingpages     \plusone
888   \tracingparagraphs\plustwo
889   \tracingrestores  \plusone
890   \tracinggroups    \plusone
891   \tracingifs       \plusone
892   \tracingnesting   \plusthree
893   \tracingassigns   \plustwo
894   \tracingmath      \plusone
895   \tracingalignments\plustwo   % > 1: also show preamble
896   \showboxbreadth   \maxcount
897   \showboxdepth     \maxcount
898   \tracingonline    \plusone}
899
900\permanent\protected\def\tracingless
901  {\tracingall
902   \tracingoutput    \zerocount
903   \showboxbreadth   \maxcount
904   \showboxdepth     \plusten}
905
906\permanent\protected\def\loggingall
907  {\tracingall
908   \tracingonline    \zerocount}
909
910\permanent\protected\def\tracingnone
911  {\tracingonline    \zerocount
912   \showboxdepth     \plusfive % lessboxtracing
913   \showboxbreadth   \plusten
914   \tracingalignments\zerocount
915   \tracingmath      \zerocount
916   \tracingassigns   \zerocount
917   \tracingnesting   \zerocount
918   \tracingifs       \zerocount
919   \tracinggroups    \zerocount
920   \tracingrestores  \zerocount
921   \tracingparagraphs\zerocount
922   \tracingpages     \zerocount
923   \tracingoutput    \zerocount
924   \tracingmacros    \zerocount
925   \tracingcommands  \zerocount
926   \tracingonline    \zerocount}
927
928%D When we want to see a box we can as well show all of it.
929
930% \showboxdepth  \maxcount
931% \showboxbreadth\maxcount
932
933\lessboxtracing
934
935%D Just for tracing purposes we set:
936
937\tracingstats\plusone
938
939%D This is only used when we load \CONTEXT. Nesting is not supported here.
940
941\permanent\def\pushoverloadmode
942  {\enforced\permanent\protected\edef\popoverloadmode{\normaloverloadmode\the\normaloverloadmode\enforced\let\popoverloadmode\relax}%
943   \normaloverloadmode\zerocount}
944
945\aliased\let\popoverloadmode\relax
946
947\let\pushrunstate\relax % will be defined later
948\let\poprunstate \relax % will be defined later
949
950\newtoks\everydump
951
952\pushoverloadmode
953
954\permanent\protected\def\dump
955  {\the\everydump
956   \global\everydump\emptytoks
957   \pushoverloadmode
958   \enforced\glet\dump\relax
959   \popoverloadmode
960   %let\pushoverloadmode\relax
961   %let\popoverloadmode\relax
962 % \tracingall
963   \normaldump}
964
965\permanent\protected\def\input
966  {\normalinput}
967
968\popoverloadmode
969
970%D \macros
971%D   {newconditional,
972%D    settrue, setfalse,
973%D    ifconditional,then}
974%D
975%D \TEX's lacks boolean variables, although the \PLAIN\ format implements \type
976%D {\newif}. The main disadvantage of this scheme is that it takes three hash table
977%D entries. A more memory saving alternative is presented here. A conditional is
978%D defined by:
979%D
980%D \starttyping
981%D \newconditional\doublesided
982%D \setfalse
983%D \stoptyping
984%D Setting a conditional is done by \type{\settrue} and
985%D \type{\setfalse}:
986%D
987%D \starttyping
988%D \doublesided\conditionaltrue
989%D \setfalse
990%D \stoptyping
991%D while testing is accomplished by:
992%D
993%D \starttyping
994%D \ifconditional\doublesided  ... \else ... \fi
995%D \setfalse
996%D \stoptyping
997%D We cannot use the simple scheme:
998%D
999%D \starttyping
1000%D \def\settrue #1{\let#1=\iftrue}
1001%D \def\setfalse#1{\let#1=\iffalse}
1002%D \stoptyping
1003%D
1004%D Such an implementation gives problems with nested conditionals. The next
1005%D implementation is about as fast and just as straightforward:
1006
1007\aliased\let\conditionalfalse\plusone    % maybe we will have a dedicated count/chardef
1008\aliased\let\conditionaltrue \zerocount  % maybe we will have a dedicated count/chardef
1009
1010% \permanent\protected\def\settrue #1{\integerdef#1\conditionaltrue }
1011% \permanent\protected\def\setfalse#1{\integerdef#1\conditionalfalse}
1012%
1013% \permanent\protected\def\settruevalue #1{\expandafter\integerdef\csname#1\endcsname\conditionaltrue }
1014% \permanent\protected\def\setfalsevalue#1{\expandafter\integerdef\csname#1\endcsname\conditionalfalse}
1015
1016\permanent\protected\def\settrue       #1{\enforced\let#1\conditionaltrue }
1017\permanent\protected\def\setfalse      #1{\enforced\let#1\conditionalfalse}
1018\permanent\protected\def\setconditional#1{\enforced\let#1}
1019
1020\permanent\protected\def\settruevalue #1{\enforced\letcsname#1\endcsname\conditionaltrue }
1021\permanent\protected\def\setfalsevalue#1{\enforced\letcsname#1\endcsname\conditionalfalse}
1022
1023
1024\aliased\let\newconditional\setfalse
1025%aliased\let\ifconditional \ifcase
1026\aliased\let\ifconditional \ifzeronum   % permits \unless\ifconditional
1027
1028\permanent\protected\lettonothing\then % so that we can say: \ifnum1>2\then -)
1029
1030\permanent\def\truecondition {\iftrue}
1031\permanent\def\falsecondition{\iffalse}
1032
1033% This one has to be unprotected otherwise we get a files-ends-to-soon but it's ok
1034% as conditions expand anyway.
1035
1036\permanent\def\quitcondition{\orelse\iffalse}
1037
1038%D \macros
1039%D   {newmacro,setnewmacro,newfraction}
1040%D
1041%D Let's be complete and also introduce some definers. These are not mandate
1042%D but handy for grepping. We make these mutable because they are \type
1043%D {\let} (the only advantage is that we often give them names with some
1044%D prefix.
1045
1046\permanent\protected\def\newmacro   #1{\mutable\lettonothing#1}
1047\permanent\protected\def\setnewmacro#1{\mutable\let#1}
1048
1049\permanent\protected\def\newfraction#1{\mutable\let#1\!!plusone}
1050
1051\def\!!zerocount{0} % later redefined
1052\def\!!plusone  {1} % later redefined
1053
1054%D It would be handy to have a primitive \type {\unless\ifcase} because then we
1055%D could use nicer values. Anyhow, this conditional code used to be in the \type
1056%D {syst-aux} module but is now promoted to here.
1057
1058%D \macros
1059%D   {ifzeropt}
1060%D
1061%D The next macro is both cosmetic and byte saving. It is pretty \type
1062%D {\if}||safe too. It can be used in cases like:
1063%D
1064%D \starttyping
1065%D \ifzeropt \somedimen ... \else ... \fi
1066%D \stoptyping
1067
1068\aliased\let\ifzeropt\ifzerodim % was \let\ifzeropt\ifcase
1069\aliased\let\ifzero  \ifzeronum % was \let\ifzeropt\ifcase
1070
1071% these token list helpers might move to syst-aux.mkiv
1072%
1073% we assume a \cs. not toks0 or so
1074%
1075% \protected\def\appendtotoks #1#{\def\temp{#1}\afterassignment\doappendtotoks \scratchtoks=}
1076% \protected\def\prependtotoks#1#{\def\temp{#1}\afterassignment\doprependtotoks\scratchtoks=}
1077
1078\newtoks\t_syst_toks_temp \let\m_syst_toks_temp\t_syst_toks_temp
1079
1080\permanent\protected\def\appendtotoks #1{\let\m_syst_toks_temp#1\afterassignment\syst_toks_append_l \t_syst_toks_temp=}
1081\permanent\protected\def\prependtotoks#1{\let\m_syst_toks_temp#1\afterassignment\syst_toks_prepend_l\t_syst_toks_temp=}
1082
1083% \def\syst_toks_append {\m_syst_toks_temp\expandafter\expandafter\expandafter{\expandafter\the\expandafter\m_syst_toks_temp\the\t_syst_toks_temp}}}
1084% \def\syst_toks_prepend{\m_syst_toks_temp\expandafter\expandafter\expandafter{\expandafter\the\expandafter\t_syst_toks_temp\the\m_syst_toks_temp}}}
1085
1086\permanent\protected\def\globalappendtotoks #1{\let\m_syst_toks_temp#1\afterassignment\syst_toks_append_g \t_syst_toks_temp=}
1087\permanent\protected\def\globalprependtotoks#1{\let\m_syst_toks_temp#1\afterassignment\syst_toks_prepend_g\t_syst_toks_temp=}
1088
1089\def\syst_toks_append_l {\normalexpanded{\m_syst_toks_temp{\the\m_syst_toks_temp\the\t_syst_toks_temp}}}
1090\def\syst_toks_prepend_l{\normalexpanded{\m_syst_toks_temp{\the\t_syst_toks_temp\the\m_syst_toks_temp}}}
1091
1092\def\syst_toks_append_g {\global\syst_toks_append_l }
1093\def\syst_toks_prepend_g{\global\syst_toks_prepend_l}
1094
1095\permanent\protected\def\addtotoks      #1{\let\m_syst_toks_temp#1\afterassignment\syst_toks_add_l\let\next}
1096\permanent\protected\def\globaladdtotoks#1{\let\m_syst_toks_temp#1\afterassignment\syst_toks_add_g\let\next}
1097
1098\def\syst_toks_add_l{\m_syst_toks_temp\expandafter\bgroup\the\m_syst_toks_temp}
1099\def\syst_toks_add_g{\global\syst_toks_add_l}
1100
1101\permanent\protected\def\addtotokscs      #1#2{#1{\the#1#2}}        % saves a few bytes
1102\permanent\protected\def\globaladdtotokscs#1#2{\global#1{\the#1#2}} % saves a few bytes
1103
1104%D \macros
1105%D   {begcsname}
1106%D
1107%D Handy for \ETEX-only usage (avoids making \type {\relax}'s:
1108
1109% \def\begcsname#1\endcsname{\ifcsname#1\endcsname\csname#1\endcsname\fi}
1110
1111\aliased\let\begcsname\begincsname
1112
1113%D Now come a few macros that might be needed in successive loading. We redefine the
1114%D \type {\par} primitive pretty soon so that we get the equivalents right.
1115
1116% too tricky: \par is use more often than a par starts so we have too much change
1117% that we get assymetrical behaviour
1118%
1119% \newtoks\everyendpar
1120%
1121% \protected\def\endpar{\the\everyendpar\normalpar}
1122% \protected\def\par   {\endpar}
1123%
1124% \protected\def\reseteverypar
1125%   {\everypar   \emptytoks
1126%    \everyendpar\emptytoks}
1127
1128\permanent\protected\def\reseteverypar
1129  {\everypar\emptytoks}
1130
1131\aliased\let\endgraf\par % plain, a kind of funny name
1132%aliased\let\endline\cr  % plain, not needed and probably also confusing
1133
1134\permanent\protected\def\null{\hpack{}}
1135
1136%D The following two might be overloaded later on but some modules need then
1137%D earlier. These functionality is reflected in the name and will not change.
1138
1139% \bgroup
1140%     \catcode`\^^M=\activecatcode%
1141%     \gdef\obeylines{\catcode`\^^M\activecatcode \let^^M\par}%
1142%     \glet^^M\par%
1143% \egroup
1144%
1145% \bgroup
1146%     \gdef\obeyspaces{\catcode`\ \activecatcode}%
1147%     \obeyspaces\glet =\space%
1148% \egroup
1149
1150\def\obeylines {\catcode\endoflineasciicode\activecatcode\letcharcode\endoflineasciicode\par  } % check if these can be \permanent
1151\def\obeyspaces{\catcode\spaceasciicode    \activecatcode\letcharcode\spaceasciicode    \space} % check if these can be \permanent
1152
1153% %D A constant:
1154%
1155% \let\endoflinetoken=^^M
1156
1157%D Also needed might be a simple loop structure and we borrow plain \TEX's one
1158%D as it is often expected to be present and it is about the fastest you can
1159%D get. Beware: this macro does not support nested loops. We use a namespace
1160%D prefix \type {@@pln}.
1161
1162\let\syst_plain_body\relax
1163
1164\permanent\def\loop#1\repeat{\def\syst_plain_body{#1}\syst_plain_iterate} % might go
1165
1166%D The following makes \type {\loop} \unknown\ \type {\if} \unknown\ \type
1167%D {\repeat} skippable (clever trick):
1168
1169\permanent\let\repeat\fi % so both \loop and \repeat are reserved words!
1170
1171%D The original (no \type {syst_plain_} there):
1172%D
1173%D \starttyping
1174%D \def\syst_plain_iterate
1175%D   {\syst_plain_body
1176%D    \let\next\syst_plain_iterate
1177%D    \else
1178%D      \let\next\relax
1179%D    \fi
1180%D    \next}
1181%D \stoptyping
1182%D
1183%D A more efficient alternative:
1184%D
1185%D \starttyping
1186%D \def\syst_plain_iterate
1187%D   {\syst_plain_body
1188%D    \expandafter\syst_plain_iterate
1189%D    \else\expandafter\relax\fi}
1190%D \stoptyping
1191%D
1192%D An even more efficient one:
1193
1194\def\syst_plain_iterate
1195  {\syst_plain_body
1196   \expandafter\syst_plain_iterate\else\fi}
1197
1198%D We don't define a real output routine yet but at least get rid of pages:
1199
1200\output{\shipout\box\normalpagebox}
1201
1202%D Although we don't add pagenumbers yet we alias the default register used
1203%D for counting pages:
1204
1205\permanent\countdef\pageno\zerocount \pageno\plusone % first page is number 1
1206
1207%D Beside the raw counter \type {\pageno} the \type {\folio} macro provides
1208%D the value.
1209
1210\permanent\def\folio{\the\pageno} % kind of expected and therefore reserved
1211
1212%D The following registers are kind of standard and (for the moment) we define
1213%D them here. This might change.
1214
1215\newgluespec \bigskipamount    \bigskipamount   = 12pt plus 4pt minus 4pt
1216\newgluespec \medskipamount    \medskipamount   =  6pt plus 2pt minus 2pt
1217\newgluespec \smallskipamount  \smallskipamount =  3pt plus 1pt minus 1pt
1218
1219\baselineskip  = 12pt
1220\lineskip      =  1pt
1221\lineskiplimit =  0pt
1222
1223%D Sometimes kerns make more sense than glue but we need to be in the right mode:
1224
1225\ifdefined\vkern    \else \permanent\protected\def\vkern   {\ifhmode\par           \fi\kern}    \fi
1226\ifdefined\hkern    \else \permanent\protected\def\hkern   {\ifvmode\dontleavehmode\fi\kern}    \fi
1227
1228\ifdefined\vpenalty \else \permanent\protected\def\vpenalty{\ifhmode\par           \fi\penalty} \fi
1229\ifdefined\hpenalty \else \permanent\protected\def\hpenalty{\ifvmode\dontleavehmode\fi\penalty} \fi
1230
1231%D Again a few kind-of-extensions the core. These come from plain \TEX\ but are
1232%D probably not used in \CONTEXT.
1233
1234\newgluespec \hideskip   \hideskip  = -1000pt plus 1fill           % obsolete
1235\newgluespec \centering  \centering = 0pt plus 1000pt minus 1000pt % obsolete
1236
1237% \permanent\def\hidewidth % for alignment entries that can stick out
1238%   {\hskip\hideskip}
1239%
1240% \permanent\def\ialign % initialized \halign, to be used grouped!
1241%   {\everycr\emptytoks
1242%    \tabskip\zeroskip
1243%    \halign}
1244
1245\newcount \mscount
1246
1247\permanent\def\spanomit{\span\omit} % bypass error message
1248
1249\permanent\def\multispan#1%
1250  {\omit
1251   \mscount#1\relax
1252   \loop
1253     \ifnum\mscount>\plusone
1254       \spanomit \advanceby\mscount\minusone
1255   \repeat}
1256
1257\let\nopdfcompression        \relax % later
1258\let\onlypdfobjectcompression\relax % later
1259\let\maximumpdfcompression   \relax % later
1260\let\normalpdfcompression    \relax % later
1261
1262%D Basic status stuff.
1263
1264% \newif\ifproductionrun % already defined
1265
1266%D For those who expect this \unknown
1267
1268\ifdefined\fmtname    \else \immutable\def\fmtname   {ConTeXt Initial TeX} \fi
1269\ifdefined\fmtversion \else \immutable\def\fmtversion{3.1415926}           \fi
1270
1271%D A few bonus macros:
1272
1273%permanent\def\modulonumber#1#2{\tointeger{#2-((((#2+(#1/2))/#1)-1)*#1)}}
1274\permanent\def\modulonumber#1#2{\tointeger {#2-(#2:#1)*#1}}
1275\permanent\def\dividenumber#1#2{\tointeger{(#2-(#1/2))/#1}}
1276
1277%D These could be set at the \LUA\ end instead:
1278
1279\immutable\edef\texenginename         {\directlua{tex.print(LUATEXENGINE)}}
1280\immutable\edef\texengineversion      {\directlua{tex.print(LUATEXVERSION)}}
1281\immutable\edef\texenginefunctionality{\directlua{tex.print(LUATEXFUNCTIONALITY)}}
1282
1283%D We have no reason not to enable this:
1284
1285\savingvdiscards\plusone
1286
1287%D We only can set this one via directives (system.synctex) and we only support
1288%D the context variant. This will go away completely.
1289
1290\newcount\synctex % \let\normalsynctex\synctex
1291
1292%D We get rid of the funny \TEX\ offset defaults of one inch by setting them to zero.
1293
1294% \voffset\zeropoint \overloaded\let\voffset\relax \newdimen\voffset \let\normalvoffset\voffset
1295% \hoffset\zeropoint \overloaded\let\hoffset\relax \newdimen\hoffset \let\normalhoffset\hoffset
1296
1297\matheqnogapstep\zerocount % for now
1298
1299%D Now we define a few helpers that we need in a very early stage. We have no
1300%D message system yet but redundant definitions are fatal anyway.
1301
1302\newcount\c_syst_helpers_n_of_namespaces \c_syst_helpers_n_of_namespaces\pluseight % 1-8 reserved for catcodes
1303
1304\def\v_interfaces_prefix_template_system{\the       \c_syst_helpers_n_of_namespaces>>}
1305%def\v_interfaces_prefix_template_system{\characters\c_syst_helpers_n_of_namespaces>>} % no \characters yet
1306
1307\protected\def\installsystemnamespace#1% will be redefined
1308  {\ifcsname ??#1\endcsname
1309     \immediate\write\statuswrite{fatal error: duplicate system namespace '#1'}%
1310   \else
1311     \global\advanceby\c_syst_helpers_n_of_namespaces\plusone
1312     \immutable\cdefcsname ??#1\endcsname{\v_interfaces_prefix_template_system}%
1313   \fi}
1314
1315%D It makes more sense to have these here:
1316
1317\aliased\let\normalstartimath  \Ustartmath
1318\aliased\let\normalstopimath   \Ustopmath
1319\aliased\let\normalstartdmath  \Ustartdisplaymath
1320\aliased\let\normalstopdmath   \Ustopdisplaymath
1321
1322\aliased\let\normalUchar       \tocharacter
1323
1324% These are the old U* commands:
1325
1326\aliased\let\Usuperscript      \superscript
1327\aliased\let\Usubscript        \subscript
1328\aliased\let\Uprimescript      \primescript
1329\aliased\let\Unosuperscript    \nosuperscript
1330\aliased\let\Unosubscript      \nosubscript
1331\aliased\let\Usuperprescript   \superprescript
1332\aliased\let\Usubprescript     \subprescript
1333\aliased\let\Unosuperprescript \nosuperprescript
1334\aliased\let\Unosubprescript   \nosubprescript
1335
1336\aliased\let\Ustack            \mathstack
1337\aliased\let\Umathdict         \mathdictionary
1338\aliased\let\Umathclass        \mathclass
1339
1340\aliased\let\Ustyle            \givenmathstyle
1341
1342\aliased\let\Uchar             \tocharacter
1343
1344% Todo:
1345
1346% \aliased\let\Umathchar            \mathcharacter
1347% \aliased\let\Umathchardef         \mathcharacterdef
1348% \aliased\let\Umathdictdef         \mathdictionarydef
1349% \aliased\let\Umathchardef         \mathcharacterdef
1350
1351% \aliased\let\Udelimited           \mathdelimited           % left right math
1352% \aliased\let\Udelimiterover       \mathdelimiterover       % top math
1353% \aliased\let\Udelimiterunder      \mathdelimiterunder      % bottom math
1354
1355% \aliased\let\Uhextensible         \mathhextensible         % middle
1356% \aliased\let\Uoverdelimiter       \mathoverdelimiter       % top math
1357% \aliased\let\Uunderdelimiter      \mathunderdelimiter      % bottom math
1358
1359% \aliased\let\Uradical             \mathdelimitedradical    % left math
1360% \aliased\let\Uroot                \mathdelimitedroot       % left degree math
1361% \aliased\let\Urooted              \mathdelimitedrooted     % left right degree math
1362
1363% \aliased\let\Uabove               \mathabove
1364% \aliased\let\Uabovewithdelims     \mathabovewithdelims
1365% \aliased\let\Uatop                \mathatop
1366% \aliased\let\Uatopwithdelims      \mathatopwithdelims
1367% \aliased\let\Uover                \mathover
1368% \aliased\let\Uoverwithdelims      \mathoverwithdelims
1369% \aliased\let\Uskewed              \mathskewed
1370% \aliased\let\Uskewedwithdelims    \mathskewedwithdelims
1371% \aliased\let\Ustretched           \mathstretched
1372% \aliased\let\Ustretchedwithdelims \mathstretchedwithdelims
1373
1374% \aliased\let\Uleft                \mathleftfence
1375% \aliased\let\Umiddle              \mathmiddlefence
1376% \aliased\let\Uoperator            \mathoperator
1377% \aliased\let\Uright               \mathrightfence
1378% \aliased\let\Uvextensible         \mathvextensible
1379
1380% \aliased\let\overline             \mathoverline
1381% \aliased\let\underline            \mathunderline
1382
1383% \aliased\let\Udelimiter           \Umathdelimiter
1384% \aliased\let\Umathaccent          \Umathaccented
1385% \aliased\let\Udelcode             \mathdelimitercode
1386% \aliased\let\Umathcode            \mathcharactercode
1387
1388% \aliased\let\Umathadapttoleft     \mathadapttoleft
1389% \aliased\let\Umathadapttoright    \mathadapttoright
1390% \aliased\let\Umathlimits          \mathlimits
1391% \aliased\let\Umathnoaxis          \mathnoaxis
1392% \aliased\let\Umathnolimits        \mathnolimits
1393% \aliased\let\Umathopenupdepth     \mathopenupdepth
1394% \aliased\let\Umathopenupheight    \mathopenupheight
1395% \aliased\let\Umathphantom         \mathphantom
1396% \aliased\let\Umathsource          \mathsource
1397% \aliased\let\Umathuseaxis         \mathuseaxis
1398% \aliased\let\Umathvoid            \mathvoid
1399
1400% \aliased\let\Ustartdisplaymath    \mathstartdisplaymath % otherwise conflict
1401% \aliased\let\Ustartmath           \mathstartmath        % idem
1402% \aliased\let\Ustartmathmode       \mathstartmathmode    % idem
1403% \aliased\let\Ustopdisplaymath     \mathstopdisplaymath  % idem
1404% \aliased\let\Ustopmath            \mathstopmath         % idem
1405% \aliased\let\Ustopmathmode        \mathstopmathmode     % idem
1406
1407%D Also better here:
1408
1409\immutable\def\wildcardsymbol{*}
1410
1411%D For a while we will keep these useless numbers as for instance tikz checks for them:
1412
1413\immutable\integerdef\eTeXversion    2
1414\immutable\def       \eTeXrevision {.2} % there is a funny period here
1415
1416% %D Just in case users use this (or some styles still have it):
1417
1418\aliased\let\immediateassigned\localcontrolled
1419
1420%D Needed (maybe no longer the multiple next ones):
1421
1422\mutable\let\nexttoken   \relax
1423\mutable\let\next        \relax
1424\mutable\let\nextnext    \relax
1425\mutable\let\nextnextnext\relax
1426
1427%D For now here: will get a proper solution
1428
1429% \pushoverloadmode
1430% \mutable\let\par\par
1431% \popoverloadmode
1432
1433%D Often used as cs key:
1434
1435\mutable\let\on  \relax % \empty
1436\mutable\let\of  \relax % \empty
1437\mutable\let\and \relax % \empty
1438\mutable\let\with\relax % \empty
1439
1440\mutable\lettonothing\nop % used often
1441\mutable\lettonothing\yes % used often
1442
1443%D Another experiment:
1444
1445\def\syst_suggested_alias#1#2% expandable
1446  {\beginlocalcontrol
1447   \writestatus{suggestion}{use \string#2 instead of \string#1}%
1448   \enforced\glet#1#2%
1449   \endlocalcontrol
1450   #2}
1451
1452\permanent\protected\def\suggestedalias#1#2% old new
1453  {\ifflags#2\permanent\permanent\fi % the rest is taken with the copy
1454   \def#1{\syst_suggested_alias#1#2}}
1455
1456% A few traditional allocations (these might go too):
1457
1458% \countdef \count@   255 % hm, used in \newif .. todo: replace it there
1459% \dimendef \dimen@     0
1460% \dimendef \dimen@i    1 % global only
1461% \dimendef \dimen@ii   2
1462
1463\suggestedalias \count@   \scratchcounter
1464\suggestedalias \dimen@   \scratchdimen
1465\suggestedalias \dimen@i  \scratchdimenone
1466\suggestedalias \dimen@ii \scratchdimentwo
1467
1468%D The next feature is experimental and could go into another system module, but it
1469%D feels more natural to have it here.
1470%D
1471%D \starttyping
1472%D \begingroup
1473%D   \newlocaldimen\mydimena % \mydimena1\onepoint
1474%D   \newlocaldimen\mydimenb % \mydimenb2\onepoint
1475%D   \begingroup
1476%D     \newlocaldimen\mydimena % \mydimena3\onepoint
1477%D     \newlocaldimen\mydimenb % \mydimenb4\onepoint
1478%D     \newlocaldimen\mydimenc % \mydimenc5\onepoint
1479%D   \endgroup
1480%D \endgroup
1481%D
1482%D \begingroup
1483%D   \setlocaldimen\mydimena 1\onepoint
1484%D   \setlocaldimen\mydimenb 2\onepoint
1485%D   \begingrou
1486%D     \setlocaldimen\mydimena 3\onepoint
1487%D     \setlocaldimen\mydimenb 4\onepoint
1488%D     \setlocaldimen\mydimenc 5\onepoint
1489%D   \endgroup
1490%D \endgroup
1491%D \stoptyping
1492%D
1493%D There is a little extra overhead in the overload protection but not that much.
1494
1495% integerdef is local
1496
1497\permanent\countdef\c_syst_local_count  = 231 \c_syst_local_count  = \c_syst_max_allocated_count
1498\permanent\countdef\c_syst_local_dimen  = 232 \c_syst_local_dimen  = \c_syst_max_allocated_dimen
1499\permanent\countdef\c_syst_local_skip   = 233 \c_syst_local_skip   = \c_syst_max_allocated_skip
1500\permanent\countdef\c_syst_local_muskip = 234 \c_syst_local_muskip = \c_syst_max_allocated_muskip
1501\permanent\countdef\c_syst_local_box    = 235 \c_syst_local_box    = \c_syst_max_allocated_box
1502\permanent\countdef\c_syst_local_toks   = 236 \c_syst_local_toks   = \c_syst_max_allocated_toks
1503\permanent\countdef\c_syst_local_read   = 237 \c_syst_local_read   = \c_syst_max_allocated_read
1504\permanent\countdef\c_syst_local_write  = 238 \c_syst_local_write  = \c_syst_max_allocated_write
1505
1506\c_syst_max_allocated_count    \numexpr\c_syst_max_allocated_count   :2\relax % floor
1507\c_syst_max_allocated_dimen    \numexpr\c_syst_max_allocated_dimen   :2\relax % floor
1508\c_syst_max_allocated_skip     \numexpr\c_syst_max_allocated_skip    :2\relax % floor
1509\c_syst_max_allocated_muskip   \numexpr\c_syst_max_allocated_muskip  :2\relax % floor
1510\c_syst_max_allocated_toks     \numexpr\c_syst_max_allocated_toks    :2\relax % floor
1511\c_syst_max_allocated_box      \numexpr\c_syst_max_allocated_box     :2\relax % floor
1512\c_syst_max_allocated_read     \numexpr\c_syst_max_allocated_read    :2\relax % floor
1513\c_syst_max_allocated_write    \numexpr\c_syst_max_allocated_write   :2\relax % floor
1514
1515\permanent\protected\def\syst_local_overflow#1#2{\writestatus\m!system{no room for local #1 \string#2}\wait}
1516
1517\permanent\protected\def\setnewlocalcount#1%
1518  {\ifnum\c_syst_local_count>\c_syst_max_allocated_count
1519     \advanceby\c_syst_local_count\minusone
1520     \overloaded\frozen\countdef#1\c_syst_local_count
1521   \else
1522     \syst_local_overflow_count#1%
1523   \fi
1524   #1}
1525
1526\permanent\protected\def\setnewlocaldimen#1%
1527  {\ifnum\c_syst_local_dimen>\c_syst_max_allocated_dimen
1528     \advanceby\c_syst_local_dimen\minusone\dimendef#1\c_syst_local_dimen
1529   \else
1530     \syst_local_overflow_dimen#1%
1531   \fi
1532   #1}
1533
1534\permanent\protected\def\setnewlocalskip#1%
1535  {\ifnum\c_syst_local_skip>\c_syst_max_allocated_skip
1536     \advanceby\c_syst_local_skip\minusone
1537     \overloaded\frozen\skipdef#1\c_syst_local_skip
1538   \else
1539     \syst_local_overflow_skip#1%
1540   \fi
1541   #1}
1542
1543\permanent\protected\def\setnewlocalmuskip#1%
1544  {\ifnum\c_syst_local_muskip>\c_syst_max_allocated_muskip
1545     \advanceby\c_syst_local_muskip\minusone
1546     \overloaded\frozen\muskipdef#1\c_syst_local_muskip
1547   \else
1548     \syst_local_overflow_muskip#1%
1549   \fi
1550   #1}
1551
1552\permanent\protected\def\setnewlocaltoks#1%
1553  {\ifnum\c_syst_local_toks>\c_syst_max_allocated_toks
1554     \advanceby\c_syst_local_toks\minusone
1555     \overloaded\frozen\toksdef#1\c_syst_local_toks
1556   \else
1557     \syst_local_overflow_toks#1%
1558   \fi
1559   #1}
1560
1561\permanent\protected\def\setnewlocalbox#1%
1562  {\ifnum\c_syst_local_box>\c_syst_max_allocated_box
1563     \advanceby\c_syst_local_box\minusone
1564     \overloaded\frozen\integerdef#1\c_syst_local_box
1565   \else
1566     \syst_local_overflow_box#1%
1567   \fi
1568   \setbox#1}
1569
1570\permanent\protected\def\newlocalread#1% so no set
1571  {\ifnum\c_syst_local_read>\c_syst_max_allocated_read
1572     \advanceby\c_syst_local_read\minusone
1573     \overloaded\frozen\integerdef#1\c_syst_local_read
1574   \else
1575     \syst_local_overflow_read#1%
1576   \fi}
1577
1578\permanent\protected\def\newlocalwrite#1% so no set
1579  {\ifnum\c_syst_local_write>\c_syst_max_allocated_write
1580     \advanceby\c_syst_local_write\minusone
1581     \overloaded\frozen\integerdef#1\c_syst_local_write
1582   \else
1583     \syst_local_overflow_write#1%
1584   \fi}
1585
1586%D The error handlers:
1587
1588\permanent\protected\def\syst_local_overflow_count {\syst_local_overflow {count}}
1589\permanent\protected\def\syst_local_overflow_dimen {\syst_local_overflow {dimen}}
1590\permanent\protected\def\syst_local_overflow_skip  {\syst_local_overflow  {skip}}
1591\permanent\protected\def\syst_local_overflow_muskip{\syst_local_overflow{muskip}}
1592\permanent\protected\def\syst_local_overflow_toks  {\syst_local_overflow  {toks}}
1593\permanent\protected\def\syst_local_overflow_box   {\syst_local_overflow   {box}}
1594\permanent\protected\def\syst_local_overflow_read  {\syst_local_overflow  {read}}
1595\permanent\protected\def\syst_local_overflow_write {\syst_local_overflow {write}}
1596
1597%D We sacrifice a little performance but save some tokens by not defining these
1598%D completely:
1599
1600\permanent\protected\def\newlocalcount #1{\setnewlocalcount #1\zerocount }
1601\permanent\protected\def\newlocaldimen #1{\setnewlocaldimen #1\zeropoint }
1602\permanent\protected\def\newlocalskip  #1{\setnewlocalskip  #1\zeroskip  }
1603\permanent\protected\def\newlocalmuskip#1{\setnewlocalmuskip#1\zeromuskip}
1604\permanent\protected\def\newlocaltoks  #1{\setnewlocaltoks  #1\emptytoks }
1605\permanent\protected\def\newlocalbox   #1{\setnewlocalbox   #1\emptybox  }
1606
1607%D Let's be detailed: grouplevel:inputlevel:catcodetable (bits 1 2 4)
1608
1609\tracinglevels\plusthree
1610
1611\permanent\protected\def\tracingcatcodes{\tracinglevels\plusseven}
1612
1613%D We just report duplicate patterns being ignored:
1614
1615\tracinghyphenation\plusone
1616
1617%D Sometimes nicer:
1618
1619\let\ifexpression\ifnumexpression
1620
1621%D So we register implicit (newline) pars. When we set bit 2 and define a macro
1622%D with \type {\par} as delimiter, an explicit \par is expected and newline pars
1623%D are then part of the argument.
1624
1625% newline :
1626%     bit 1: text
1627%         set  : <end_paragraph_cmd,new_line_end_paragraph_code>
1628%         unset: par_loc
1629%     bit 2: macro
1630%         set  : par_command_match
1631%         unset: use token
1632%     bit 3: go on
1633%         set  : don't increment loc
1634%         unset: increment loc
1635%
1636%     default:
1637%         inject : par_loc
1638%         macro  : use token
1639%         input  : increment loc
1640%
1641%     only      bit 1 set: macros work with \par as normal
1642%     when also bit 2 set: embedded empty lines grabbed too
1643
1644\autoparagraphmode\plusone
1645
1646%D The same values apply as \type {\shownodedetails}. When set the box is shown in
1647%D the the log file but that is pretty slow when we have much detail.
1648
1649\tracingfullboxes\zerocount
1650
1651%D We don't do this:
1652
1653% \setdefaultmathcodes % initializes traditional codes
1654
1655%D Catch
1656
1657\ifdefined\mathpunctuation \else \let\mathpunctuation\mathpunct \fi % fixed in 2.10.06
1658
1659%D We keep this for a while (suggested correction by KB):
1660
1661\ifdefined\linebreakcriterion   \aliased\let\linebreakcriterium   \linebreakcriterion   \fi
1662\ifdefined\ignoredepthcriterion \aliased\let\ignoredepthcriterium \ignoredepthcriterion \fi
1663
1664%D Special purpose:
1665
1666\permanent\protected\def\if_false{\iffalse}
1667\permanent\protected\def\if_true {\iftrue}
1668
1669%D Pseudo primitives:
1670
1671\permanent\untraced\def\localcontrolledrepeating{\localcontrolledrepeat\maxcount}
1672\permanent\untraced\def\expandedrepeating       {\expandedrepeat       \maxcount}
1673\permanent\untraced\def\unexpandedrepeating     {\unexpandedrepeat     \maxcount}
1674
1675\aliased\let\lastchkinteger\lastchknumber
1676\aliased\let\ifchkinteger  \ifchknumber
1677
1678%D Let's be neat:
1679
1680\permanent\untraced\def\userunitcode#1#2%
1681  {\numexpr(`#1-\alowercaseasciicode)*26+(`#2-\alowercaseasciicode)\relax}
1682
1683\permanent\protected\def\newuserunit#1#2#3%
1684  {\associateunit#1=\numexpr(`#2-\alowercaseasciicode)*26+(`#3-\alowercaseasciicode)\relax}
1685
1686\newdimension\piunit \piunit 3.1415926535898pt % 205887sp % for Mikael
1687\newdimension\ftunit \ftunit 12in              % foot     % for Alan
1688\newdimension\uunit  \uunit  1cm
1689
1690\newuserunit \piunit pi
1691\newuserunit \ftunit ft
1692\newuserunit \uunit  uu
1693
1694%D We enable special escapes:
1695
1696\parametermode \plusone
1697
1698%D While the buildbot is down:
1699
1700\ifdefined\protecteddetokenize\else
1701    \aliased\let\protecteddetokenize\detokenize
1702\fi
1703
1704%D Consistency:
1705
1706\let\boxwidth \wd
1707\let\boxheight\ht
1708\let\boxdepth \dp
1709
1710%D Because we use the variable class:
1711
1712\variablefam-\plustwo % obey class 7
1713
1714%D For now here:
1715
1716% \fitnessdemerits 5
1717%     99          \plusone
1718%     12          \plusone
1719%     \zerocount  \plusone
1720%     12          \plusone
1721%     99          \plusone
1722
1723
1724\pushoverloadmode
1725
1726%D We now group these penalties in specification sets. For practical purposes we no longer
1727%D use the built in single penalties but map them onto the plurals. We also redefine the
1728%D display math penalties but we never use these.
1729
1730\permanent\protected\untraced\def\widowpenalty       {\widowpenalties       \minusone} % once
1731\permanent\protected\untraced\def\clubpenalty        {\clubpenalties        \minusone} % once
1732\permanent\protected\untraced\def\displaywidowpenalty{\displaywidowpenalties\minusone} % once
1733\permanent\protected\untraced\def\brokenpenalty      {\brokenpenalties      \minusone} % singular anyway
1734\permanent\protected\untraced\def\orphanpenalty      {\orphanpenalties      \minusone} % once
1735\permanent\protected\untraced\def\toddlerpenalty     {\toddlerpenalties     \minusone} % once
1736\permanent\protected\untraced\def\interlinepenalty   {\interlinepenalties   \plusone } % repeats
1737%permanent\protected\untraced\def\adjdemerits        {\adjacentdemerits     \minusone}
1738
1739\popoverloadmode
1740
1741%D See \type {mult-sys.mkxl} for an explanation of \type {\blankspace} definition. This one
1742%D is more explanatory when ending (for instance) a keyword.
1743
1744\ifdefined\relaxedspace
1745  % could be a primitive
1746\else
1747    \normalexpanded{\permanent\let\noexpand\relaxedspace=\space\space}
1748\fi
1749
1750%D Only when testing non \CONTEXT\ usage:
1751
1752% \let\saved_reqno \eqno
1753% \let\saved_leqno \leqno
1754
1755\protect \endinput
1756
1757% performance experiment:
1758%
1759% \def\footest
1760%   {\iftrue
1761%      \relax\relax\relax\relax\relax\relax\relax\relax\relax\relax
1762%      \relax\relax\relax\relax\relax\relax\relax\relax\relax\relax
1763%    % \quitfinow\ignorerest % n=11000000 : 0.304 -> 0.224
1764%    \else
1765%      \relax\relax\relax\relax\relax\relax\relax\relax\relax\relax
1766%      \relax\relax\relax\relax\relax\relax\relax\relax\relax\relax
1767%    \fi}
1768