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