math-ini.mkxl /size: 204 Kb    last modification: 2025-02-21 11:03
1%D \module
2%D   [       file=math-ini,
3%D        version=2008.01.02,
4%D          title=\CONTEXT\ Math Macros,
5%D       subtitle=Initializations,
6%D         author={Hans Hagen \& Mikael Sundqvist},
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\writestatus{loading}{ConTeXt Math Macros / Initializations}
15
16% Needs checking:
17%
18% \Umathruleheight
19% \Umathruledepth
20% \Umathfractionnumup
21% \Umathfractionnumdown
22% \Umathfractiondelsize
23% \Umathskeweddelimitertolerance
24
25%D This is the \LMTX\ version of math support what evolved over decades. We started
26%D out with native display math, battled for years with the heuristic spacing,
27%D assumptions wrt number locations etc. Advanced alignments were implemented with
28%D the help of Aditya. In \MKIV\ everything got upgraded, and we ended up with three
29%D models for spacing and numbering: traditional (display), improved (using some
30%D \LUATEX\ control options), and future (using emulated display) where we also
31%D could handle multi|-|line formulas well. As \LUAMETATEX\ evolved it became clear
32%D that we should drop the first two models completely and stick to the emulated
33%D display mode combined with the ability to format multi|-|line formulas in greater
34%D detail.
35%D
36%D One can wonder what this does with compatibility. Of course we try to be
37%D interface compatible but better micro typography spacing has consequences.
38%D However, in practice it looks like we get better results without too many side
39%D effects. Also, we're not bound to for instance \AMS\ math because \CONTEXT\ is
40%D not used by scientific publishers. In fact over the 15 plus years of development
41%D (2022), no professional publisher (or large scale \TEX\ user) ever expressed
42%D interest in \LUATEX\ and \LUAMETATEX, definitely not in relation to math, which
43%D made it even more easy to upgrade the engine as well as \CONTEXT\ math and over
44%D time users have demonstrated to appreciate improvements. We can do as we like, as
45%D long as users like it too. It's with that mindset that Mikael Sundqvist and I
46%D undertook this effort which took a year to mature. It started out with
47%D implementing advanced spacing models based on inter|-|atom properties and control
48%D but stepwise more got added and improved. We also settled on the fact that fonts
49%D will never be perfect and that we need runtime fixing. That took some work but in
50%D the end put less burden on the engine.
51%D
52%D After an extremely short discussion MS and HH decided that we will not support
53%D \quote {BS ISO 80000-2:2009} because it doesn't comply to the CMS quality
54%D standards and is BS anyway.
55
56%D Musical timestamp for the April 2022 math (inline) snapping sub activity: eNerd⁴
57%D Time Capsule 2020 a.k.a. Farewell Party for Normalcy (DSD on the squeezebox with
58%D a proper DAC connected but it can hardly keep up which also counts for me with MS
59%D testing faster than I can provide variants (www.youtube.com/watch?v=xzQCqAJNOSM).
60
61\unprotect
62
63\newdimension  \mathstrutht
64\newdimension  \mathstrutdp
65\newinteger    \mathnestinglevel
66
67\newcount      \c_math_strc_hangafter
68\newdimen      \d_math_strc_hangindent
69
70\newcount      \c_strc_math_n_of_lines
71
72\newdimension  \d_strc_math_max_right
73\newdimension  \d_strc_math_first_right
74\newdimension  \d_strc_math_last_right
75
76\newdimension  \d_strc_math_max_left
77\newdimension  \d_strc_math_first_left
78\newdimension  \d_strc_math_last_left
79
80\newdimension  \d_strc_math_first_height
81\newdimension  \d_strc_math_last_depth
82
83\newdimension  \d_strc_math_display_width
84\newdimension  \d_strc_math_indent
85\newconditional\c_strc_math_indent
86
87\newdimension  \d_strc_math_left_shift
88\newdimension  \d_strc_math_right_shift
89
90\newinteger    \currentmathblob
91\newinteger    \currentmathblobnesting % could be a primitive
92
93\registerctxluafile{math-ini}{autosuffix}
94\registerctxluafile{math-dim}{autosuffix}
95%registerctxluafile{math-act}{autosuffix}
96\registerctxluafile{math-ext}{autosuffix} % might go
97\registerctxluafile{math-vfu}{autosuffix}
98\registerctxluafile{math-ttv}{autosuffix}
99\registerctxluafile{math-map}{autosuffix}
100\registerctxluafile{math-act}{autosuffix}
101\registerctxluafile{math-ren}{autosuffix}
102\registerctxluafile{math-noa}{autosuffix}
103\registerctxluafile{math-tag}{autosuffix}
104\registerctxluafile{math-fbk}{autosuffix}
105%registerctxluafile{math-dir}{autosuffix}
106\registerctxluafile{math-spa}{autosuffix}
107\registerctxluafile{math-fnt}{autosuffix}
108\registerctxluafile{math-pre}{autosuffix}
109\registerctxluafile{math-txt}{autosuffix}
110
111%D Some neat units:
112
113\aliased\let\Umathemwidth\Umathquad
114
115\protected\def\mathaxisunit    {\scaledmathaxis    \mathstyle\norelax}
116\protected\def\mathexheightunit{\scaledmathexheight\mathstyle\norelax}
117\protected\def\mathquadunit    {\scaledmathemwidth \mathstyle\norelax}
118
119\newuserunit \mathaxisunit     ma
120\newuserunit \mathexheightunit mx
121\newuserunit \mathquadunit     mq
122
123%D Basic spacing:
124
125% \mathfencesmode \plusone % gone
126
127\delimiterfactor    \plusthousand
128\delimitershortfall \zeropoint
129
130%D Low level only:
131
132% \fixedsuperorsubscriptsmodecode
133% \fixedsuperandsubscriptsmodecode
134%
135% Needed for multiple scripts:
136%
137% \mathscriptsmode\ignoreemptyscriptsmodecode
138
139\integerdef\ignoreemptyscriptsmodecode\numexpr
140    \ignoreemptysuperscriptsmodecode
141  + \ignoreemptysubscriptsmodecode
142  + \ignoreemptyprimescriptsmodecode
143\relax
144
145\mathscriptsmode\ignoreemptyscriptsmodecode % we default to this but in manuals we can set it to zero
146
147% These need to be set because otherwise the engine will not honor some font
148% properties. It also permits tracing. These might become engine defaults. As a
149% consequence we no longer check for traditional fonts but one can use font control
150% options.
151
152% \mathcontrolmode\plusone
153
154\mathfontcontrol\numexpr
155    \zerocount
156   +\overrulemathcontrolcode                % let the node family/font win over current family/font
157   +\underrulemathcontrolcode               % idem
158   +\radicalrulemathcontrolcode             % idem
159   +\fractionrulemathcontrolcode            % idem
160   +\accentskewhalfmathcontrolcode          % fall back to half width skewing when no topaccent is given
161   +\accentskewapplymathcontrolcode         % use topaccent, otherwise use skew char
162   +\applyordinarykernpairmathcontrolcode   % old fonts
163   +\applyverticalitalickernmathcontrolcode % best do this indeed
164   +\applyordinaryitalickernmathcontrolcode % best do this indeed
165 % +\applycharitalickernmathcontrolcode     % not done
166 % +\reboxcharitalickernmathcontrolcode     % old code path
167   +\applyboxeditalickernmathcontrolcode    % best do this indeed
168   +\staircasekernmathcontrolcode           % use these when set
169   +\applytextitalickernmathcontrolcode
170   +\checktextitalickernmathcontrolcode
171 % +\checkspaceitalickernmathcontrolcode    % old code path
172   +\applyscriptitalickernmathcontrolcode
173 % +\italicshapekernmathcontrolcode         % obsolete: instead of adding pre italic to the shift, inject a kern
174   +\analyzescriptnucleuscharmathcontrolcode
175   +\analyzescriptnucleuslistmathcontrolcode
176   +\analyzescriptnucleusboxmathcontrolcode
177   +\accenttopskewwithoffsetmathcontrolcode
178 % +\ignorekerndimensionsmathcontrolcode    % xits needs this (bad depth of fences)
179 % +\ignoreflataccentsmathcontrolcode
180   +\extendaccentsmathcontrolcode
181   +\extenddelimitersmathcontrolcode
182\relax
183
184% \mathpenaltiesmode\plusone
185
186% These are frozen values because otherwise we need to sync them when the predefined
187% muskip (internal) registers are changed.
188
189\immutable\mugluespecdef\defaultthickermuskip    7mu plus 5mu
190\immutable\mugluespecdef\defaultthickmuskip      5mu plus 3mu minus 1mu
191\immutable\mugluespecdef\defaultmedmuskip        4mu plus 2mu minus 2mu
192\immutable\mugluespecdef\defaultthinmuskip       3mu
193\immutable\mugluespecdef\defaulttinymuskip       2mu minus 1mu
194\immutable\mugluespecdef\defaultpettymuskip      1mu minus 0.5mu
195
196\immutable\mugluespecdef\halfthickmuskip         2.5mu plus 1.5mu minus 0.5mu
197\immutable\mugluespecdef\halfmedmuskip           2mu plus 1mu minus 1mu
198\immutable\mugluespecdef\halfthinmuskip          1.5mu
199\immutable\mugluespecdef\halftinymuskip          1mu minus 0.5mu
200\immutable\mugluespecdef\halfpettymuskip         0.5mu minus 0.25mu
201
202\immutable\mugluespecdef\hairmuskip                .15mu
203
204\immutable\integerdef   \defaultrelpenalty       500
205\immutable\integerdef   \defaultbinoppenalty     700
206\immutable\integerdef   \defaultprerelpenalty   -100
207\immutable\integerdef   \defaultprebinoppenalty -100
208
209\newmuskip\thickermuskip      \thickermuskip      \defaultthickermuskip
210\newmuskip\fencemuskip        \fencemuskip        \defaultpettymuskip
211\newmuskip\continuationmuskip \continuationmuskip \zeromuskip
212
213% Handy
214
215\setnewconstant\mathstylevariantidentity  "01234567
216\setnewconstant\mathstylevariantcramped   "11335577
217\setnewconstant\mathstylevariantuncramped "00224466
218
219% Beware: we don't support mathinner any longer. We do have construct, wrapper, ellipsis etc
220% as replacements and all inner spacing is basically unset.
221
222\setnewconstant\mathallcode             \mathclassvalue all
223\setnewconstant\mathbegincode           \mathclassvalue begin
224\setnewconstant\mathendcode             \mathclassvalue end
225\setnewconstant\mathunsetcode           \mathclassvalue unset
226
227\setnewconstant\mathordinarycode        \mathclassvalue ordinary         \aliased\let\mathordcode  \mathordinarycode
228\setnewconstant\mathoperatorcode        \mathclassvalue operator         \aliased\let\mathopcode   \mathoperatorcode
229\setnewconstant\mathbinarycode          \mathclassvalue binary           \aliased\let\mathbincode  \mathbinarycode
230\setnewconstant\mathrelationcode        \mathclassvalue relation         \aliased\let\mathrelcode  \mathrelationcode
231\setnewconstant\mathopencode            \mathclassvalue open
232\setnewconstant\mathclosecode           \mathclassvalue close
233\setnewconstant\mathpunctuationcode     \mathclassvalue punctuation      \aliased\let\mathpunctcode\mathpunctuationcode
234\setnewconstant\mathvariablecode        \mathclassvalue variable
235\setnewconstant\mathactivecode          \mathclassvalue active
236\setnewconstant\mathinnercode           \mathclassvalue inner
237\setnewconstant\mathundercode           \mathclassvalue under
238\setnewconstant\mathovercode            \mathclassvalue over
239\setnewconstant\mathfractioncode        \mathclassvalue fraction
240\setnewconstant\mathradicalcode         \mathclassvalue radical
241\setnewconstant\mathmiddlecode          \mathclassvalue middle
242\setnewconstant\mathprimecode           \mathclassvalue prime
243\setnewconstant\mathaccentcode          \mathclassvalue accent
244\setnewconstant\mathfencedcode          \mathclassvalue fenced          % unlikely to be seen but can be used
245\setnewconstant\mathghostcode           \mathclassvalue ghost           % transparent for classes
246\setnewconstant\mathvcentercode         \mathclassvalue vcenter
247\setnewconstant\mathexplicitcode        \mathclassvalue explicit        % only for for control
248\setnewconstant\mathimaginarycode       \mathclassvalue imaginary
249\setnewconstant\mathdifferentialcode    \mathclassvalue differential
250\setnewconstant\mathexponentialcode     \mathclassvalue exponential
251\setnewconstant\mathintegralcode        \mathclassvalue integral
252\setnewconstant\mathellipsiscode        \mathclassvalue ellipsis        % replacement for inner
253\setnewconstant\mathfunctioncode        \mathclassvalue function
254\setnewconstant\mathdigitcode           \mathclassvalue digit
255\setnewconstant\mathdivisioncode        \mathclassvalue division
256\setnewconstant\mathfactorialcode       \mathclassvalue factorial
257\setnewconstant\mathwrappedcode         \mathclassvalue wrapped         % replacement for inner
258\setnewconstant\mathconstructcode       \mathclassvalue construct       % replacement for inner
259\setnewconstant\mathdimensioncode       \mathclassvalue dimension
260\setnewconstant\mathunarycode           \mathclassvalue unary           % dedicated to Alan
261\setnewconstant\mathtextpunctuationcode \mathclassvalue textpunctuation % for punctuation in text font followed by interword spacing
262\setnewconstant\mathunspacedcode        \mathclassvalue unspaced        % for cases where we don't want spacing at all
263\setnewconstant\mathexperimentalcode    \mathclassvalue experimental    % for MS and HH testing purposed only
264\setnewconstant\mathfakecode            \mathclassvalue fake
265\setnewconstant\mathnumbergroupcode     \mathclassvalue numbergroup
266\setnewconstant\mathcontinuationcode    \mathclassvalue continuation
267
268%D \starttyping
269%D \enabletrackers[math.suspicious]
270%D
271%D \Umathchardef \foo \mathmaybeordinarycode 0 `o
272%D \Umathchardef \oof \mathmayberelationcode 0 `=
273%D \Umathchardef \ofo \mathmaybebinarycode   0 `+
274%D
275%D \starttext
276%D     $ \foo _ 1 \ofo \foo _ 2 \oof \foo _ 3 + 4 $
277%D \stoptext
278%D \stoptyping
279%D
280%D Gives:
281%D
282%D \starttyping
283%D mathematics     > suspicious > class 36, U+1D45C 𝑜
284%D mathematics     > suspicious > class 38, U+0002B +
285%D mathematics     > suspicious > class 37, U+0003D =
286%D \stoptyping
287
288\setnewconstant\mathmaybeordinarycode \mathclassvalue maybeordinary
289\setnewconstant\mathmayberelationcode \mathclassvalue mayberelation
290\setnewconstant\mathmaybebinarycode   \mathclassvalue maybebinary
291
292%D Chemistry
293
294\setnewconstant\mathchemicalbondcode  \mathclassvalue chemicalbond
295\setnewconstant\mathimplicationcode   \mathclassvalue implication
296
297%setnewconstant\mathtopaccentcode     \mathclassvalue topaccent    % these are private and above 31
298%setnewconstant\mathbottomaccentcode  \mathclassvalue bottomaccent % these are private and above 31
299%setnewconstant\mathdelimitercode     \mathclassvalue delimiter    % these are private and above 31
300%setnewconstant\mathrootcode          \mathclassvalue root         % these are private and above 31
301%setnewconstant\mathprimecode         \mathclassvalue prime        % these are private and above 31
302
303%letmathspacing \mathimaginarycode    \mathordinarycode \mathordinarycode \mathordinarycode \mathordinarycode
304%letmathspacing \mathdifferentialcode \mathordinarycode \mathordinarycode \mathordinarycode \mathordinarycode
305%letmathspacing \mathexponentialcode  \mathordinarycode \mathordinarycode \mathordinarycode \mathordinarycode
306%letmathspacing \mathfunctioncode     \mathordinarycode \mathordinarycode \mathordinarycode \mathordinarycode
307%letmathspacing \mathdigitcode        \mathordinarycode \mathordinarycode \mathordinarycode \mathordinarycode
308
309\copymathspacing \mathimaginarycode      \mathordinarycode
310\copymathspacing \mathdifferentialcode   \mathordinarycode
311\copymathspacing \mathfactorialcode      \mathordinarycode
312\copymathspacing \mathexponentialcode    \mathordinarycode
313\copymathspacing \mathintegralcode       \mathoperatorcode
314\copymathspacing \mathdigitcode          \mathordinarycode
315\copymathspacing \mathfunctioncode       \mathoperatorcode
316\copymathspacing \mathwrappedcode        \mathfractioncode
317\copymathspacing \mathunarycode          \mathordinarycode
318
319\copymathspacing \mathvariablecode       \mathordinarycode
320
321\copymathspacing \mathmaybeordinarycode  \mathordinarycode
322\copymathspacing \mathmayberelationcode  \mathrelationcode
323\copymathspacing \mathmaybebinarycode    \mathbinarycode
324
325%copymathspacing \mathnumbergroupcode    \mathpunctuationcode
326\copymathspacing \mathnumbergroupcode    \mathrelationcode     % for now
327
328\copymathspacing \mathchemicalbondcode   \mathordinarycode
329\copymathspacing \mathimplicationcode    \mathrelationcode
330
331\setnewconstant\mathlimopcode \plusone % these will go away
332\setnewconstant\mathnolopcode \plusone % these will go away
333
334\pushoverloadmode % so we drop \mathaccent !
335
336\aliased\let\mathordinary   \normalmathord
337\aliased\let\mathoperator   \normalmathop
338\aliased\let\mathbinary     \normalmathbin
339\aliased\let\mathrelation   \normalmathrel
340\aliased\let\mathopen       \normalmathopen
341\aliased\let\mathclose      \normalmathclose
342\aliased\let\mathpunctuation\normalmathpunct
343\aliased\let\mathinner      \normalmathinner
344
345%untraced\protected\def\mathordinary    {\mathatom \s!class \mathordinarycode    } % use \mathord
346%untraced\protected\def\mathoperator    {\mathatom \s!class \mathoperatorcode    } % use \mathop
347%untraced\protected\def\mathbinary      {\mathatom \s!class \mathbinarycode      } % use \mathbin
348%untraced\protected\def\mathrelation    {\mathatom \s!class \mathrelationcode    } % use \mathrel
349%untraced\protected\def\mathopen        {\mathatom \s!class \mathopencode        } % primitive
350%untraced\protected\def\mathclose       {\mathatom \s!class \mathclosecode       } % primitive
351%untraced\protected\def\mathpunctuation {\mathatom \s!class \mathpunctuationcode } % use \mathpunct
352%untraced\protected\def\mathinner       {\mathatom \s!class \mathinnercode       } % primitive
353%untraced\protected\def\mathover        {\mathatom \s!class \mathovercode        } % macro
354%untraced\protected\def\mathunder       {\mathatom \s!class \mathundercode       } % macro
355\untraced\protected\def\mathfraction    {\mathatom \s!class \mathfractioncode    } % use \mathfrac
356\untraced\protected\def\mathradical     {\mathatom \s!class \mathradicalcode     } % use \mathrad
357\untraced\protected\def\mathmiddle      {\mathatom \s!class \mathmiddlecode      } % primitive
358\untraced\protected\def\mathaccent      {\mathatom \s!class \mathaccentcode      } % primitive
359\untraced\protected\def\mathfenced      {\mathatom \s!class \mathfencedcode      } % primitive
360\untraced\protected\def\mathghost       {\mathatom \s!class \mathghostcode       } % primitive
361\untraced\protected\def\mathvariable    {\mathatom \s!class \mathvariablecode    } % alphabetical
362\untraced\protected\def\mathactive      {\mathatom \s!class \mathactivecode      } % useless
363\untraced\protected\def\mathvcenter     {\mathatom \s!class \mathvcentercode     } % useless
364\untraced\protected\def\mathimaginary   {\mathatom \s!class \mathimaginarycode   }
365\untraced\protected\def\mathdifferential{\mathatom \s!class \mathdifferentialcode}
366\untraced\protected\def\mathexponential {\mathatom \s!class \mathexponentialcode }
367%untraced\protected\def\mathintegral    {\mathatom \s!class \mathintegralcode    }
368%untraced\protected\def\mathfunction    {\mathatom \s!class \mathfunctioncode    } % macro
369\untraced\protected\def\mathdigit       {\mathatom \s!class \mathdigitcode       }
370%untraced\protected\def\mathexplicit    {\mathatom \s!class \mathexplicitcode    } % dangerous
371\untraced\protected\def\mathdivision    {\mathatom \s!class \mathdivisioncode    }
372\untraced\protected\def\mathfactorial   {\mathatom \s!class \mathfactorialcode   }
373\untraced\protected\def\mathwrapped     {\mathatom \s!class \mathwrappedcode     }
374\untraced\protected\def\mathconstruct   {\mathatom \s!class \mathconstructcode   }
375\untraced\protected\def\mathchemicalbond{\mathatom \s!class \mathchemicalbondcode}
376\untraced\protected\def\mathimplication {\mathatom \s!class \mathimplicationcode }
377\untraced\protected\def\mathdimension   {\mathatom \s!class \mathdimensioncode   }
378%untraced\protected\def\mathbegin       {\mathatom \s!class \mathbegincode       } % dangerous
379%untraced\protected\def\mathend         {\mathatom \s!class \mathendcode         } % dangerous
380\untraced\protected\def\mathunary       {\mathatom \s!class \mathunarycode       }
381
382\popoverloadmode
383
384% obsolete
385
386\setnewconstant\mathboxcode     \zerocount
387\setnewconstant\mathchoicecode  \zerocount
388\setnewconstant\mathalphacode   \zerocount
389\setnewconstant\mathnothingcode \zerocount
390
391%D At some point we will drop these in the \LUAMETATEX\ engine becuase we have many
392%D more options there.
393
394\pushoverloadmode
395    \untraced\permanent\protected\def\binoppenalty   {\setmathpostpenalty\mathbinarycode}
396    \untraced\permanent\protected\def\prebinoppenalty{\setmathprepenalty \mathbinarycode}
397    \untraced\permanent\protected\def\relpenalty     {\setmathpostpenalty\mathrelationcode}
398    \untraced\permanent\protected\def\prerelpenalty  {\setmathprepenalty \mathrelationcode}
399\popoverloadmode
400
401%D These verbose commands are obsolete because there are plenty more classes in
402%D \LMTX\ than in \MKIV, so \typ {\ordordspacing}, typ {\fractionclosespacing}
403%D are gone now.
404
405% \setmathignore\Umathspacebeforescript  \plusone
406% \setmathignore\Umathspaceafterscript   \plusone
407% \setmathignore\Umathradicaldegreebefore\plusone % done in math-rad.mklx
408
409\setmathignore\Umathspacebeforescript\zerocount
410\setmathignore\Umathspaceafterscript \zerocount
411
412% \setmathignore \Umathspacebeforescript\plustwo % can be set but does not init
413% \setmathignore \Umathspaceafterscript \plustwo % can be set but does not init
414
415% \setmathignore\Umathxscale\plustwo
416% \setmathignore\Umathyscale\plustwo
417
418% can become
419%
420% \setmathignore \Umathspacebeforescript\plustwo % can be set but does not init
421% \setmathignore \Umathspaceafterscript \plustwo % idem
422
423\mathslackmode       \plusone
424\mathgroupingmode    \plusone
425%mathdoublescriptmode\zerocount % -1 will give an error (as usual) .. "LLRR (left class, right class)
426
427%D \starttyping
428%D \startTEXpage[offset=1dk]
429%D     $ 1 {\red +} 2$\par
430%D     $ 1 \color[red]{+} 2$\par
431%D     \mathgroupingmode0
432%D     $ 1 {\red +} 2$\par
433%D     $ 1 \mathbinary{\red +} 2$\par
434%D     $ 1 \color[red]{+} 2$\par
435%D \stopTEXpage
436%D \stoptyping
437
438% $x ^^1__2 ^3_4 ^5_6 ^7_8 $
439
440\integerdef\defaultmathclassoptions\numexpr
441   \zerocount
442 % +\nopreslackclassoptioncode
443 % +\nopostslackclassoptioncode
444 % +\lefttopkernclassoptioncode        % applied in a late stage e.g. division
445 % +\righttopkernclassoptioncode       % applied in a late stage e.g. division
446 % +\leftbottomkernclassoptioncode     % applied in a late stage e.g. division
447 % +\rightbottomkernclassoptioncode    % applied in a late stage e.g. division
448 % +\lookaheadforendclassoptioncode    % signed whatevers
449 % +\noitaliccorrectionclassoptioncode
450 % +\openfenceclassoptioncode          % the engine doesn't really used this property but maybe
451 % +\closefenceclassoptioncode         % at some point we want to have to have access to it at
452 % +\middlefenceclassoptioncode        % lua end ... so we keep it (also in the engine) commented
453 % +\checkligatureclassoptioncode      % no font provides this so it is more a compatibility feature
454 % +\checkkernpairclassoptioncode
455 % +\flattenclassoptioncode
456 % +\omitpenaltyclassoptioncode        % old school check, we do pairwise instead
457 % +\carryoverlefttopkernclassoptioncode
458 % +\carryoverleftbottomkernclassoptioncode
459 % +\carryoverrighttopkernclassoptioncode
460 % +\carryoverrightbottomkernclassoptioncode
461 % +\preferdelimiterdimensionsclassoptioncode
462\relax
463
464% \showmakeup[penalty]
465%
466% \preinlinepenalty       23 \postinlinepenalty      56 x$xx$x\par x$x$x\par x$x^2$x\par x$!$x\par
467% \preshortinlinepenalty 123 \postshortinlinepenalty456 x$xx$x\par x$x$x\par x$x^2$x\par x$!$x\par
468
469% \immutable\integerdef\defaultpreshortinlinepenalty  150
470
471% when we want \preshortinlinepenalty to kick in here we need to have a bit more shrink
472% maybe advance it by \shortinlinemaththreshold/100
473%
474% \startbuffer[1]
475% The Pythagorean theorem states that for a right triangle with legs \im{a} and \im{b}, and hypotenuse \im{c}, it holds that \im{a^2 + b^2 = c^2}. This is a famous theorem with many different proofs.
476% \stopbuffer
477% \startbuffer[2]
478% The Pythagorean theorem states that for a right triangle with legs \im{\frac{a}{b}} and \im{\hat{b}}, and hypotenuse \im{\hat{c}}, it holds that \im{\hat{a}^2 + \hat{b}^2 = \hat{c}^2}. This is a famous theorem with many different proofs.
479% \stopbuffer
480% \hsize 12.25cm
481% \bgroup
482% \preshortinlinepenalty 300
483% \getbuffer[1]
484% \egroup
485% \bgroup
486% \xspaceskip\interwordspace plus \interwordstretch minus 2\interwordshrink
487% \spaceskip \interwordspace plus \interwordstretch minus 2\interwordshrink
488% \preshortinlinepenalty 300
489% \getbuffer[2]
490% \egroup
491
492\preshortinlinepenalty 150
493
494\appendtoks
495    \shortinlinemaththreshold\emwidth % only for boxed stuff like accents and fractions
496\to \everybodyfont
497
498%D Actually a bit low level so it might move:
499
500\permanent\protected\untraced\def\setmathoption
501  {\afterassigned
502     {\afterassigned
503        {\scratchcounter\setmathoptions\scratchcounterone
504         \bitwiseflip\scratchcounter\scratchcountertwo
505         \setmathoptions\scratchcounterone\scratchcounter}%
506      \scratchcountertwo}%
507    \scratchcounterone}
508
509\permanent\protected\untraced\def\resetmathoption
510  {\afterassigned
511     {\afterassigned
512        {\scratchcounter\setmathoptions\scratchcounterone
513         \bitwiseflip\scratchcounter-\scratchcountertwo
514         \setmathoptions\scratchcounterone\scratchcounter}%
515      \scratchcountertwo}%
516    \scratchcounterone}
517
518% \midaligned{\infofont open  : \showbits{classoptioncodes}\setmathoptions\mathopencode}
519% \midaligned{\infofont close : \showbits{classoptioncodes}\setmathoptions\mathclosecode}
520
521%D The initial values, best don't change these:
522
523\setmathoptions\mathordinarycode\numexpr
524    \zerocount
525   +\noitaliccorrectionclassoptioncode
526 % +\checkligatureclassoptioncode
527   +\checkkernpairclassoptioncode
528 % +\flattenclassoptioncode
529   +\shortinlineclassoptioncode
530\relax
531
532\setmathoptions\mathoperatorcode\numexpr
533    \zerocount
534   +\nopreslackclassoptioncode
535   +\nopostslackclassoptioncode
536 % +\checkligatureclassoptioncode
537   +\checkkernpairclassoptioncode
538\relax
539
540\setmathoptions\mathintegralcode\numexpr
541    \zerocount
542   +\nopreslackclassoptioncode
543   +\nopostslackclassoptioncode
544 % +\checkligatureclassoptioncode
545   +\checkkernpairclassoptioncode
546\relax
547
548% we tweak away weird italics so only special cases see this:
549%
550% \def\IntOr{\Umathchar\mathordinarycode"00"00222B }
551% \def\IntOp{\Umathchar\mathoperatorcode"00"00222B }
552%
553% \showglyphs \showfontitalics
554% $\IntOp\limits x \quad \IntOp\limits^1_2 x \quad \IntOp\nolimits^1_2 x $\blank
555% $\IntOr\limits x \quad \IntOr\limits^1_2 x \quad \IntOr\nolimits^1_2 x $\blank
556%
557% $\mathop{f}     (x) \quad \mathop{f}\limits     (x) \quad \mathop{f}\nolimits     (x)$\blank
558% $\mathop{f}^a_b (x) \quad \mathop{f}\limits^a_b (x) \quad \mathop{f}\nolimits^a_b (x)$\blank
559
560\setmathoptions\mathbinarycode\numexpr
561    \zerocount
562   +\nopreslackclassoptioncode
563   +\nopostslackclassoptioncode
564   +\lookaheadforendclassoptioncode
565   +\noitaliccorrectionclassoptioncode
566 % +\checkligatureclassoptioncode
567   +\checkkernpairclassoptioncode
568 % +\flattenclassoptioncode
569   +\obeynestingclassoptioncode
570   +\shortinlineclassoptioncode
571\relax
572
573\setmathoptions\mathrelationcode\numexpr
574    \zerocount
575   +\nopreslackclassoptioncode
576   +\nopostslackclassoptioncode
577   +\noitaliccorrectionclassoptioncode
578 % +\checkligatureclassoptioncode
579   +\checkkernpairclassoptioncode
580 % +\flattenclassoptioncode
581 % +\omitpenaltyclassoptioncode
582   +\obeynestingclassoptioncode
583   +\shortinlineclassoptioncode
584\relax
585
586\setmathoptions\mathimplicationcode\numexpr
587    \zerocount
588   +\nopreslackclassoptioncode
589   +\nopostslackclassoptioncode
590   +\noitaliccorrectionclassoptioncode
591 % +\checkligatureclassoptioncode
592   +\checkkernpairclassoptioncode
593 % +\flattenclassoptioncode
594 % +\omitpenaltyclassoptioncode
595   +\obeynestingclassoptioncode
596   +\shortinlineclassoptioncode
597\relax
598
599\setmathoptions\mathopencode\numexpr
600    \zerocount
601   +\nopreslackclassoptioncode
602 % +\nopostslackclassoptioncode
603   +\noitaliccorrectionclassoptioncode
604 % +\openfenceclassoptioncode
605 % +\checkligatureclassoptioncode
606   +\checkkernpairclassoptioncode
607   +\pushnestingclassoptioncode
608   +\shortinlineclassoptioncode
609\relax
610
611\setmathoptions\mathclosecode\numexpr
612    \zerocount
613 % +\nopreslackclassoptioncode
614   +\nopostslackclassoptioncode
615   +\noitaliccorrectionclassoptioncode
616 % +\closefenceclassoptioncode
617 % +\checkligatureclassoptioncode
618   +\checkkernpairclassoptioncode
619   +\raiseprimeclassoptioncode
620   +\popnestingclassoptioncode
621   +\shortinlineclassoptioncode
622\relax
623
624\setmathoptions\mathpunctuationcode\numexpr
625    \zerocount
626   +\nopreslackclassoptioncode
627   +\nopostslackclassoptioncode
628   +\noitaliccorrectionclassoptioncode
629 % +\checkligatureclassoptioncode
630 % +\flattenclassoptioncode
631   +\checkkernpairclassoptioncode
632   +\removeitaliccorrectionclassoptioncode
633   +\obeynestingclassoptioncode
634   +\shortinlineclassoptioncode
635\relax
636
637\setmathoptions\mathvariablecode\numexpr
638    \zerocount
639   +\noitaliccorrectionclassoptioncode
640   +\shortinlineclassoptioncode
641\relax
642
643\setmathoptions\mathactivecode\numexpr
644    \zerocount
645   +\noitaliccorrectionclassoptioncode
646\relax
647
648%setmathoptions\mathinnercode\numexpr
649%   \noitaliccorrectionclassoptioncode
650%  +\flattenclassoptioncode
651%relax
652
653\setmathoptions\mathmiddlecode\numexpr
654    \zerocount
655   +\noitaliccorrectionclassoptioncode
656 % +\middlefenceclassoptioncode
657   +\raiseprimeclassoptioncode
658   +\carryoverlefttopkernclassoptioncode
659   +\carryoverleftbottomkernclassoptioncode
660   +\carryoverrighttopkernclassoptioncode
661   +\carryoverrightbottomkernclassoptioncode
662   +\preferdelimiterdimensionsclassoptioncode
663\relax
664
665\setmathoptions\mathfractioncode\numexpr
666    \zerocount
667   +\nopreslackclassoptioncode
668   +\nopostslackclassoptioncode
669   +\raiseprimeclassoptioncode
670   +\carryoverlefttopkernclassoptioncode
671   +\carryoverleftbottomkernclassoptioncode
672   +\carryoverrighttopkernclassoptioncode
673   +\carryoverrightbottomkernclassoptioncode
674   +\preferdelimiterdimensionsclassoptioncode
675   +\shortinlineclassoptioncode
676\relax
677
678\setmathoptions\mathradicalcode\numexpr
679    \zerocount
680   +\nopreslackclassoptioncode
681   +\nopostslackclassoptioncode
682   +\raiseprimeclassoptioncode
683   +\carryoverlefttopkernclassoptioncode
684   +\carryoverleftbottomkernclassoptioncode
685   +\carryoverrighttopkernclassoptioncode
686   +\carryoverrightbottomkernclassoptioncode
687   +\preferdelimiterdimensionsclassoptioncode
688   +\shortinlineclassoptioncode
689\relax
690
691\setmathoptions\mathaccentcode\numexpr
692    \zerocount
693   +\nopreslackclassoptioncode
694   +\nopostslackclassoptioncode
695   +\autoinjectclassoptioncode
696   +\shortinlineclassoptioncode
697   +\lefttopkernclassoptioncode
698   +\leftbottomkernclassoptioncode
699   +\righttopkernclassoptioncode
700   +\rightbottomkernclassoptioncode
701\relax
702
703% ord spacing but with support for \m{m^2/x__3}
704
705\setmathoptions\mathdivisioncode\numexpr
706    \zerocount
707   +\nopreslackclassoptioncode
708   +\nopostslackclassoptioncode
709   +\lefttopkernclassoptioncode
710 % +\righttopkernclassoptioncode
711 % +\leftbottomkernclassoptioncode
712   +\rightbottomkernclassoptioncode
713   +\shortinlineclassoptioncode
714\relax
715
716\setmathoptions\mathbegincode\numexpr
717    \zerocount
718   +\nopostslackclassoptioncode
719\relax
720
721\setmathoptions\mathendcode\numexpr
722    \zerocount
723   +\nopreslackclassoptioncode
724\relax
725
726% Fenced is only used internally as these fences become open, middle and close
727% subtypes. If we don't set the following we should actually also define the
728% spacing rules.
729
730\setmathoptions\mathfencedcode\numexpr
731    \zerocount
732   +\unpackclassoptioncode
733   +\carryoverlefttopkernclassoptioncode
734   +\carryoverleftbottomkernclassoptioncode
735   +\carryoverrighttopkernclassoptioncode
736   +\carryoverrightbottomkernclassoptioncode
737   +\preferdelimiterdimensionsclassoptioncode
738\relax
739
740% MS will check
741
742\setmathoptions\mathexponentialcode\numexpr
743    \zerocount
744   +\shortinlineclassoptioncode
745\relax
746
747\setmathoptions\mathimaginarycode\numexpr
748    \zerocount
749   +\shortinlineclassoptioncode
750\relax
751
752\setmathoptions\mathdifferentialcode\numexpr
753    \zerocount
754   +\shortinlineclassoptioncode
755\relax
756
757\setmathoptions\mathdigitcode\numexpr
758    \zerocount
759   +\shortinlineclassoptioncode
760\relax
761
762% test case for \lefttopkernclassoptioncode and \leftbottomkernclassoptioncode in cambria close:
763%
764% \setupbodyfont[cambria]
765% %\enableexperiments[math.extensibles]
766% %\disableexperiments[math.extensibles]
767%
768% \startTEXpage[offset=1dk]
769%     \startformula \showglyphs
770%         \left\{ \mathatom class \mathfractioncode {\raise .6ex\hbox{\blackrule[color=blue,  height=3cm,depth=3cm]}} \right\} ^1 _4 +
771%         \left\( \mathatom class \mathfractioncode {\raise .6ex\hbox{\blackrule[color=green, height=4cm,depth=4cm]}} \right\) ^2 _3 -
772%         \left\{ \mathatom class \mathfractioncode {\raise .6ex\hbox{\blackrule[color=red,   height=2cm,depth=2cm]}} \right\} ^3 _2 +
773%         \left\( \mathatom class \mathfractioncode {\raise .6ex\hbox{\blackrule[color=yellow,height=1cm,depth=1cm]}} \right\) ^4 _1
774%     \stopformula
775% \stopTEXpage
776
777%D For now \unknown (todo: make it adapt to style but we're in text anyway)
778
779\permanent\protected\def\math_discretionary_plus {\discretionary class \mathbinarycode {$+$}{$+$}{$+$}}
780\permanent\protected\def\math_discretionary_minus{\discretionary class \mathbinarycode {$-$}{$-$}{$-$}}
781
782\newtoks\everymathdiscretionaries
783
784\appendtoks
785    \enforced\let\+\math_discretionary_plus
786    \enforced\let\-\math_discretionary_minus
787\to \everymathdiscretionaries
788
789\appendtoks
790    \ifconditional\c_math_discretionaries
791        \expand\everymathdiscretionaries
792    \fi
793\to \everymathematics
794
795\newconditional\c_math_discretionaries
796
797\installtexexperiment
798  {mathematics.discretionaries}
799  {\c_math_discretionaries\conditionaltrue}
800  {\c_math_discretionaries\conditionalfalse}
801
802%D This is moved here from supp-mat:
803
804\permanent\protected\def\dimension#1%
805  {\mathematics
806     {\mathatom
807        \s!leftclass  \mathdimensioncode
808        \s!rightclass \mathordinarycode
809      {\tf #1}}}
810
811\permanent\protected\def\nodimension#1%
812  {#1}
813
814%D A starter:
815%D
816%D \startbuffer
817%D \mathsurround    10pt
818%D \mathsurroundskip30pt
819%D x $x + \ruledhbox{$x$} + x$ x
820%D \stopbuffer
821%D
822%D \typebuffer
823%D
824%D \start \blank \getbuffer \blank \stop
825
826% \newinteger\mathnestinglevel % see top
827
828\appendtoks
829    \advanceby\mathnestinglevel\plusone
830\to \everymathematics
831
832%D The attributes that we will use (todo: pack some into one but uglier code):
833
834\definesystemattribute[mathalphabet]   [public]
835%definesystemattribute[mathsize]       [public] % we now use the engine features
836\definesystemattribute[mathpunctuation][public]
837\definesystemattribute[mathgreek]      [public] % will become generic
838\definesystemattribute[mathalternate]  [public]
839\definesystemattribute[mathrendering]  [public]
840\definesystemattribute[mathcategory]   [public]
841\definesystemattribute[mathmode]       [public]
842%definesystemattribute[mathitalics]    [public]
843\definesystemattribute[mathkernpairs]  [public]
844\definesystemattribute[mathbidi]       [public]
845\definesystemattribute[mathdomain]     [public]
846\definesystemattribute[mathcollapsing] [public]
847\definesystemattribute[mathunstack]    [public]
848\definesystemattribute[mathvariant]    [public]
849\definesystemattribute[mathnumbers]    [public]
850\definesystemattribute[mathspacing]    [public]
851\definesystemattribute[mathfencing]    [public]
852\definesystemattribute[mathintervals]  [public]
853
854% \mathflattenmode\numexpr
855%     \ordmathflattencode
856%    +\binmathflattencode
857%    +\relmathflattencode
858%    +\punctmathflattencode
859%    +\innermathflattencode
860% \relax
861
862\ifdefined\ordlimits\else
863    \let\ordlimits\Umathlimits % downward compatible
864\fi
865
866\appendtoks
867    \c_attr_mathmode\plusone % actually we don't use display math
868\to \everydisplay
869
870\appendtoks
871    \c_attr_mathmode\plusone
872\to \everybeforedisplayformula
873
874% defined at lua end \permanent\protected\def\resetmathattributes{\resetmathattributes}
875
876% handy
877
878\newconditional\indisplaymath
879
880\appendtoks
881    \indisplaymath\conditionalfalse
882\to \everymath
883
884\appendtoks
885    \indisplaymath\conditionaltrue % actually we don't use display math
886\to \everydisplay
887
888% \appendtoks
889%     \linebreakpasses\zerocount
890% \to \everymathematics
891
892\permanent\def\inlineordisplaymath{\ifconditional\indisplaymath\expandafter\secondoftwoarguments\else\expandafter\firstoftwoarguments\fi}
893
894\permanent\protected\def\forcedisplaymath
895  {\ifmmode
896     \displaystyle
897     \indisplaymath\conditionaltrue
898   \fi}
899
900\permanent\protected\def\forceinlinemath
901  {\ifmmode
902     \textstyle
903     \indisplaymath\conditionalfalse
904   \fi}
905
906\permanent\protected\def\startforceddisplaymath
907  {\Ustartmathmode\displaystyle
908   \begingroup % can go
909   \indisplaymath\conditionaltrue
910   \expand\everyinsidemathematics\relax % check
911}
912
913\permanent\protected\def\stopforceddisplaymath
914  {\endgroup % can go
915   \Ustopmathmode}
916
917\permanent\protected\def\startpickupmath % for the moment private
918  {\ifconditional\indisplaymath
919     \startforceddisplaymath
920     \enforced\let\stoppickupmath\stopforceddisplaymath
921   \else
922     \startimath % maybe also forced and conditional etc
923     \enforced\let\stoppickupmath\stopimath
924   \fi}
925
926\aliased\let\stoppickupmath\relax
927
928\permanent\protected\def\rawmathematics#1% slow but only for tracing
929  {\begingroup
930   \ifmmode
931     \resetmathattributes#1%
932   \else
933     \startimath\resetmathattributes#1\stopimath
934   \fi
935   \endgroup}
936
937%D Some measures (maybe spac-mth):
938
939% \def\mathskipsmall {\mskip\thinmuskip}
940% \def\mathskipmedium{\mskip\medmuskip}
941% \def\mathskipbig   {\mskip\thickmuskip}
942
943%D \macros
944%D   {setupmathematics}
945%D
946%D Configuration for integrals. (If needed we can speed this up and make it
947%D installable; no processaction is needed then).
948
949\installcorenamespace{mathematics}
950
951\installswitchcommandhandler \??mathematics {mathematics} \??mathematics
952
953\installmacrostack\currentmathematics
954
955\permanent\protected\tolerant\def\startmathematics[#1]% no grouping, if ever then also an optional second
956  {\push_macro_currentmathematics
957   \cdef\currentmathematics{#1}% check for valid
958   \expand\everyswitchmathematics}
959
960\permanent\protected\def\stopmathematics
961  {\pop_macro_currentmathematics
962   \expand\everyswitchmathematics} % only needed at level zero
963
964\definemathematics[\v!default] % not needed, but nicer when nesting back to normal
965
966% Now we redefine \type {\mathematics} and \type {\m}:
967
968\pushoverloadmode
969    \permanent\protected\def\mathematics{\doifelsenextoptionalcs\math_m_yes\math_m_nop}
970
971    \aliased\let\m   \mathematics % we keep the simple versions
972    \aliased\let\math\mathematics % we keep the simple versions
973\popoverloadmode
974
975\def\math_m_yes
976  {\relax
977   \ifmmode
978     \expandafter\math_m_yes_math
979   \else
980     \expandafter\math_m_yes_text
981   \fi}
982
983\def\math_m_yes_math[#1]#2%
984  {#2} % grouping permits \mathbf etc
985
986\def\math_m_yes_text[#S#1]%
987  {\begingroup
988   \ifhastok={#1}%
989     \setupcurrentmathematics[#1]%
990   \else
991     \cdef\currentmathematics{#1}% todo: check for valid
992   \fi
993   \expand\everyswitchmathematics % kind of special here as we append to it/ check
994   \usemathematicscolorparameter\c!color
995   \ifcstok{\mathematicsparameter\c!openup}\v!yes
996     \expandafter\math_m_yes_text_openedup
997   \else
998     \expandafter\math_m_yes_text_normal
999   \fi}
1000
1001\def\math_m_yes_text_openedup#1%
1002  {\setbox\scratchbox\hbox\bgroup
1003      \expand\everyswitchmathematics\relax
1004      \Ustartmathmode\expandedmathstyleparameter\mathematicsparameter\c!mathstyle
1005      \math_style_set_main % here
1006      \expand\everyinsidemathematics\relax
1007      #1%
1008      \Ustopmathmode
1009   \egroup
1010   \ifdim\ht\scratchbox>\strutht
1011     \math_inline_openup_start_yes
1012   \orelse\ifdim\dp\scratchbox>\strutdp
1013     \math_inline_openup_start_yes
1014   \else
1015     \math_inline_openup_start_nop
1016   \fi
1017   \unhbox\scratchbox % \normalstartimath#1\normalstopimath
1018   \math_inline_openup_stop
1019   \endgroup}
1020
1021\def\math_m_yes_text_normal#1%
1022  {\expand\everyswitchmathematics\relax
1023   \Ustartmathmode\expandedmathstyleparameter\mathematicsparameter\c!mathstyle
1024   \math_style_set_main % here
1025   \expand\everyinsidemathematics\relax
1026   \begingroup#1\endgroup % grouping permits aftergroups trickery
1027   \Ustopmathmode
1028   \endgroup}
1029
1030\def\math_m_nop#1%
1031  {\relax
1032   \ifmmode
1033     #1%
1034   \else
1035     \normalstartimath
1036     \usemathstyleparameter\mathematicsparameter\c!mathstyle
1037     \expand\everyinsidemathematics\relax
1038     \begingroup#1\endgroup % grouping permits aftergroups trickery
1039     \normalstopimath
1040   \fi}
1041
1042%D We wrap in a construct so that we can do:
1043%D
1044%D \starttyping
1045%D \startformula
1046%D     \dm{f(x) = \frac{x}{y}} \mtp{,}
1047%D     \im{g(x) = \frac{x}{y}} \mtp{.}
1048%D \stopformula
1049%D \stoptyping
1050
1051\let\math_trace_blobs\relax
1052
1053\def\math_trace_blobs_indeed_yes
1054  {\markblobindexdone{\currentlanguage}\scratchcounter
1055   \normalexpanded{\csname\v!mathnote\endcsname
1056     [\v!mathnote:\currentlanguage:\the\scratchcounter]%
1057     {\definedfont[\s!MathRoman]\getmathtextblob{\currentlanguage}\the\currentmathblob}}}
1058
1059\def\math_trace_blobs_indeed_nop
1060  {\normalexpanded{\note[\v!mathnote:\currentlanguage:\the\scratchcounter]}}
1061
1062\protected\def\math_trace_blobs_indeed
1063  {\dontleavehmode
1064   \hbox to \zeropoint \bgroup
1065      \resetinteractioncontrastcolor
1066      \resetinteractionstyle
1067      \scratchcounter\getmathblobindex\currentmathblob
1068      \bgroup
1069        \darkgray
1070        \vrule \s!height .9\strutht \s!depth .9\strutdp \s!width \onepoint \relax
1071        \hbox to \zeropoint \bgroup
1072          \smallinfofont
1073          \the\currentmathblob\hss
1074          \hbox to \zeropoint \s!yoffset -.8\strutdp \bgroup
1075            \currentlanguage
1076            \ifconditional\c_strc_tags_global
1077              \space
1078              \tohexadecimal\getmathblobmapping\currentmathblob
1079            \fi
1080            \hss
1081          \egroup
1082        \egroup
1083      \egroup
1084      \ifinsidefloat
1085        \math_trace_blobs_indeed_yes
1086      \orelse\ifblobindexdone{\currentlanguage}\scratchcounter
1087        \math_trace_blobs_indeed_nop
1088      \else
1089        \math_trace_blobs_indeed_yes
1090      \fi
1091      \hss
1092   \egroup}
1093
1094\protected\def\math_trace_blobs_checked
1095  {\iftrialtypesetting
1096     % no need for it, not even the note dimensions
1097   \orelse\ifnum\currentmathblobnesting<\zerocount\else
1098     \aftergroup\math_trace_blobs_indeed
1099   \fi}
1100
1101\installtextracker
1102  {math.textblobs}
1103  {\let\math_trace_blobs\math_trace_blobs_checked}
1104  {\let\math_trace_blobs\relax}
1105
1106\appendtoks
1107    \math_trace_blobs
1108\to \everymathematics
1109
1110\permanent\protected\def\dm#1%
1111  {\relax
1112   \ifmmode
1113    %\beginmathgroup\forcedisplaymath#1\endmathgroup
1114    %\mathconstruct{\forcedisplaymath#1}%
1115     \mathconstruct{\displaystyle\indisplaymath\conditionaltrue#1}%
1116   \else
1117    %\startimath\begingroup\forcedisplaymath#1\endgroup\stopimath
1118     \Ustartmathmode\displaystyle
1119       \indisplaymath\conditionaltrue
1120       \expand\everyinsidemathematics\relax % check
1121       #1%
1122     \Ustopmathmode % grouping for \aftergroup ?
1123   \fi}
1124
1125\permanent\protected\def\im#1%
1126  {\relax
1127   \ifmmode
1128    %\beginmathgroup\forceinlinemath#1\endmathgroup
1129    %\mathconstruct{\forceinlinemath#1}%
1130     \mathconstruct{\textstyle\indisplaymath\conditionalfalse#1}%
1131   \else
1132    %\startimath#1\stopimath
1133     \Ustartmathmode\textstyle
1134       \indisplaymath\conditionalfalse
1135       \expand\everyinsidemathematics\relax % check
1136       #1%
1137     \Ustopmathmode
1138   \fi}
1139
1140% \aliased\let\m\mathematics % we keep the simple versions
1141
1142% e.g.: \definemathematics[i:mp][setups=i:tight,openup=yes]
1143
1144% we need to control these otherwise:
1145%
1146% \prerelpenalty  \defaultprerelpenalty
1147% \prebinoppenalty\defaultprebinoppenalty
1148
1149\startsetups math:spacing:default
1150    \thickmuskip    \defaultthickmuskip
1151    \medmuskip      \defaultmedmuskip
1152    \thinmuskip     \defaultthinmuskip
1153    \tinymuskip     \defaulttinymuskip
1154    \pettymuskip    \defaultpettymuskip
1155    \relpenalty     \defaultrelpenalty
1156    \binoppenalty   \defaultbinoppenalty
1157    \prebinoppenalty\maxdimen
1158    \prerelpenalty  \maxdimen
1159\stopsetups
1160
1161\startsetups math:spacing:split
1162    \thickmuskip    \defaultthickmuskip
1163    \medmuskip      \defaultmedmuskip
1164    \thinmuskip     \defaultthinmuskip
1165    \tinymuskip     \defaulttinymuskip
1166    \pettymuskip    \defaultpettymuskip
1167    \relpenalty     \defaultrelpenalty
1168    \binoppenalty   \defaultbinoppenalty
1169    \prebinoppenalty\defaultprebinoppenalty
1170    \prerelpenalty  \defaultprerelpenalty
1171\stopsetups
1172
1173\startsetups math:spacing:half
1174    \thickmuskip    \halfthickmuskip
1175    \medmuskip      \halfmedmuskip
1176    \thinmuskip     \halfthinmuskip
1177    \tinymuskip     \halftinymuskip
1178    \pettymuskip    \halfpettymuskip
1179    \relpenalty     \defaultrelpenalty
1180    \binoppenalty   \defaultbinoppenalty
1181    \prebinoppenalty\maxdimen
1182    \prerelpenalty  \maxdimen
1183\stopsetups
1184
1185\startsetups math:spacing:tight
1186    \ifcase\raggedstatus
1187        \thickmuskip   \halfthickmuskip
1188        \medmuskip     \halfmedmuskip
1189        \thinmuskip    \halfthinmuskip
1190        \tinymuskip    \halftinymuskip
1191        \pettymuskip   \halfpettymuskip
1192    \else
1193        \thickmuskip  1\halfthickmuskip
1194        \medmuskip    1\halfmedmuskip
1195        \thinmuskip   1\halfthinmuskip
1196        \tinymuskip   1\halftinymuskip
1197        \pettymuskip  1\halfpettymuskip
1198    \fi
1199    \relpenalty     \defaultrelpenalty
1200    \binoppenalty   \maxdimen
1201    \prebinoppenalty\maxdimen
1202    \prerelpenalty  \maxdimen
1203\stopsetups
1204
1205\startsetups math:spacing:fixed
1206    \ifcase\raggedstatus
1207        \thickmuskip   \halfthickmuskip
1208        \medmuskip     \halfmedmuskip
1209        \thinmuskip    \halfthinmuskip
1210        \tinymuskip    \halftinymuskip
1211        \pettymuskip   \halfpettymuskip
1212    \else
1213        \thickmuskip  1\halfthickmuskip
1214        \medmuskip    1\halfmedmuskip
1215        \thinmuskip   1\halfthinmuskip
1216        \tinymuskip   1\halftinymuskip
1217        \pettymuskip  1\halfpettymuskip
1218    \fi
1219    \relpenalty     \maxdimen
1220    \binoppenalty   \maxdimen
1221    \prebinoppenalty\maxdimen
1222    \prerelpenalty  \maxdimen
1223\stopsetups
1224
1225% this will reset the spacing to default values
1226
1227% \Umathspacingmode\allmathstyles\plusone % always pair driven
1228
1229%D \starttyping
1230%D \startformula
1231%D f(x) = \sin x \mt{,} x
1232%D \stopformula
1233%D
1234%D $f(x) = \sin x \mt{,} x$
1235%D \stoptyping
1236
1237% mu based: 18mu == quad, preferred
1238
1239\newmuskip\mathinterwordmuskip
1240
1241% Hans:
1242%
1243% \mathinterwordmuskip 9mu plus .45mu minus .225mu
1244%
1245% Lansburg, p. 296: "A quad---nothing less, but also nothing more---is set between all independent formulas, independent of their length,
1246% height or character.
1247
1248\mathinterwordmuskip 18mu
1249
1250\permanent\protected\def\mtp#1{\mathatom class \mathtextpunctuationcode {\hbox{#1}}} % only at the outer level (text, display)
1251
1252% granular, but more clutter
1253%
1254% \newgluespec\mathinterwordtextskip
1255% \newgluespec\mathinterwordscriptskip
1256% \newgluespec\mathinterwordscriptscriptskip
1257%
1258% \appendtoks
1259%     \mathinterwordtextskip         \fontinterwordspace\textfont        \zerocount \fontinterwordstretch\textfont        \zerocount \fontinterwordshrink\textfont        \zerocount \relax
1260%     \mathinterwordscriptskip       \fontinterwordspace\scriptfont      \zerocount \fontinterwordstretch\scriptfont      \zerocount \fontinterwordshrink\scriptfont      \zerocount \relax
1261%     \mathinterwordscriptscriptskip \fontinterwordspace\scriptscriptfont\zerocount \fontinterwordstretch\scriptscriptfont\zerocount \fontinterwordshrink\scriptscriptfont\zerocount \relax
1262% \to \everymathematics
1263%
1264% \inherited\setmathspacing \mathtextpunctuationcode \mathordcode \allmathstyles         \mathinterwordtextskip
1265% \inherited\setmathspacing \mathtextpunctuationcode \mathordcode \allscriptstyles       \mathinterwordscriptskip
1266% \inherited\setmathspacing \mathtextpunctuationcode \mathordcode \allscriptscriptstyles \mathinterwordscriptscriptskip
1267
1268\startsetups math:spacing:presets
1269    \resetmathspacing
1270    %
1271  % \inherited\setmathspacing \mathordinarycode        \mathordinarycode        \allmathstyles    \zeromuskip
1272    \inherited\setmathspacing \mathordinarycode        \mathoperatorcode        \allmathstyles    \thinmuskip
1273    \inherited\setmathspacing \mathordinarycode        \mathbinarycode          \allsplitstyles   \medmuskip
1274    \inherited\setmathspacing \mathordinarycode        \mathbinarycode          \allunsplitstyles \pettymuskip
1275    \inherited\setmathspacing \mathordinarycode        \mathrelationcode        \allsplitstyles   \thickmuskip
1276    \inherited\setmathspacing \mathordinarycode        \mathrelationcode        \allunsplitstyles \pettymuskip
1277  % \inherited\setmathspacing \mathordinarycode        \mathopencode            \allmathstyles    \zeromuskip
1278    \inherited\setmathspacing \mathordinarycode        \mathmiddlecode          \allsplitstyles   \thickmuskip
1279    \inherited\setmathspacing \mathordinarycode        \mathmiddlecode          \allunsplitstyles \pettymuskip
1280    \inherited\setmathspacing \mathordinarycode        \mathclosecode           \allmathstyles    \fencemuskip
1281  % \inherited\setmathspacing \mathordinarycode        \mathpunctuationcode     \allmathstyles    \zeromuskip
1282    \inherited\setmathspacing \mathordinarycode        \mathconstructcode       \allsplitstyles   \thinmuskip
1283    \inherited\setmathspacing \mathordinarycode        \mathconstructcode       \allunsplitstyles \pettymuskip
1284    \inherited\setmathspacing \mathordinarycode        \mathellipsiscode        \allsplitstyles   \thinmuskip
1285    \inherited\setmathspacing \mathordinarycode        \mathellipsiscode        \allunsplitstyles \pettymuskip
1286    \inherited\setmathspacing \mathordinarycode        \mathfractioncode        \allsplitstyles   \thinmuskip
1287    \inherited\setmathspacing \mathordinarycode        \mathfractioncode        \allunsplitstyles \pettymuskip
1288  % \inherited\setmathspacing \mathordinarycode        \mathradicalcode         \allsplitstyles   \tinymuskip  % 220705 Results in an unwanted space
1289  % \inherited\setmathspacing \mathordinarycode        \mathradicalcode         \allunsplitstyles \pettymuskip % 220705 Results in an unwanted space
1290    %
1291    \inherited\setmathspacing \mathoperatorcode        \mathordinarycode        \allmathstyles    \thinmuskip
1292    \inherited\setmathspacing \mathoperatorcode        \mathoperatorcode        \allmathstyles    \thinmuskip
1293  % \inherited\setmathspacing \mathoperatorcode        \mathbinarycode          \allmathstyles    \zeromuskip
1294    \inherited\setmathspacing \mathoperatorcode        \mathrelationcode        \allsplitstyles   \thickmuskip
1295    \inherited\setmathspacing \mathoperatorcode        \mathrelationcode        \allunsplitstyles \pettymuskip
1296  % \inherited\setmathspacing \mathoperatorcode        \mathopencode            \allmathstyles    \zeromuskip
1297    \inherited\setmathspacing \mathoperatorcode        \mathmiddlecode          \allsplitstyles   \thickmuskip
1298    \inherited\setmathspacing \mathoperatorcode        \mathmiddlecode          \allunsplitstyles \pettymuskip
1299    \inherited\setmathspacing \mathoperatorcode        \mathclosecode           \allmathstyles    \fencemuskip
1300  % \inherited\setmathspacing \mathoperatorcode        \mathpunctuationcode     \allmathstyles    \zeromuskip
1301    \inherited\setmathspacing \mathoperatorcode        \mathconstructcode       \allsplitstyles   \thinmuskip
1302    \inherited\setmathspacing \mathoperatorcode        \mathconstructcode       \allunsplitstyles \pettymuskip
1303    \inherited\setmathspacing \mathoperatorcode        \mathellipsiscode        \allsplitstyles   \thinmuskip
1304    \inherited\setmathspacing \mathoperatorcode        \mathellipsiscode        \allunsplitstyles \pettymuskip
1305    \inherited\setmathspacing \mathoperatorcode        \mathfractioncode        \allsplitstyles   \medmuskip
1306    \inherited\setmathspacing \mathoperatorcode        \mathfractioncode        \allunsplitstyles \pettymuskip
1307    \inherited\setmathspacing \mathoperatorcode        \mathradicalcode         \allmathstyles    \thinmuskip
1308    %
1309    \inherited\setmathspacing \mathbinarycode          \mathordinarycode        \allsplitstyles   \medmuskip
1310    \inherited\setmathspacing \mathbinarycode          \mathordinarycode        \allunsplitstyles \pettymuskip
1311    \inherited\setmathspacing \mathbinarycode          \mathoperatorcode        \allsplitstyles   \medmuskip
1312    \inherited\setmathspacing \mathbinarycode          \mathoperatorcode        \allunsplitstyles \pettymuskip
1313 %% \inherited\setmathspacing \mathbinarycode          \mathbinarycode          \allmathstyles    \zeromuskip
1314 %% \inherited\setmathspacing \mathbinarycode          \mathrelationcode        \allmathstyles    \zeromuskip
1315    \inherited\setmathspacing \mathbinarycode          \mathopencode            \allsplitstyles   \medmuskip
1316    \inherited\setmathspacing \mathbinarycode          \mathopencode            \allunsplitstyles \pettymuskip
1317    \inherited\setmathspacing \mathbinarycode          \mathmiddlecode          \allsplitstyles   \thickmuskip
1318    \inherited\setmathspacing \mathbinarycode          \mathmiddlecode          \allunsplitstyles \pettymuskip
1319    \inherited\setmathspacing \mathbinarycode          \mathclosecode           \allmathstyles    \fencemuskip
1320    \inherited\setmathspacing \mathbinarycode          \mathpunctuationcode     \allsplitstyles   \medmuskip
1321    \inherited\setmathspacing \mathbinarycode          \mathpunctuationcode     \allunsplitstyles \pettymuskip
1322    \inherited\setmathspacing \mathbinarycode          \mathconstructcode       \allsplitstyles   \medmuskip
1323    \inherited\setmathspacing \mathbinarycode          \mathconstructcode       \allunsplitstyles \pettymuskip
1324    \inherited\setmathspacing \mathbinarycode          \mathellipsiscode        \allsplitstyles   \medmuskip
1325    \inherited\setmathspacing \mathbinarycode          \mathellipsiscode        \allunsplitstyles \pettymuskip
1326    \inherited\setmathspacing \mathbinarycode          \mathfractioncode        \allsplitstyles   \medmuskip
1327    \inherited\setmathspacing \mathbinarycode          \mathfractioncode        \allunsplitstyles \pettymuskip
1328    \inherited\setmathspacing \mathbinarycode          \mathradicalcode         \allsplitstyles   \medmuskip
1329    \inherited\setmathspacing \mathbinarycode          \mathradicalcode         \allunsplitstyles \pettymuskip
1330    %
1331    \inherited\setmathspacing \mathrelationcode        \mathordinarycode        \allsplitstyles   \thickmuskip
1332    \inherited\setmathspacing \mathrelationcode        \mathordinarycode        \allunsplitstyles \pettymuskip
1333    \inherited\setmathspacing \mathrelationcode        \mathoperatorcode        \allsplitstyles   \thickmuskip
1334    \inherited\setmathspacing \mathrelationcode        \mathoperatorcode        \allunsplitstyles \pettymuskip
1335 %% \inherited\setmathspacing \mathrelationcode        \mathbinarycode          \allmathstyles    \zeromuskip
1336  % \inherited\setmathspacing \mathrelationcode        \mathrelationcode        \allmathstyles    \zeromuskip
1337    \inherited\setmathspacing \mathrelationcode        \mathopencode            \allsplitstyles   \thickmuskip
1338    \inherited\setmathspacing \mathrelationcode        \mathopencode            \allunsplitstyles \pettymuskip
1339    \inherited\setmathspacing \mathrelationcode        \mathmiddlecode          \allsplitstyles   \thickmuskip
1340    \inherited\setmathspacing \mathrelationcode        \mathmiddlecode          \allunsplitstyles \thinmuskip
1341    \inherited\setmathspacing \mathrelationcode        \mathclosecode           \allmathstyles    \fencemuskip
1342    \inherited\setmathspacing \mathrelationcode        \mathpunctuationcode     \allsplitstyles   \thickmuskip
1343    \inherited\setmathspacing \mathrelationcode        \mathpunctuationcode     \allunsplitstyles \pettymuskip
1344    \inherited\setmathspacing \mathrelationcode        \mathconstructcode       \allsplitstyles   \thickmuskip
1345    \inherited\setmathspacing \mathrelationcode        \mathconstructcode       \allunsplitstyles \pettymuskip
1346    \inherited\setmathspacing \mathrelationcode        \mathellipsiscode        \allsplitstyles   \thickmuskip
1347    \inherited\setmathspacing \mathrelationcode        \mathellipsiscode        \allunsplitstyles \pettymuskip
1348    \inherited\setmathspacing \mathrelationcode        \mathfractioncode        \allsplitstyles   \thickmuskip
1349    \inherited\setmathspacing \mathrelationcode        \mathfractioncode        \allunsplitstyles \pettymuskip
1350    \inherited\setmathspacing \mathrelationcode        \mathradicalcode         \allsplitstyles   \thickmuskip
1351    \inherited\setmathspacing \mathrelationcode        \mathradicalcode         \allunsplitstyles \pettymuskip
1352    %
1353    \inherited\setmathspacing \mathopencode            \mathordinarycode        \allmathstyles    \fencemuskip
1354    \inherited\setmathspacing \mathopencode            \mathoperatorcode        \allmathstyles    \fencemuskip
1355    \inherited\setmathspacing \mathopencode            \mathbinarycode          \allmathstyles    \fencemuskip
1356    \inherited\setmathspacing \mathopencode            \mathrelationcode        \allmathstyles    \fencemuskip
1357    \inherited\setmathspacing \mathopencode            \mathopencode            \allmathstyles    \fencemuskip
1358    \inherited\setmathspacing \mathopencode            \mathmiddlecode          \allmathstyles    \pettymuskip
1359    \inherited\setmathspacing \mathopencode            \mathclosecode           \allmathstyles    \pettymuskip
1360    \inherited\setmathspacing \mathopencode            \mathpunctuationcode     \allmathstyles    \pettymuskip
1361    \inherited\setmathspacing \mathopencode            \mathconstructcode       \allmathstyles    \pettymuskip
1362    \inherited\setmathspacing \mathopencode            \mathellipsiscode        \allmathstyles    \pettymuskip
1363    \inherited\setmathspacing \mathopencode            \mathradicalcode         \allmathstyles    \fencemuskip
1364    \inherited\setmathspacing \mathopencode            \mathfractioncode        \allsplitstyles   \pettymuskip
1365    \inherited\setmathspacing \mathopencode            \mathfractioncode        \allunsplitstyles \pettymuskip
1366    %
1367    \inherited\setmathspacing \mathclosecode           \mathordinarycode        \allmathstyles    \tinymuskip
1368    \inherited\setmathspacing \mathclosecode           \mathoperatorcode        \allmathstyles    \thinmuskip
1369    \inherited\setmathspacing \mathclosecode           \mathbinarycode          \allsplitstyles   \medmuskip
1370    \inherited\setmathspacing \mathclosecode           \mathbinarycode          \allunsplitstyles \pettymuskip
1371    \inherited\setmathspacing \mathclosecode           \mathrelationcode        \allsplitstyles   \thickmuskip
1372    \inherited\setmathspacing \mathclosecode           \mathrelationcode        \allunsplitstyles \pettymuskip
1373    \inherited\setmathspacing \mathclosecode           \mathopencode            \alltextstyles    \tinymuskip
1374    \inherited\setmathspacing \mathclosecode           \mathopencode            \alldisplaystyles \thinmuskip
1375    \inherited\setmathspacing \mathclosecode           \mathopencode            \allunsplitstyles \pettymuskip
1376%
1377% todo: see asciimath or at least to be checked
1378%
1379% \inherited\setmathspacing \mathclosecode \mathmiddlecode                    \alldisplaystyles   \thickmuskip
1380% \inherited\setmathspacing \mathclosecode \mathmiddlecode                    \allunsplitstyles   \pettymuskip
1381%
1382  % \inherited\setmathspacing \mathclosecode           \mathmiddlecode          \allmathstyles    \zeromuskip
1383    \inherited\setmathspacing \mathclosecode           \mathclosecode           \allmathstyles    \fencemuskip
1384  % \inherited\setmathspacing \mathclosecode           \mathpunctuationcode     \allmathstyles    \zeromuskip
1385    \inherited\setmathspacing \mathclosecode           \mathconstructcode       \allsplitstyles   \thinmuskip
1386    \inherited\setmathspacing \mathclosecode           \mathconstructcode       \allunsplitstyles \pettymuskip
1387    \inherited\setmathspacing \mathclosecode           \mathfactorialcode       \allmathstyles    \zeromuskip
1388    \inherited\setmathspacing \mathclosecode           \mathellipsiscode        \allsplitstyles   \thinmuskip
1389    \inherited\setmathspacing \mathclosecode           \mathellipsiscode        \allunsplitstyles \pettymuskip
1390    \inherited\setmathspacing \mathclosecode           \mathfractioncode        \allsplitstyles   \thinmuskip
1391    \inherited\setmathspacing \mathclosecode           \mathfractioncode        \allunsplitstyles \pettymuskip
1392  % \inherited\setmathspacing \mathclosecode           \mathradicalcode         \allmathstyles    \zeromuskip
1393    %
1394    \inherited\setmathspacing \mathpunctuationcode     \mathordinarycode        \allsplitstyles   \medmuskip
1395    \inherited\setmathspacing \mathpunctuationcode     \mathordinarycode        \allunsplitstyles \tinymuskip
1396    \inherited\setmathspacing \mathpunctuationcode     \mathoperatorcode        \allsplitstyles   \medmuskip
1397    \inherited\setmathspacing \mathpunctuationcode     \mathoperatorcode        \allunsplitstyles \tinymuskip
1398  % \inherited\setmathspacing \mathpunctuationcode     \mathbinarycode          \allmathstyles    \zeromuskip
1399    \inherited\setmathspacing \mathpunctuationcode     \mathrelationcode        \allsplitstyles   \medmuskip
1400    \inherited\setmathspacing \mathpunctuationcode     \mathrelationcode        \allunsplitstyles \tinymuskip
1401    \inherited\setmathspacing \mathpunctuationcode     \mathopencode            \allsplitstyles   \medmuskip
1402    \inherited\setmathspacing \mathpunctuationcode     \mathopencode            \allunsplitstyles \tinymuskip
1403    \inherited\setmathspacing \mathpunctuationcode     \mathmiddlecode          \allsplitstyles   \thickmuskip
1404    \inherited\setmathspacing \mathpunctuationcode     \mathmiddlecode          \allunsplitstyles \tinymuskip
1405    \inherited\setmathspacing \mathpunctuationcode     \mathclosecode           \allsplitstyles   \medmuskip
1406    \inherited\setmathspacing \mathpunctuationcode     \mathclosecode           \allunsplitstyles \tinymuskip
1407    \inherited\setmathspacing \mathpunctuationcode     \mathpunctuationcode     \allsplitstyles   \medmuskip
1408    \inherited\setmathspacing \mathpunctuationcode     \mathpunctuationcode     \allunsplitstyles \tinymuskip
1409    \inherited\setmathspacing \mathpunctuationcode     \mathconstructcode       \allsplitstyles   \medmuskip
1410    \inherited\setmathspacing \mathpunctuationcode     \mathconstructcode       \allunsplitstyles \tinymuskip
1411    \inherited\setmathspacing \mathpunctuationcode     \mathellipsiscode        \allsplitstyles   \medmuskip
1412    \inherited\setmathspacing \mathpunctuationcode     \mathellipsiscode        \allunsplitstyles \tinymuskip
1413    \inherited\setmathspacing \mathpunctuationcode     \mathfractioncode        \allsplitstyles   \medmuskip
1414    \inherited\setmathspacing \mathpunctuationcode     \mathfractioncode        \allunsplitstyles \tinymuskip
1415    \inherited\setmathspacing \mathpunctuationcode     \mathradicalcode         \allsplitstyles   \medmuskip
1416    \inherited\setmathspacing \mathpunctuationcode     \mathradicalcode         \allunsplitstyles \tinymuskip
1417    %
1418    \inherited\setmathspacing \mathconstructcode       \mathordinarycode        \allsplitstyles   \thinmuskip
1419    \inherited\setmathspacing \mathconstructcode       \mathordinarycode        \allunsplitstyles \pettymuskip
1420    \inherited\setmathspacing \mathconstructcode       \mathoperatorcode        \allmathstyles    \thinmuskip
1421    \inherited\setmathspacing \mathconstructcode       \mathbinarycode          \allsplitstyles   \medmuskip
1422    \inherited\setmathspacing \mathconstructcode       \mathbinarycode          \allunsplitstyles \pettymuskip
1423    \inherited\setmathspacing \mathconstructcode       \mathrelationcode        \allsplitstyles   \thickmuskip
1424    \inherited\setmathspacing \mathconstructcode       \mathrelationcode        \allunsplitstyles \pettymuskip
1425    \inherited\setmathspacing \mathconstructcode       \mathopencode            \allsplitstyles   \thinmuskip
1426    \inherited\setmathspacing \mathconstructcode       \mathopencode            \allunsplitstyles \pettymuskip
1427    \inherited\setmathspacing \mathconstructcode       \mathmiddlecode          \allsplitstyles   \thickmuskip
1428    \inherited\setmathspacing \mathconstructcode       \mathmiddlecode          \allunsplitstyles \pettymuskip
1429    \inherited\setmathspacing \mathconstructcode       \mathclosecode           \allmathstyles    \pettymuskip
1430    \inherited\setmathspacing \mathconstructcode       \mathpunctuationcode     \allsplitstyles   \thinmuskip
1431    \inherited\setmathspacing \mathconstructcode       \mathpunctuationcode     \allunsplitstyles \pettymuskip
1432    \inherited\setmathspacing \mathconstructcode       \mathconstructcode       \allsplitstyles   \thinmuskip
1433    \inherited\setmathspacing \mathconstructcode       \mathconstructcode       \allunsplitstyles \pettymuskip
1434    \inherited\setmathspacing \mathconstructcode       \mathfractioncode        \allsplitstyles   \thinmuskip
1435    \inherited\setmathspacing \mathconstructcode       \mathfractioncode        \allunsplitstyles \pettymuskip
1436    \inherited\setmathspacing \mathconstructcode       \mathradicalcode         \allsplitstyles   \thinmuskip
1437    \inherited\setmathspacing \mathconstructcode       \mathradicalcode         \allunsplitstyles \pettymuskip
1438    %
1439    \inherited\setmathspacing \mathellipsiscode        \mathordinarycode        \allsplitstyles   \thinmuskip
1440    \inherited\setmathspacing \mathellipsiscode        \mathordinarycode        \allunsplitstyles \pettymuskip
1441    \inherited\setmathspacing \mathellipsiscode        \mathoperatorcode        \allmathstyles    \thinmuskip
1442    \inherited\setmathspacing \mathellipsiscode        \mathbinarycode          \allsplitstyles   \medmuskip
1443    \inherited\setmathspacing \mathellipsiscode        \mathbinarycode          \allunsplitstyles \pettymuskip
1444    \inherited\setmathspacing \mathellipsiscode        \mathrelationcode        \allsplitstyles   \thickmuskip
1445    \inherited\setmathspacing \mathellipsiscode        \mathrelationcode        \allunsplitstyles \pettymuskip
1446    \inherited\setmathspacing \mathellipsiscode        \mathopencode            \allsplitstyles   \thinmuskip
1447    \inherited\setmathspacing \mathellipsiscode        \mathopencode            \allunsplitstyles \pettymuskip
1448    \inherited\setmathspacing \mathellipsiscode        \mathmiddlecode          \allsplitstyles   \thickmuskip
1449    \inherited\setmathspacing \mathellipsiscode        \mathmiddlecode          \allunsplitstyles \pettymuskip
1450    \inherited\setmathspacing \mathellipsiscode        \mathclosecode           \allmathstyles    \pettymuskip
1451    \inherited\setmathspacing \mathellipsiscode        \mathpunctuationcode     \allsplitstyles   \thinmuskip
1452    \inherited\setmathspacing \mathellipsiscode        \mathpunctuationcode     \allunsplitstyles \pettymuskip
1453    \inherited\setmathspacing \mathellipsiscode        \mathconstructcode       \allsplitstyles   \thinmuskip
1454    \inherited\setmathspacing \mathellipsiscode        \mathconstructcode       \allunsplitstyles \pettymuskip
1455    \inherited\setmathspacing \mathellipsiscode        \mathellipsiscode        \allsplitstyles   \thinmuskip
1456    \inherited\setmathspacing \mathellipsiscode        \mathellipsiscode        \allunsplitstyles \pettymuskip
1457    \inherited\setmathspacing \mathellipsiscode        \mathfractioncode        \allsplitstyles   \thinmuskip
1458    \inherited\setmathspacing \mathellipsiscode        \mathfractioncode        \allunsplitstyles \pettymuskip
1459    \inherited\setmathspacing \mathellipsiscode        \mathradicalcode         \allsplitstyles   \thinmuskip
1460    \inherited\setmathspacing \mathellipsiscode        \mathradicalcode         \allunsplitstyles \pettymuskip
1461    %
1462    \inherited\setmathspacing \mathfractioncode        \mathordinarycode        \allsplitstyles   \thinmuskip
1463    \inherited\setmathspacing \mathfractioncode        \mathordinarycode        \allunsplitstyles \pettymuskip
1464    \inherited\setmathspacing \mathfractioncode        \mathoperatorcode        \allsplitstyles   \medmuskip
1465    \inherited\setmathspacing \mathfractioncode        \mathoperatorcode        \allunsplitstyles \pettymuskip
1466    \inherited\setmathspacing \mathfractioncode        \mathbinarycode          \allsplitstyles   \medmuskip
1467    \inherited\setmathspacing \mathfractioncode        \mathbinarycode          \allunsplitstyles \pettymuskip
1468    \inherited\setmathspacing \mathfractioncode        \mathrelationcode        \allsplitstyles   \thickmuskip
1469    \inherited\setmathspacing \mathfractioncode        \mathrelationcode        \allunsplitstyles \pettymuskip
1470    \inherited\setmathspacing \mathfractioncode        \mathopencode            \allsplitstyles   \thinmuskip
1471    \inherited\setmathspacing \mathfractioncode        \mathopencode            \allunsplitstyles \pettymuskip
1472    \inherited\setmathspacing \mathfractioncode        \mathmiddlecode          \allsplitstyles   \thickmuskip
1473    \inherited\setmathspacing \mathfractioncode        \mathmiddlecode          \allunsplitstyles \pettymuskip
1474    \inherited\setmathspacing \mathfractioncode        \mathclosecode           \allmathstyles    \pettymuskip
1475    % \inherited\setmathspacing \mathfractioncode        \mathclosecode           \allunsplitstyles \pettymuskip
1476    \inherited\setmathspacing \mathfractioncode        \mathpunctuationcode     \allsplitstyles   \tinymuskip
1477    \inherited\setmathspacing \mathfractioncode        \mathpunctuationcode     \allunsplitstyles \pettymuskip
1478    \inherited\setmathspacing \mathfractioncode        \mathtextpunctuationcode \allmathstyles    \tinymuskip
1479    \inherited\setmathspacing \mathfractioncode        \mathconstructcode       \allsplitstyles   \thinmuskip
1480    \inherited\setmathspacing \mathfractioncode        \mathconstructcode       \allunsplitstyles \pettymuskip
1481    \inherited\setmathspacing \mathfractioncode        \mathellipsiscode        \allsplitstyles   \thinmuskip
1482    \inherited\setmathspacing \mathfractioncode        \mathellipsiscode        \allunsplitstyles \pettymuskip
1483    \inherited\setmathspacing \mathfractioncode        \mathfractioncode        \allsplitstyles   \thinmuskip
1484    \inherited\setmathspacing \mathfractioncode        \mathfractioncode        \allunsplitstyles \pettymuskip
1485    \inherited\setmathspacing \mathfractioncode        \mathradicalcode         \allsplitstyles   \thinmuskip
1486    \inherited\setmathspacing \mathfractioncode        \mathradicalcode         \allunsplitstyles \pettymuskip
1487    \inherited\setmathspacing \mathfractioncode        \mathdifferentialcode    \allsplitstyles   \medmuskip
1488    \inherited\setmathspacing \mathfractioncode        \mathdifferentialcode    \allunsplitstyles \pettymuskip
1489    %
1490    \inherited\setmathspacing \mathradicalcode         \mathordinarycode        \allsplitstyles   \tinymuskip
1491    \inherited\setmathspacing \mathradicalcode         \mathordinarycode        \allunsplitstyles \pettymuskip
1492    \inherited\setmathspacing \mathradicalcode         \mathoperatorcode        \allmathstyles    \thinmuskip
1493    \inherited\setmathspacing \mathradicalcode         \mathbinarycode          \allsplitstyles   \medmuskip
1494    \inherited\setmathspacing \mathradicalcode         \mathbinarycode          \allunsplitstyles \pettymuskip
1495    \inherited\setmathspacing \mathradicalcode         \mathrelationcode        \allsplitstyles   \thickmuskip
1496    \inherited\setmathspacing \mathradicalcode         \mathrelationcode        \allunsplitstyles \pettymuskip
1497  % \inherited\setmathspacing \mathradicalcode         \mathopencode            \allmathstyles    \zeromuskip
1498    \inherited\setmathspacing \mathradicalcode         \mathmiddlecode          \allsplitstyles   \thickmuskip
1499    \inherited\setmathspacing \mathradicalcode         \mathmiddlecode          \allunsplitstyles \pettymuskip
1500    \inherited\setmathspacing \mathradicalcode         \mathclosecode           \allmathstyles    \pettymuskip
1501    \inherited\setmathspacing \mathradicalcode         \mathpunctuationcode     \allsplitstyles   \pettymuskip
1502    \inherited\setmathspacing \mathradicalcode         \mathpunctuationcode     \allunsplitstyles \tinymuskip
1503    \inherited\setmathspacing \mathradicalcode         \mathconstructcode       \allsplitstyles   \thinmuskip
1504    \inherited\setmathspacing \mathradicalcode         \mathconstructcode       \allunsplitstyles \pettymuskip
1505    \inherited\setmathspacing \mathradicalcode         \mathellipsiscode        \allsplitstyles   \thinmuskip
1506    \inherited\setmathspacing \mathradicalcode         \mathellipsiscode        \allunsplitstyles \pettymuskip
1507    \inherited\setmathspacing \mathradicalcode         \mathfractioncode        \allsplitstyles   \tinymuskip
1508    \inherited\setmathspacing \mathradicalcode         \mathfractioncode        \allunsplitstyles \pettymuskip
1509    \inherited\setmathspacing \mathradicalcode         \mathradicalcode         \allsplitstyles   \thinmuskip
1510    \inherited\setmathspacing \mathradicalcode         \mathradicalcode         \allunsplitstyles \pettymuskip
1511    %
1512    \inherited\setmathspacing \mathmiddlecode          \mathordinarycode        \allsplitstyles   \thickmuskip
1513    \inherited\setmathspacing \mathmiddlecode          \mathordinarycode        \allunsplitstyles \pettymuskip
1514    \inherited\setmathspacing \mathmiddlecode          \mathoperatorcode        \allmathstyles    \thickmuskip
1515    \inherited\setmathspacing \mathmiddlecode          \mathbinarycode          \allsplitstyles   \medmuskip
1516    \inherited\setmathspacing \mathmiddlecode          \mathbinarycode          \allunsplitstyles \pettymuskip
1517    \inherited\setmathspacing \mathmiddlecode          \mathrelationcode        \allsplitstyles   \thickmuskip
1518    \inherited\setmathspacing \mathmiddlecode          \mathrelationcode        \allunsplitstyles \pettymuskip
1519    \inherited\setmathspacing \mathmiddlecode          \mathopencode            \allsplitstyles   \thickmuskip
1520    \inherited\setmathspacing \mathmiddlecode          \mathopencode            \allscriptstyles  \pettymuskip
1521    \inherited\setmathspacing \mathmiddlecode          \mathmiddlecode          \allsplitstyles   \thickmuskip
1522    \inherited\setmathspacing \mathmiddlecode          \mathmiddlecode          \allunsplitstyles \pettymuskip
1523    \inherited\setmathspacing \mathmiddlecode          \mathclosecode           \allsplitstyles   \thickmuskip
1524    \inherited\setmathspacing \mathmiddlecode          \mathclosecode           \allunsplitstyles \pettymuskip
1525    \inherited\setmathspacing \mathmiddlecode          \mathpunctuationcode     \allsplitstyles   \thickmuskip
1526    \inherited\setmathspacing \mathmiddlecode          \mathpunctuationcode     \allunsplitstyles \pettymuskip
1527    \inherited\setmathspacing \mathmiddlecode          \mathconstructcode       \allsplitstyles   \thickmuskip
1528    \inherited\setmathspacing \mathmiddlecode          \mathconstructcode       \allunsplitstyles \pettymuskip
1529    \inherited\setmathspacing \mathmiddlecode          \mathellipsiscode        \allsplitstyles   \thickmuskip
1530    \inherited\setmathspacing \mathmiddlecode          \mathellipsiscode        \allunsplitstyles \pettymuskip
1531    \inherited\setmathspacing \mathmiddlecode          \mathfractioncode        \allsplitstyles   \thickmuskip
1532    \inherited\setmathspacing \mathmiddlecode          \mathfractioncode        \allunsplitstyles \pettymuskip
1533    \inherited\setmathspacing \mathmiddlecode          \mathradicalcode         \allsplitstyles   \thickmuskip
1534    \inherited\setmathspacing \mathmiddlecode          \mathradicalcode         \allmathstyles    \pettymuskip
1535    %
1536    \inherited\setmathspacing \mathclosecode           \mathdifferentialcode    \allsplitstyles   \thinmuskip
1537    \inherited\setmathspacing \mathclosecode           \mathdifferentialcode    \allunsplitstyles \pettymuskip
1538    \inherited\setmathspacing \mathordinarycode        \mathdifferentialcode    \allsplitstyles   \thinmuskip
1539    \inherited\setmathspacing \mathordinarycode        \mathdifferentialcode    \allunsplitstyles \pettymuskip
1540    \inherited\setmathspacing \mathfactorialcode       \mathordinarycode        \allsplitstyles   \thinmuskip
1541    \inherited\setmathspacing \mathfactorialcode       \mathordinarycode        \allunsplitstyles \pettymuskip
1542    \inherited\setmathspacing \mathfactorialcode       \mathfactorialcode       \allmathstyles    \zeromuskip
1543    %
1544    \inherited\setmathspacing \mathopencode            \mathconstructcode       \allmathstyles    \thinmuskip
1545    \inherited\setmathspacing \mathconstructcode       \mathclosecode           \allmathstyles    \thinmuskip
1546    %
1547    \inherited\setmathspacing \mathdimensioncode       \mathdimensioncode       \allmathstyles    \zeromuskip
1548    \inherited\setmathspacing \mathordinarycode        \mathdimensioncode       \allsplitstyles   \thinmuskip
1549    \inherited\setmathspacing \mathordinarycode        \mathdimensioncode       \allunsplitstyles \pettymuskip
1550    \inherited\setmathspacing \mathdigitcode           \mathdimensioncode       \allsplitstyles   \thinmuskip
1551    \inherited\setmathspacing \mathdigitcode           \mathdimensioncode       \allunsplitstyles \pettymuskip
1552    \inherited\setmathspacing \mathclosecode           \mathdimensioncode       \allsplitstyles   \thinmuskip
1553    \inherited\setmathspacing \mathclosecode           \mathdimensioncode       \allunsplitstyles \pettymuskip
1554    \inherited\setmathspacing \mathfunctioncode        \mathbinarycode          \allsplitstyles   \medmuskip
1555    \inherited\setmathspacing \mathfunctioncode        \mathbinarycode          \allunsplitstyles \pettymuskip
1556    %
1557    % A bit more spacing before parentheses
1558    %
1559    \inherited\setmathspacing \mathfunctioncode        \mathopencode            \allsplitstyles    \pettymuskip
1560    \inherited\setmathspacing \mathdifferentialcode    \mathopencode            \allsplitstyles    \pettymuskip
1561    %
1562    % integral inherited from operator, with the differences below
1563    %
1564    \inherited\setmathspacing \mathintegralcode        \mathordinarycode        \allmathstyles    \pettymuskip
1565    \inherited\setmathspacing \mathintegralcode        \mathdigitcode           \allmathstyles    \pettymuskip
1566    \inherited\setmathspacing \mathintegralcode        \mathoperatorcode        \allmathstyles    \pettymuskip
1567    \inherited\setmathspacing \mathintegralcode        \mathdifferentialcode    \allmathstyles    \pettymuskip
1568    \inherited\setmathspacing \mathintegralcode        \mathexponentialcode     \allmathstyles    \pettymuskip
1569    \inherited\setmathspacing \mathintegralcode        \mathimaginarycode       \allmathstyles    \pettymuskip
1570    %
1571    % \im{1\unit{hour} 20 \unit{minute} 56 \unit{second}}
1572    %
1573    \inherited\setmathspacing \mathdimensioncode       \mathdigitcode           \allmathstyles    \thickmuskip
1574    \inherited\setmathspacing \mathdimensioncode       \mathbinarycode          \allsplitstyles   \medmuskip
1575    \inherited\setmathspacing \mathdimensioncode       \mathbinarycode          \allunsplitstyles \pettymuskip
1576    \inherited\setmathspacing \mathdimensioncode       \mathrelationcode        \allsplitstyles   \thickmuskip
1577    \inherited\setmathspacing \mathdimensioncode       \mathrelationcode        \allunsplitstyles \pettymuskip
1578    %
1579    \inherited\setmathspacing \mathfakecode            \mathallcode             \allmathstyles    \tinymuskip
1580    \inherited\setmathspacing \mathallcode             \mathfakecode            \allmathstyles    \tinymuskip
1581    %
1582    \inherited\setmathspacing \mathtextpunctuationcode \mathordinarycode        \allmathstyles    \mathinterwordmuskip
1583    \inherited\setmathspacing \mathtextpunctuationcode \mathoperatorcode        \allmathstyles    \mathinterwordmuskip
1584    \inherited\setmathspacing \mathtextpunctuationcode \mathbinarycode          \allmathstyles    \mathinterwordmuskip
1585    \inherited\setmathspacing \mathtextpunctuationcode \mathrelationcode        \allmathstyles    \mathinterwordmuskip
1586    \inherited\setmathspacing \mathtextpunctuationcode \mathopencode            \allmathstyles    \mathinterwordmuskip
1587    \inherited\setmathspacing \mathtextpunctuationcode \mathmiddlecode          \allmathstyles    \mathinterwordmuskip
1588    \inherited\setmathspacing \mathtextpunctuationcode \mathclosecode           \allmathstyles    \mathinterwordmuskip
1589    \inherited\setmathspacing \mathtextpunctuationcode \mathpunctuationcode     \allmathstyles    \mathinterwordmuskip
1590    \inherited\setmathspacing \mathtextpunctuationcode \mathconstructcode       \allmathstyles    \mathinterwordmuskip
1591    \inherited\setmathspacing \mathtextpunctuationcode \mathellipsiscode        \allmathstyles    \mathinterwordmuskip
1592    \inherited\setmathspacing \mathtextpunctuationcode \mathfractioncode        \allmathstyles    \mathinterwordmuskip
1593    \inherited\setmathspacing \mathtextpunctuationcode \mathradicalcode         \allmathstyles    \mathinterwordmuskip
1594    \inherited\setmathspacing \mathtextpunctuationcode \mathdifferentialcode    \allmathstyles    \mathinterwordmuskip
1595    \inherited\setmathspacing \mathtextpunctuationcode \mathpunctuationcode     \allmathstyles    \mathinterwordmuskip
1596    %
1597    \inherited\setmathspacing \mathordinarycode        \mathtextpunctuationcode \allmathstyles    \pettymuskip
1598    \inherited\setmathspacing \mathoperatorcode        \mathtextpunctuationcode \allmathstyles    \pettymuskip
1599    \inherited\setmathspacing \mathbinarycode          \mathtextpunctuationcode \allmathstyles    \pettymuskip
1600    \inherited\setmathspacing \mathrelationcode        \mathtextpunctuationcode \allmathstyles    \pettymuskip
1601    \inherited\setmathspacing \mathopencode            \mathtextpunctuationcode \allmathstyles    \pettymuskip
1602    \inherited\setmathspacing \mathmiddlecode          \mathtextpunctuationcode \allmathstyles    \pettymuskip
1603    \inherited\setmathspacing \mathclosecode           \mathtextpunctuationcode \allmathstyles    \pettymuskip
1604    \inherited\setmathspacing \mathpunctuationcode     \mathtextpunctuationcode \allmathstyles    \pettymuskip
1605    \inherited\setmathspacing \mathconstructcode       \mathtextpunctuationcode \allmathstyles    \pettymuskip
1606    \inherited\setmathspacing \mathellipsiscode        \mathtextpunctuationcode \allmathstyles    \pettymuskip
1607    \inherited\setmathspacing \mathfractioncode        \mathtextpunctuationcode \allmathstyles    \pettymuskip
1608    \inherited\setmathspacing \mathradicalcode         \mathtextpunctuationcode \allmathstyles    \pettymuskip
1609    \inherited\setmathspacing \mathdifferentialcode    \mathtextpunctuationcode \allmathstyles    \pettymuskip
1610    \inherited\setmathspacing \mathpunctuationcode     \mathtextpunctuationcode \allmathstyles    \pettymuskip
1611    %
1612    % todo: check with relation and see where it differs
1613    %
1614    \inherited\setmathspacing \mathimplicationcode     \mathordinarycode        \alldisplaystyles \thickermuskip
1615    \inherited\setmathspacing \mathimplicationcode     \mathbinarycode          \alldisplaystyles \thickermuskip
1616    \inherited\setmathspacing \mathimplicationcode     \mathdigitcode           \alldisplaystyles \thickermuskip
1617    \inherited\setmathspacing \mathordinarycode        \mathimplicationcode     \alldisplaystyles \thickermuskip
1618    \inherited\setmathspacing \mathbinarycode          \mathimplicationcode     \alldisplaystyles \thickermuskip
1619    \inherited\setmathspacing \mathdigitcode           \mathimplicationcode     \alldisplaystyles \thickermuskip
1620    \inherited\setmathspacing \mathclosecode           \mathimplicationcode     \alldisplaystyles \thickermuskip
1621    \inherited\setmathspacing \mathradicalcode         \mathimplicationcode     \alldisplaystyles \thickermuskip
1622    \inherited\setmathspacing \mathfractioncode        \mathimplicationcode     \alldisplaystyles \thickermuskip
1623    \inherited\setmathspacing \mathfunctioncode        \mathimplicationcode     \alldisplaystyles \thickermuskip
1624    \inherited\setmathspacing \mathoperatorcode        \mathimplicationcode     \alldisplaystyles \thickermuskip
1625    \inherited\setmathspacing \mathellipsiscode        \mathimplicationcode     \alldisplaystyles \thickermuskip
1626    \inherited\setmathspacing \mathconstructcode       \mathimplicationcode     \alldisplaystyles \thickermuskip
1627    \inherited\setmathspacing \mathghostcode           \mathimplicationcode     \alldisplaystyles \thickermuskip
1628    \inherited\setmathspacing \mathwrappedcode         \mathimplicationcode     \alldisplaystyles \thickermuskip
1629\stopsetups
1630
1631\directsetup{math:spacing:default}
1632\directsetup{math:spacing:presets}
1633
1634% \dorecurse{80}{test \m[i:tight]{\red \fakeformula} test }
1635
1636%setupmathematics            [\c!setups=math:spacing:default]
1637
1638\definemathematics[i:default][\c!setups=math:spacing:equal]
1639\definemathematics[i:half]   [\c!setups=math:spacing:half]
1640\definemathematics[i:tight]  [\c!setups=math:spacing:tight]
1641\definemathematics[i:fixed]  [\c!setups=math:spacing:fixed]
1642
1643% Normally the next is applied to only one character.
1644%
1645% $ABC$ $\cal ABC$ $\mathaltcal ABC$
1646
1647% todo: only in mmode
1648% these commands are semi-public but should not be used directly (lua names wil change)
1649
1650%permanent\protected\def\setmathattribute  #1#2{\ifmmode\clf_setmathattribute{#1}{#2}\fi}
1651%permanent\protected\def\setmathalphabet     #1{\ifmmode\clf_setmathalphabet{#1}\fi}
1652%permanent\protected\def\setmathfontstyle    #1{\ifmmode\clf_setmathstyle{#1}\fi}
1653%permanent\protected\def\setmathfontalternate#1{\ifmmode\clf_setmathalternate{#1}\fi}
1654
1655\installcorenamespace{mathstylealternative} % might become a setuphandler
1656
1657\permanent\protected\def\setmathfontstylealternate#1%
1658  {\ifcsname\??mathstylealternative\fontclass:#1\endcsname
1659     \expandafter\setmathfontalternate\lastnamedcs
1660   \orelse\ifcsname\??mathstylealternative#1\endcsname
1661     \expandafter\setmathfontalternate\lastnamedcs
1662   \fi}
1663
1664\permanent\tolerant\protected\def\setupmathrendering[#1]#*[#S#2]% the name might change
1665  {\ifparameter#2\or
1666     \getparameters[\??mathstylealternative#1:][#2]%
1667   \else
1668     \getparameters[\??mathstylealternative][#1]%
1669   \fi}
1670
1671\appendtoks
1672    \edef\p_stylealternative{\mathematicsparameter\c!stylealternative}%
1673    \ifempty\p_stylealternative\else
1674        \presetmathfontalternate{\p_stylealternative}%
1675    \fi
1676\to \everymathematics
1677
1678% if there were many features we could have a feature pass over math nodes but it makes no
1679% sense now so we have commands to deal with it
1680
1681% \enabletrackers[math.alternates]
1682% \setupbodyfont[lucidaot]
1683%
1684% \startTEXpage
1685%     \setupmathematics[stylealternative={reset}]$x+\mathcal A$\par
1686%     \setupmathematics[stylealternative={reset,calligraphic}]$x+\mathcal A$\par
1687%     \setupmathematics[stylealternative={reset,italic}]$x+\mathcal A$\par
1688%     \setupmathematics[stylealternative={reset,calligraphic,italic}]$x+\mathcal A$
1689% \stopTEXpage
1690
1691% no longer needed now we have enforce so the next few lines will go
1692
1693% \pushoverloadmode
1694%     \enforced\let\dotlessi\dotlessi
1695%     \enforced\let\dotlessj\dotlessj
1696% \popoverloadmode
1697
1698\permanent\protected\def\mathaltcalligraphic{\setmathfontalternate{calligraphic}\cal}          % set via goody file
1699\permanent\protected\def\mathaltitalic      {\setmathfontalternate{italic}}                    % set via goody file
1700\permanent\protected\def\mathslashedzero    {\begingroup\setmathfontalternate{zero}\endgroup} % set via goody file or automatic
1701\permanent\protected\def\mathdotless        {\setmathfontalternate{dotless}}                   % set via goody file or automatic
1702\permanent\protected\def\mathdotfull        {\setmathfontalternate{-dotless}}
1703\permanent\protected\def\mathdotlessi       {\begingroup\mathdotless i\endgroup}
1704\permanent\protected\def\mathdotlessj       {\begingroup\mathdotless j\endgroup}
1705
1706\aliased\let\mathaltcal\mathaltcalligraphic
1707\aliased\let\mathaltit \mathaltitalic
1708
1709%aliased\let\textslashedzero\slashedzero \permanent\protected\def\autoslashedzero{\mathortext\mathslashedzero\textslashedzero}
1710\aliased\let\textdotlessi   \dotlessi    \permanent\protected\def\autodotlessi   {\mathortext\mathdotlessi   \textdotlessi}
1711\aliased\let\textdotlessj   \dotlessj    \permanent\protected\def\autodotlessj   {\mathortext\mathdotlessj   \textdotlessj}
1712
1713\appendtoks
1714    %enforced\let\slashedzero\autoslashedzero
1715    \enforced\let\dotlessi\autodotlessi
1716    \enforced\let\dotlessj\autodotlessj
1717\to \everymathematics
1718
1719\aliased\let\setmathfontalternative     \setmathfontalternate
1720\aliased\let\setmathfontstylealternative\setmathfontstylealternate
1721\aliased\let\mathalternate              \setmathfontalternate
1722
1723\permanent\protected\def\math_upright     {\setmathattribute\s!regular\s!tf\setmathfontstylealternate\s!tf}
1724\permanent\protected\def\math_italic      {\setmathattribute\s!regular\s!it\setmathfontstylealternate\s!it}
1725%permanent\protected\def\math_script      {\setmathalphabet \s!script      \setmathfontstylealternate\s!script\setmathvariant\s!handwriting}
1726%permanent\protected\def\math_calligraphic{\setmathalphabet \s!script      \setmathfontstylealternate\s!script\setmathvariant\s!calligraphy}
1727\permanent\protected\def\math_script      {\setmathalphabet \s!script      \setmathfontstylealternate\s!script}
1728\permanent\protected\def\math_calligraphic{\setmathalphabet \s!calligraphic\setmathfontstylealternate\s!calligraphic}
1729\permanent\protected\def\math_fraktur     {\setmathalphabet \s!fraktur     \setmathfontstylealternate\s!fraktur}
1730\permanent\protected\def\math_blackboard  {\setmathalphabet \s!blackboard  \setmathfontstylealternate\s!blackboard}
1731
1732\permanent\protected\def\mathupright     {\mathgroupedcommandcs\math_upright     }
1733\permanent\protected\def\mathitalic      {\mathgroupedcommandcs\math_italic      }
1734\permanent\protected\def\mathscript      {\mathgroupedcommandcs\math_script      }
1735\permanent\protected\def\mathcalligraphic{\mathgroupedcommandcs\math_calligraphic}
1736\permanent\protected\def\mathfraktur     {\mathgroupedcommandcs\math_fraktur     }
1737\permanent\protected\def\mathblackboard  {\mathgroupedcommandcs\math_blackboard  }
1738
1739\permanent\protected\def\math_rm{\setmathattribute\s!rm\s!tf\setmathfontstylealternate\s!tf}
1740\permanent\protected\def\math_ss{\setmathattribute\s!ss\s!tf\setmathfontstylealternate\s!tf}
1741\permanent\protected\def\math_tt{\setmathattribute\s!tt\s!tf\setmathfontstylealternate\s!tf}
1742
1743\permanent\protected\def\math_tf{\setmathfontstyle\s!tf\setmathfontstylealternate\s!tf}
1744\permanent\protected\def\math_sl{\setmathfontstyle\s!it\setmathfontstylealternate\s!it} % no sl
1745\permanent\protected\def\math_it{\setmathfontstyle\s!it\setmathfontstylealternate\s!it}
1746
1747\permanent\protected\def\math_bf{\setmathfontstyle\s!bf\setmathfontstylealternate\s!bf}
1748\permanent\protected\def\math_bs{\setmathfontstyle\s!bi\setmathfontstylealternate\s!bi} % no sl
1749\permanent\protected\def\math_bi{\setmathfontstyle\s!bi\setmathfontstylealternate\s!bi}
1750
1751\permanent\protected\def\mathrm{\mathgroupedcommandcs\math_rm} % \relax not needed
1752\permanent\protected\def\mathss{\mathgroupedcommandcs\math_ss}
1753\permanent\protected\def\mathtt{\mathgroupedcommandcs\math_tt}
1754
1755\permanent\protected\def\mathtf{\mathgroupedcommandcs\math_tf}
1756\permanent\protected\def\mathsl{\mathgroupedcommandcs\math_sl}
1757\permanent\protected\def\mathit{\mathgroupedcommandcs\math_it}
1758
1759\permanent\protected\def\mathbf{\mathgroupedcommandcs\math_bf}
1760\permanent\protected\def\mathbs{\mathgroupedcommandcs\math_bs}
1761\permanent\protected\def\mathbi{\mathgroupedcommandcs\math_bi}
1762
1763\aliased\let\math_default\math_italic
1764\aliased\let\mathdefault \math_italic
1765
1766\appendtoks
1767    \ifcstok{\mathematicsparameter\c!default}\v!normal
1768      \enforced\let\mathdefault \math_upright
1769      \enforced\let\math_default\math_upright
1770    \else
1771      \enforced\let\mathdefault \math_italic
1772      \enforced\let\math_default\math_italic
1773    \fi
1774% \to \everysetupmathematics
1775\to \everyswitchmathematics
1776
1777\setupmathematics
1778  [\c!default=\v!italic]
1779
1780\aliased\let\tfmath\mathtf % maybe a grouped command
1781\aliased\let\slmath\mathsl
1782\aliased\let\itmath\mathit
1783
1784\aliased\let\bfmath\mathbf
1785\aliased\let\bsmath\mathbs
1786\aliased\let\bimath\mathbi
1787
1788\aliased\let\Bbb\mathblackboard
1789
1790\permanent\protected\def\frak      {\ifmmode\expandafter\mathfraktur     \fi}
1791\permanent\protected\def\cal       {\ifmmode\expandafter\mathcalligraphic\fi}
1792\permanent\protected\def\bbd       {\ifmmode\expandafter\mathblackboard  \fi}
1793\permanent\protected\def\blackboard{\ifmmode\expandafter\mathblackboard  \fi}
1794\permanent\protected\def\fraktur   {\ifmmode\expandafter\mathfraktur     \fi}
1795\permanent\protected\def\gothic    {\ifmmode\expandafter\mathfraktur     \fi}
1796
1797\aliased\let\mathcal \mathcalligraphic % for AMS compatibility
1798\aliased\let\mathscr \mathscript       % for AMS compatibility
1799\aliased\let\mathfrak\mathfraktur      % for AMS compatibility
1800\aliased\let\mathbb  \mathblackboard   % for AMS compatibility
1801
1802\ifdefined\normaltf \else \permanent\let\normaltf\tf \fi \permanent\protected\def\tf{\ifmmode\expandafter\mathtf\else\expandafter\normaltf\fi}
1803\ifdefined\normalbf \else \permanent\let\normalbf\bf \fi \permanent\protected\def\bf{\ifmmode\expandafter\mathbf\else\expandafter\normalbf\fi}
1804\ifdefined\normalit \else \permanent\let\normalit\it \fi \permanent\protected\def\it{\ifmmode\expandafter\mathit\else\expandafter\normalit\fi}
1805\ifdefined\normalsl \else \permanent\let\normalsl\sl \fi \permanent\protected\def\sl{\ifmmode\expandafter\mathsl\else\expandafter\normalsl\fi}
1806\ifdefined\normalbi \else \permanent\let\normalbi\bi \fi \permanent\protected\def\bi{\ifmmode\expandafter\mathbi\else\expandafter\normalbi\fi}
1807\ifdefined\normalbs \else \permanent\let\normalbs\bs \fi \permanent\protected\def\bs{\ifmmode\expandafter\mathbs\else\expandafter\normalbs\fi}
1808
1809\permanent\protected\def\rm{\ifmmode\expandafter\mathrm\else\expandafter\normalrm\fi}
1810\permanent\protected\def\ss{\ifmmode\expandafter\mathss\else\expandafter\normalss\fi}
1811\permanent\protected\def\tt{\ifmmode\expandafter\mathtt\else\expandafter\normaltt\fi}
1812
1813\ifdefined\mr \else \let\mr\relax \fi % hm ... permanent
1814\ifdefined\mb \else \let\mb\relax \fi % hm ... permanent
1815
1816% 1: $\setmathattribute{ss}{bf}3$
1817% 2: $\setmathattribute{ss}{bf}\setmathfontstylealternate{bf}3$
1818% 3: $\setmathattribute{ss}{bf}\setmathfontstyle{bf}3$
1819% 4: $\setmathattribute{ss}{bf}\setmathfontstyle{bf}\setmathfontstylealternate{bf}3$
1820% 5: $e=mc^2 \quad \mb e=mc^2$
1821
1822\prependtoks
1823    \math_default
1824\to \everymathematics
1825
1826%D We could set the rendering attribute at the \LUA\ end but as there can be many
1827%D small math snippets we keep track of the state at the \TEX\ end (mapping is
1828%D export safe).
1829%D
1830%D \starttyping
1831%D \startformula
1832%D     \reals {\mathbf R} \utfchar{"0211D} \utfchar{"1D411}
1833%D \stopformula
1834%D
1835%D \setupmathematics
1836%D   [symbolset=blackboard-to-bold]
1837%D
1838%D \startformula
1839%D     \reals {\mathbf R} \utfchar{"0211D} \utfchar{"1D411}
1840%D \stopformula
1841%D \stoptyping
1842
1843\newinteger\c_math_renderings_attribute
1844
1845\appendtoks
1846    \c_math_renderings_attribute\clf_mathrenderset{\mathematicsparameter\c!symbolset}\relax
1847% \to \everysetupmathematics % only in mathematics
1848\to \everyswitchmathematics
1849
1850\appendtoks
1851    \ifcase\c_math_renderings_attribute\else
1852        \c_attr_mathrendering\c_math_renderings_attribute
1853    \fi
1854\to \everymathematics
1855
1856\setupmathematics
1857  [\c!symbolset=]
1858
1859%D \macros
1860%D   {boldsymbol}
1861%D
1862%D To be done.
1863
1864\mutable\let\mathboldsymbol\relax % yet unsupported, will be
1865
1866\permanent\protected\def\boldsymbol
1867  {\mathortext\mathboldsymbol\bold}
1868
1869%D Helpers (defined at the \LUA\ end):
1870
1871% \utfmathclass          #1
1872% \utfmathstretch        #1
1873% \utfmathcommand        #1
1874% \utfmathfiller         #1
1875%
1876% \utfmathcommandabove   #1..
1877% \utfmathcommandbelow   #1..
1878% \utfmathcommandfiller  #1..
1879%
1880% \doifelseutfmathaccent #1#2#3
1881% \doifelseutfmathabove  #1#2#3
1882% \doifelseutfmathbelow  #1#2#3
1883% \doifelseutfmathfiller #1#2#3
1884% \doifelseutfmathlimop  #1#2#3
1885
1886\aliased\let\doifutfmathaccentelse \doifelseutfmathaccent
1887\aliased\let\doifutfmathaboveelse  \doifelseutfmathabove
1888\aliased\let\doifutfmathbelowelse  \doifelseutfmathbelow
1889\aliased\let\doifutfmathfillerelse \doifelseutfmathfiller
1890\aliased\let\doifutfmathlimopelse  \doifelseutfmathlimop
1891
1892%D Not used that much:
1893
1894\permanent\protected\def\mathlimop#1{\normalmathop{#1}} %no \limits
1895\permanent\protected\def\mathbox  #1{\dontleavehmode\hbox\Ustartmath\mathsurround\zeropoint#1\Ustopmath}
1896\permanent\protected\def\mathnolop#1{\normalmathop{#1}\nolimits}
1897
1898% \permanent\protected\def\mathlimop#1{\mathatom \mathoperatorcode options "C0000 {#1}} % auto "40000 + "80000
1899% \permanent\protected\def\mathnolop#1{\mathatom \mathoperatorcode options "80000 {#1}}
1900
1901% \aliased\let\mathnothing\firstofoneunexpanded
1902% \aliased\let\mathalpha  \firstofoneunexpanded
1903
1904\ifdefined\mathop    \else \aliased\let\mathop   \normalmathoperator    \aliased\let\normalmathop   \normalmathoperator    \fi
1905\ifdefined\mathord   \else \aliased\let\mathord  \normalmathordinary    \aliased\let\normalmathord  \normalmathordinary    \fi
1906\ifdefined\mathbin   \else \aliased\let\mathbin  \normalmathbinary      \aliased\let\normalmathbin  \normalmathbinary      \fi
1907\ifdefined\mathrel   \else \aliased\let\mathrel  \normalmathrelation    \aliased\let\normalmathrel  \normalmathrelation    \fi
1908\ifdefined\mathpunct \else \aliased\let\mathpunct\normalmathpunctuation \aliased\let\normalmathpunct\normalmathpunctuation \fi
1909\ifdefined\underline \else \aliased\let\underline\normalmathunderline   \aliased\let\normalunderline\normalmathunderline   \fi
1910\ifdefined\overline  \else \aliased\let\overline \normalmathoverline    \aliased\let\normaloverline \normalmathoverline    \fi
1911
1912\permanent\def\mathcodechecked#1%
1913  {\numexpr
1914     \ifempty{#1}%
1915       \mathordinarycode
1916     \orelse\ifchknumber#1\or
1917       \lastchknumber
1918     \orelse\ifchknumber\begincsname math#1code\endcsname\or % maybe some day a hash for this
1919       \lastchknumber
1920     \else
1921       \mathordinarycode
1922     \fi
1923   \relax}
1924
1925\permanent\def\mathcodenumber#1%
1926  {\the\mathcodechecked{#1}}
1927
1928\permanent\protected\def\mathcodecommand#1%
1929  {\mathatom \s!class \mathcodechecked{#1}}
1930
1931\permanent\protected\def\mathcodeallcommand#1#2%
1932  {\mathatom \s!class \mathcodechecked{#1} \s!all \mathcodechecked{#2}}
1933
1934\def\math_class_by_parameter    #1#2{\normalexpanded{\noexpand\mathcodechecked{#1#2}}}
1935\def\math_atom_by_parameter       #1{\normalexpanded{\noexpand\math_atom_by_parameter_indeed{#1\c!mathclass}}}
1936\def\math_atom_by_parameter_indeed#1{\mathatom \s!class \mathcodechecked{#1}}
1937
1938% \startlines
1939% $\mathopnolimits{\rm d}x$
1940% $\mathopnolimits{\kern\zeropoint \rm d}x$
1941% $\mathcodecommand{nolop}{\rm d}x$
1942% $\mathcodecommand{nolop}{\kern\zeropoint\rm d}x$
1943% \blank
1944% $\mathcodecommand{nolop}{\mr d}x$
1945% $\mathcodecommand{nolop}{\kern\zeropoint\mr d}x$
1946% $\mathop{\kern\zeropoint\mr d}x$
1947% $\mathopnolimits{\kern\zeropoint d}x$
1948% \stoplines
1949
1950\installcorenamespace{mathcommand}
1951
1952\permanent\tolerant\protected\def\definemathcommand[#1]#*[#2]#*[#3]#:#*#4% command class args meaning
1953  {\ifparameter#3\or
1954     \ifcstok{#3}\v!one
1955       \frozen\protected\defcsname\??mathcommand#1\endcsname##1{\mathcodecommand{#2}{#4{##1}}}%
1956     \orelse\ifcstok{#3}\v!two
1957       \frozen\protected\defcsname\??mathcommand#1\endcsname##1##2{\mathcodecommand{#2}{#4{##1}{##2}}}%
1958     \orelse\ifchknum\mathcodechecked{#3}\or
1959       \frozen\protected\defcsname\??mathcommand#1\endcsname{\mathcodeallcommand{#2}{#3}{#4}}%
1960     \else
1961       \frozen\protected\defcsname\??mathcommand#1\endcsname{\mathcodecommand{#2}{#4}}%
1962     \fi
1963   \orelse\ifparameter#2\or
1964     \frozen\protected\defcsname\??mathcommand#1\endcsname{\mathcodecommand{#2}{#4}}%
1965   \else
1966     \frozen\protected\defcsname\??mathcommand#1\endcsname{#4}%
1967   \fi
1968   \ifparameter#1\or % safeguard
1969     \letcsname#1\expandafter\endcsname\csname\??mathcommand#1\endcsname
1970   \fi}
1971
1972\permanent\protected\def\mathcommand#1%
1973  {\begincsname\??mathcommand#1\endcsname}
1974
1975% \definemathsymbol[wedontlikethisone][3]["2979]
1976% \definemathsymbol[wedontlikethisone][relation]["2979]
1977
1978\permanent\tolerant\protected\def\definemathsymbol[#1]#*[#2]#*[#3]%
1979  {\frozen\expandafter\Umathchardef\csname#1\endcsname
1980     \ifparameter#3\or
1981        \mathcodechecked{#2}%
1982        \zerocount
1983        \numexpr#3% \relax
1984    \else
1985        \zerocount
1986        \zerocount
1987        \numexpr#2% \relax
1988    \fi\relax}
1989
1990%D Let's define a few comands here:
1991
1992%definemathcommand [mathstrut]               {\vphantom{(}}
1993%definemathcommand [joinrel]                 {\mathrel{\mkern-3mu}}
1994%definemathcommand [joinrel]   [\s!relation] {\mkern-3mu}
1995
1996\immutable\chardef\c_math_strut"28
1997
1998%D For the evolution of these struts see the git repositories and older code in
1999%D \MKIV\ and \MKI\ (commented code removed end April 2022).
2000
2001\let\math_strut_math_style\normalmathstyle
2002
2003% using \s!font \mathstylefontid\mathstyle\fam would needs expansion and guesswork
2004
2005\appendtoks
2006    \Umathruleheight\allmainstyles        \strutheightfactor\fontspecifiedsize\textfont        \zerocount
2007    \Umathruledepth \allmainstyles        \strutdepthfactor \fontspecifiedsize\textfont        \zerocount
2008    \Umathruleheight\allscriptstyles      \strutheightfactor\fontspecifiedsize\scriptfont      \zerocount
2009    \Umathruledepth \allscriptstyles      \strutdepthfactor \fontspecifiedsize\scriptfont      \zerocount
2010    \Umathruleheight\allscriptscriptstyles\strutheightfactor\fontspecifiedsize\scriptscriptfont\zerocount
2011    \Umathruledepth \allscriptscriptstyles\strutdepthfactor \fontspecifiedsize\scriptscriptfont\zerocount
2012\to \everybodyfont
2013
2014% The unset height and depth default to this sig    nal that then tells
2015% the engine what to apply from the char dimensions.
2016
2017\protected\def\math_strut
2018  {\normalsrule
2019     %s!width \zeropoint
2020     \s!fam   \fam
2021     \s!char  \c_math_strut
2022   \relax}
2023
2024\permanent\protected\def\math_strut_height
2025  {\normalsrule
2026     %s!width \zeropoint
2027     \s!depth \zeropoint
2028     \s!fam   \fam
2029     \s!char  \c_math_strut
2030   \relax}
2031
2032\permanent\protected\def\math_strut_depth
2033  {\normalsrule
2034     %s!width \zeropoint
2035     \s!height\zeropoint
2036     \s!fam   \fam
2037     \s!char  \c_math_strut
2038   \relax}
2039
2040\permanent\protected\def\showmathstruts % let's not overload \math_strut_normal
2041  {\showmakeup[strut]}
2042
2043\pushoverloadmode
2044    \permanent\protected\def\mathstrut      {\math_strut}
2045    \permanent\protected\def\mathheightstrut{\math_strut_height}
2046    \permanent\protected\def\mathdepthstrut {\math_strut_depth}
2047\popoverloadmode
2048
2049% \permanent\protected\def\topstrut{\normalsrule\s!width\zeropoint\s!height\strutht  \s!depth\zeropoint\relax}
2050% \permanent\protected\def\botstrut{\normalsrule\s!width\zeropoint\s!height\zeropoint\s!depth\strutdp  \relax}
2051
2052\permanent\protected\def\topstrut{\normalsrule\s!height\strutht\relax}
2053\permanent\protected\def\botstrut{\normalsrule\s!depth \strutdp\relax}
2054
2055% \newdimension\mathstrutht % see top
2056% \newdimension\mathstrutdp % see top
2057
2058\appendtoks
2059    \mathstrutht\strutht
2060    \mathstrutdp\strutdp
2061  % \writestatus{!!!!!!}{\the\mathstrutht,\the\mathstrutdp}%
2062\to \everymathematics
2063
2064%D We could have a arg variant \unknown\ but not now.
2065
2066\permanent\protected\def\mathopwithlimits#1#2{\mathop{#1{#2}}\limits}
2067\permanent\protected\def\stackrel        #1#2{\mathrel{\mathop{#2}\limits^{#1}}}
2068
2069%D Moved from font-ini.mkiv:
2070%D
2071%D \macros
2072%D   {mf,mbox,enablembox,mathop}
2073%D
2074%D Todo:
2075
2076\permanent\protected\def\mf{\begincsname\fontalternative\endcsname} % todo: \frozen
2077
2078% \let\normalmathop\mathop % already defined
2079
2080\permanent\protected\def\normalmbox
2081  {\normalhbox\bgroup
2082   \usemathematicsstyleandcolor\c!textstyle\c!textcolor % new
2083   \dowithnextboxcs\math_mbox_finish\normalhbox}
2084
2085\def\math_mbox_finish
2086  {\flushnextbox
2087   \egroup}
2088
2089\permanent\protected\def\mbox % we cannot add \dontleavehmode ... else no \setbox0\mbox possible
2090  {\ifmmode\normalmbox\else\normalhbox\fi}
2091
2092\permanent\protected\def\enablembox
2093  {\toksapp\everymathematics{\math_enable_mbox}}
2094
2095\permanent\def\math_enable_mbox % brrrr
2096  {\enforced\let\hbox\mbox}
2097
2098\permanent\protected\def\snappedmath#1% sort of \struttedbox
2099  {\dontleavehmode
2100   \begingroup
2101   \setbox\scratchbox\normalhbox\bgroup
2102     \startimath#1\stopimath
2103   \egroup
2104   \ht\scratchbox\strutht
2105   \dp\scratchbox\strutdp
2106   \box\scratchbox
2107   \endgroup}
2108
2109\permanent\protected\def\mtext#1%
2110  {\begingroup
2111   \currentmathblobnesting\minusone
2112   \dostarttaggednodetail\t!mtext
2113   \text{\usemathematicsstyleandcolor\c!textstyle\c!textcolor#1}%
2114   \dostoptagged
2115   \endgroup}
2116
2117\protected\permanent\def\textmathematics#1%
2118  {\begingroup
2119   \currentmathblobnesting\minusone
2120   \mathematics{#1}%
2121   \endgroup}
2122
2123%D The next hack is needed needed for sine, cosine etc.
2124
2125\aliased\let\mathfunction\firstofoneunexpanded
2126
2127\let\math_tags_function         \firstofoneunexpanded
2128\let\math_tags_functionlabeltext\mathlabeltext
2129
2130% \let\math_tags_mo\firstofoneunexpanded
2131% \let\math_tags_mi\firstofoneunexpanded
2132
2133% \protected\def\math_tags_mn#1{\begingroup\math_upright\math_set_o_both#1\endgroup}
2134% \protected\def\math_tags_ms#1{\begingroup\math_upright\math_set_p_both#1\endgroup} % why not just \text
2135
2136% Once this is stable we can store the number at the tex end which is
2137% faster. Functions getnumbers >= 1000.
2138
2139% \setupmathematics[functionstyle=normal] % will give ligatures and kerning
2140
2141\setupmathematics
2142  [\c!textstyle=,     % rm ss etc i.e. known alternatives, otherwise math
2143   \c!textcolor=,
2144   \c!functionstyle=, % rm ss etc i.e. known alternatives, otherwise math
2145   \c!functioncolor=]
2146
2147% in char-def:
2148%
2149%
2150% \Umathcode"2061 = \mathghostcode \zerocount "2061 % \applyfunction
2151% \Umathcode"2062 = \mathghostcode \zerocount "2062 % \invisibletimes
2152% \Umathcode"2063 = \mathghostcode \zerocount "2063 % \invisiblecomma
2153% \Umathcode"2064 = \mathghostcode \zerocount "2063 % \invisibleplus
2154
2155%D For previous variants of the function styling you can check the git repository
2156%D end April 2022. We dropped the optional apply feature.
2157
2158% \startTEXpage[offset=1dk]
2159%                           $\sin(x) = 10$
2160%     \m[functionstyle=sans]{\sin(x) = 10}
2161%     \startformula                     \sin(x) = 10 \stopformula
2162%     \startformula[functionstyle=sans] \sin(x) = 10 \stopformula
2163% \stopTEXpage
2164
2165\installcorenamespace{mathfunction}
2166
2167\installcommandhandler \??mathfunction {mathfunction} \??mathfunction
2168
2169\appendtoks
2170    \frozen\protected\edefcsname\currentmathfunction\endcsname{\math_function_handle\plusone{\currentmathfunction}{}}% \instance
2171\to \everydefinemathfunction
2172
2173\aliased\let\setupmathfunctions\setupmathfunction
2174
2175\setupmathfunctions
2176  [\c!color=\mathematicsparameter\c!functioncolor,
2177   \c!style=\mathematicsparameter\c!functionstyle,
2178   \s!class=function]
2179
2180\newconstant\c_function_method
2181
2182\def\math_function_handle_normal#1#2#3%
2183  {\begingroup
2184   \mathdotfull
2185   \cdef\currentmathfunction{#2}%
2186   \setupcurrentmathfunction[#3]%
2187   \edef\p_limits{\mathfunctionparameter\c!mathlimits}%
2188   \edef\p_left{\mathfunctionparameter\c!left}%
2189   \edef\p_right{\mathfunctionparameter\c!right}%
2190   \c_function_method
2191     \ifempty\p_left
2192       \ifempty\p_right
2193         \zerocount % prefix no argument
2194       \else
2195         \plustwo % postfix with argument
2196       \fi
2197     \orelse\ifempty\p_right
2198       \plusone % prefix with argument
2199     \else
2200       \plusthree % pre- and postfix with argument
2201     \fi
2202   \ifcase\c_function_method
2203     \expandafter\math_function_handle_normal_string
2204   \else
2205     \expandafter\math_function_handle_normal_symbol
2206   \fi#1} % constant
2207
2208\def\math_function_handle_normal_string#1%
2209  {\dostarttagged\t!mfunction\currentmathfunction% todo: pass lab id
2210   \math_tags_mfunctionlab\plusone{\currentmathfunction}{\mathfunctionparameter\c!method}%
2211   \mathatom
2212     mathfont
2213     single % behave like a character
2214     class \mathcodechecked{\mathfunctionparameter\s!class}
2215     \ifx\p_limits\v!no
2216       nolimits
2217     \orelse\ifx\p_limits\v!yes
2218       limits
2219     \orelse\ifx\p_limits\v!auto
2220       nolimits
2221       limits
2222     \fi
2223 % \ifcstok{\mathfunctionparameter\c!mathlimits}\v!no
2224 %   nolimits
2225 % \orelse\iflastnamedcs\v!yes
2226 %   limits
2227 % \orelse\iflastnamedcs\v!auto
2228 %   nolimits
2229 %   limits
2230 % \fi
2231   \bgroup % textfont but can be anything
2232   \usemathfunctioncolorparameter\c!color
2233   \edef\p_functionstyle{\mathfunctionparameter\c!style}%
2234   % no need for \expandafter here
2235   \ifempty\p_functionstyle
2236     \expandafter\math_upright
2237   \orelse\ifcsname\??alternativestyle\p_functionstyle\endcsname
2238     \expandafter\lastnamedcs
2239   \else
2240     \expandafter\p_functionstyle
2241   \fi
2242%    \ifcase#1\or % so #1 can go away
2243     \mathlabeltext{\currentmathfunction}%
2244     % needed for StixTwo Diff
2245     \scratchdimen\rightmathkern{\currentmathfunction}%
2246     \ifzeropt\scratchdimen\else\hkern\scratchdimen\fi
2247%    \fi
2248   \egroup
2249   \dostoptagged
2250   \endgroup}
2251
2252\definesystemattribute[mathstack][public]
2253
2254\newinteger\c_mathfunctionstack
2255
2256\def\math_function_handle_normal_symbol#1#2%
2257  {\global\advanceby\c_mathfunctionstack\plusone
2258   \attribute\mathstackattribute\c_mathfunctionstack
2259   \math_tags_mfunctionlab\plusone{\currentmathfunction}{\mathfunctionparameter\c!method}%
2260   \dostarttagged\t!mfunctionstack\currentmathfunction
2261   \mathghost carryover \bgroup
2262      \p_left
2263      \begingroup
2264      \attribute\mathstackattribute\attributeunsetvalue
2265      #2%
2266      \endgroup
2267      \p_right
2268   \egroup
2269   \dostoptagged
2270   \endgroup}
2271
2272\def\math_function_handle_language_indeed#1#2#3%
2273  {\cdef\currentmathfunction{#2}%
2274   \setupcurrentmathfunction[#3]%
2275   \edef\p_command{\mathfunctionparameter\c!command}%
2276   \ifempty\p_command
2277     \endgroup\math_function_handle_normal#1{#2}{#3}%
2278   \else
2279     \normalexpanded{\endgroup\p_command\expandafter}%
2280   \fi}
2281
2282\def\math_function_handle_language#1#2%
2283  {\begingroup
2284   \let\math_function_handle\math_function_handle_language_indeed
2285   \csname\currentmainlanguage:#2\endcsname}
2286
2287\tolerant\protected\def\math_function_handle#1#2#3%
2288  {\ifcsname\currentmainlanguage:#2\endcsname
2289     \expandafter\math_function_handle_language
2290   \else
2291     \expandafter\math_function_handle_normal
2292   \fi#1{#2}{#3}}
2293
2294\permanent\tolerant\protected\def\mfunctionlabeltext[#1]%
2295  {\math_function_handle\plusone{#1}{}}
2296
2297% \mfunction [settings][name]  [settings]{name}  [name]  {name}
2298
2299\permanent\tolerant\protected\def\mfunction[#1]%
2300  {\ifhastok={#1}%
2301     \expandafter\mfunction_yes
2302   \orelse\ifparameter#1\or
2303     \expandafter\mfunction_nop
2304   \else
2305     \expandafter\mfunction_yop
2306   \fi{#1}}
2307
2308\permanent\tolerant\protected\def\mfunction_yes#1#*[#2]#;#3{\math_function_handle\zerocount{#2#3}{#1}}
2309\permanent\protected\def\mfunction_nop                   #1{\math_function_handle\zerocount{#1}{}}
2310\permanent\protected\def\mfunction_yop                 #1#2{\math_function_handle\zerocount{#2}{}}
2311
2312\appendtoks
2313%     \edef\p_functionstyle{\formulaparameter\c!functionstyle}%
2314%     \ifempty\p_functionstyle\else
2315%         \letmathematicsparameter\c!functionstyle\p_functionstyle
2316%     \fi
2317%     \edef\p_functioncolor{\formulaparameter\c!functioncolor}%
2318%     \ifempty\p_functioncolor\else
2319%         \letmathematicsparameter\c!functioncolor\p_functioncolor
2320%     \fi
2321\to \everybeforedisplayformula
2322
2323\let\math_tags_mfunctionlab         \gobblethreearguments
2324\def\math_tags_mfunctionlabattribute#-#-#-{\zerocount}
2325
2326% \permanent\protected\def\math_tags_mo_indeed#1{\begingroup             \c_attr_mathcategory\plusone                  #1\endgroup}
2327% \permanent\protected\def\math_tags_mi_indeed#1{\begingroup             \c_attr_mathcategory\plustwo                  #1\endgroup}
2328% \permanent\protected\def\math_tags_mn_indeed#1{\begingroup\math_upright\c_attr_mathcategory\plusthree\math_set_o_both#1\endgroup}
2329% \permanent\protected\def\math_tags_ms_indeed#1{\begingroup\math_upright\c_attr_mathcategory\plusfour \math_set_p_both#1\endgroup} % todo: mathoptext
2330
2331\permanent\protected\def\math_tags_mo#1{\mathatom \s!class \mathoperatorcode        {#1}}
2332\permanent\protected\def\math_tags_mi#1{\mathatom \s!class \mathordinarycode        {#1}}
2333%permanent\protected\def\math_tags_mn#1{\mathatom \s!class \mathdigitcode           {\math_upright #1}}
2334\permanent\protected\def\math_tags_ms#1{\mathatom \s!class \mathtextpunctuationcode {\math_upright #1}}
2335
2336\permanent\protected\def\math_tags_mn#1%
2337  {\dostarttaggednodetail\t!mdigits
2338   \mathatom \s!class \mathdigitcode {\math_upright #1}%
2339   \dostoptagged}
2340
2341\newconditional\c_apply_function
2342
2343\ifdefined\apply \else \aliased\let\apply\relax \fi
2344
2345\mutable\let\mo\relax
2346\mutable\let\mi\relax
2347\mutable\let\mn\relax
2348\mutable\let\ms\relax
2349
2350\appendtoks
2351    \enforced\let\math_tags_mfunctionlab         \clf_tagmfunctionlab
2352    \enforced\let\math_tags_mfunctionlabattribute\clf_tagmfunctionlabattribute
2353\to \everyenableelements
2354
2355\permanent\protected\def\registermathfunction[#1]% experimental
2356  {\begingroup
2357   \scratchcounter\clf_tagmfunctionlabattribute
2358     \plusone
2359     {#1}%
2360     {}%
2361   \endgroup}
2362
2363% domain language name meaning
2364% language name meaning
2365% name meaning
2366
2367\permanent\protected\def\registermathsymbol[#1]#*[#2]#*[#3]#*[#4]% experimental
2368  {\ifparameter#4\or
2369     \clf_registerverbosemathlabel{#1}{#2}{#3}{#4}%
2370   \orelse\ifparameter#3\or
2371     \clf_registerverbosemathlabel{\s!default}{#1}{#2}{#3}%
2372   \else
2373     \clf_registerverbosemathlabel{\s!default}{\s!en}{#1}{#2}%
2374   \fi}
2375
2376\appendtoks
2377    \enforced\let\mo   \math_tags_mo
2378    \enforced\let\mi   \math_tags_mi
2379    \enforced\let\mn   \math_tags_mn
2380    \enforced\let\ms   \math_tags_ms
2381    \enforced\let\apply\math_tags_apply
2382\to\everymathematics
2383
2384\mutable\def\currentmscaledstyle{rm} % will be plugged into the typeface text=ss option
2385
2386\permanent\protected\def\mscaledtext#1%
2387  {\mathchoice
2388     {\hbox{\csname\currentmscaledstyle\endcsname\tf  #1}}
2389     {\hbox{\csname\currentmscaledstyle\endcsname\tf  #1}}
2390     {\hbox{\csname\currentmscaledstyle\endcsname\tfx #1}}
2391     {\hbox{\csname\currentmscaledstyle\endcsname\tfxx#1}}}
2392
2393\permanent\protected\def\setmathfunctionstyle#1%
2394  {\setupmathematics[\c!functionstyle=#1]} % for old times sake
2395
2396%D Usage:
2397%D
2398%D \starttyping
2399%D \setmathfunctionstyle\fontstyle % or {rm} or {ss} or ..
2400%D \rm test $\sin{(x^{\sin(x^{\sin(x)})})}$ test
2401%D \ss test $\sin{(x^{\sin(x^{\sin(x)})})}$ test
2402%D \tt test $\sin{(x^{\sin(x^{\sin(x)})})}$ test
2403%D \stoptyping
2404
2405%D \macros
2406%D   {nonknuthmode, donknuthmode}
2407%D
2408%D The underscore is frequently used in manuals but unfortunately \TEX\ prefers
2409%D it to be a math specific character. And since computer modern fonts didn't
2410%D have an underscore, one had to use commands to fake one. Nowadays we do
2411%D have underscores in latin modern, and since all other fonts have them, we
2412%D decided to get away from the restriction to use the underscore character in
2413%D text mode.
2414%D
2415%D \starttyping
2416%D \def\test#1{#1}
2417%D
2418%D \nonknuthmode $x_2$ x_2 \test{$x_2$} \test{x_2}
2419%D
2420%D \donknuthmode $x_2$ x_2 \test{$x_2$} \test{x_2}
2421%D \stoptyping
2422%D
2423%D The result is as expected: the first line typesets ok, while the second one
2424%D triggers an error message.
2425
2426% \setnewconstant\activemathcharcode "8000
2427%
2428% \newtoks\activatedmathcharacters
2429%
2430% \permanent\protected\def\activatemathcharacter#1%
2431%   {\appendtoks
2432%      \global\mathcode#1=\activemathcharcode
2433%    \to \activatedmathcharacters}
2434%
2435% \permanent\def\activatemathcharacters
2436%   {\the\activatedmathcharacters}
2437%
2438% % beware, not runtime, so has to happen at format generation
2439%
2440% \activatemathcharacter\circumflexasciicode
2441% \activatemathcharacter\underscoreasciicode
2442% %activatemathcharacter\ampersandasciicode
2443
2444% % already done in catc-def.mkxl:
2445%
2446% \amcode \circumflexasciicode \superscriptcatcode
2447% \amcode \underscoreasciicode \subscriptcatcode
2448% \amcode \barasciicode        \othercatcode
2449% \amcode \tildeasciicode      \othercatcode
2450
2451% \Umathcode\circumflexasciicode="0 "0 \circumflexasciicode
2452% \Umathcode\underscoreasciicode="0 "0 \underscoreasciicode
2453
2454% \permanent\def\normalmathaligntab{&}
2455%
2456% \appendtoks
2457%     \edef\p_ampersand{\mathematicsparameter\s!ampersand}%
2458%     \ifx\p_ampersand\v!normal
2459%         \enforced\let\specialmathaligntab\normalmathaligntab
2460%     \else
2461%         \enforced\let\specialmathaligntab\mathampersand
2462%     \fi
2463% \to \everysetupmathematics
2464% \to \everyswitchmathematics
2465
2466%D A simplified version of this code is:
2467%D
2468%D \starttyping
2469%D \catcode"26=12
2470%D
2471%D \bgroup
2472%D     \global\mathcode"26="8000
2473%D
2474%D     \catcode"26=4
2475%D
2476%D     \xdef\normalmathaligntab{&}
2477%D
2478%D     \catcode"26=13
2479%D
2480%D     \global\everymath{\def&{\normalmathaligntab}}
2481%D \egroup
2482%D \stoptyping
2483%D
2484%D The following works okay:
2485%D
2486%D \starttyping
2487%D A & B
2488%D \stoptyping
2489%D
2490%D As does:
2491%D
2492%D \starttyping
2493%D $A \Umathchar"2"0"26 B$
2494%D \stoptyping
2495%D
2496%D But the next code:
2497%D
2498%D \starttyping
2499%D $A \char"26 B$
2500%D \stoptyping
2501%D
2502%D fails with: \type{Misplaced alignment tab character &} and here is the reason.
2503%D
2504%D When we have a letter or other category a check happens for an active character
2505%D and when it has one then it gets expanded and fed back into the scanner (sort
2506%D of).
2507%D
2508%D A \type {\char} is also fed back as raw character and again when it's letter of
2509%D other goes through the same process.
2510%D
2511%D This means that we cannot have a definition like:
2512%D
2513%D \starttyping
2514%D \def\AND{\char"26\relax}
2515%D \stoptyping
2516%D
2517%D that can be used in math mode, which is why the cweb macros do:
2518%D
2519%D \starttyping
2520%D \def\AND{\def\AND{\mathchar"2026\relax}\AND}
2521%D \stoptyping
2522%D
2523%D Maybe we need an option to treat chars like chars.
2524
2525%D The commented prime related code (dating from \MKII\ times has been removed in
2526%D April 2022 but it's in the archives. In \LUAMETATEX\ primes are part of the
2527%D machinery and additional magic (as in \MKIV) happens elsewhere. There is no
2528%D need to remember old stuff because \MKII\ times are long gone.
2529
2530\ifdefined \prime \else
2531    \Umathchardef\prime "0 "0 "2032
2532\fi
2533
2534%D We also dropped the option to let ampersands be alignment tabs. That has never
2535%D been a \CONTEXT\ feature|/|habit anyway.
2536
2537% \bgroup
2538%
2539%     \catcode\underscoreasciicode\activecatcode
2540%     \catcode\circumflexasciicode\activecatcode
2541%
2542%     \aliased\glet\specialmathaligntab\normalmathaligntab
2543%
2544%     \permanent\protected\gdef\obeymathcatcodes{%
2545%         \enforced\let _\normalsubscript
2546%         \enforced\let ^\normalsuperscript
2547%     }
2548%
2549%     \gtoksapp\everymathematics{\obeymathcatcodes}%
2550%
2551% \egroup
2552
2553%D We keep this, just for the fun of it:
2554
2555\newtoks\everydonknuthmode
2556\newtoks\everynonknuthmode
2557
2558\newconditional \knuthmode
2559
2560\aliased\let\nonknuthmode\relax % no longer needed in MkIV
2561\aliased\let\donknuthmode\relax % no longer needed in MkIV
2562
2563% \def\nonknuthmode
2564%   {\pushcatcodetable
2565%    \setcatcodetable\ctxcatcodes
2566%    \expand\everynonknuthmode
2567%    \let\nonknuthmode\relax
2568%    \popcatcodetable}
2569%
2570% \def\donknuthmode
2571%   {\pushcatcodetable
2572%    \setcatcodetable\ctxcatcodes
2573%    \expand\everydonknuthmode
2574%    \popcatcodetable}
2575%
2576% \bgroup
2577%
2578%     \catcode\underscoreasciicode\activecatcode
2579%     \catcode\circumflexasciicode\activecatcode
2580%     \catcode\ampersandasciicode \activecatcode
2581%
2582%     \global \everynonknuthmode {\appendtoks
2583%         \let_\normalsubscript
2584%         \let^\normalsuperscript
2585%         \let&\normalmathaligntab % use \def when it's \aligntab
2586%     \to \everymathematics}
2587%
2588% \egroup
2589%
2590% \appendtoks
2591%     \knuthmode\conditionalfalse
2592%     \catcode\underscoreasciicode\othercatcode
2593%     \catcode\circumflexasciicode\othercatcode
2594%     \catcode\ampersandasciicode \othercatcode
2595% \to \everynonknuthmode
2596%
2597% \appendtoks
2598%     \knuthmode\conditionaltrue
2599%     \catcode\underscoreasciicode\subscriptcatcode
2600%     \catcode\circumflexasciicode\superscriptcatcode
2601%     \catcode\ampersandasciicode \alignmentcatcode
2602% \to \everydonknuthmode
2603%
2604% \appendtoks
2605%     \startextendcatcodetable\ctxcatcodes
2606%         \catcode\underscoreasciicode\othercatcode
2607%         \catcode\circumflexasciicode\othercatcode
2608%         \catcode\ampersandasciicode \othercatcode
2609%     \stopextendcatcodetable
2610% \to \everynonknuthmode
2611%
2612% \appendtoks
2613%     \startextendcatcodetable\ctxcatcodes
2614%         \catcode\underscoreasciicode\subscriptcatcode
2615%         \catcode\circumflexasciicode\superscriptcatcode
2616%         \catcode\ampersandasciicode \alignmentcatcode
2617%     \stopextendcatcodetable
2618% \to \everydonknuthmode
2619
2620%D Even more drastic (this code will move as nonknuthmode is default now)
2621
2622% \protected\def\enableasciimode
2623%   {\ctxlua{resolvers.macros.enablecomment()}%
2624%    \glet\enableasciimode\relax}
2625%
2626% \protected\def\asciimode
2627%   {\catcodetable\txtcatcodes
2628%    \enableasciimode
2629%    \nonknuthmode}
2630%
2631% \protected\def\startasciimode
2632%   {\pushcatcodetable
2633%    \catcodetable\txtcatcodes
2634%    \enableasciimode
2635%    \nonknuthmode}
2636%
2637% \protected\def\stopasciimode
2638%   {\popcatcodetable
2639%    \ifconditional\knuthmode\else\donknuthmode\fi}
2640
2641\permanent\protected\def\enableasciimode
2642  {\clf_enableasciimode} % relaxes itself
2643
2644\permanent\protected\def\asciimode
2645  {\catcodetable\txtcatcodes
2646   \clf_enableasciimode}
2647
2648\permanent\protected\def\startasciimode
2649  {\pushcatcodetable
2650   \catcodetable\txtcatcodes
2651   \clf_enableasciimode}
2652
2653\permanent\protected\def\stopasciimode
2654  {\popcatcodetable}
2655
2656%D Needed for unicode:
2657
2658\permanent\def\nulloperator{\mathortext{\mathop{\emptyhbox}}{\emptyhbox}}
2659
2660%D Memory saver:
2661
2662\def\math_basics_check_compact
2663  {\ifcstok{\mathematicsparameter\c!compact}\v!yes
2664     \expandafter\enabledirectives
2665   \else
2666     \expandafter\disabledirectives
2667   \fi
2668   [math.virtual.optional]}
2669
2670\appendtoks
2671    \ifempty\currentmathematics
2672        \math_basics_check_compact % less tracing
2673    \fi
2674% \to \everysetupmathematics
2675\to \everyswitchmathematics
2676
2677\setupmathematics
2678  [\c!compact=\v!no]
2679
2680% \enabletrackers[typesetters.directions.math]
2681
2682%D Right||to||left typesetting in math is supported by the \type {align} parameter
2683%D with as option the \type {bidi} parameter. Of course support for special symbols
2684%D like square roots depends on the font as well. We probably need to mirror a few
2685%D more characters.
2686%D
2687%D \startbuffer
2688%D     \removeunwantedspaces
2689%D     \m{   (  1 =   1)   }\quad
2690%D     \m{   (123 = 123)   }\quad
2691%D     \m{ a (  1 =   1) b }\quad
2692%D     \m{ a (123 = 123) b }\quad
2693%D     \m{ x = 123 y + (1 / \sqrt {x}) }
2694%D \stopbuffer
2695%D
2696%D \typebuffer
2697%D
2698%D \starttabulate[|T|T||]
2699%D \HL
2700%D \NC align \NC bidi \NC                                                  \NC \NR
2701%D \HL
2702%D \NC l2r   \NC no   \NC \setupmathematics[bidi=no]            \getbuffer \NC \NR
2703%D \NC l2r   \NC yes  \NC \setupmathematics[bidi=yes]           \getbuffer \NC \NR
2704%D \NC r2l   \NC no   \NC \setupmathematics[align=r2l,bidi=no]  \getbuffer \NC \NR
2705%D \NC r2l   \NC yes  \NC \setupmathematics[align=r2l,bidi=yes] \getbuffer \NC \NR
2706%D \HL
2707%D \stoptabulate
2708
2709% We will use proper constants when we go numbers instead of XXX.
2710
2711\newconditional\c_math_right_to_left
2712
2713\installcorenamespace{mathaligndirection}
2714
2715\defcsname\??mathaligndirection           r2l\endcsname{\c_math_right_to_left\conditionaltrue}
2716\defcsname\??mathaligndirection\v!righttoleft\endcsname{\c_math_right_to_left\conditionaltrue}
2717
2718\appendtoks
2719    \ifcsname\??mathaligndirection\mathematicsparameter\c!align\endcsname
2720      \lastnamedcs
2721    \else
2722      \c_math_right_to_left\conditionalfalse
2723    \fi
2724\to \everyswitchmathematics
2725
2726\protected\def\math_basics_synchronize_direction
2727  {\mathdirection\ifconditional\c_math_right_to_left\directionrighttoleft\else\directionlefttoright\fi}
2728
2729% Not \everymathematics as it comes too late and I'm not in the mood for a mixed mode
2730% kludge now (should be a property of beginmath nodes and passed to callbacks).
2731
2732\appendtoks
2733    \math_basics_synchronize_direction
2734\to \everyswitchmathematics
2735
2736% experimental (needed for an article) .. this is is no longer neded
2737
2738% \installcorenamespace {mathbidi}
2739%
2740% \newcount\c_math_bidi
2741%
2742% \def\math_bidi_enable {\clf_setmathdirection\plusone  \relax\c_math_bidi\plusone}
2743% \def\math_bidi_disable{\clf_setmathdirection\zerocount\relax\c_math_bidi\attributeunsetvalue}
2744%
2745% \letcsname\??mathbidi\v!yes\endcsname\math_bidi_enable
2746% \letcsname\??mathbidi\v!no \endcsname\math_bidi_disable
2747%
2748% \appendtoks
2749%     \edef\p_bidi{\mathematicsparameter\c!bidi}% still needed ?
2750%     \ifcsname\??mathbidi\p_bidi\endcsname\lastnamedcs\else\math_bidi_disable\fi
2751% \to \everysetupmathematics
2752% \to \everyswitchmathematics
2753%
2754% \appendtoks
2755%     \c_attr_mathbidi\ifconditional\c_math_right_to_left\c_math_bidi\else\attributeunsetvalue\fi
2756% \to \everyswitchmathematics
2757
2758%D Delayed: greek.
2759%D
2760%D \starttyping
2761%D \usetypescript[cambria]\setupbodyfont[cambria]
2762%D \startTEXpage
2763%D     $\alpha \mathgreekupright \alpha \mathgreekitalic \alpha$
2764%D \stopTEXpage
2765%D \stoptyping
2766
2767% [lc uc] normal (upright) = 2, italic = 3, none = 0/1
2768
2769% We can move the setting to the lua end and use abstract numbers instead
2770% if funny ones here.
2771
2772\installcorenamespace{mathgreek}
2773
2774\newconstant\c_math_greek_attribute
2775
2776\defcsname\??mathgreek\v!none  \endcsname{1}
2777\defcsname\??mathgreek\v!normal\endcsname{2}
2778\defcsname\??mathgreek\v!italic\endcsname{3}
2779
2780% \appendtoks
2781%     \edef\p_sygreek{\mathematicsparameter\s!sygreek}% still needed ?
2782%     \edef\p_lcgreek{\mathematicsparameter\s!lcgreek}% still needed ?
2783%     \edef\p_ucgreek{\mathematicsparameter\s!ucgreek}% still needed ?
2784%     \c_math_greek_attribute"% hex digits
2785%       \ifcsname\??mathgreek\p_sygreek\endcsname\lastnamedcs\else1\fi
2786%       \ifcsname\??mathgreek\p_lcgreek\endcsname\lastnamedcs\else1\fi
2787%       \ifcsname\??mathgreek\p_ucgreek\endcsname\lastnamedcs\else1\fi
2788%     \relax
2789%     \ifcase\c_math_greek_attribute
2790%       \c_math_greek_attribute\attributeunsetvalue
2791%     \fi
2792% \to \everyswitchmathematics
2793
2794\appendtoks
2795    \c_math_greek_attribute"% hex digits
2796      \ifcsname\??mathgreek\mathematicsparameter\s!sygreek\endcsname\lastnamedcs\else1\fi
2797      \ifcsname\??mathgreek\mathematicsparameter\s!lcgreek\endcsname\lastnamedcs\else1\fi
2798      \ifcsname\??mathgreek\mathematicsparameter\s!ucgreek\endcsname\lastnamedcs\else1\fi
2799    \relax
2800    \ifcase\c_math_greek_attribute
2801      \c_math_greek_attribute\attributeunsetvalue
2802    \fi
2803\to \everyswitchmathematics
2804
2805% only used local
2806
2807\permanent\protected\def\mathgreekupright{\c_attr_mathgreek"222\relax}
2808\permanent\protected\def\mathgreekitalic {\c_attr_mathgreek"333\relax}
2809\permanent\protected\def\mathgreekdefault{\c_attr_mathgreek"000\relax}
2810
2811\aliased\let\mathgreeknormal\mathgreekupright
2812\aliased\let\mathgreeknone  \mathgreekdefault
2813
2814\appendtoks
2815    \c_attr_mathgreek\c_math_greek_attribute
2816\to \everymathematics
2817
2818\setupmathematics
2819  [\s!sygreek=\v!normal,
2820   \s!lcgreek=\v!italic,
2821   \s!ucgreek=\v!normal] % was: none
2822
2823%D Math collapsing (ligatures)
2824
2825\installcorenamespace{mathcollapsing}
2826
2827\setnewconstant\c_math_collapsing_attribute\attributeunsetvalue
2828
2829\permanent\protected\def\resetmathcollapsing{\c_attr_mathcollapsing\attributeunsetvalue}
2830
2831\letcsname\??mathcollapsing         0\endcsname\zerocount            % enforced (primes)
2832\letcsname\??mathcollapsing\s!tex    \endcsname\zerocount
2833\letcsname\??mathcollapsing         1\endcsname\plusone              % enforced | specials
2834\letcsname\??mathcollapsing\v!default\endcsname\plusone
2835\letcsname\??mathcollapsing         2\endcsname\plustwo              % enforced | specials | mathlist
2836\letcsname\??mathcollapsing\v!all    \endcsname\plustwo
2837\letcsname\??mathcollapsing         3\endcsname\plusthree            % enforced | mathlist | specials
2838\letcsname\??mathcollapsing\v!list   \endcsname\plusthree
2839\letcsname\??mathcollapsing\v!none   \endcsname\attributeunsetvalue
2840\letcsname\??mathcollapsing\v!reset  \endcsname\attributeunsetvalue
2841
2842\def\math_collapsing_initialize
2843  {\ifnum\c_math_collapsing_attribute=\attributeunsetvalue \else
2844     \clf_initializemathcollapsing % one time
2845     \glet\math_collapsing_initialize\relax
2846   \fi}
2847
2848\appendtoks
2849    \edef\p_collapsing{\mathematicsparameter\s!collapsing}%
2850    \c_math_collapsing_attribute
2851        \ifcsname\??mathcollapsing\p_collapsing\endcsname\lastnamedcs\else\attributeunsetvalue\fi
2852    \relax
2853\to \everyswitchmathematics % only in mathematics
2854
2855\appendtoks
2856    \math_collapsing_initialize
2857    \c_attr_mathcollapsing\c_math_collapsing_attribute
2858\to \everymathematics
2859
2860\setupmathematics
2861  [\s!collapsing=1] % so that we at least do primes
2862
2863%D Math kerns (experiment)
2864
2865\installcorenamespace{mathkernpairs}
2866
2867\setnewconstant\c_math_kernpairs_attribute\attributeunsetvalue % no real need for an extra constant
2868
2869\def\math_kernpairs_initialize
2870  {\ifnum\c_math_kernpairs_attribute=\attributeunsetvalue \else
2871     \clf_initializemathkernpairs % one time
2872     \glet\math_kernpairs_initialize\relax
2873   \fi}
2874
2875\appendtoks
2876    \edef\p_kernpairs{\mathematicsparameter\s!kernpairs}%
2877    \c_math_kernpairs_attribute\ifx\p_kernpairs\v!yes\plusone\else\attributeunsetvalue\fi\relax
2878\to \everyswitchmathematics % only in mathematics
2879
2880\appendtoks
2881    \math_kernpairs_initialize
2882    \c_attr_mathkernpairs\c_math_kernpairs_attribute
2883\to \everymathematics
2884
2885\setupmathematics
2886  [\s!kernpairs=\v!no]
2887
2888%D \macros
2889%D   {enablemathpunctuation,disablemathpunctuation}
2890%D
2891%D \startbuffer
2892%D \enablemathpunctuation$(1,2) (1, 2) (1{,}2) \hbox{foo, not bar}$
2893%D \stopbuffer
2894%D
2895%D \typebuffer
2896%D
2897%D \blank{\getbuffer}\blank
2898
2899% \newconditional\automathpunctuation
2900%
2901% \protected\def\enablemathpunctuation {\automathpunctuation\conditionaltrue}
2902% \protected\def\disablemathpunctuation{\automathpunctuation\conditionalfalse}
2903%
2904% \appendtoks
2905%     \ifcstok{\mathematicsparameter\c!autopunctuation}\v!yes
2906%       \automathpunctuation\conditionaltrue
2907%     \else
2908%       \automathpunctuation\conditionalfalse
2909%     \fi
2910% \to \everyswitchmathematics
2911%
2912% \setupmathematics
2913%   [\c!autopunctuation=\v!no]
2914%
2915% \def\math_punctuation_next{\ifx\nexttoken\blankspace\signalcharacter\fi}
2916%
2917% \protected\def\math_punctuation_comma {\textcomma \futurelet\nexttoken\math_punctuation_next}
2918% \protected\def\math_punctuation_period{\textperiod\futurelet\nexttoken\math_punctuation_next}
2919%
2920% \setnewconstant\commaasciicode  "002C
2921% \setnewconstant\periodasciicode "002E
2922% \setnewconstant\c_math_special"8000
2923%
2924% \bgroup
2925%
2926%     \catcode\commaasciicode \activecatcode
2927%     \catcode\periodasciicode\activecatcode
2928%
2929%     \protected\gdef\math_punctuation_initialize_indeed
2930%       {\mathcode\commaasciicode \c_math_special
2931%        \mathcode\periodasciicode\c_math_special
2932%        \let,\math_punctuation_comma
2933%        \let.\math_punctuation_period
2934%        \c_attr_mathpunctuation\plustwo}
2935%
2936%     \protected\gdef\math_punctuation_initialize_yes
2937%       {\c_attr_mathpunctuation\plustwo}
2938%
2939%     \protected\gdef\math_punctuation_initialize_nop
2940%       {\c_attr_mathpunctuation\plusone}
2941%
2942% \egroup
2943%
2944% \appendtoks
2945%     \ifconditional\automathpunctuation
2946%       \math_punctuation_initialize_indeed
2947%       \math_punctuation_initialize_yes
2948%       \let\enablemathpunctuation \math_punctuation_initialize_yes
2949%       \let\disablemathpunctuation\math_punctuation_initialize_nop
2950%     \fi
2951% \to \everymathematics
2952
2953% Later I will look again into a \LUATEX\ based solution. It only makes sense
2954% to delegate to \LUA\ when we have more variants and need analysis (experimental
2955% trickery removed for a while).
2956
2957% \def\math_punctuation_comma_next {\ifx\nexttoken\blankspace\mathpunct\else\mathord\fi{\textcomma }}
2958% \def\math_punctuation_period_next{\ifx\nexttoken\blankspace\mathpunct\else\mathord\fi{\textperiod}}
2959%
2960% \protected\def\math_punctuation_nop_comma {\mathpunct{\textcomma}}
2961% \protected\def\math_punctuation_nop_period{\mathord{\textperiod}}
2962%
2963% \protected\def\math_punctuation_all_comma {\futurelet\nexttoken\math_punctuation_comma_next}
2964% \protected\def\math_punctuation_all_period{\futurelet\nexttoken\math_punctuation_period_next}
2965%
2966%            \let\math_punctuation_yes_comma \math_punctuation_all_comma
2967%            \let\math_punctuation_yes_period\math_punctuation_nop_period
2968%
2969% The next one is more efficient as it produces more flat noad lists for numbers.
2970
2971%D This is a dirty trick. In order to prevent a loop due to reinjection, when a
2972%D active one is seen, the amcode is set to other. So, afterwards we need to
2973%D reactivate. Eventually this feature will be dropped in favor of a more modern
2974%D mechanism.
2975
2976%D These amcodes can be alignmenttab, superscript, subscript, letter, otherchar, or
2977%D active. That way we can avoid the "8000 hackery and let characters keep the
2978%D proper class. The code is checked when we run into an active character in math
2979%D mode
2980
2981\def\math_activeate_comma    {\amcode\commaasciicode    \activecatcode}
2982\def\math_activeate_period   {\amcode\periodasciicode   \activecatcode}
2983\def\math_activeate_semicolon{\amcode\semicolonasciicode\activecatcode}
2984
2985\def\math_set_o_comma    {\Umathcode\commaasciicode    \mathordinarycode   \zerocount\commaasciicode}
2986\def\math_set_p_comma    {\Umathcode\commaasciicode    \mathpunctuationcode\zerocount\commaasciicode}
2987\def\math_set_o_period   {\Umathcode\periodasciicode   \mathordinarycode   \zerocount\periodasciicode}
2988\def\math_set_p_period   {\Umathcode\periodasciicode   \mathpunctuationcode\zerocount\periodasciicode}
2989\def\math_set_o_semicolon{\Umathcode\semicolonasciicode\mathordinarycode   \zerocount\semicolonasciicode}
2990\def\math_set_p_semicolon{\Umathcode\semicolonasciicode\mathpunctuationcode\zerocount\semicolonasciicode}
2991
2992\edef\math_set_o_both{\math_set_o_period\math_set_o_comma}
2993\edef\math_set_p_both{\math_set_p_period\math_set_p_comma}
2994
2995% We cannot use \mathchardef'd variants because then are intercepted as active, so:
2996
2997\protected\def\math_punctuation_nop_comma    {\begingroup\math_set_p_comma    ,\endgroup\math_activeate_comma    }
2998\protected\def\math_punctuation_nop_period   {\begingroup\math_set_o_period   .\endgroup\math_activeate_period   }
2999\protected\def\math_punctuation_nop_semicolon{\begingroup\math_set_p_semicolon;\endgroup\math_activeate_semicolon}
3000
3001\def\math_punctuation_comma_next    {\begingroup\Umathcode\commaasciicode    \ifx\nexttoken\blankspace\mathpunctuationcode\else\mathordinarycode\fi\zerocount\commaasciicode    ,\endgroup\math_activeate_comma    }
3002\def\math_punctuation_period_next   {\begingroup\Umathcode\periodasciicode   \ifx\nexttoken\blankspace\mathpunctuationcode\else\mathordinarycode\fi\zerocount\periodasciicode   .\endgroup\math_activeate_period   }
3003\def\math_punctuation_semicolon_next{\begingroup\Umathcode\semicolonasciicode\ifx\nexttoken\blankspace\mathpunctuationcode\else\mathordinarycode\fi\zerocount\semicolonasciicode;\endgroup\math_activeate_semicolon}
3004
3005% So, nicer is:
3006%
3007% \protected\def\math_punctuation_nop_comma    {\Umathclass\mathpunctuationcode\commaasciicode    \math_activeate_comma    }
3008% \protected\def\math_punctuation_nop_period   {\Umathclass\mathordinarycode   \periodasciicode   \math_activeate_period   }
3009% \protected\def\math_punctuation_nop_semicolon{\Umathclass\mathpunctuationcode\semicolonasciicode\math_activeate_semicolon}
3010%
3011% \def\math_punctuation_comma_next    {\Umathclass\ifx\nexttoken\blankspace\mathpunctuationcode\else\mathordinarycode\fi\commaasciicode    \math_activeate_comma    }
3012% \def\math_punctuation_period_next   {\Umathclass\ifx\nexttoken\blankspace\mathpunctuationcode\else\mathordinarycode\fi\periodasciicode   \math_activeate_period   }
3013% \def\math_punctuation_semicolon_next{\Umathclass\ifx\nexttoken\blankspace\mathpunctuationcode\else\mathordinarycode\fi\semicolonasciicode\math_activeate_semicolon}
3014
3015\protected\def\math_punctuation_all_comma    {\futurelet\nexttoken\math_punctuation_comma_next}
3016\protected\def\math_punctuation_all_period   {\futurelet\nexttoken\math_punctuation_period_next}
3017\protected\def\math_punctuation_all_semicolon{\futurelet\nexttoken\math_punctuation_semicolon_next}
3018
3019          \let\math_punctuation_yes_comma    \math_punctuation_all_comma
3020          \let\math_punctuation_yes_period   \math_punctuation_nop_period
3021          \let\math_punctuation_yes_semicolon\math_punctuation_all_semicolon
3022
3023\installcorenamespace {mathautopunctuation}
3024
3025% \bgroup
3026%
3027%     \catcode\commaasciicode    \activecatcode
3028%     \catcode\periodasciicode   \activecatcode
3029%     \catcode\semicolonasciicode\activecatcode
3030%
3031%     \gdefcsname\??mathautopunctuation\v!no\endcsname
3032%       {\let,\math_punctuation_nop_comma
3033%        \let.\math_punctuation_nop_period
3034%        \let;\math_punctuation_nop_semicolon}
3035%
3036%     \gdefcsname\??mathautopunctuation\v!yes\endcsname
3037%       {\let,\math_punctuation_yes_comma
3038%        \let.\math_punctuation_yes_period
3039%        \let;\math_punctuation_nop_semicolon}
3040%
3041%     \gdefcsname\??mathautopunctuation\v!all\endcsname
3042%       {\let,\math_punctuation_all_comma
3043%        \let.\math_punctuation_all_period
3044%        \let;\math_punctuation_nop_semicolon}
3045%
3046%     \gdefcsname\??mathautopunctuation comma\endcsname
3047%       {\let,\math_punctuation_yes_comma
3048%        \let.\math_punctuation_yes_period
3049%        \let;\math_punctuation_nop_semicolon}
3050%
3051%     \gdefcsname\??mathautopunctuation\v!yes\string,semicolon\endcsname
3052%       {\let,\math_punctuation_yes_comma
3053%        \let.\math_punctuation_yes_period
3054%        \let;\math_punctuation_yes_semicolon}
3055%
3056%     \gdefcsname\??mathautopunctuation comma\string,semicolon\endcsname
3057%       {\let,\math_punctuation_yes_comma
3058%        \let.\math_punctuation_yes_period
3059%        \let;\math_punctuation_yes_semicolon}
3060%
3061%     \gdefcsname\??mathautopunctuation\v!all\string,semicolon\endcsname
3062%       {\let,\math_punctuation_all_comma
3063%        \let.\math_punctuation_all_period
3064%        \let;\math_punctuation_all_semicolon}
3065%
3066% \egroup
3067
3068\defcsname\??mathautopunctuation\v!no\endcsname
3069  {\letcharcode\commaasciicode    \math_punctuation_nop_comma
3070   \letcharcode\periodasciicode   \math_punctuation_nop_period
3071   \letcharcode\semicolonasciicode\math_punctuation_nop_semicolon}
3072
3073\defcsname\??mathautopunctuation\v!yes\endcsname
3074  {\letcharcode\commaasciicode    \math_punctuation_yes_comma
3075   \letcharcode\periodasciicode   \math_punctuation_yes_period
3076   \letcharcode\semicolonasciicode\math_punctuation_nop_semicolon}
3077
3078\defcsname\??mathautopunctuation\v!all\endcsname
3079  {\letcharcode\commaasciicode    \math_punctuation_all_comma
3080   \letcharcode\periodasciicode   \math_punctuation_all_period
3081   \letcharcode\semicolonasciicode\math_punctuation_nop_semicolon}
3082
3083\defcsname\??mathautopunctuation comma\endcsname
3084  {\letcharcode\commaasciicode    \math_punctuation_yes_comma
3085   \letcharcode\periodasciicode   \math_punctuation_yes_period
3086   \letcharcode\semicolonasciicode\math_punctuation_nop_semicolon}
3087
3088\defcsname\??mathautopunctuation\v!yes\string,semicolon\endcsname
3089  {\letcharcode\commaasciicode    \math_punctuation_yes_comma
3090   \letcharcode\periodasciicode   \math_punctuation_yes_period
3091   \letcharcode\semicolonasciicode\math_punctuation_yes_semicolon}
3092
3093\defcsname\??mathautopunctuation comma\string,semicolon\endcsname
3094  {\letcharcode\commaasciicode    \math_punctuation_yes_comma
3095   \letcharcode\periodasciicode   \math_punctuation_yes_period
3096   \letcharcode\semicolonasciicode\math_punctuation_yes_semicolon}
3097
3098\defcsname\??mathautopunctuation\v!all\string,semicolon\endcsname
3099  {\letcharcode\commaasciicode    \math_punctuation_all_comma
3100   \letcharcode\periodasciicode   \math_punctuation_all_period
3101   \letcharcode\semicolonasciicode\math_punctuation_all_semicolon}
3102
3103% \appendtoks
3104%     \global\mathcode\commaasciicode    \c_math_special
3105%     \global\mathcode\periodasciicode   \c_math_special
3106%     \global\mathcode\semicolonasciicode\c_math_special
3107% \to \everyjob
3108
3109% \activatemathcharacter\commaasciicode
3110% \activatemathcharacter\periodasciicode
3111% \activatemathcharacter\semicolonasciicode
3112
3113% \appendtoks
3114%     \mathcode\commaasciicode    \c_math_special
3115%     \mathcode\periodasciicode   \c_math_special
3116%     \mathcode\semicolonasciicode\c_math_special
3117%     \begincsname\??mathautopunctuation\mathematicsparameter\c!autopunctuation\endcsname
3118% \to \everymathematics
3119
3120\appendtoks
3121    \math_activeate_comma
3122    \math_activeate_period
3123    \math_activeate_semicolon
3124    \begincsname\??mathautopunctuation\mathematicsparameter\c!autopunctuation\endcsname
3125\to \everymathematics
3126
3127\appendtoks
3128    \ifcsname\??mathautopunctuation\mathematicsparameter\c!autopunctuation\endcsname \else
3129        \letmathematicsparameter\c!autopunctuation\v!no
3130    \fi
3131% \to \everysetupmathematics
3132\to \everyswitchmathematics
3133
3134\permanent\protected\def\enablemathpunctuation {\csname\??mathautopunctuation\v!no \endcsname}
3135\permanent\protected\def\disablemathpunctuation{\csname\??mathautopunctuation\v!yes\endcsname}
3136
3137\setupmathematics
3138  [\c!autopunctuation=\v!no] % no | yes | all | comma | yes,semicolon | all,semicolon
3139
3140%D The next replaces the above:
3141
3142% [0x2E] = { 0x2E, 0x2C, 0x002E, 0x002C, 0x2008, 0x2008 },
3143% [0x2C] = { 0x2C, 0x2E, 0x2008, 0x2008, 0x002E, 0x002C },
3144
3145% \startbuffer
3146%     \im{x + 1,222,333.44 + x}\par
3147%     \im{x + 1.222.333,44 + x}\par
3148%     \im{x + 1, 222, 333. 44 + x}\par
3149%     \im{(1.5, 1.5) + (1,5;1,5)}\par
3150%     \im{111 2222}\par
3151%     \im{f: \reals\to\reals}\par
3152%     \im{f : \reals\to\reals}\par
3153%     \im{f\colon\reals\to\reals}\par
3154%     \im{f \colon\reals\to\reals}\par
3155% \stopbuffer
3156%
3157% \startTEXpage[offset=1dk]
3158%     \setupmathematics[autospacing=yes] \getbuffer \blank
3159%     \setupmathematics[autonumbers=1]   \getbuffer \blank
3160%     \setupmathematics[autonumbers=2]   \getbuffer \blank
3161%     \setupmathematics[autonumbers=3]   \getbuffer \blank
3162%     \setupmathematics[autonumbers=4]   \getbuffer \blank
3163%     \setupmathematics[autonumbers=5]   \getbuffer \blank
3164%     \setupmathematics[autonumbers=6]   \getbuffer \blank
3165% \stopTEXpage
3166
3167\installcorenamespace{autospacing}
3168
3169\permanent\protected\def\enablemathautospacing
3170  {\attribute\mathspacingattribute\plusone
3171   \clf_initializemathspacing}
3172
3173\permanent\protected\def\disablemathautospacing
3174  {\attribute\mathspacingattribute\attributeunsetvalue}
3175
3176\appendtoks
3177    \ifcstok{\mathematicsparameter\c!autospacing}\v!yes
3178      \enablemathautospacing
3179    \else
3180      \disablemathautospacing
3181    \fi
3182% \to \everysetupmathematics
3183\to \everyswitchmathematics
3184
3185\setupmathematics
3186  [\c!autospacing=\v!no]
3187
3188\permanent\protected\def\enablemathautonumbers
3189  {\attribute\mathnumbersattribute\plusone
3190   \clf_initializemathnumbers}
3191
3192\permanent\protected\def\disablemathautonumbers
3193  {\attribute\mathnumbersattribute\attributeunsetvalue}
3194
3195\appendtoks
3196    \edef\p_autonumbers{\mathematicsparameter\c!autonumbers}%
3197    \ifchknum\p_autonumbers\or
3198      \enablemathautonumbers % default
3199      \attribute\mathnumbersattribute\p_autonumbers\relax
3200    \orelse\ifx\p_autonumbers\v!no
3201      \disablemathautonumbers
3202    \else
3203      \enablemathautonumbers % default
3204    \fi
3205% \to \everysetupmathematics
3206\to \everyswitchmathematics
3207
3208\setupmathematics
3209  [\c!autonumbers=\v!no]
3210
3211\installcorenamespace{autofencing}
3212
3213\permanent\protected\def\enablemathautofencing
3214  {\attribute\mathfencingattribute\plusone
3215   \clf_initializemathfencing}
3216
3217\permanent\protected\def\disablemathautofencing
3218  {\attribute\mathfencingattribute\attributeunsetvalue}
3219
3220\appendtoks
3221    \ifcstok{\mathematicsparameter\c!autofencing}\v!yes
3222      \enablemathautofencing
3223      \autofences
3224    \else
3225      \disablemathautofencing
3226    \fi
3227% \to \everysetupmathematics
3228\to \everyswitchmathematics
3229
3230\setupmathematics
3231  [\c!autofencing=\v!no]
3232
3233%D The consequences of setting this are as follows:
3234%D
3235%D \def\TestA#1#2#3%
3236%D   {\ifnum#1=0 \type{#2}\else\setupmathematics[autopunctuation={#2}]$#3$\fi}
3237%D \def\TestB#1#2%
3238%D   {\NC \TestA{#1}{no}           {#2}
3239%D    \NC \TestA{#1}{yes}          {#2}
3240%D    \NC \TestA{#1}{yes,semicolon}{#2}
3241%D    \NC \TestA{#1}{all}          {#2}
3242%D    \NC \TestA{#1}{all,semicolon}{#2}
3243%D    \NC \NR}
3244%D \starttabulate[|c|c|c|c|c|]
3245%D     \TestB{0}{}
3246%D     \TestB{1}{(1,2)=(1, 2)}
3247%D     \TestB{1}{(1.2)=(1. 2)}
3248%D     \TestB{1}{(1;2)=(1; 2)}
3249%D \stoptabulate
3250
3251% 0 = display
3252% 1 = crampeddisplay
3253% 2 = text
3254% 3 = crampedtext
3255% 4 = script
3256% 5 = crampedscript
3257% 6 = scriptscript
3258% 7 = crampedscriptscript
3259
3260\permanent\def\uncramped#1%
3261  {\beginmathgroup
3262   \ifmathstyle
3263    \or \displaystyle      \or
3264    \or \textstyle         \or
3265    \or \scriptstyle       \or
3266    \or \scriptscriptstyle \fi
3267   #1%
3268   \endmathgroup}
3269
3270\permanent\def\cramped#1%
3271  {\beginmathgroup
3272   \ifmathstyle
3273    \crampeddisplaystyle      \or \or % 0 -> 1
3274    \crampedtextstyle         \or \or % 2 -> 3
3275    \crampedscriptstyle       \or \or % 4 -> 5
3276    \crampedscriptscriptstyle \fi     % 6 -> 7
3277   #1%
3278   \endmathgroup}
3279
3280\permanent\def\triggermathstyle#1{\givenmathstyle{\numexpr#1\relax}}
3281%permanent\def\mathstyletrigger#1{\numexpr#1\relax}
3282\permanent\let\mathstyletrigger   \firstofoneargument
3283
3284\def\triggeredmathstyle#1{\givenmathstyle\numexpr\number#1\relax} % expandable
3285
3286\permanent\def\triggeredmathstyleparameter#1% to bypass the relax
3287  {\ifcase\numexpr\normalmathstyle\relax
3288     #1\displaystyle             \or % 0
3289     #1\crampeddisplaystyle      \or % 1
3290     #1\textstyle                \or % 2
3291     #1\crampedtextstyle         \or % 3
3292     #1\scriptstyle              \or % 4
3293     #1\crampedscriptstyle       \or % 5
3294     #1\scriptscriptstyle        \or % 6
3295     #1\crampedscriptscriptstyle \else
3296     % error
3297   \fi}
3298
3299\permanent\def\mathstylefont#1% #1 is number (\normalmathstyle)
3300  {\ifcase\numexpr#1\relax
3301     \textfont         \or
3302     \textfont         \or
3303     \textfont         \or
3304     \textfont         \or
3305     \scriptfont       \or
3306     \scriptfont       \or
3307     \scriptscriptfont \or
3308     \scriptscriptfont \else
3309     \textfont
3310   \fi\fam} % was \zerocount
3311
3312\permanent\def\somemathstylefont#1% #1 is number (\normalmathstyle)
3313  {\ifcase\numexpr#1\relax
3314     \textfont         \or
3315     \textfont         \or
3316     \textfont         \or
3317     \textfont         \or
3318     \scriptfont       \or
3319     \scriptfont       \or
3320     \scriptscriptfont \or
3321     \scriptscriptfont \else
3322     \textfont
3323   \fi}
3324
3325\permanent\def\mathsmallstylefont#1% #1 is number (\normalmathstyle)
3326  {\ifcase\numexpr#1\relax
3327     \scriptfont       \or
3328     \scriptfont       \or
3329     \scriptfont       \or
3330     \scriptfont       \or
3331     \scriptscriptfont \or
3332     \scriptscriptfont \or
3333     \scriptscriptfont \or
3334     \scriptscriptfont \else
3335     \scriptfont
3336   \fi\fam} % was \zerocount
3337
3338\permanent\def\mathstyleface#1% #1 is number (\normalmathstyle)
3339  {\ifcase\numexpr#1\relax
3340     \textface         \or
3341     \textface         \or
3342     \textface         \or
3343     \textface         \or
3344     \scriptface       \or
3345     \scriptface       \or
3346     \scriptscriptface \or
3347     \scriptscriptface \else
3348     \textface
3349   \fi}
3350
3351% \permanent\def\mathstyleface#1% #1 is number (\normalmathstyle)
3352%   {\mathstylefont#1\relax}
3353
3354\permanent\def\mathsmallstyleface#1% #1 is number (\normalmathstyle)
3355  {\ifcase\numexpr#1\relax
3356     \scriptface       \or
3357     \scriptface       \or
3358     \scriptface       \or
3359     \scriptface       \or
3360     \scriptscriptface \or
3361     \scriptscriptface \or
3362     \scriptscriptface \or
3363     \scriptscriptface \else
3364     \scriptface
3365   \fi}
3366
3367% \permanent\def\mathsmallstyleface#1% #1 is number (\normalmathstyle)
3368%   {\mathstylefont\ifcase\numexpr#1\relax
3369%      \scriptstyle       \or
3370%      \scriptstyle       \or
3371%      \scriptstyle       \or
3372%      \scriptstyle       \or
3373%      \scriptscriptstyle \or
3374%      \scriptscriptstyle \or
3375%      \scriptscriptstyle \or
3376%      \scriptscriptstyle \else
3377%      \scriptstyle
3378%    \fi}
3379
3380\permanent\def\mathstylecommand#1#2#3%
3381  {\ifcase\numexpr\normalmathstyle\relax
3382     \expandafter#1\or
3383     \expandafter#1\or
3384     \expandafter#1\or
3385     \expandafter#1\or
3386     \expandafter#2\or
3387     \expandafter#2\or
3388     \expandafter#3\or
3389     \expandafter#3\else
3390     \expandafter#1\fi}
3391
3392% \permanent\def\textstyleface#1% #1 is number (\normalmathstyle)
3393%   {\ifcase\numexpr#1\relax
3394%      \tf   \or
3395%      \tf   \or
3396%      \tf   \or
3397%      \tf   \or
3398%      \tfx  \or
3399%      \tfx  \or
3400%      \tfxx \or
3401%      \tfxx \else
3402%      \tf
3403%    \fi}
3404
3405\permanent\protected\def\verbosemathstyle#1% #1 is number (\normalmathstyle)
3406  {{\normalexpanded{\relax\darkgray\ttxx[\number#1:\ifcase\numexpr#1\relax
3407                display\or   % 0
3408         crampeddisplay\or   % 1
3409                   text\or   % 2
3410            crampedtext\or   % 3
3411                 script\or   % 4
3412          crampedscript\or   % 5
3413           scriptscript\or   % 6
3414    crampedscriptscript\else % 7
3415                unknown\fi]}}}
3416
3417\permanent\protected\def\showmathstyle{\verbosemathstyle\normalmathstyle}
3418
3419%D Handy too:
3420
3421\permanent\def\mathcharwd{\scaledfontcharwd\mathstylefont\normalmathstyle}
3422\permanent\def\mathcharht{\scaledfontcharht\mathstylefont\normalmathstyle}
3423\permanent\def\mathchardp{\scaledfontchardp\mathstylefont\normalmathstyle}
3424
3425%D Some dimension fun:
3426
3427\aliased  \let\mathexheight \exheight                   % also in math-ini.mkiv
3428\permanent\def\mathemwidth {\Umathquad\normalmathstyle} % also in math-ini.mkiv
3429
3430%D A plain inheritance:
3431
3432\permanent\def\mathpalette#1#2%
3433  {\mathchoice
3434     {#1\displaystyle     {#2}}%
3435     {#1\textstyle        {#2}}%
3436     {#1\scriptstyle      {#2}}%
3437     {#1\scriptscriptstyle{#2}}}
3438
3439%D \macros
3440%D    {cramedllap, crampedrlap, crampedclap}
3441%D
3442%D In many cases, one wants to use the \tex {clap} macro in math mode while using
3443%D subscripts. Normally, subscripts are in cramped mode, and these macros allow you
3444%D to go to cramped mode. For example:
3445%D
3446%D \startbuffer
3447%D \startformula
3448%D   \sum_{a^2 < b^2 < c^2} \quad
3449%D   \sum_{\clap{a^2 < b^2 < c^2}} \quad
3450%D   \sum_{\crampedclap{a^2 < b^2 < c^2}}
3451%D \stopformula
3452%D \stopbuffer
3453%D
3454%D \start
3455%D   \typebuffer
3456%D   \switchtobodyfont[24pt]
3457%D   \getbuffer
3458%D \stop
3459%D
3460%D This used to be in \type {supp-math.mkxl}:
3461
3462\permanent\protected\def\crampedllap#1{\llap{\cramped#1}}
3463\permanent\protected\def\crampedrlap#1{\rlap{\cramped#1}}
3464\permanent\protected\def\crampedclap#1{\clap{\cramped#1}}
3465
3466%D Often we can use:
3467%D
3468%D \startbuffer
3469%D $x^{\mathstylehbox{x^{\mathstylehbox{x}}}}$
3470%D \stopbuffer
3471%D
3472%D \typebuffer \getbuffer
3473
3474% to be tested: {#1} but it could have side effects
3475
3476\permanent\protected\def\mathstylehbox#1#% sensitive for: a \over b => {a\over b} or \frac{a}{b}
3477  {\math_style_hbox{#1}}
3478
3479\protected\def\math_style_hbox#1#2% sensitive for: a \over b => {a\over b} or \frac{a}{b}
3480  {\normalexpanded{\hbox#1\bgroup
3481     \startimath\triggeredmathstyle\normalmathstyle}\mathsurround\zeropoint#2\stopimath\egroup}
3482
3483% adaptive variant:
3484%
3485% \protected\def\math_style_hbox#1#2% sensitive for: a \over b => {a\over b} or \frac{a}{b}
3486%   {\normalexpanded{\setbox\scratchbox\hbox#1\bgroup
3487%   \mathbeginclass\lastrightclass
3488%   \startimath\givenmathstyle\the\mathstyle\relax}%
3489%      \mathsurround\zeropoint#2\stopimath\egroup
3490%      \box\scratchbox
3491%   \mathrightclass\lastrightclass   }
3492
3493\permanent\protected\def\mathstylevbox#1%
3494  {\normalexpanded{\vbox\bgroup
3495     \startimath\triggeredmathstyle\normalmathstyle}\mathsurround\zeropoint#1\stopimath\egroup}
3496
3497\permanent\protected\def\mathstylevcenter#1%
3498  {\normalexpanded{\vcenter\bgroup
3499     \startimath\triggeredmathstyle\normalmathstyle}\mathsurround\zeropoint#1\stopimath\egroup}
3500
3501\permanent\protected\def\mathstylevcenteredhbox#1%
3502  {\normalexpanded{\vcenter\bgroup\hbox\bgroup
3503     \startimath\triggeredmathstyle\normalmathstyle}\mathsurround\zeropoint#1\stopimath\egroup\egroup}
3504
3505\permanent\protected\def\mathstylevcenteredvbox#1%
3506  {\normalexpanded{\vcenter\bgroup\vbox\bgroup
3507     \startimath\triggeredmathstyle\normalmathstyle}\mathsurround\zeropoint#1\stopimath\egroup\egroup}
3508
3509\permanent\protected\def\setmathsmalltextbox#1#2#%
3510  {\normalizebodyfontsize\m_math_text_choice_face{\mathsmallstyleface\normalmathstyle}%
3511   \setbox#1#2\bgroup
3512     \font_basics_switchtobodyfont\m_math_text_choice_face
3513     \let\next}
3514
3515\permanent\protected\def\setmathtextbox#1#2#%
3516  {\normalizebodyfontsize\m_math_text_choice_face{\mathstyleface\normalmathstyle}%
3517   \setbox#1#2\bgroup
3518     \font_basics_switchtobodyfont\m_math_text_choice_face
3519     \let\next}
3520
3521%D Here is the new mechanism ... it might replace some of the above but we will do
3522%D that stepwise. Keep in mind that cramped only affects superscripts and even then,
3523%D only when in a smaller size than normal.
3524%D
3525%D \def\TestMe#1%
3526%D   {\NC \ttbf #1
3527%D    \NC \ruledhbox{$\setupmathstyle[#1]x + x_j^2 + x_i^{e^2} + \frac{1}{x}$}
3528%D    \NC \ruledhbox{$\setupmathstyle[#1,small]x + x_j^2 + x_i^{e^2} + \frac{1}{x}$}
3529%D    \NC \NR}
3530%D
3531%D \starttabulate[|l|r|l|]
3532%D \HL
3533%D \NC \NC \NC \ttbf ...,small \NC \NR
3534%D \HL
3535%D \TestMe{text}         \TestMe{text,cramped}
3536%D \TestMe{script}       \TestMe{script,cramped}
3537%D \TestMe{scriptscript} \TestMe{scriptscript,cramped}
3538%D \TestMe{display}      \TestMe{display,cramped}
3539%D \HL
3540%D \stoptabulate
3541
3542\permanent\def\triggerdisplaystyle
3543  {\ifmathstyle
3544     \displaystyle        \or
3545     \crampeddisplaystyle \or
3546     \displaystyle        \or
3547     \crampeddisplaystyle \or
3548     \displaystyle        \or
3549     \crampeddisplaystyle \or
3550     \displaystyle        \or
3551     \crampeddisplaystyle \or
3552   \fi}
3553
3554\permanent\def\triggertextstyle
3555  {\ifmathstyle
3556     \textstyle        \or
3557     \crampedtextstyle \or
3558     \textstyle        \or
3559     \crampedtextstyle \or
3560     \textstyle        \or
3561     \crampedtextstyle \or
3562     \textstyle        \or
3563     \crampedtextstyle \else
3564   \fi}
3565
3566\permanent\def\triggerscriptstyle
3567  {\ifmathstyle
3568     \scriptstyle        \or
3569     \crampedscriptstyle \or
3570     \scriptstyle        \or
3571     \crampedscriptstyle \or
3572     \scriptstyle        \or
3573     \crampedscriptstyle \or
3574     \scriptstyle        \or
3575     \crampedscriptstyle \or
3576   \fi}
3577
3578\permanent\def\triggerscriptscriptstyle
3579  {\ifmathstyle
3580     \scriptscriptstyle        \or
3581     \crampedscriptscriptstyle \or
3582     \scriptscriptstyle        \or
3583     \crampedscriptscriptstyle \or
3584     \scriptscriptstyle        \or
3585     \crampedscriptscriptstyle \or
3586     \scriptscriptstyle        \or
3587     \crampedscriptscriptstyle \or
3588   \fi}
3589
3590\permanent\def\triggeruncrampedstyle
3591  {\ifmathstyle
3592     \currentlysetmathstyle\or
3593     \displaystyle         \or
3594     \currentlysetmathstyle\or
3595     \textstyle            \or
3596     \currentlysetmathstyle\or
3597     \scriptstyle          \or
3598     \currentlysetmathstyle\or
3599     \scriptscriptstyle
3600   \fi}
3601
3602\permanent\def\triggercrampedstyle
3603  {\ifmathstyle
3604     \crampeddisplaystyle     \or
3605     \currentlysetmathstyle   \or
3606     \crampedtextstyle        \or
3607     \currentlysetmathstyle   \or
3608     \crampedscriptstyle      \or
3609     \currentlysetmathstyle   \or
3610     \crampedscriptscriptstyle\or
3611     \currentlysetmathstyle
3612   \fi}
3613
3614\permanent\def\triggersmallstyle
3615  {\ifmathstyle
3616     \scriptstyle              \or
3617     \crampedscriptstyle       \or
3618     \scriptstyle              \or
3619     \crampedscriptstyle       \or
3620     \scriptscriptstyle        \or
3621     \crampedscriptscriptstyle \or
3622     \scriptscriptstyle        \or
3623     \crampedscriptscriptstyle \or
3624    \fi}
3625
3626\permanent\def\triggeruncrampedsmallstyle
3627  {\ifmathstyle
3628     \scriptstyle       \or
3629     \scriptstyle       \or
3630     \scriptstyle       \or
3631     \scriptstyle       \or
3632     \scriptscriptstyle \or
3633     \scriptscriptstyle \or
3634     \scriptscriptstyle \or
3635     \scriptscriptstyle \or
3636    \fi}
3637
3638\permanent\def\triggercrampedsmallstyle
3639  {\ifmathstyle
3640     \crampedscriptstyle       \or
3641     \crampedscriptstyle       \or
3642     \crampedscriptstyle       \or
3643     \crampedscriptstyle       \or
3644     \crampedscriptscriptstyle \or
3645     \crampedscriptscriptstyle \or
3646     \crampedscriptscriptstyle \or
3647     \crampedscriptscriptstyle \or
3648    \fi}
3649
3650\permanent\def\triggerbigstyle
3651  {\ifmathstyle
3652     \displaystyle        \or
3653     \crampeddisplaystyle \or
3654     \textstyle           \or
3655     \crampedtextstyle    \or
3656     \textstyle           \or
3657     \crampedtextstyle    \or
3658     \scriptstyle         \or
3659     \crampedscriptstyle  \or
3660    \fi}
3661
3662\permanent\def\triggeruncrampedbigstyle
3663  {\ifmathstyle
3664     \displaystyle \or
3665     \displaystyle \or
3666     \textstyle    \or
3667     \textstyle    \or
3668     \textstyle    \or
3669     \textstyle    \or
3670     \scriptstyle  \or
3671     \scriptstyle  \or
3672    \fi}
3673
3674\permanent\def\triggercrampedbigstyle
3675  {\ifmathstyle
3676     \crampeddisplaystyle \or
3677     \crampeddisplaystyle \or
3678     \crampedtextstyle    \or
3679     \crampedtextstyle    \or
3680     \crampedtextstyle    \or
3681     \crampedtextstyle    \or
3682     \crampedscriptstyle  \or
3683     \crampedscriptstyle  \or
3684    \fi}
3685
3686\newinteger\c_math_saved_style
3687
3688\permanent\protected\def\pushmathstyle % assumes begingroup .. endgroup
3689  {\c_math_saved_style\mathstyle}
3690
3691\permanent\protected\def\popmathstyle
3692  {\ifnum\mathstyle=\c_math_saved_style\else
3693     \triggermathstyle\c_math_saved_style
3694   \fi}
3695
3696\installcorenamespace{mathstylecommand}
3697\installcorenamespace{mathstylecachem}
3698\installcorenamespace{mathstylecachet}
3699
3700\newconstant\c_math_styles_state_style
3701\newconstant\c_math_styles_state_cramped
3702\newconstant\c_math_styles_state_size
3703
3704\def\math_style_add_to_cache_choice {%
3705  \ifcase\c_math_styles_state_size
3706    \ifcase\c_math_styles_state_style
3707        \ifcase\c_math_styles_state_cramped
3708        \currentlysetmathstyle\or
3709        \triggeruncrampedstyle\or
3710        \triggercrampedstyle  \fi
3711    \or\ifcase\c_math_styles_state_cramped
3712        \ifmode\triggerdisplaystyle\else\displaystyle\fi
3713        \or\displaystyle\or\crampeddisplaystyle\fi
3714    \or\ifcase\c_math_styles_state_cramped
3715        \ifmode\triggertextstyle\else\textstyle\fi
3716        \or\textstyle\or\crampedtextstyle\fi
3717    \or\ifcase\c_math_styles_state_cramped
3718        \ifmode\triggerscriptstyle\else\scriptstyle\fi
3719        \or\scriptstyle\or\crampedscriptstyle\fi
3720    \or\ifcase\c_math_styles_state_cramped
3721        \ifmode\triggerscriptscriptstyle\else\scriptscriptstyle\fi
3722        \or\scriptscriptstyle\or\crampedscriptscriptstyle\fi
3723    \fi
3724  \or % small
3725    \ifcase\c_math_styles_state_style
3726        \ifcase\c_math_styles_state_cramped
3727        \triggersmallstyle         \or
3728        \triggeruncrampedsmallstyle\or
3729        \triggercrampedsmallstyle  \fi
3730    \or\ifcase\c_math_styles_state_cramped
3731        \ifmode\triggerscriptstyle\else\scriptstyle\fi
3732        \or\scriptstyle\or\crampedscriptstyle\fi
3733    \or\ifcase\c_math_styles_state_cramped
3734        \ifmode\triggerscriptstyle\else\scriptstyle\fi
3735        \or\scriptstyle\or\crampedscriptstyle\fi
3736    \or\ifcase\c_math_styles_state_cramped
3737        \ifmode\triggerscriptscriptstyle\else\scriptscriptstyle\fi
3738        \or\scriptscriptstyle\or\crampedscriptscriptstyle\fi
3739    \or\ifcase\c_math_styles_state_cramped
3740        \ifmode\triggerscriptscriptstyle\else\scriptscriptstyle\fi
3741        \or\scriptscriptstyle\or\crampedscriptscriptstyle\fi
3742    \fi
3743  \or % large
3744    \ifcase\c_math_styles_state_style
3745        \ifcase\c_math_styles_state_cramped
3746        \triggerbigstyle         \or
3747        \triggeruncrampedbigstyle\or
3748        \triggercrampedbigstyle  \fi
3749    \or\ifcase\c_math_styles_state_cramped
3750        \ifmode\triggerdisplaystyle\else\displaystyle\fi
3751        \or\displaystyle\or\crampeddisplaystyle\fi
3752    \or\ifcase\c_math_styles_state_cramped
3753        \ifmode\triggertextstyle\else\textstyle\fi
3754        \or\textstyle\or\crampedtextstyle\fi
3755    \or\ifcase\c_math_styles_state_cramped
3756        \ifmode\triggertextstyle\else\textstyle\fi
3757        \or\textstyle\or\crampedtextstyle\fi
3758    \or\ifcase\c_math_styles_state_cramped
3759        \ifmode\triggerscriptstyle\else\scriptstyle\fi
3760        \or\scriptstyle\or\crampedscriptstyle\fi
3761    \fi
3762  \else
3763    \currentlysetmathstyle
3764  \fi
3765}
3766
3767\permanent\def\installmathstyle#1#2%
3768  {\ifcsname\??mathstylecommand#1\endcsname \else
3769     \defcsname\??mathstylecommand#1\endcsname{#2}%
3770   \fi}
3771
3772\def\math_style_collect#1%
3773  {\csname\??mathstylecommand#1\endcsname}
3774
3775\defcsname\??mathstylecommand\s!display     \endcsname{\indisplaymath\conditionaltrue \c_math_styles_state_style\plusone}
3776\defcsname\??mathstylecommand\s!text        \endcsname{\indisplaymath\conditionalfalse\c_math_styles_state_style\plustwo}
3777\defcsname\??mathstylecommand\s!script      \endcsname{\indisplaymath\conditionalfalse\c_math_styles_state_style\plusthree}
3778\defcsname\??mathstylecommand\s!scriptscript\endcsname{\indisplaymath\conditionalfalse\c_math_styles_state_style\plusfour}
3779
3780\defcsname\??mathstylecommand\s!uncramped   \endcsname{\c_math_styles_state_cramped\plusone}
3781\defcsname\??mathstylecommand\s!cramped     \endcsname{\c_math_styles_state_cramped\plustwo}
3782\defcsname\??mathstylecommand\v!normal      \endcsname{\c_math_styles_state_cramped\plusone}
3783\defcsname\??mathstylecommand\v!packed      \endcsname{\c_math_styles_state_cramped\plustwo}
3784
3785\defcsname\??mathstylecommand\v!small       \endcsname{\c_math_styles_state_size\plusone}
3786\defcsname\??mathstylecommand\v!big         \endcsname{\c_math_styles_state_size\plustwo}
3787
3788% \def\math_styles_check_style_parameter#1#2%
3789%    {\ifempty{#1\c!mathstyle}%
3790%       \normalexpanded{#2{\c!mathstyle}{\m_math_styles_current}}%
3791%     \fi}
3792
3793\immutable\def\m_math_styles_current
3794  {\ifmathstyle \s!display
3795   \or          \s!text
3796   \or          \s!text,\s!cramped
3797   \or          \s!script
3798   \or          \s!script,\s!cramped
3799   \or          \s!scriptscript
3800   \or          \s!scriptscript,\s!cramped
3801   \fi}
3802
3803%D A \type {mathstyle} is a set of:
3804%D
3805%D \starttabulate[|lT|lT|]
3806%D \BC style   \NC display text script scriptscript \NC \NR
3807%D \BC variant \NC uncramped cramped normal packed \NC \NR
3808%D \BC size    \NC small big \NC \NR
3809%D \stoptabulate
3810%D
3811%D \startbuffer
3812%D \m{x\foo}
3813%D \m[mathstyle=text]{x\foo}
3814%D \m[mathstyle={cramped,text}]{x\foo}
3815%D \m[mathstyle=scriptscript]{x\foo \scriptstyle\foo}
3816%D \stopbuffer
3817%D
3818%D \typebuffer \getbuffer
3819%D
3820%D \startbuffer
3821%D \definemathstyle[mystyle][scriptscript]
3822%D
3823%D $text\startmathstyle[mystyle]scriptscript\stopmathstyle text$
3824%D \stopbuffer
3825%D
3826%D \typebuffer \blank \start \getbuffer \stop \blank
3827
3828% maybe move this to the lua end ...
3829
3830\installcorenamespace {mathstyle}
3831
3832\letcsname\??mathstyle      \endcsname\empty
3833%letcsname\??mathstylecachem\endcsname\empty
3834%letcsname\??mathstylecachet\endcsname\empty
3835
3836%D test case:
3837%D
3838%D \starttyping
3839%D \startformula
3840%D \frac{1}{2} + \sqrt{\frac{1}{2} + 1}
3841%D \stopformula%
3842%D \stoptyping
3843
3844% \permanent\def\expandedmathstyleparameter#1#2%
3845%   {\beginlocalcontrol
3846%    \edef\m_math_style_asked{#1#2}%
3847%    \edef\m_math_style_asked{\math_style_set_expanded\m_math_style_asked}%
3848%    \endlocalcontrol
3849%    \ifempty\m_math_style_asked
3850%      \mathstyle
3851%    \else
3852%      \m_math_style_asked
3853%    \fi}
3854
3855\permanent\def\expandedmathstyleparameter#1#2%
3856  {\ifcstok{#1#2}\emptytoks
3857     \mathstyle
3858   \else
3859     \expandafter\math_style_set_expanded\expandafter{\lastnamedcs}%
3860   \fi}
3861
3862\def\math_style_set_expanded#1% in caller: \math_style_set_main
3863  {\ifcsname\??mathstyle#1\endcsname
3864     \lastnamedcs
3865   \orelse\ifcsname\ifmmode\??mathstylecachem\the\mathstyle:\else\??mathstylecachet\fi#1\endcsname
3866     \lastnamedcs
3867   \else
3868     \math_style_set_mathstyle_mathstylecache{#1}%
3869   \fi}
3870
3871\def\math_style_set_main{\indisplaymath\ifcase\mathstyle\conditionaltrue\else\conditionalfalse\fi} % for fractions
3872
3873\def\math_style_set_indeed
3874  {\ifcsname\??mathstyle\m_math_style_asked\endcsname
3875     \lastnamedcs
3876   \orelse\ifcsname\ifmmode\??mathstylecachem\the\mathstyle:\else\??mathstylecachet\fi\m_math_style_asked\endcsname
3877     \lastnamedcs
3878   \else
3879     \math_style_set_mathstyle_mathstylecache\m_math_style_asked
3880   \fi
3881   \math_style_set_main}
3882
3883\permanent\protected\def\usemathstyleparameter#1#2%
3884  {\edef\m_math_style_asked{#1#2}%
3885   \ifempty\m_math_style_asked \else
3886     \math_style_set_indeed
3887   \fi}
3888
3889\permanent\tolerant\protected\def\setmathstyle[#1]#;#=% so we accept [] and {}
3890  {\edef\m_math_style_asked{#1#2\c!mathstyle}%
3891   \ifempty\m_math_style_asked \else
3892     \math_style_set_indeed
3893   \fi}
3894
3895\permanent\protected\def\setupmathstyle[#1]%
3896  {\edef\m_math_style_asked{#1}%
3897   \ifempty\m_math_style_asked \else
3898     \math_style_set_indeed
3899   \fi}
3900
3901\def\math_style_set_mathstyle_mathstylecache#1%
3902  {\beginlocalcontrol % so we can expand
3903   \edef\m_math_style_asked{#1}%
3904   \c_math_styles_state_style  \zerocount
3905   \c_math_styles_state_cramped\zerocount
3906   \c_math_styles_state_size   \zerocount
3907   \rawprocesscommacommand[\m_math_style_asked]\math_style_collect
3908   \gletcsname\ifmmode\??mathstylecachem\the\mathstyle:\else\??mathstylecachet\fi\m_math_style_asked\normalexpanded
3909     {\endcsname\math_style_add_to_cache_choice}%
3910   \endlocalcontrol
3911   \csname\ifmmode\??mathstylecachem\the\mathstyle:\else\??mathstylecachet\fi\m_math_style_asked\endcsname
3912   \math_style_set_main}
3913
3914% \letcsname\??mathstyle     \??mathstyle     \endcsname\math_style_set_mathstyle_mathstyle      % still needed?
3915% \letcsname\??mathstylecache\??mathstylecache\endcsname\math_style_set_mathstyle_mathstylecache % still needed?
3916
3917%D \startbuffer
3918%D $x\begingroup\setupmathstyle[script]x\endgroup x$
3919%D $x{\setupmathstyle[script]x}x$
3920%D $x\startmathstyle[script]x\stopmathstyle x$
3921%D \stopbuffer
3922%D
3923%D \typebuffer \getbuffer
3924
3925\permanent\protected\def\startmathstyle[#1]%
3926  {\edef\m_math_style_asked{#1}%
3927   \ifempty\m_math_style_asked
3928     \enforced\aliased\let\stopmathstyle\relax
3929   \else
3930     \beginmathgroup % \bgroup
3931     \math_style_set_indeed
3932     \enforced\aliased\let\stopmathstyle\endmathgroup % \egroup
3933   \fi}
3934
3935\aliased\let\stopmathstyle\relax
3936
3937\permanent\protected\def\startusemathstyleparameter#1#2%
3938  {\edef\m_math_style_asked{#1#2}%
3939   \ifempty\m_math_style_asked
3940     \enforced\let\stopusemathstyleparameter\relax
3941   \else
3942     \beginmathgroup % \bgroup
3943     \math_style_set_indeed
3944     \enforced\let\stopusemathstyleparameter\endmathgroup % \egroup
3945   \fi}
3946
3947\aliased\let\stopusemathstyleparameter\relax
3948
3949%D Something similar can be used in the (re|)|definition of \type {\text}. This
3950%D version is a variation on the one in the math module (see \type{m-math} and|/|or
3951%D \type {m-newmat}).
3952
3953\let\m_math_text_choice_face\relax
3954
3955%D We accept a low level box specification so that one can make helpers:
3956%D
3957%D \startbuffer
3958%D \startformula
3959%D     \startalign[m=2,align={middle}]
3960%D         \NC \text to 6cm{One\hfill}           \NC a = 1 \NR
3961%D         \NC \text to 6cm{One Two\hfill}       \NC b = 2 \NR
3962%D         \NC \text to 6cm{One Two Three\hfill} \NC c = 3 \NR
3963%D     \stopalign
3964%D \stopformula
3965%D \stopbuffer
3966%D
3967%D \typebuffer \getbuffer
3968
3969% %mathscriptboxmode    \plusthree % lists and boxes with \boundary=1 (also for testing and demo)
3970% %mathscriptboxmode    \plusone   % collapsed and then removed, now control option
3971% %mathscriptcharmode   \plusone   % idem
3972%
3973% %mathrulethicknessmode\plusone   % adaptive
3974
3975% We keep this as reference:
3976%
3977% \def\math_text_choice_font#1#2#%
3978%   {\normalizebodyfontsize\m_math_text_choice_face{\mathstyleface\normalmathstyle}%
3979%    \hbox#2\bgroup
3980%    \bgroup
3981%    \aftergroup\hss
3982%    \aftergroup\egroup
3983%    \hss
3984%    \font_basics_switchtobodyfont\m_math_text_choice_face
3985%    #1%
3986%    \let\next}
3987%
3988% \def\math_text_choice_word#1#2#%
3989%   {\normalizebodyfontsize\m_math_text_choice_face{\mathstyleface\normalmathstyle}%
3990%    \hbox#2\bgroup
3991%    \bgroup
3992%    \aftergroup\hss
3993%    \aftergroup\egroup
3994%    \hss
3995%    \font_basics_switchtobodyfont\m_math_text_choice_face
3996%    #1%
3997%    \nospacing % \normalnospaces\plusone
3998%    \let\next}
3999%
4000% % \ruledhbox{$\mathtext{abc ffi}$}
4001% % \ruledhbox{$\mathword{abc ffi}$}
4002%
4003% \permanent\protected\def\mathtext  {\mathortext{\math_text_choice_font\relax}\hbox}
4004% \permanent\protected\def\mathword  {\mathortext{\math_text_choice_word\relax}\hbox}
4005%
4006% \permanent\protected\def\mathtexttf{\mathortext{\math_text_choice_font\tf}\hbox}
4007% \permanent\protected\def\mathtextit{\mathortext{\math_text_choice_font\it}\hbox}
4008% \permanent\protected\def\mathtextsl{\mathortext{\math_text_choice_font\sl}\hbox}
4009% \permanent\protected\def\mathtextbf{\mathortext{\math_text_choice_font\bf}\hbox}
4010% \permanent\protected\def\mathtextbi{\mathortext{\math_text_choice_font\bi}\hbox}
4011% \permanent\protected\def\mathtextbs{\mathortext{\math_text_choice_font\bs}\hbox}
4012%
4013% \permanent\protected\def\mathwordtf{\mathortext{\math_text_choice_word\tf}\hbox}
4014% \permanent\protected\def\mathwordit{\mathortext{\math_text_choice_word\it}\hbox}
4015% \permanent\protected\def\mathwordsl{\mathortext{\math_text_choice_word\sl}\hbox}
4016% \permanent\protected\def\mathwordbf{\mathortext{\math_text_choice_word\bf}\hbox}
4017% \permanent\protected\def\mathwordbi{\mathortext{\math_text_choice_word\bi}\hbox}
4018% \permanent\protected\def\mathwordbs{\mathortext{\math_text_choice_word\bs}\hbox}
4019
4020%D The split option is sort or a gimmick but one never knows how it might come in
4021%D handy. It was also an interesting test for how easy we can get this done (an extra
4022%D option as well as cheating in the line break function). And it was a good excuse
4023%D to add options to glue (which was pending). Actually, the main reason for this
4024%D trickery was that unrolling lists into the main math list could have strange side
4025%D effects, due to glue being ignored in math in the libereak routine, so better get
4026%D it working than explaining why if could have side effects.
4027
4028%D The fact that one can pass e.g \type {to 4cm} before the content is an old and
4029%D probably never used feature that we keep in order to remain compatible.
4030
4031\installcorenamespace{mathtext}
4032
4033\installcommandhandler \??mathtext {mathtext} \??mathtext
4034
4035\setupmathtext
4036  [\s!leftclass=\mathtextparameter\s!class,
4037   \s!rightclass=\mathtextparameter\s!class,
4038   \s!class=\mathordinarycode]
4039
4040\appendtoks
4041    \frozen\protected\edefcsname\currentmathtext\endcsname{\math_text_handle{\currentmathtext}}
4042\to \everydefinemathtext
4043
4044\newtoks\everymathtext
4045
4046\tolerant\protected\def\math_text_handle_indeed#1#*[#S#2]#:#3#%
4047  {\begingroup
4048   \cdef\currentmathtext{#1}%
4049   \setupcurrentmathtext[#2]%
4050   \normalizebodyfontsize\m_math_text_choice_face{\mathstyleface\normalmathstyle}%
4051   \ifcstok{\mathtextparameter\c!alternative}\v!split
4052     \mathatom
4053       unroll
4054       class      \mathcodechecked{\mathtextparameter\s!class}
4055       leftclass  \mathcodechecked{\mathtextparameter\s!leftclass}
4056       rightclass \mathcodechecked{\mathtextparameter\s!rightclass}
4057       \bgroup
4058     \hbox#3\bgroup
4059     \aftergroup\egroup
4060     \aftergroup\endgroup
4061   \else
4062     \hbox#3\bgroup
4063     \atendofgroup\hss
4064     \aftergroup\endgroup
4065     \ifcstok{\mathtextparameter\c!alternative}\v!word
4066       \nospacing % \normalnospaces\plusone
4067     \fi
4068     \hss
4069   \fi
4070   \font_basics_switchtobodyfont\m_math_text_choice_face
4071   \usemathtextstyleandcolor\c!style\c!color
4072   \expand\everymathtext\relax
4073   \let\next}
4074
4075\protected\def\math_text_handle#1%
4076   {\mathortext{\math_text_handle_indeed{#1}}\hbox}
4077
4078\definemathtext[mathtext]
4079\definemathtext[mathtexttf][mathtext][\c!style=\tf]
4080\definemathtext[mathtextit][mathtext][\c!style=\it]
4081\definemathtext[mathtextsl][mathtext][\c!style=\sl]
4082\definemathtext[mathtextbf][mathtext][\c!style=\bf]
4083\definemathtext[mathtextbi][mathtext][\c!style=\bi]
4084\definemathtext[mathtextbs][mathtext][\c!style=\bs]
4085
4086\definemathtext[mathword]  [mathtext][\c!alternative=\v!word]
4087\definemathtext[mathwordtf][mathword][\c!style=\tf]
4088\definemathtext[mathwordit][mathword][\c!style=\it]
4089\definemathtext[mathwordsl][mathword][\c!style=\sl]
4090\definemathtext[mathwordbf][mathword][\c!style=\bf]
4091\definemathtext[mathwordbi][mathword][\c!style=\bi]
4092\definemathtext[mathwordbs][mathword][\c!style=\bs]
4093
4094\definemathtext[mathsplit]  [mathtext] [\c!alternative=\v!split]
4095\definemathtext[mathsplittf][mathsplit][\c!style=\tf]
4096\definemathtext[mathsplitit][mathsplit][\c!style=\it]
4097\definemathtext[mathsplitsl][mathsplit][\c!style=\sl]
4098\definemathtext[mathsplitbf][mathsplit][\c!style=\bf]
4099\definemathtext[mathsplitbi][mathsplit][\c!style=\bi]
4100\definemathtext[mathsplitbs][mathsplit][\c!style=\bs]
4101
4102% \startbuffer
4103%     $
4104%     {    x\! \neq x!} \quad {\ss     x\! \neq x!} \qquad
4105%     {\it x\! \neq x!} \quad {\ss \it x\! \neq x!} \qquad
4106%     {\bf x\! \neq x!} \quad {\ss \bf x\! \neq x!} \qquad
4107%     {\bi x\! \neq x!} \quad {\ss \bi x\! \neq x!}
4108%     $
4109% \stopbuffer
4110%
4111% \startTEXpage[offset=1dk]
4112%     \getbuffer \par \automathtext \getbuffer
4113% \stopTEXpage
4114
4115\newconditional\c_mathtextauto % we need aproper key: \c_mathtextauto\conditionaltrue
4116
4117\permanent\protected\def\automathtext{\c_mathtextauto\conditionaltrue}
4118
4119\let\currentmathalphabet \s!rm
4120\let\currentmathfontstyle\s!tf
4121
4122\permanent\protected\def\mathtextauto#1#2%
4123  {\ifconditional\c_mathtextauto
4124     \mathortext
4125       {\mathpunct
4126          {\begincsname\currentmathalphabet\endcsname
4127           \begincsname mathtext\currentmathfontstyle\endcsname
4128           {#1}}}%
4129       {#1}%
4130   \else
4131     #2%
4132   \fi}
4133
4134%D Actually in spac-hor.mkxl we defined them using \suggestedalias which redefines
4135%D these so basically we now make that sort of obsolete.
4136%D
4137%D \starttyping
4138%D $x\, x$\quad\automathtext$x\, x$
4139%D \stoptyping
4140
4141\pushoverloadmode
4142    \permanent\protected\def\.{\mathtextauto{.}{.}}
4143    \permanent\protected\def\,{\mathtextauto{,}{\thinspace }}
4144    \permanent\protected\def\:{\mathtextauto{:}{\medspace  }}
4145    \permanent\protected\def\;{\mathtextauto{;}{\thickspace}}
4146    \permanent\protected\def\!{\mathtextauto{!}{\negthinspace}}
4147    \permanent\protected\def\?{\mathtextauto{?}{?}}
4148\popoverloadmode
4149
4150\appendtoks \obeydiscretionaries   \to \everymathtext
4151\appendtoks \ignorediscretionaries \to \everymathematics
4152
4153%D Safeguard against redefinitions:
4154
4155\appendtoks
4156    \enforced\let\_\normalunderscore % is textunderscore or fakeunderscore
4157\to \everymathematics
4158
4159%D Because we may overload \type {\text} in other (structuring) macros, we say:
4160
4161\appendtoks
4162    \enforced\let\text\mathtext
4163\to \everymathematics
4164
4165\newinteger\interdisplaylinepenalty \interdisplaylinepenalty\plushundred
4166
4167%D Text in math:
4168
4169\permanent\protected\def\mathortext
4170  {\ifmmode
4171     \expandafter\firstoftwoarguments
4172   \else
4173     \expandafter\secondoftwoarguments
4174   \fi}
4175
4176% \defineactivecharacter _ {\mathortext{_}{\_}} text_text  $a^2$
4177
4178% force text mode, will be overloaded later
4179
4180\ifdefined\text\else \aliased\let\text\hbox \fi
4181
4182% \protected\def\mathoptext#1{\mathop{\text{#1}}}
4183
4184\newtoks\everymathoptext
4185
4186\appendtoks
4187    \let|\textbar
4188\to \everymathoptext
4189
4190\permanent\protected\def\mathoptext
4191  {\normalizebodyfontsize\m_math_text_choice_face{\mathstyleface\normalmathstyle}%
4192  %\showmathstyle
4193   \dowithnextbox
4194     {\mathop{\box\nextbox}}%
4195     \hbox\bgroup
4196     \expandtoks\everymathoptext
4197     \font_basics_switchtobodyfont
4198     \m_math_text_choice_face
4199     \let\next}
4200
4201% new:
4202
4203% \startsetups math:morespacing
4204%     \Umathordordspacing\textstyle 1mu plus .5mu minus .25mu\relax
4205% \stopsetups
4206%
4207% \setupmathematics
4208%   [setups=math:morespacing]
4209
4210\newtoks\everyinsidemathematics
4211
4212\appendtoks
4213    \edef\p_setups{\mathematicsparameter\c!setups}%
4214    \ifempty\p_setups\else
4215        \directsetup\p_setups
4216    \fi
4217%to \everyswitchmathematics
4218\to \everyinsidemathematics
4219
4220% new:
4221
4222\permanent\protected\def\smallmathsymbol#1%
4223  {\mathematics{\mathbin{\normalexpanded{\raise.15\exheight\hbox{\normalstartimath
4224     \triggeredmathstyle{\the\numexpr\normalmathstyle+2\relax}#1%
4225   \normalstopimath}}}}}
4226
4227% this should be a primitive:
4228
4229%permanent\def\mathextensiblecode#1#2{\clf_extensiblecode{#1}{#2}} % at lua end
4230%permanent\def\mathhorizontalcode#1#2{\clf_horizontalcode{#1}{#2}} % at lua end
4231
4232% experimental:
4233
4234%D \starttyping
4235%D \enabletrackers[math.openedup]
4236%D
4237%D \dorecurse{10}{\dorecurse{#1}{whatever }}
4238%D
4239%D \startitemize[packed]
4240%D     \startitem whatever \openedupimath{\frac{1}{2}} whatever
4241%D     \startitem whatever \openedupimath{\frac{1}{2}} whatever
4242%D     \startitem whatever \openedupimath{\frac{1}{2}} whatever
4243%D \stopitemize
4244%D \startitemize[packed,columns]
4245%D     \startitem whatever \openedupimath{\frac{1}{2}} whatever
4246%D     \startitem whatever \openedupimath{\frac{1}{2}} whatever
4247%D     \startitem whatever \openedupimath{\frac{1}{2}} whatever
4248%D     \startitem whatever \openedupimath{\frac{1}{2}} whatever
4249%D     \startitem whatever \openedupimath{\frac{1}{2}} whatever
4250%D     \startitem whatever \openedupimath{\frac{1}{2}} whatever
4251%D \stopitemize
4252%D
4253%D \dorecurse{5}{\dorecurse{#1}{whatever }\openedupimath{\frac{1}{2}} }
4254%D
4255%D \startitemize[packed,columns]
4256%D     \startitem whatever \openedupimath{1+2} whatever
4257%D     \startitem whatever \openedupimath{1+2} whatever
4258%D     \startitem whatever \openedupimath{\frac{1}{2}} whatever
4259%D     \startitem whatever \openedupimath{1+2} whatever
4260%D     \startitem whatever \openedupimath{1+2} whatever
4261%D \stopitemize
4262%D
4263%D \dorecurse{5}{\dorecurse{#1}{whatever }\openedupimath{1+2} }
4264%D
4265%D \startitemize[packed]
4266%D     \startitem whatever \openedupimath{\frac{1}{2}} whatever
4267%D     \startitem whatever \openedupimath{\frac{1}{2}} whatever
4268%D     \startitem whatever \openedupimath{\frac{1}{2}} whatever
4269%D \stopitemize
4270%D
4271%D \dorecurse{10}{whatever }
4272%D \dorecurse {5}{\dorecurse{#1}{whatever }\openedupimath{\frac{1}{2}} }
4273%D \dorecurse{10}{whatever }
4274%D \stoptyping
4275
4276% \def\m_math_inline_openup_ht{\dimexpr\ifinsidecolumns\strutdp\else\lineheight\fi/\plusfour\relax}
4277% \def\m_math_inline_openup_dp{\dimexpr\ifinsidecolumns\strutdp\else\lineheight\fi/\plusfour\relax}
4278
4279\def\m_math_inline_openup_ht{(\ifinsidecolumns\strutdp\else\lineheight\fi/\plusfour)}
4280\def\m_math_inline_openup_dp{(\ifinsidecolumns\strutdp\else\lineheight\fi/\plusfour)}
4281
4282% \def\m_math_inline_openup_ht{\dimexpr\lineheight/\ifinsidecolumns\pluseight\else\plusfour\fi\relax}
4283% \def\m_math_inline_openup_dp{\dimexpr\lineheight/\ifinsidecolumns\pluseight\else\plusfour\fi\relax}
4284
4285\installtextracker
4286  {math.openedup}
4287  {\let\math_inline_openup_start_yes\math_inline_openup_traced_start}
4288  {\let\math_inline_openup_start_yes\math_inline_openup_normal_start}
4289
4290\protected\def\math_inline_openup_normal_start
4291  {\scratchheight{\ht\scratchbox+\m_math_inline_openup_ht}%
4292   \scratchdepth {\dp\scratchbox+\m_math_inline_openup_dp}%
4293   \vrule\s!width\zeropoint\s!height\scratchheight\s!depth\scratchdepth\relax
4294   \begingroup
4295   \let\math_inline_openup_stop\math_inline_openup_normal_stop}
4296
4297\protected\def\math_inline_openup_normal_stop
4298   {\endgroup
4299    \vrule\s!width\zeropoint\s!height\scratchheight\s!depth\scratchdepth\relax}
4300
4301\protected\def\math_inline_openup_traced_start
4302  {\scratchtopoffset   \ht\scratchbox
4303   \scratchbottomoffset\dp\scratchbox
4304   \scratchheight      {\scratchtopoffset   +\m_math_inline_openup_ht}%
4305   \scratchdepth       {\scratchbottomoffset+\m_math_inline_openup_dp}%
4306   \vrule\s!width\zeropoint\s!height\scratchheight\s!depth\scratchdepth\relax
4307   \begingroup
4308     \dousecolorparameter{darkred}%
4309     \vrule\s!width\emwidth\s!height\scratchheight\s!depth-\scratchtopoffset\relax
4310   \endgroup
4311   \kern-\emwidth
4312   \begingroup
4313   \let\math_inline_openup_stop\math_inline_openup_traced_stop}
4314
4315\protected\def\math_inline_openup_traced_stop
4316  {\endgroup
4317   \kern-\emwidth
4318   \begingroup
4319     \dousecolorparameter{darkblue}%
4320     \vrule\s!width\emwidth\s!height-\scratchbottomoffset\s!depth\scratchdepth\relax
4321   \endgroup
4322   \vrule\s!width\zeropoint\s!height\scratchheight\s!depth\scratchdepth\relax}
4323
4324\let\math_inline_openup_start_yes\math_inline_openup_normal_start
4325\let\math_inline_openup_stop     \relax
4326
4327\def\math_inline_openup_start_nop
4328  {\let\math_inline_openup_stop\relax}
4329
4330\permanent\protected\def\openedupimath
4331  {\dontleavehmode
4332   \begingroup
4333   \ifmmode
4334     \expandafter\openedupimath_math
4335   \else
4336     \expandafter\openedupimath_text
4337   \fi}
4338
4339\protected\def\openedupimath_math#1%
4340  {\setbox\scratchbox\mathstylehbox{#1}%
4341   \ifdim\ht\scratchbox>\strutht
4342     \math_inline_openup_start_yes
4343   \orelse\ifdim\dp\scratchbox>\strutdp
4344     \math_inline_openup_start_yes
4345   \else
4346     \math_inline_openup_start_nop
4347   \fi
4348   #1%
4349   \math_inline_openup_stop
4350   \endgroup}
4351
4352\protected\def\openedupimath_text#1%
4353  {\setbox\scratchbox\hbox{\startimath#1\stopimath}%
4354   \ifdim\ht\scratchbox>\strutht
4355     \math_inline_openup_start_yes
4356   \orelse\ifdim\dp\scratchbox>\strutdp
4357     \math_inline_openup_start_yes
4358   \else
4359     \math_inline_openup_start_nop
4360   \fi
4361   \startimath
4362   #1%
4363   \stopimath
4364   \math_inline_openup_stop
4365   \endgroup}
4366
4367% Also handy, especially for units:
4368%
4369% 0x002B=plus 0x2212=minus 0x2013=endash
4370
4371\permanent\protected\def\mathplus     {+}
4372\permanent\protected\def\mathminus    {\ifmmode \orelse\iffontchar\font`−−\else \fi}
4373\permanent\protected\def\mathplusminus{±}
4374
4375%D Experiment, replaced by dictionaries but for now we keep the code as the domain key
4376%D might come back.
4377%
4378% \newinteger\c_math_domain_attribute
4379%
4380% \def\math_domain_initialize
4381%   {\ifnum\c_math_domain_attribute=\attributeunsetvalue \else
4382%      \clf_initializemathdomain % one time
4383%      \glet\math_domain_initialize\relax
4384%    \fi}
4385%
4386% \appendtoks
4387%     \edef\p_domain{\mathematicsparameter\c!domain}%
4388%     \ifempty\p_domain
4389%         \c_math_domain_attribute\attributeunsetvalue
4390%     \else
4391%         \c_math_domain_attribute\clf_getmathdomain\p_domain\relax
4392%         \math_domain_initialize
4393%     \fi
4394% \to \everyswitchmathematics % only in mathematics
4395%
4396% \appendtoks
4397%     \c_attr_mathdomain\c_math_domain_attribute
4398% \to \everymathematics
4399
4400\newinteger\c_math_domain_attribute
4401
4402\appendtoks
4403    \edef\p_domain{\mathematicsparameter\c!domain}%
4404    \ifempty\p_domain
4405        \c_math_domain_attribute\attributeunsetvalue
4406    \else
4407        \c_math_domain_attribute\clf_domainattribute{\p_domain}\relax
4408    \fi
4409\to \everyswitchmathematics % only in mathematics
4410
4411\appendtoks
4412    \c_attr_mathdomain\c_math_domain_attribute
4413\to \everymathematics
4414
4415%D For special purposes (koeieletters) we set this one:
4416
4417\installcorenamespace{mathrules}
4418
4419\permanent\protected\def\enablemathrules{\gletcsname\??mathrules\fontclass\endcsname\plusone}
4420
4421\appendtoks
4422    \mathrulesmode\ifcsname\??mathrules\fontclass\endcsname
4423      \lastnamedcs
4424    \else
4425      \zerocount
4426    \fi
4427    \mathrulesfam\zerocount
4428\to \everymathematics
4429
4430%D Maybe:
4431
4432% \starttabulate[|||c|c|]
4433% \BC positive                            \BC negative                               \BC text                           \BC math \NC \NR
4434% \NC \tex {f1} \tex {hairspace}  \tex{,} \NC \tex {b1} \tex {neghairspace}          \NC {\darkred\vl}\f1{\darkblue\vl} \NC ${\darkred\vl}\f1{\darkblue\vl}$ \NC \NR
4435% \NC \tex {f2} \tex {thinspace}  \tex{:} \NC \tex {b2} \tex {negthinspace}  \tex{!} \NC {\darkred\vl}\f2{\darkblue\vl} \NC ${\darkred\vl}\f2{\darkblue\vl}$ \NC \NR
4436% \NC \tex {f3} \tex {medspace}   \tex{;} \NC \tex {b3} \tex {negmedspace}           \NC {\darkred\vl}\f3{\darkblue\vl} \NC ${\darkred\vl}\f3{\darkblue\vl}$ \NC \NR
4437% \NC \tex {f4} \tex {thickspace}         \NC \tex {b4} \tex {negthickspace}         \NC {\darkred\vl}\f4{\darkblue\vl} \NC ${\darkred\vl}\f4{\darkblue\vl}$ \NC \NR
4438% \NC \tex {f5} \tex {enspace}            \NC \tex {b5}                              \NC {\darkred\vl}\f5{\darkblue\vl} \NC ${\darkred\vl}\f5{\darkblue\vl}$ \NC \NR
4439% \NC \tex {f6} \tex {emspace}            \NC \tex {b6}                              \NC {\darkred\vl}\f6{\darkblue\vl} \NC ${\darkred\vl}\f6{\darkblue\vl}$ \NC \NR
4440% \stoptabulate
4441
4442% \protected\def\negenspace{\kern-.5\emwidth}
4443% \protected\def\negemspace{\kern-  \emwidth}
4444%
4445% \protected\def\math_f#1%
4446%   {\ifcase#1\or
4447%      \hairspace
4448%    \or
4449%      \thinspace
4450%    \or
4451%      \medspace
4452%    \or
4453%      \thickspace
4454%    \or
4455%      \enspace
4456%    \or
4457%      \emspace
4458%    \fi}
4459%
4460% \protected\def\math_b#1%
4461%   {\ifcase#1\or
4462%      \neghairspace
4463%    \or
4464%      \negthinspace
4465%    \or
4466%      \negmedspace
4467%    \or
4468%      \negthickspace
4469%    \or
4470%      \negenspace
4471%    \or
4472%      \negemspace
4473%    \fi}
4474%
4475% \appendtoks
4476%     \let\f\math_f
4477%     \let\b\math_b
4478% \to \everymathematics
4479
4480%D Experiment
4481
4482\permanent\protected\def\math_scripts_stack
4483  {\c_attr_mathunstack\attributeunsetvalue}
4484
4485\permanent\protected\def\math_scripts_unstack
4486  {\clf_enablescriptunstacking
4487   \c_attr_mathunstack\plustwo} % \plusone for the other way around
4488
4489\ifdefined\stackscripts   \else \aliased\let\stackscripts  \relax \fi
4490\ifdefined\unstackscripts \else \aliased\let\unstackscripts\relax \fi
4491
4492\appendtoks
4493    \enforced\let\stackscripts  \math_scripts_stack
4494    \enforced\let\unstackscripts\math_scripts_unstack
4495\to \everymathematics
4496
4497%D Expensive (tracing and inject) but a primitive (using factors) is tricky as we
4498%D want this frozen support.
4499
4500% \def\math_openup_parameter#1#2%
4501%   {\ifzeropt#1\displaystyle            \orelse\ifdim#1\displaystyle            =\maxdimen\else\frozen#1\displaystyle            #2#1\displaystyle            \fi
4502%    \ifzeropt#1\crampeddisplaystyle     \orelse\ifdim#1\crampeddisplaystyle     =\maxdimen\else\frozen#1\crampeddisplaystyle     #2#1\crampeddisplaystyle     \fi
4503%    \ifzeropt#1\textstyle               \orelse\ifdim#1\textstyle               =\maxdimen\else\frozen#1\textstyle               #2#1\textstyle               \fi
4504%    \ifzeropt#1\crampedtextstyle        \orelse\ifdim#1\crampedtextstyle        =\maxdimen\else\frozen#1\crampedtextstyle        #2#1\crampedtextstyle        \fi
4505%    \ifzeropt#1\scriptstyle             \orelse\ifdim#1\scriptstyle             =\maxdimen\else\frozen#1\scriptstyle             #2#1\scriptstyle             \fi
4506%    \ifzeropt#1\crampedscriptstyle      \orelse\ifdim#1\crampedscriptstyle      =\maxdimen\else\frozen#1\crampedscriptstyle      #2#1\crampedscriptstyle      \fi
4507%    \ifzeropt#1\scriptscriptstyle       \orelse\ifdim#1\scriptscriptstyle       =\maxdimen\else\frozen#1\scriptscriptstyle       #2#1\scriptscriptstyle       \fi
4508%    \ifzeropt#1\crampedscriptscriptstyle\orelse\ifdim#1\crampedscriptscriptstyle=\maxdimen\else\frozen#1\crampedscriptscriptstyle#2#1\crampedscriptscriptstyle\fi}
4509
4510% \def\mdim#1#2%
4511%   {\ifcase\ifzeropt#1#2\plusone\orelse\ifdim#1#2=\maxdimen\plusone\else\zerocount\fi}
4512%
4513% \def\mdim
4514%   {\afterassignment\mmdim\scratchdimen}
4515%
4516% \def\mmdim
4517%   {\ifcase\ifzeropt\scratchdimen\plusone\orelse\ifdim\scratchdimen=\maxdimen\plusone\else\zerocount\fi}
4518%
4519% \def\math_openup_parameter#1#2%
4520%   {\ifcondition\mdim#1\displaystyle            \frozen#1\displaystyle            #2\dimexpr#1\displaystyle            \relax\fi
4521%    \ifcondition\mdim#1\crampeddisplaystyle     \frozen#1\crampeddisplaystyle     #2\dimexpr#1\crampeddisplaystyle     \relax\fi
4522%    \ifcondition\mdim#1\textstyle               \frozen#1\textstyle               #2\dimexpr#1\textstyle               \relax\fi
4523%    \ifcondition\mdim#1\crampedtextstyle        \frozen#1\crampedtextstyle        #2\dimexpr#1\crampedtextstyle        \relax\fi
4524%    \ifcondition\mdim#1\scriptstyle             \frozen#1\scriptstyle             #2\dimexpr#1\scriptstyle             \relax\fi
4525%    \ifcondition\mdim#1\crampedscriptstyle      \frozen#1\crampedscriptstyle      #2\dimexpr#1\crampedscriptstyle      \relax\fi
4526%    \ifcondition\mdim#1\scriptscriptstyle       \frozen#1\scriptscriptstyle       #2\dimexpr#1\scriptscriptstyle       \relax\fi
4527%    \ifcondition\mdim#1\crampedscriptscriptstyle\frozen#1\crampedscriptscriptstyle#2\dimexpr#1\crampedscriptscriptstyle\relax\fi}
4528
4529% \ifmathparameter : 0=zero, 1=set, 2=unset (les stracing clutter this way)
4530
4531%D New stuff:
4532%D
4533%D \starttyping
4534%D $\mathopenupparameter\Umathradicalvgap{10.5}\sqrt[3]{x}$
4535%D \stoptyping
4536
4537\permanent\protected\def\mathopenupparameter#1#2%
4538  {\ifmathparameter#1\displaystyle            \or\frozen#1\displaystyle            #2#1\displaystyle            \fi
4539   \ifmathparameter#1\crampeddisplaystyle     \or\frozen#1\crampeddisplaystyle     #2#1\crampeddisplaystyle     \fi
4540   \ifmathparameter#1\textstyle               \or\frozen#1\textstyle               #2#1\textstyle               \fi
4541   \ifmathparameter#1\crampedtextstyle        \or\frozen#1\crampedtextstyle        #2#1\crampedtextstyle        \fi
4542   \ifmathparameter#1\scriptstyle             \or\frozen#1\scriptstyle             #2#1\scriptstyle             \fi
4543   \ifmathparameter#1\crampedscriptstyle      \or\frozen#1\crampedscriptstyle      #2#1\crampedscriptstyle      \fi
4544   \ifmathparameter#1\scriptscriptstyle       \or\frozen#1\scriptscriptstyle       #2#1\scriptscriptstyle       \fi
4545   \ifmathparameter#1\crampedscriptscriptstyle\or\frozen#1\crampedscriptscriptstyle#2#1\crampedscriptscriptstyle\fi}
4546
4547%D New stuff:
4548%D
4549%D \startbuffer
4550%D $x\mathopen   {!}+123+\mathclose  {!}x$
4551%D $x\tomathopen  ! +123+\tomathclose ! x$
4552%D $x\mathclose  {!}+123+\mathopen   {!}x$
4553%D $x\tomathclose ! +123+\tomathopen  ! x$
4554%D $x             ! +123+             ! x$
4555%D \stopbuffer
4556%D
4557%D \typebuffer
4558%D
4559%D \startlines
4560%D \getbuffer
4561%D \stoplines
4562
4563\permanent\protected\def\tomathord  {\Umathclass\zerocount}
4564\permanent\protected\def\tomathop   {\Umathclass\plusone  } % \mathinfix
4565\permanent\protected\def\tomathbin  {\Umathclass\plustwo  }
4566\permanent\protected\def\tomathrel  {\Umathclass\plusthree}
4567\permanent\protected\def\tomathopen {\Umathclass\plusfour } % \mathprefix
4568\permanent\protected\def\tomathclose{\Umathclass\plusfive } % \mathsuffix
4569\permanent\protected\def\tomathpunct{\Umathclass\plussix  }
4570
4571%D Prescripts. These work in \CONTEXT\ because we have the super- and subscript
4572%D triggers enabled as active characters but when we would have
4573%D
4574%D \starttyping
4575%D \catcode\underscoreasciicode\subscriptcatcode
4576%D \catcode\circumflexasciicode\superscriptcatcode
4577%D \stoptyping
4578%D
4579%D we also need the next line to disable character escaping via \type {^} in
4580%D math mode:
4581%D
4582%D \startbuffer
4583%D \blank \hbox{
4584%D     \ruledhbox{${\tf X} ^1 _2 ^^3 __4$}
4585%D     \ruledhbox{${\tf X} ^1           $}
4586%D     \ruledhbox{${\tf X}    _2        $}
4587%D     \ruledhbox{${\tf X}       ^^3    $}
4588%D     \ruledhbox{${\tf X}           __4$}
4589%D     \ruledhbox{${\tf X} ^1 _2        $}
4590%D     \ruledhbox{${\tf X} ^1    ^^3    $}
4591%D     \ruledhbox{${\tf X} ^1        __4$}
4592%D     \ruledhbox{${\tf X}    _2 ^^3    $}
4593%D     \ruledhbox{${\tf X}    _2     __4$}
4594%D     \ruledhbox{${\tf X} ^1 _2 ^^3    $}
4595%D     \ruledhbox{${\tf X} ^1 _2     __4$}
4596%D     \ruledhbox{${\tf X}    _2 ^^3    $}
4597%D     \ruledhbox{${\tf X}    _2 ^^3 __4$}
4598%D     \ruledhbox{${\tf X}       ^^3 __4$}
4599%D } \blank
4600%D
4601%D \typebuffer \getbuffer
4602
4603\normalsupmarkmode\plusone % 2 also disable ^[^+] in text mode
4604
4605\permanent\protected\tolerant\def\supscr[#1]#:#2%
4606  {\ifchkdimension#1\or\Umathopenupheight\lastchkdimension\fi
4607   \superscript{#2}}
4608
4609\permanent\protected\tolerant\def\subscr[#1]#:#2%
4610  {\ifchkdimension#1\or\Umathopenupdepth\lastchkdimension\fi
4611   \subscript{#2}}
4612
4613\permanent\protected\tolerant\def\supsubscr[#1]#:#2#3%
4614  {\ifchkdimension#1\or\Umathopenupheight\lastchkdimension\Umathopenupdepth\lastchkdimension\relax\fi
4615   \superscript{#2}\subscript{#3}}
4616
4617\permanent\protected\tolerant\def\subsupscr[#1]#:#*#2#3%
4618  {\ifchkdimension#1\or\Umathopenupheight\lastchkdimension\Umathopenupdepth\lastchkdimension\relax\fi
4619   \subscript{#2}\superscript{#3}}
4620
4621\permanent\protected\tolerant\def\supprescr[#1]#:#2%
4622  {\ifchkdimension#1\or\Umathopenupheight\lastchkdimension\fi
4623   \superprescript{#2}}
4624
4625\permanent\protected\tolerant\def\subprescr[#1]#:#2%
4626  {\ifchkdimension#1\or\Umathopenupdepth\lastchkdimension\fi
4627   \subprescript{#2}}
4628
4629\permanent\protected\tolerant\def\supsubprescr[#1]#:#2#3%
4630  {\ifchkdimension#1\or\Umathopenupheight\lastchkdimension\Umathopenupdepth\lastchkdimension\fi
4631   \superprescript{#2}\subprescript{#3}}
4632
4633\permanent\protected\tolerant\def\subsupprescr[#1]#:#*#2#3%
4634  {\ifchkdimension#1\or\Umathopenupheight\lastchkdimension\Umathopenupdepth\lastchkdimension\fi
4635   \subprescript{#2}\superprescript{#3}}
4636
4637%D For now (needed in asciimath):
4638
4639\def\math_relax_limits{\enforced\let\limits\relax}
4640
4641%D Something new:
4642%D
4643%D \starttyping
4644%D \definemathpreset[whatever][factor=.5,style=all,list={fraction*gap}]
4645%D % \presetmathematics[whatever] % less more zero
4646%D \stoptyping
4647%D
4648%D as well as:
4649%D
4650%D \starttyping
4651%D $\Umathxscale\textstyle  800 a + b + x + d + e = f $\par
4652%D $\Umathxscale\textstyle 1000 a + b + x + d + e = f $\par
4653%D $\Umathxscale\textstyle 1200 a + b + x + d + e = f $\blank
4654%D
4655%D $\showboxes\setupmathspacing[narrow] a + b + x + d + e = f $\par
4656%D $\showboxes\setupmathspacing[normal] a + b + x + d + e = f $\par
4657%D $\showboxes\setupmathspacing[wide]   a + b + x + d + e = f $\blank
4658%D
4659%D $\showboxes\setupmathspacing[tight]  x^2_1$\quad
4660%D $\showboxes\setupmathspacing[normal] x^2_1$\quad
4661%D $\showboxes\setupmathspacing[loose]  x^2_1$\blank
4662%D \stoptyping
4663
4664\installcorenamespace{mathspacing}
4665
4666\permanent\tolerant\protected\def\definemathspacing[#1]#*[#2]#*[#3]%
4667  {\ifcstok{#2}\v!horizontal
4668     \edefcsname\??mathspacing#1\endcsname
4669       {\Umathxscale\allmathstyles\ifchknum#3\or#3\else\plusthousand\fi\relax}%
4670   \orelse\ifcstok{#2}\v!vertical
4671     \edefcsname\??mathspacing#1\endcsname
4672       {\Umathyscale\allmathstyles\ifchknum#3\or#3\else\plusthousand\fi\relax}%
4673   \else
4674     \edefcsname\??mathspacing#1\endcsname
4675       {\Umathxscale\allmathstyles\ifchknum#2\or\number#2\else\plusthousand\fi\relax
4676        \Umathyscale\allmathstyles\ifchknum#3\or\number#3\orelse\ifchknum#2\or\number#2\else\plusthousand\fi\relax}%
4677   \fi}
4678
4679\definemathspacing[\v!normal]                [1000] [1000]
4680\definemathspacing[\v!tight] [\c!vertical]    [900]
4681\definemathspacing[\v!loose] [\c!vertical]   [1100]
4682\definemathspacing[\v!narrow][\c!horizontal]  [900]
4683\definemathspacing[\v!wide]  [\c!horizontal] [1100]
4684\definemathspacing[\v!less]                   [900]  [900]
4685\definemathspacing[\v!more]                  [1100] [1100]
4686
4687\permanent\protected\def\setupmathspacing[#1]%
4688  {\begincsname\??mathspacing#1\endcsname}
4689
4690%D We're done with the double dollars:
4691%D
4692%D \startbuffer
4693%D     before $                  i = 1 $                   after\par
4694%D     before $                  i = 2 \Ustopmath{}        after\par
4695%D     before \Ustartmath        i = 3 $                   after\par
4696%D     before \Ustartmath        i = 4 \Ustopmath{}        after\par
4697%D     before $$                 d = 1 $$                  after\par
4698%D     before $$                 d = 2 \Ustopdisplaymath{} after\par
4699%D     before \Ustartdisplaymath d = 3 $$                  after\par
4700%D     before \Ustartdisplaymath d = 4 \Ustopdisplaymath{} after\par
4701%D \stopbuffer
4702%D
4703%D \startpacked {\mathdisplaymode\zerocount \getbuffer} \stoppacked
4704%D \startpacked {\mathdisplaymode\plusone   \getbuffer} \stoppacked
4705%D
4706%D So we do:
4707
4708\mathdisplaymode\plusone
4709
4710%D Just to be sure:
4711
4712\immutable\integerdef\c_math_glyph_options_default\numexpr
4713    \noexpansionglyphoptioncode
4714   +\noprotrusionglyphoptioncode
4715\relax
4716
4717\immutable\integerdef\c_math_glyph_options_hz\numexpr
4718    \noprotrusionglyphoptioncode
4719\relax
4720
4721\appendtoks
4722    \ifcstok{\mathematicsparameter\c!hz}\v!yes
4723      \glyphoptions\c_math_glyph_options_hz
4724    \else
4725      \glyphoptions\c_math_glyph_options_default
4726    \fi
4727\to \everymathematics
4728
4729%D Math italics: see \MKIV\ files for how this was done because in \LMTX\ we ditched
4730%D them. The flags that we set with glyphoptions no longer apply. Correction with
4731%D surrounding text is also set elsewhere.
4732
4733% \def\math_italics_initialize
4734%   {\clf_initializemathitalics
4735%    \gdef\math_italics_initialize
4736%      {%bitwiseflip\discretionaryoptions-\textcheckitalicdiscoptioncode % is this really needed
4737%       \bitwiseflip\glyphoptions-\textcheckitalicglyphoptioncode % is this really needed
4738%       \bitwiseflip\glyphoptions \mathcheckitalicglyphoptioncode}%
4739%    \math_italics_initialize}
4740
4741\def\math_italics_initialize
4742  {\clf_initializemathitalics % one time, so permanent
4743   \gdef\math_italics_initialize{\bitwiseflip\glyphoptions\mathcheckitalicglyphoptioncode}%
4744   \math_italics_initialize}
4745
4746\appendtoks
4747    \ifcstok{\mathematicsparameter\s!italics}\v!yes
4748        \math_italics_initialize
4749    \fi
4750\to \everymathematics
4751
4752%D Bonus for testing:
4753
4754% styles       : regular sansserif monospaced fraktur script blackboard
4755% alternatives : normal bold italic bolditalic
4756% sets         : ucletters lcletters digits ucgreek lcgreek symbols
4757
4758% \def\CheckMathHat#1{\ruledhbox{\im{\widehat{\tocharacter#1}_1^2__3^^4}}}
4759%
4760% \dontleavehmode \traversemath{regular}{bold}{digits}{\CheckMathHat{#1}\hskip1em}
4761
4762\aliased\let\mathtraversecommand\relax
4763
4764\permanent\protected\def\traversemath#1#2#3#4%
4765  {\pushmacro\mathtraversecommand
4766   \enforced\def\mathtraversecommand##1{#4}%
4767   \clf_traversemath{#1}{#2}{#3}\mathtraversecommand
4768   \popmacro\mathtraversecommand}
4769
4770\permanent\protected\def\traverseblock#1#2%
4771  {\pushmacro\mathtraversecommand
4772   \enforced\def\mathtraversecommand##1{#2}%
4773   \clf_traverseblock{#1}\mathtraversecommand
4774   \popmacro\mathtraversecommand}
4775
4776%D Just some features:
4777%D
4778%D \starttyping
4779%D $ x + \mathatom         class \mathordcode {xxx} \Umathphantom + x $\par
4780%D $ x + \mathatom         class \mathordcode {xxx} \Umathvoid    + x $\par
4781%D $ x + \mathatom phantom class \mathordcode {xxx}               + x $\par
4782%D $ x + \mathatom void    class \mathordcode {xxx}               + x $\par
4783%D
4784%D \def\rab{\Umathchar"1"00"007C }
4785%D
4786%D $
4787%D \color[green]{\rab\Umathadapttoright^{\black 1}_{\black 2}^^3__4}
4788%D \color[blue] {\mathinner{\vrule height 30mm depth 30mm width 5mm}}
4789%D \color[red]  {\rab\Umathadapttoleft ^5_6^^{\black 7}__{\black 8}}
4790%D $
4791%D
4792%D $
4793%D     \rab\Umathadapttoright^1_2^^3__4
4794%D     \mathinner{\vrule height 30mm depth 30mm width 5mm}
4795%D     \rab\Umathadapttoleft^5_6^^7__8
4796%D $
4797%D \stoptyping
4798
4799%D Just in case someone uses it:
4800
4801% \appendtoks
4802%     \scriptspace.05\Umathquad\textstyle % for Mikael
4803% \to \everymathematics
4804
4805\scriptspace\zeropoint
4806
4807%D New:
4808
4809% \startformula
4810%     \mathatom class 0 all \mathbincode      {a b c d} \breakhere
4811%     \mathatom class 0 all \mathfractioncode {a b c d} \breakhere
4812%     \base    {FE03} \breakhere
4813%     \base[16]{FE03} \breakhere
4814%     \base[8] {7204}
4815% \stopformula
4816
4817\permanent\tolerant\def\mathdigits#1%
4818  {\ifmmode
4819     \mathatom \s!class \mathdigitcode \s!all \mathdigitcode {#1}%
4820   \else
4821     #1%
4822   \fi}
4823
4824\permanent\tolerant\protected\def\base[#1]#*#:#2%
4825  {\ifmmode
4826     \mathdigits{\tf#2}\ifparameter#1\or\subscript{\mathdigits{\tf#1}}\fi
4827   \else
4828     #2\ifparameter#1\or\low{#1}\fi
4829   \fi}
4830
4831%D New:
4832
4833\permanent\tolerant\protected\def\definemathgroupset[#1]#*[#2]%
4834  {\clf_registergroupset{#1}{#2}}
4835
4836\permanent\tolerant\protected\def\setmathgroupset[#1]%
4837  {\mathdictgroup\clf_groupsetgroup{#1}\relax}
4838
4839\setmathgroupset
4840  [every]
4841
4842%D Only for testing (limited line span):
4843%D
4844%D \starttyping
4845%D test \im {z + \mathaxisbelow x + 2 - a = 1} test \par
4846%D test \im {z + \mathaxisontop x + 2 - a = 1} test
4847%D \stoptyping
4848
4849%D \starttyping
4850%D $ x^2 + x_2 + x_2^2\mathaxisbelow\mathscriptbelow$\par
4851%D $ x^g + x_g + x_g^g\mathaxisbelow\mathscriptbelow$
4852%D \stoptyping
4853
4854\definesystemattribute[mathaxis][public]
4855
4856\def\math_axis_inject_indeed#1%
4857  {\srule
4858     \s!height {%
4859        (\scratchdimentwo+\scratchdimenone)*%
4860        \ifnum\c_math_m_scaled=\plusthousand
4861          \glyphscale/\plusthousand
4862        \else
4863          \c_math_m_scaled*\glyphscale/\plusthousand/\plusthousand
4864        \fi
4865     }%
4866     \s!depth - {%
4867        (\scratchdimentwo-\scratchdimenone)*%
4868         \ifnum\c_math_m_scaled=\plusthousand
4869           \glyphscale/\plusthousand
4870         \else
4871           \c_math_m_scaled*\glyphscale/\plusthousand/\plusthousand
4872         \fi
4873     }%
4874     \s!attr \mathaxisattribute#1%
4875   \relax}
4876
4877\def\math_axis_inject#1#2%
4878  {\mathatom \s!class \mathghostcode \s!unpack {
4879   \showmakeup[strut]% todo: shortcut
4880   \ifcase#1%
4881     % nothing
4882   \or
4883     \scratchdimenone.5\Umathfractionrule\mathstyle
4884     \scratchdimentwo\Umathaxis\mathstyle
4885     \math_axis_inject_indeed#2%
4886   \or
4887     \scratchdimenone.25\Umathfractionrule\mathstyle
4888     \scratchdimentwo\Umathsupshiftup\mathstyle
4889     \math_axis_inject_indeed#2%
4890     \scratchdimentwo-\Umathsubshiftdown\mathstyle
4891     \math_axis_inject_indeed#2%
4892     \scratchdimentwo-\Umathsubsupshiftdown\mathstyle
4893     \math_axis_inject_indeed#2%
4894   % \scratchdimenone.125\Umathfractionrule\mathstyle
4895     \divideby\scratchdimenone\plustwo
4896     \scratchdimentwo\Umathprimeshiftup\mathstyle
4897     \math_axis_inject_indeed#2%
4898   \fi}}
4899
4900\permanent\protected\def\mathaxisbelow  {\math_axis_inject\plusone\plusone}
4901\permanent\protected\def\mathaxisontop  {\math_axis_inject\plusone\plustwo}
4902\permanent\protected\def\mathscriptbelow{\math_axis_inject\plustwo\plusone}
4903\permanent\protected\def\mathscriptontop{\math_axis_inject\plustwo\plustwo}
4904
4905%D \macros{kt}
4906%D
4907%D Bonus (keep together):
4908%D
4909%D \startbuffer
4910%D test $a + b + c +                    d + x + x + e + f  + g = h$ test
4911%D test $a + b + c + \keeptogether{\red d + x + x + e + f} + g = h$ test
4912%D \stopbuffer
4913%D
4914%D \typebuffer
4915%D
4916%D \startlines \getbuffer \stoplines
4917
4918\mathinlinepenaltyfactor  = 1500 % a reasonable default
4919\mathdisplaypenaltyfactor = 1000
4920
4921\setmathpostpenalty\mathpunctuationcode\plustenthousand
4922
4923\installcorenamespace{mathnesting}
4924
4925\installcommandhandler \??mathnesting {mathnesting} \??mathnesting
4926
4927\appendtoks
4928    \frozen\protected\instance\edefcsname\currentmathnesting\endcsname{\math_nesting[\currentmathnesting]}%
4929\to \everydefinemathnesting
4930
4931\newconstant\c_math_boundary_old
4932\newconstant\c_math_boundary_new
4933
4934\protected\tolerant\def\math_nesting[#1]#*[#S#2]%
4935  {\groupedcommand
4936     {\cdef\currentmathnesting{#1}%
4937      \setupcurrentmathnesting[#2]% \ifparameter#2\or...\fi can't work here due to nesting
4938      \mathnestingparameter\c!left
4939      \c_math_boundary_old\c_math_boundary_new
4940      \c_math_boundary_new
4941        \ifconditional\indisplaymath
4942          \ifchknum\mathnestingparameter\c!displayfactor\or\lastnamedcs\else\mathdisplaypenaltyfactor\fi
4943        \else
4944          \ifchknum\mathnestingparameter\c!inlinefactor \or\lastnamedcs\else\mathinlinepenaltyfactor \fi
4945        \fi
4946        \relax
4947      \mathboundary\plustwo  \c_math_boundary_new}%
4948     {\mathboundary\plusthree\c_math_boundary_old
4949      \mathnestingparameter\c!right}}
4950
4951\permanent\tolerant\protected\def\mathnesting[#1]%
4952  {\groupedcommand
4953     {\c_math_boundary_old\c_math_boundary_new
4954      \c_math_boundary_new\ifchknum#1\or#1\orelse\ifconditional\indisplaymath\mathdisplaypenaltyfactor\else\mathinlinepenaltyfactor\fi\relax
4955      \mathboundary\plustwo  \c_math_boundary_new}%
4956     {\mathboundary\plusthree\c_math_boundary_old}}
4957
4958% \definemathnesting[triplet][left=(,right=),inlinefactor=500]
4959% $ (a,b,c) + \triplet{1,2,3} + (p,q,r) $
4960
4961\definemathnesting[mathtogether][\c!inlinefactor=1500]
4962\definemathnesting[mathloose]   [\c!inlinefactor=0500]
4963
4964% \nofmathvariants % defined at lua end
4965% \getmathvariant  % defined at lua end
4966% \getmathcharone  % defined at lua end
4967% \getmathchartwo  % defined at lua end
4968
4969%D Snapping scripts:
4970%D
4971%D \startbuffer
4972%D \setupmathematics[snap=yes]
4973%D
4974%D \im {
4975%D     \mathscriptbelow \mathaxisbelow
4976%D     (x)^1_2 + \left(x\right)^1_2 + \left(\frac{1}{2}\right)^1_2
4977%D }
4978%D \stopbuffer
4979%D
4980%D \typebuffer
4981%D
4982%D This will align scripts as in: \inlinebuffer.
4983
4984\setupmathematics % currently not implemented
4985  [\c!snap=\v!no]
4986
4987%D Here is a new one (that abstracts the scripts being abused):
4988%D
4989%D \startbuffer
4990%D \startformula
4991%D     \showstruts
4992%D      \mathannotation[top=my text here,bottom=my text there]{\underbrace{x+y+z}}
4993%D \stopformula
4994%D \stopbuffer
4995%D
4996%D \typebuffer
4997%D
4998%D \getbuffer
4999
5000\installcorenamespace {mathannotation}
5001
5002\installcommandhandler \??mathannotation {mathannotation} \??mathannotation
5003
5004\setupmathannotation
5005  [\c!top=,
5006   \c!bottom=,
5007   \c!strut=\v!yes,
5008   \c!mathclass=\mathconstructcode]
5009
5010\appendtoks
5011    \frozen\protected\tolerant\edefcsname\currentmathannotation\endcsname{\math_annotation{\currentmathannotation}}
5012\to \everydefinemathannotation
5013
5014\tolerant\protected\def\math_annotation#1[#S#2]#:#3%
5015  {\beginmathgroup
5016   \edef\currentmathannotation{#1}%
5017   \setupcurrentmathannotation[#2]%
5018   \edef\p_strut{\mathannotationparameter\c!strut}%
5019   \mathatom
5020      limits
5021      \s!class\mathcodechecked{\mathannotationparameter\c!mathclass}%
5022     {#3}%
5023   \ifempty{\mathannotationparameter\c!top}\else
5024     % todo: tag this differently
5025     \superscript{%
5026        \ifx\p_strut\v!yes\botstrut\fi
5027        \mtext{\mathannotationparameter\c!top}%
5028      }%
5029   \fi
5030   \ifempty{\mathannotationparameter\c!bottom}\else
5031     % todo: tag this differently
5032     \subscript{%
5033        \ifx\p_strut\v!yes\topstrut\fi
5034        \mtext{\mathannotationparameter\c!bottom}%
5035     }%
5036   \fi
5037   \endmathgroup}
5038
5039\definemathannotation[mathannotation]
5040
5041%D By default we enable proper tensor multiple script alignment:
5042
5043\mathdoublescriptmode
5044  "\tohexadecimal\numexpr
5045     \inheritclassdoublescriptmodecode
5046   + \discardshapekerndoublescriptmodecode
5047   + \realignscriptsdoublescriptmodecode
5048   + \reorderprescriptsdoublescriptmodecode
5049   \relax
5050   \tohexadecimal\mathcontinuationcode % 2 bytes
5051   \tohexadecimal\mathcontinuationcode % 2 bytes
5052   \tohexadecimal\mathcontinuationcode % 2 bytes
5053
5054\immutable\integerdef\c_math_alignscripts_bits\numexpr
5055    "1000000 * \realignscriptsdoublescriptmodecode
5056\relax
5057
5058\immutable\integerdef\c_math_obeyempty_bits\numexpr
5059    \ignoreemptysuperscriptsmodecode
5060   +\ignoreemptysubscriptsmodecode
5061   +\ignoreemptyprimescriptsmodecode
5062\relax
5063
5064\letempty\m_math_alignscripts
5065
5066\def\m_math_update_alignscripts
5067   {\ifx\m_alignscripts\v!yes
5068      \bitwiseflip\mathdoublescriptmode \c_math_alignscripts_bits  % align
5069      \bitwiseflip\mathscriptsmode     -\c_math_obeyempty_bits     % obey empty
5070    \orelse\ifx\m_alignscripts\v!always
5071      \bitwiseflip\mathdoublescriptmode \c_math_alignscripts_bits  % align
5072      \bitwiseflip\mathscriptsmode      \c_math_obeyempty_bits     % ignore empty
5073    \orelse\ifx\m_alignscripts\v!empty
5074      \bitwiseflip\mathdoublescriptmode-\c_math_alignscripts_bits  % don't align
5075      \bitwiseflip\mathscriptsmode      \c_math_obeyempty_bits     % ignore empty
5076    \else
5077      \bitwiseflip\mathdoublescriptmode-\c_math_alignscripts_bits  % don't align
5078      \bitwiseflip\mathscriptsmode     -\c_math_obeyempty_bits     % obey empty
5079    \fi
5080    \let\m_math_alignscripts\m_alignscripts}
5081
5082\appendtoks
5083    \cdef\m_alignscripts{\mathematicsparameter\c!alignscripts}%
5084    \ifx\m_math_alignscripts\m_alignscripts\else
5085        \m_math_update_alignscripts
5086    \fi
5087% \to \everysetupmathematics
5088\to \everyswitchmathematics
5089
5090\appendtoks
5091    \scriptspacebetweenfactor\numericscale\mathematicsparameter\c!interscriptfactor\relax
5092% \to \everysetupmathematics
5093\to \everyswitchmathematics
5094
5095\setupmathematics
5096  [\c!alignscripts=\v!always,
5097   \c!interscriptfactor=1]
5098
5099%D Needed for spacing, tagging, etc.
5100
5101\newinteger\c_math_intervals
5102
5103\appendtoks
5104    \ifcstok{\mathematicsparameter\c!autointervals}\v!yes
5105      \c_math_intervals\plusone
5106    \else
5107      \c_math_intervals\attributeunsetvalue
5108    \fi
5109% \to \everysetupmathematics
5110\to \everyswitchmathematics
5111
5112\appendtoks
5113    \attribute\mathintervalsattribute\c_math_intervals
5114\to \everymathematics
5115
5116\setupmathematics
5117  [\c!autointervals=\v!yes]
5118
5119%D This is needed for tagging blobs:
5120
5121\definesystemattribute[mathblob][public]
5122
5123% \newinteger\currentmathblob
5124% \newinteger\currentmathblobnesting % could be a primitive
5125
5126\newconditional\overloadedmathmeaning
5127
5128\permanent\protected\def\math_start_meaning
5129  {\begingroup
5130   \let\math_trace_blobs\relax
5131   \setbox\scratchbox\hpack\bgroup\startmathexport[math:export]%
5132   \startimath}
5133
5134\permanent\protected\def\math_stop_meaning
5135  {\stopimath
5136   \stopmathexport
5137   \egroup
5138   \endgroup
5139   \global\overloadedmathmeaning\conditionaltrue}
5140
5141\appendtoks
5142    \enforced\let\startmathmeaning\math_start_meaning
5143    \enforced\let\stopmathmeaning \math_stop_meaning
5144\to \everyenableelements
5145
5146\permanent\protected\def\startmathmeaning
5147  {\gobbleuntil\stopmathmeaning}
5148
5149\protected\def\math_bump_blob_state
5150  {\ifnum\currentmathblobnesting<\zerocount\else
5151     \ifcase\currentmathblobnesting
5152       \ifconditional\overloadedmathmeaning
5153         \global\overloadedmathmeaning\conditionalfalse
5154       \else
5155         \global\advanceby\currentmathblob\plusone
5156       \fi
5157       \attribute\mathblobattribute\currentmathblob
5158     \fi
5159     \advanceby\currentmathblobnesting\plusone
5160   \fi}
5161
5162\appendtoks
5163    \math_bump_blob_state
5164\to \everymathematics
5165
5166% \appendtoks
5167%    \ifcstok{\taggingparameter\c!state}\v!start
5168%        \clf_enablecollectingmath
5169%    \fi
5170% \to \everysetuptagging
5171
5172\appendtoks
5173    \clf_enablecollectingmath
5174\to \everyenableelements
5175
5176\appendtoks
5177    \clf_disablecollectingmath
5178\to \everydisableelements
5179
5180% needed for verbose: \im {C \of (a,b) \neq C^2 \of (a,b)}
5181
5182\permanent\protected\def\math_application_of
5183%  {\mathatom class \mathghostcode unpack {\Umathchar \mathghostcode \zerocount "2061}} % only lists gets upacked !
5184  {\mathatom class \mathghostcode unpack {\applyfunctionof}} % only lists gets upacked !
5185
5186\appendtoks
5187    \aliased\let\of\math_application_of
5188\to \everymathematics
5189
5190\protect \endinput
5191
5192% % not used (yet)
5193%
5194% \newtoks \everystartimath
5195% \newtoks \everystopimath
5196%
5197% \protected\def\startimath{\Ustartmath\expand\everystartimath}
5198% \protected\def\stopimath {\expand\everystopimath\Ustopmath}
5199%
5200% \protected\def\m%
5201%   {\relax
5202%    \ifmmode\expandafter\math_m_stay\else\expandafter\math_m_math\fi}
5203%
5204% \protected\def\math_m_math#1%
5205%   {\startimath#1\stopimath}
5206%
5207% \let\math_m_stay\firstofoneargument
5208
5209% Maybe
5210%
5211% % \showmakeup[mathglue] \mathspacingmode1
5212% % \im{x \not< M}
5213% % \im{x + x \not+ M + M}
5214% % \im{x + x \not+ M + M}
5215% % \im{x + x \not [\not ] M}
5216%
5217% \protected\def\abnormalnot#1%
5218%   {\ifcsname\csstring\not\csstring#1\endcsname
5219%      \lastnamedcs
5220%    \else
5221%      \begingroup
5222%      \aliased\let\not\normalnot % else weird recursion and even a crash (stack probably)
5223%      % we need to block look_ahead_for_end_class_option (todo: via boundary
5224%      \setbox\scratchboxone\mathstylehbox{\normalnot}%
5225%      \setbox\scratchboxtwo\mathstylehbox{\hbox{}#1\hbox{}}% fool the bin
5226%      \scratchcounterone\the\lastleftclass
5227%      \scratchcountertwo\the\lastrightclass
5228%       \mathatom leftclass \scratchcounterone rightclass \scratchcountertwo
5229%     {\hpack{%
5230%        \scratchdimenone\wd\scratchboxone
5231%        \scratchdimentwo\wd\scratchboxtwo
5232%        \kern.5\dimexpr\scratchdimentwo-\scratchdimenone\relax
5233%        \unhbox\scratchboxone
5234%        \kern-.5\dimexpr\scratchdimenone+\scratchdimentwo\relax
5235%        \unhbox\scratchboxtwo
5236%      }}%
5237%      \endgroup
5238%   \fi}
5239%
5240% \appendtoks
5241%   \aliased\let\normalnot\not
5242%   \aliased\let\not\abnormalnot
5243% \to \everymathematics
5244