math-ini.mkiv /size: 94 Kb    last modification: 2023-12-21 09:44
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,
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% todo: hpack as we skip math anyway
17%
18% todo: 0x2061 : function application
19% todo: 0x2062 : invisible times
20% todo: 0x2063 : invisible comma
21
22% a bit tricky way to set ... no (pseudo) registers but math hash values:
23%
24% \normalexpanded{\Umathlimitabovevgap\displaystyle=40\dimexpr\the\Umathlimitabovevgap\displaystyle\relax}
25
26% Todo in luatex maincontrol.w: also accept a number here:
27%
28%    case set_math_param_cmd:
29%        p = cur_chr;
30%        get_token();
31%        if (cur_cmd != math_style_cmd) {
32%
33% plus two new math styles: larger/smaller
34%
35% \unexpanded\def\Umathshow#1%
36%   {\hbox{\infofont(\string#1:\the#1\textstyle,\the#1\scriptstyle,\the#1\scriptscriptstyle)}}
37
38%D This module provides namespaces for math fonts, thereby permitting mixed usage of
39%D math fonts. Although not strictly needed, we also provide a family name mapping
40%D mechanism as used in the (original) AMS math definition files, but here these
41%D names can recursively be remapped and if needed, dynamically be changed. We've
42%D tried to minimize the number of definition commands and use plain \TEX\
43%D definitions as fallback. We've tried to follow a couple of conventions from plain
44%D and AMS math in order to achieve backward compatinility. We also kept an eye on
45%D future usage of these modules in the perspective of MathML and unicode fonts.
46
47%D There is a subtle issue with grouping: the \type {\begingroup} method will not
48%D restore a changed mathstyle so best avoid that one. However, there are cases where
49%D we really need to use such grouping.
50
51% Weird, these fail, maybe amp is solved in a later state from char noads (needs a
52% fix in luatex):
53%
54% $\char"26$
55% $\a$
56% $\string&$
57
58% mathop applied to characters centers it vertically
59
60\unprotect
61
62%D We move these definitions into the format:
63
64% test  [[\char948 \cldcontext{utf.char(948)}]]
65% test $[[\char948 \cldcontext{utf.char(948)}]]$
66
67\registerctxluafile{math-ini}{}
68\registerctxluafile{math-dim}{}
69\registerctxluafile{math-act}{}
70\registerctxluafile{math-ext}{}
71\registerctxluafile{math-vfu}{}
72\registerctxluafile{math-ttv}{}
73\registerctxluafile{math-map}{optimize}
74\registerctxluafile{math-ren}{}
75\registerctxluafile{math-noa}{optimize}
76\registerctxluafile{math-tag}{}
77\registerctxluafile{math-fbk}{}
78\registerctxluafile{math-dir}{}
79\registerctxluafile{math-spa}{}
80
81%D A starter:
82%D
83%D \startbuffer
84%D \mathsurround    10pt
85%D \mathsurroundskip30pt
86%D x $x + \ruledhbox{$x$} + x$ x
87%D \stopbuffer
88%D
89%D \typebuffer
90%D
91%D \start \blank \getbuffer \blank \stop
92
93\newcount\mathnestinglevel
94
95\appendtoks
96    \advance\mathnestinglevel\plusone
97\to \everymathematics
98
99%D A few compatibility helpers:
100
101\def\Umathbotaccent{\Umathaccent \s!bottom }
102\def\Umathtopaccent{\Umathaccent \s!top    }
103\def\Umathaccents  {\Umathaccent \s!both   }
104
105\ifdefined\Umathcharclass \else
106    \def\Umathcharclass{\numexpr\cldcontext{tex.getmathcode(token.scan_int())[1]}\relax}
107    \def\Umathcharfam  {\numexpr\cldcontext{tex.getmathcode(token.scan_int())[2]}\relax}
108    \def\Umathcharslot {\numexpr\cldcontext{tex.getmathcode(token.scan_int())[3]}\relax}
109\fi
110
111%D The attributes that we will use (todo: pack some into one but uglier code):
112
113\definesystemattribute[mathalphabet]   [public]
114\definesystemattribute[mathsize]       [public]
115\definesystemattribute[mathpunctuation][public]
116\definesystemattribute[mathgreek]      [public] % will become generic
117\definesystemattribute[mathalternate]  [public]
118\definesystemattribute[mathrendering]  [public]
119\definesystemattribute[mathcategory]   [public]
120\definesystemattribute[mathmode]       [public]
121\definesystemattribute[mathitalics]    [public]
122\definesystemattribute[mathkernpairs]  [public]
123\definesystemattribute[mathbidi]       [public]
124\definesystemattribute[mathdomain]     [public]
125\definesystemattribute[mathcollapsing] [public]
126\definesystemattribute[mathunstack]    [public]
127
128\definesystemattribute[displaymath]    [public]
129
130\mathflattenmode 31
131
132\ifdefined\ordlimits\else
133    \let\ordlimits\limits
134\fi
135
136\appendtoks
137    \c_attr_mathmode\plusone
138\to \everydisplay
139
140\appendtoks
141    \c_attr_mathmode   \plusone
142    \c_attr_displaymath\plusone
143\to \everybeforedisplayformula
144
145\setnewconstant\defaultmathfamily \zerocount % 255
146
147\unexpanded\def\resetmathattributes{\clf_resetmathattributes}
148
149% handy
150
151\newconditional\indisplaymath
152
153\appendtoks
154    \setfalse\indisplaymath
155\to \everymath
156
157\appendtoks
158    \settrue\indisplaymath
159\to \everydisplay
160
161\def\inlineordisplaymath{\ifconditional\indisplaymath\expandafter\secondoftwoarguments\else\expandafter\firstoftwoarguments\fi}
162
163\unexpanded\def\forcedisplaymath
164  {\ifmmode
165     \displaystyle
166     \settrue\indisplaymath
167   \fi}
168
169\unexpanded\def\startforceddisplaymath
170  {\startimath
171   \displaystyle
172   \begingroup
173   \settrue\indisplaymath}
174
175\unexpanded\def\stopforceddisplaymath
176  {\endgroup
177   \stopimath}
178
179\unexpanded\def\startpickupmath % for the moment private
180  {\ifconditional\indisplaymath
181     \startforceddisplaymath
182     \let\stoppickupmath\stopforceddisplaymath
183   \else
184     \startimath
185     \let\stoppickupmath\stopimath
186   \fi}
187
188\let\stoppickupmath\relax
189
190% \unexpanded\def\rawmathcharacter#1% slow but only for tracing
191%   {\begingroup
192%    \ifmmode
193%      \resetmathattributes\Uchar#1%
194%    \else
195%      \startimath\resetmathattributes\Uchar#1\stopimath
196%    \fi
197%    \endgroup}
198
199\unexpanded\def\rawmathematics#1% slow but only for tracing
200  {\begingroup
201   \ifmmode
202     \clf_resetmathattributes#1%
203   \else
204     \startimath\clf_resetmathattributes#1\stopimath
205   \fi
206   \endgroup}
207
208%D Some measures (maybe spac-mth):
209
210% \def\mathskipsmall {\mskip\thinmuskip}
211% \def\mathskipmedium{\mskip\medmuskip}
212% \def\mathskipbig   {\mskip\thickmuskip}
213
214%D \macros
215%D   {setupmathematics}
216%D
217%D Configuration for integrals. (If needed we can speed this up and make it
218%D installable; no processaction is needed then).
219
220\installcorenamespace{mathematics}
221
222\installswitchcommandhandler \??mathematics {mathematics} \??mathematics
223
224\unexpanded\def\startmathematics % no grouping, if ever then also an optional second
225  {\doifelsenextoptionalcs\math_mathematics_start_yes\math_mathematics_start_nop}
226
227\installmacrostack\currentmathematics
228
229\unexpanded\def\math_mathematics_start_yes[#1]%
230  {\push_macro_currentmathematics
231   \edef\currentmathematics{#1}% check for valid
232   \the\everyswitchmathematics}
233
234\unexpanded\def\math_mathematics_start_nop
235  {\push_macro_currentmathematics
236   \let\currentmathematics\empty
237   \the\everyswitchmathematics}
238
239\unexpanded\def\stopmathematics
240  {\pop_macro_currentmathematics
241   \the\everyswitchmathematics}
242
243\definemathematics[\v!default] % not needed, but nicer when nesting back to normal
244
245% Now we redefine \type {\mathematics} and \type {\m}:
246
247\unexpanded\def\mathematics
248  {\doifelsenextoptionalcs\math_m_yes\math_m_nop}
249
250\def\math_m_yes
251  {\relax
252   \ifmmode
253     \expandafter\math_m_yes_math
254   \else
255     \expandafter\math_m_yes_text
256   \fi}
257
258\def\math_m_yes_math[#1]#2%
259  {#2}
260
261% \def\math_m_yes_text[#1]%
262%   {\begingroup
263%    \doifassignmentelse{#1}%
264%      {\setupcurrentmathematics[#1]}%
265%      {\edef\currentmathematics{#1}}% check for valid
266%    \edef\p_openup{\mathematicsparameter\c!openup}%
267%    \ifx\p_openup\v!yes
268%      \expandafter\math_m_yes_text_openedup
269%    \else
270%      \expandafter\math_m_yes_text_normal
271%    \fi}
272
273\def\math_m_yes_text[#1]%
274  {\begingroup
275   \ifcondition\validassignment{#1}%
276     \setupcurrentmathematics[#1]%
277   \else
278     \edef\currentmathematics{#1}% check for valid
279   \fi
280   \edef\p_openup{\mathematicsparameter\c!openup}%
281   \ifx\p_openup\v!yes
282     \expandafter\math_m_yes_text_openedup
283   \else
284     \expandafter\math_m_yes_text_normal
285   \fi}
286
287\def\math_m_yes_text_openedup#1%
288  {\setbox\scratchbox\hbox\bgroup
289      \the\everyswitchmathematics\relax
290      \normalstartimath
291      #1%
292      \normalstopimath
293   \egroup
294   \ifdim\ht\scratchbox>\strutht
295     \math_inline_openup_start_yes
296   \else\ifdim\dp\scratchbox>\strutdp
297     \math_inline_openup_start_yes
298   \else
299     \math_inline_openup_start_nop
300   \fi\fi
301   \unhbox\scratchbox % \normalstartimath#1\normalstopimath
302   \math_inline_openup_stop
303   \endgroup}
304
305\def\math_m_yes_text_normal#1%
306  {\the\everyswitchmathematics\relax
307   \normalstartimath
308   #1%
309   \normalstopimath
310   \endgroup}
311
312\def\math_m_nop#1%
313  {\relax
314   \ifmmode
315     #1%
316   \else
317     \normalstartimath
318     #1%
319     \normalstopimath
320   \fi}
321
322\let\m   \mathematics
323\let\math\mathematics
324
325% e.g.: \definemathematics[i:mp][setups=i:tight,openup=yes]
326
327\newmuskip\defaultthickmuskip \defaultthickmuskip 5mu plus 5mu
328\newmuskip\defaultmedmuskip   \defaultmedmuskip   4mu plus 2mu minus 4mu
329\newmuskip\defaultthinmuskip  \defaultthinmuskip  3mu
330
331\newmuskip\halfthickmuskip \halfthickmuskip 2.5mu plus 2.5mu
332\newmuskip\halfmedmuskip   \halfmedmuskip   2.0mu plus 1.0mu minus 2.0mu
333\newmuskip\halfthinmuskip  \halfthinmuskip  1.5mu
334
335\newcount \defaultrelpenalty        \defaultrelpenalty         500
336\newcount \defaultbinoppenalty      \defaultbinoppenalty       700
337\newcount \defaultprerelpenalty     \defaultprerelpenalty     -100
338\newcount \defaultprebinoppenalty   \defaultprebinoppenalty   -100
339\newcount \defaultdisplayprepenalty \defaultdisplayprepenalty  -10
340
341% For the moment this way:
342
343% \appendtoks
344%     \setmathprepenalty \mathbinarycode         \defaultdisplayprepenalty
345%   % \setmathpostpenalty\mathbinarycode         \zerocount
346%     \setmathprepenalty \mathrelationcode       \defaultdisplayprepenalty
347%   % \setmathpostpenalty\mathrelationcode       \zerocount
348%     \setmathpostpenalty\mathtextpunctuationcode\defaultdisplayprepenalty
349%   % \setmathprepenalty \mathtextpunctuationcode\zerocount
350% \to \everybeforedisplayformula
351
352% we need to control these otherwise:
353%
354% \prerelpenalty  \defaultprerelpenalty
355% \prebinoppenalty\defaultprebinoppenalty
356
357\startsetups math:spacing:default
358    \thickmuskip    \defaultthickmuskip
359    \medmuskip      \defaultmedmuskip
360    \thinmuskip     \defaultthinmuskip
361    \relpenalty     \defaultrelpenalty
362    \binoppenalty   \defaultbinoppenalty
363    \prebinoppenalty\maxdimen
364    \prerelpenalty  \maxdimen
365\stopsetups
366
367\startsetups math:spacing:split
368    \thickmuskip    \defaultthickmuskip
369    \medmuskip      \defaultmedmuskip
370    \thinmuskip     \defaultthinmuskip
371    \relpenalty     \defaultrelpenalty
372    \binoppenalty   \defaultbinoppenalty
373    \prebinoppenalty\defaultprebinoppenalty
374    \prerelpenalty  \defaultprerelpenalty
375\stopsetups
376
377\startsetups math:spacing:half
378    \thickmuskip    \halfthickmuskip
379    \medmuskip      \halfmedmuskip
380    \thinmuskip     \halfthinmuskip
381    \relpenalty     \defaultrelpenalty
382    \binoppenalty   \defaultbinoppenalty
383    \prebinoppenalty\maxdimen
384    \prerelpenalty  \maxdimen
385\stopsetups
386
387\startsetups math:spacing:tight
388    \ifcase\raggedstatus
389        \thickmuskip   \halfthickmuskip
390        \medmuskip     \halfmedmuskip
391        \thinmuskip    \halfthinmuskip
392    \else
393        \thickmuskip  1\halfthickmuskip
394        \medmuskip    1\halfmedmuskip
395        \thinmuskip   1\halfthinmuskip
396    \fi
397    \relpenalty     \defaultrelpenalty
398    \binoppenalty   \maxdimen
399    \prebinoppenalty\maxdimen
400    \prerelpenalty  \maxdimen
401\stopsetups
402
403\startsetups math:spacing:fixed
404    \ifcase\raggedstatus
405        \thickmuskip   \halfthickmuskip
406        \medmuskip     \halfmedmuskip
407        \thinmuskip    \halfthinmuskip
408    \else
409        \thickmuskip  1\halfthickmuskip
410        \medmuskip    1\halfmedmuskip
411        \thinmuskip   1\halfthinmuskip
412    \fi
413    \relpenalty     \maxdimen
414    \binoppenalty   \maxdimen
415    \prebinoppenalty\maxdimen
416    \prerelpenalty  \maxdimen
417\stopsetups
418
419% \dorecurse{80}{test \m[i:tight]{\red \fakeformula} test }
420
421\definemathematics[i:default][\c!setups=math:spacing:equal]
422\definemathematics[i:half]   [\c!setups=math:spacing:half]
423\definemathematics[i:tight]  [\c!setups=math:spacing:tight]
424\definemathematics[i:fixed]  [\c!setups=math:spacing:fixed]
425
426% Normally the next is applied to only one character.
427%
428% $ABC$ $\cal ABC$ $\mathaltcal ABC$
429
430% todo: only in mmode
431% these commands are semi-public but should not be used directly (lua names wil change)
432
433\unexpanded\def\math_set_attribute   #1#2{\ifmmode\clf_setmathattribute{#1}{#2}\fi}
434\unexpanded\def\math_set_alphabet      #1{\ifmmode\clf_setmathalphabet{#1}\fi}
435\unexpanded\def\math_set_font_style    #1{\ifmmode\clf_setmathstyle{#1}\fi}
436\unexpanded\def\math_set_font_alternate#1{\ifmmode\clf_setmathalternate\defaultmathfamily{#1}\fi}
437
438\installcorenamespace{mathstylealternative} % might become a setuphandler
439
440\unexpanded\def\math_set_font_style_alternate#1%
441  {\ifcsname\??mathstylealternative\fontclass:#1\endcsname
442    %\expandafter\math_set_font_alternate\csname\??mathstylealternate\fontclass:#1\endcsname
443     \expandafter\math_set_font_alternate\lastnamedcs
444   \else\ifcsname\??mathstylealternative#1\endcsname
445    %\expandafter\math_set_font_alternate\csname\??mathstylealternate#1\endcsname
446     \expandafter\math_set_font_alternate\lastnamedcs
447   \fi\fi}
448
449\unexpanded\def\setupmathrendering % the name might change
450  {\dodoubleargument\math_setup_rendering}
451
452\def\math_setup_rendering[#1][#2]%
453  {\ifsecondargument
454     \getparameters[\??mathstylealternative#1:][#2]%
455   \else
456     \getparameters[\??mathstylealternative][#1]%
457   \fi}
458
459\appendtoks
460    \edef\p_stylealternative{\mathematicsparameter\c!stylealternative}%
461    \ifx\p_stylealternative\empty\else
462        \clf_presetmathalternate\defaultmathfamily{\p_stylealternative}%
463    \fi
464\to \everymathematics
465
466% if there were many features we could have a feature pass over math nodes but it makes no
467% sense now so we have commands to deal with it
468
469% \enabletrackers[math.alternates]
470% \setupbodyfont[lucidaot]
471%
472% \startTEXpage
473%     \setupmathematics[stylealternative={reset}]$x+\mathcal A$\par
474%     \setupmathematics[stylealternative={reset,calligraphic}]$x+\mathcal A$\par
475%     \setupmathematics[stylealternative={reset,italic}]$x+\mathcal A$\par
476%     \setupmathematics[stylealternative={reset,calligraphic,italic}]$x+\mathcal A$
477% \stopTEXpage
478
479\unexpanded\def\mathaltcalligraphic{\math_set_font_alternate{calligraphic}\cal}          % set via goody file
480\unexpanded\def\mathaltitalic      {\math_set_font_alternate{italic}}                    % set via goody file
481\unexpanded\def\mathslashedzero    {\begingroup\math_set_font_alternate{zero}\endgroup} % set via goody file or automatic
482\unexpanded\def\mathdotless        {\math_set_font_alternate{dotless}}                   % set via goody file or automatic
483\unexpanded\def\mathdotlessi       {\begingroup\mathdotless i\endgroup}
484\unexpanded\def\mathdotlessj       {\begingroup\mathdotless j\endgroup}
485
486\let\mathaltcal\mathaltcalligraphic
487\let\mathaltit \mathaltitalic
488
489%let\textslashedzero\slashedzero \unexpanded\def\autoslashedzero{\mathortext\mathslashedzero\textslashedzero}
490\let\textdotlessi   \dotlessi    \unexpanded\def\autodotlessi   {\mathortext\mathdotlessi   \textdotlessi}
491\let\textdotlessj   \dotlessj    \unexpanded\def\autodotlessj   {\mathortext\mathdotlessj   \textdotlessj}
492
493\appendtoks
494    %let\slashedzero\autoslashedzero
495    \let\dotlessi   \autodotlessi
496    \let\dotlessj   \autodotlessj
497\to \everymathematics
498
499\let\setmathattribute           \math_set_attribute
500\let\setmathalphabet            \math_set_alphabet
501\let\setmathfontstyle           \math_set_font_style
502\let\setmathfontalternate       \math_set_font_alternate
503\let\setmathfontalternative     \math_set_font_alternate
504\let\setmathfontstylealternate  \math_set_font_style_alternate
505\let\setmathfontstylealternative\math_set_font_style_alternate
506
507\let\mathalternate              \math_set_font_alternate
508
509\unexpanded\def\mathupright   {\math_set_attribute\s!regular\s!tf\math_set_font_style_alternate\s!tf}
510\unexpanded\def\mathitalic    {\math_set_attribute\s!regular\s!it\math_set_font_style_alternate\s!it}
511\unexpanded\def\mathscript    {\math_set_alphabet \s!script      \math_set_font_style_alternate\s!script}
512\unexpanded\def\mathfraktur   {\math_set_alphabet \s!fraktur     \math_set_font_style_alternate\s!fraktur}
513\unexpanded\def\mathblackboard{\math_set_alphabet \s!blackboard  \math_set_font_style_alternate\s!blackboard}
514
515\unexpanded\def\mathrm        {\math_set_attribute\s!rm\s!tf     \math_set_font_style_alternate\s!tf}
516\unexpanded\def\mathss        {\math_set_attribute\s!ss\s!tf     \math_set_font_style_alternate\s!tf}
517\unexpanded\def\mathtt        {\math_set_attribute\s!tt\s!tf     \math_set_font_style_alternate\s!tf}
518
519\unexpanded\def\mathtf        {\math_set_font_style\s!tf         \math_set_font_style_alternate\s!tf}
520\unexpanded\def\mathsl        {\math_set_font_style\s!it         \math_set_font_style_alternate\s!it} % no sl
521\unexpanded\def\mathit        {\math_set_font_style\s!it         \math_set_font_style_alternate\s!it}
522
523\unexpanded\def\mathbf        {\math_set_font_style\s!bf         \math_set_font_style_alternate\s!bf}
524\unexpanded\def\mathbs        {\math_set_font_style\s!bi         \math_set_font_style_alternate\s!bi} % no sl
525\unexpanded\def\mathbi        {\math_set_font_style\s!bi         \math_set_font_style_alternate\s!bi}
526
527\let\mathdefault\mathitalic
528
529\appendtoks
530    \edef\p_default{\mathematicsparameter\c!default}%
531    \ifx\p_default\v!normal
532      \let\mathdefault\mathupright
533    \else
534      \let\mathdefault\mathitalic
535    \fi
536\to \everysetupmathematics
537
538\setupmathematics
539  [\c!default=\v!italic]
540
541\let\tfmath\mathtf % maybe a grouped command
542\let\slmath\mathsl
543\let\itmath\mathit
544
545\let\bfmath\mathbf
546\let\bsmath\mathbs
547\let\bimath\mathbi
548
549\let\Bbb\mathblackboard
550
551\unexpanded\def\frak      {\ifmmode\expandafter\mathfraktur   \fi}
552\unexpanded\def\cal       {\ifmmode\expandafter\mathscript    \fi}
553\unexpanded\def\bbd       {\ifmmode\expandafter\mathblackboard\fi}
554\unexpanded\def\blackboard{\ifmmode\expandafter\mathblackboard\fi}
555\unexpanded\def\fraktur   {\ifmmode\expandafter\mathfraktur   \fi}
556\unexpanded\def\gothic    {\ifmmode\expandafter\mathfraktur   \fi}
557
558\unexpanded\def\mathcal #1{{\mathscript    #1}}  % for AMS compatibility
559\unexpanded\def\mathfrak#1{{\mathfraktur   #1}}  % for AMS compatibility
560\unexpanded\def\mathbb  #1{{\mathblackboard#1}}  % for AMS compatibility
561
562\ifdefined\normaltf\else\let\normaltf\tf\fi \unexpanded\def\tf{\ifmmode\mathtf\else\normaltf\fi}
563\ifdefined\normalbf\else\let\normalbf\bf\fi \unexpanded\def\bf{\ifmmode\mathbf\else\normalbf\fi}
564\ifdefined\normalit\else\let\normalit\it\fi \unexpanded\def\it{\ifmmode\mathit\else\normalit\fi}
565\ifdefined\normalsl\else\let\normalsl\sl\fi \unexpanded\def\sl{\ifmmode\mathsl\else\normalsl\fi}
566\ifdefined\normalbi\else\let\normalbi\bi\fi \unexpanded\def\bi{\ifmmode\mathbi\else\normalbi\fi}
567\ifdefined\normalbs\else\let\normalbs\bs\fi \unexpanded\def\bs{\ifmmode\mathbs\else\normalbs\fi}
568
569\unexpanded\def\rm{\ifmmode\mathrm\else\normalrm\fi}
570\unexpanded\def\ss{\ifmmode\mathss\else\normalss\fi}
571\unexpanded\def\tt{\ifmmode\mathtt\else\normaltt\fi}
572
573\ifdefined\mr \else \let\mr\relax \fi
574\ifdefined\mb \else \let\mb\relax \fi
575
576% 1: $\setmathattribute{ss}{bf}3$
577% 2: $\setmathattribute{ss}{bf}\setmathfontstylealternate{bf}3$
578% 3: $\setmathattribute{ss}{bf}\setmathfontstyle{bf}3$
579% 4: $\setmathattribute{ss}{bf}\setmathfontstyle{bf}\setmathfontstylealternate{bf}3$
580% 5: $e=mc^2 \quad \mb e=mc^2$
581
582\prependtoks
583    \mathdefault
584\to \everymathematics
585
586%D We could set the rendering attribute at the \LUA\ end but as there can be many
587%D small math snippets we keep track of the state at the \TEX\ end (mapping is
588%D export safe).
589%D
590%D \starttyping
591%D \startformula
592%D     \reals {\mathbf R} \utfchar{"0211D} \utfchar{"1D411}
593%D \stopformula
594%D
595%D \setupmathematics
596%D   [symbolset=blackboard-to-bold]
597%D
598%D \startformula
599%D     \reals {\mathbf R} \utfchar{"0211D} \utfchar{"1D411}
600%D \stopformula
601%D \stoptyping
602
603\newcount\c_math_renderings_attribute
604
605\appendtoks
606    \c_math_renderings_attribute\clf_mathrenderset{\mathematicsparameter\c!symbolset}\relax
607\to \everysetupmathematics % only in mathematics
608
609\appendtoks
610    \ifcase\c_math_renderings_attribute\else
611        \c_attr_mathrendering\c_math_renderings_attribute
612    \fi
613\to \everymathematics
614
615\setupmathematics
616  [\c!symbolset=]
617
618%D \macros
619%D   {boldsymbol}
620%D
621%D To be done.
622
623\let\mathboldsymbol\relax % yet unsupported, will be
624
625\unexpanded\def\boldsymbol
626  {\mathortext\mathboldsymbol\bold}
627
628%D Helpers
629
630\def\utfmathclass  #1{\clf_utfmathclass  {#1}}
631\def\utfmathstretch#1{\clf_utfmathstretch{#1}}
632\def\utfmathcommand#1{\clf_utfmathcommand{#1}}
633\def\utfmathfiller #1{\clf_utfmathfiller {#1}}
634
635\def\utfmathcommandabove #1{\clf_utfmathcommandabove {#1}}
636\def\utfmathcommandbelow #1{\clf_utfmathcommandbelow {#1}}
637\def\utfmathcommandfiller#1{\clf_utfmathcommandfiller{#1}}
638
639\unexpanded\def\doifelseutfmathaccent#1{\clf_doifelseutfmathaccent{#1}}
640\unexpanded\def\doifelseutfmathabove #1{\clf_doifelseutfmathabove {#1}}
641\unexpanded\def\doifelseutfmathbelow #1{\clf_doifelseutfmathbelow {#1}}
642\unexpanded\def\doifelseutfmathfiller#1{\clf_doifelseutfmathfiller{#1}}
643\unexpanded\def\doifelseutfmathlimop #1{\clf_doifelseutfmathlimop {#1}}
644
645\let\doifutfmathaccentelse \doifelseutfmathaccent
646\let\doifutfmathaboveelse  \doifelseutfmathabove
647\let\doifutfmathbelowelse  \doifelseutfmathbelow
648\let\doifutfmathfillerelse \doifelseutfmathfiller
649\let\doifutfmathlimopelse  \doifelseutfmathlimop
650
651%D Not used that much:
652
653\installcorenamespace{mathcodecommand}
654
655\unexpanded\def\mathlimop#1{\mathop{#1}} %no \limits
656\unexpanded\def\mathbox  #1{\dontleavehmode\hbox\Ustartmath\mathsurround\zeropoint#1\Ustopmath}
657\unexpanded\def\mathnolop#1{\mathop{#1}\nolimits}
658
659\let\mathnothing\firstofoneunexpanded
660\let\mathalpha  \firstofoneunexpanded
661
662\setnewconstant\mathordcode     \zerocount  \letvalue{\??mathcodecommand     ord}\mathord
663\setnewconstant\mathopcode      \plusone    \letvalue{\??mathcodecommand      op}\mathop
664\setnewconstant\mathbincode     \plustwo    \letvalue{\??mathcodecommand     bin}\mathbin
665\setnewconstant\mathrelcode     \plusthree  \letvalue{\??mathcodecommand     rel}\mathrel
666\setnewconstant\mathopencode    \plusfour   \letvalue{\??mathcodecommand    open}\mathopen
667\setnewconstant\mathclosecode   \plusfive   \letvalue{\??mathcodecommand   close}\mathclose
668\setnewconstant\mathpunctcode   \plussix    \letvalue{\??mathcodecommand   punct}\mathpunct
669\setnewconstant\mathalphacode   \plusseven  \letvalue{\??mathcodecommand   alpha}\mathalpha
670\setnewconstant\mathinnercode   \zerocount  \letvalue{\??mathcodecommand   inner}\mathinner
671\setnewconstant\mathnothingcode \zerocount  \letvalue{\??mathcodecommand nothing}\mathnothing
672\setnewconstant\mathlimopcode   \plusone    \letvalue{\??mathcodecommand   limop}\mathlimop
673\setnewconstant\mathnolopcode   \plusone    \letvalue{\??mathcodecommand   nolop}\mathnolop
674\setnewconstant\mathboxcode     \zerocount  \letvalue{\??mathcodecommand     box}\mathbox
675\setnewconstant\mathchoicecode  \zerocount  %letvalue{\??mathcodecommand  choice}\mathnothing
676
677\setnewconstant\mathaccentcode  \pluseight
678\setnewconstant\mathradicalcode \plusnine
679
680           \def\mathcodenumber #1{\the\csname math#1code\endcsname}
681\unexpanded\def\mathcodecommand#1{\csname\??mathcodecommand#1\endcsname}
682
683% \startlines
684% $\mathopnolimits{\rm d}x$
685% $\mathopnolimits{\kern\zeropoint \rm d}x$
686% $\mathcodecommand{nolop}{\rm d}x$
687% $\mathcodecommand{nolop}{\kern\zeropoint\rm d}x$
688% \blank
689% $\mathcodecommand{nolop}{\mr d}x$
690% $\mathcodecommand{nolop}{\kern\zeropoint\mr d}x$
691% $\mathop{\kern\zeropoint\mr d}x$
692% $\mathopnolimits{\kern\zeropoint d}x$
693% \stoplines
694
695\installcorenamespace{mathcommand}
696
697\unexpanded\def\definemathcommand
698  {\dotripleempty\math_define_command}
699
700\def\math_define_command[#1][#2][#3]#4% command class args meaning
701  {\ifthirdargument
702     \edef\nofmathcommandarguments{#3}%
703     \ifx\nofmathcommandarguments\v!one
704       \setuvalue{\??mathcommand#1}##1{\mathcodecommand{#2}{#4{##1}}}%
705     \else\ifx\nofmathcommandarguments\v!two
706       \setuvalue{\??mathcommand#1}##1##2{\mathcodecommand{#2}{#4{##1}{##2}}}%
707     \else
708       \setuvalue{\??mathcommand#1}{\mathcodecommand{#2}{#4}}%
709     \fi\fi
710   \else\ifsecondargument
711     \setuvalue{\??mathcommand#1}{\mathcodecommand{#2}{#4}}%
712   \else
713     \setuvalue{\??mathcommand#1}{\mathcodecommand{nothing}{#4}}%
714   \fi\fi
715   \letcsnamecsname\csname#1\endcsname\csname\??mathcommand#1\endcsname}
716
717\unexpanded\def\mathcommand#1%
718  {\begincsname\??mathcommand#1\endcsname}
719
720%D Let's define a few comands here:
721
722%definemathcommand [mathstrut]       {\vphantom{(}}
723%definemathcommand [joinrel]         {\mathrel{\mkern-3mu}}
724\definemathcommand [joinrel]   [rel] {\mkern-3mu}
725
726\chardef\c_math_strut"28
727
728\unexpanded\def\math_strut_htdp#1%
729  {\s!height\fontcharht#1\c_math_strut
730   \s!depth \fontchardp#1\c_math_strut}
731
732\unexpanded\def\math_strut_normal
733  {\vrule
734      \normalexpanded{\math_strut_htdp{\mathstylefont\normalmathstyle}}%
735      \s!width \zeropoint
736   \relax}
737
738\unexpanded\def\math_strut_visual
739  {\hskip-.01\emwidth
740   \vrule
741      \normalexpanded{\math_strut_htdp{\mathstylefont\normalmathstyle}}%
742      \s!width .02\emwidth
743   \relax
744   \hskip-.01\emwidth}
745
746\unexpanded\def\showmathstruts % let's not overload \math_strut_normal
747  {\let\math_strut\math_strut_visual}
748
749\let\math_strut\math_strut_normal
750
751% \unexpanded\def\mathstrut{\mathcodecommand{nothing}{\math_strut}}
752
753\definemathcommand [mathstrut] {\math_strut}
754
755%D We could have a arg variant \unknown\ but not now.
756
757\unexpanded\def\mathopwithlimits#1#2{\mathop{#1{#2}}\limits}
758\unexpanded\def\stackrel        #1#2{\mathrel{\mathop{#2}\limits^{#1}}}
759
760%D Moved from font-ini.mkiv:
761%D
762%D \macros
763%D   {mf,mbox,enablembox,mathop}
764%D
765%D Todo:
766
767\unexpanded\def\mf
768  {\begincsname\fontalternative\endcsname}
769
770% \let\normalmathop\mathop % already defined
771
772% no longer needed as we no longer switch fonts
773%
774% \unexpanded\def\mathop
775%   {\normalmathop
776%    \bgroup
777%   % no: \let\rm\mf
778%    \afterassignment\math_op\let\nexttoken=}
779%
780% \def\math_op{\ifx\nexttoken\bgroup\else\nexttoken\egroup\fi}
781
782% this one too: \letvalue{\??mathcodecommand op}\mathop ?
783
784\unexpanded\def\normalmbox
785  {\normalhbox\bgroup
786   \usemathematicsstyleandcolor\c!textstyle\c!textcolor % new
787   \dowithnextboxcs\math_mbox_finish\normalhbox}
788
789\def\math_mbox_finish
790  {\flushnextbox
791   \egroup}
792
793\unexpanded\def\mbox % we cannot add \dontleavehmode ... else no \setbox0\mbox possible
794  {\ifmmode\normalmbox\else\normalhbox\fi}
795
796\unexpanded\def\enablembox
797  {\toksapp\everymathematics{\math_enable_mbox}}
798
799\def\math_enable_mbox
800  {\let\hbox\mbox}
801
802\unexpanded\def\snappedmath#1% sort of \struttedbox
803  {\dontleavehmode
804   \begingroup
805   \setbox\scratchbox\normalhbox\bgroup
806     \startimath#1\stopimath
807   \egroup
808   \ht\scratchbox\strutht
809   \dp\scratchbox\strutdp
810   \box\scratchbox
811   \endgroup}
812
813\unexpanded\def\mtext#1%
814  {\text{\usemathematicsstyleandcolor\c!textstyle\c!textcolor#1}}
815
816%D The next hack is needed needed for sine, cosine etc.
817
818\let\mathfunction\firstofoneunexpanded
819
820\let\math_tags_function         \firstofoneunexpanded
821\let\math_tags_functionlabeltext\mathlabeltext
822
823\let\math_tags_mo\firstofoneunexpanded
824\let\math_tags_mi\firstofoneunexpanded
825
826\unexpanded\def\math_tags_mn#1{\begingroup\mathupright\math_set_o_both#1\endgroup}
827\unexpanded\def\math_tags_ms#1{\begingroup\mathupright\math_set_p_both#1\endgroup}
828
829% Once this is stable we can store the number at the tex end which is
830% faster. Functions getnumbers >= 1000.
831
832% \setupmathematics[functionstyle=normal] % will give ligatures and kerning
833
834\setupmathematics
835  [\c!textstyle=,     % rm ss etc i.e. known alternatives, otherwise math
836   \c!textcolor=,
837   \c!functionstyle=, % rm ss etc i.e. known alternatives, otherwise math
838   \c!functioncolor=]
839
840\unexpanded\def\math_mfunction_styled
841  {\begingroup
842   \usemathematicscolorparameter\c!functioncolor
843   \edef\p_functionstyle{\mathematicsparameter\c!functionstyle}%
844   \ifx\p_functionstyle\empty
845     \expandafter\math_mfunction_styled_none
846   \else\ifcsname\??alternativestyle\p_functionstyle\endcsname
847     \doubleexpandafter\math_mfunction_styled_text
848   \else
849     \doubleexpandafter\math_mfunction_styled_math
850   \fi\fi}
851
852\unexpanded\def\math_mfunction_styled_text#1%
853 %{\mathoptext{\csname\??alternativestyle\p_functionstyle\endcsname#1}%
854  {\expandafter\mathoptext\expandafter{\lastnamedcs#1}%
855   \endgroup}
856
857\unexpanded\def\math_mfunction_styled_math#1%
858  {\p_functionstyle
859   #1%
860   \endgroup}
861
862\unexpanded\def\math_mfunction_styled_none#1%
863  {\mathupright
864   #1%
865   \endgroup}
866
867\unexpanded\def\mfunction#1%
868  {\begingroup
869   \math_tags_mfunctiontxt{#1}\c_apply_function
870   \math_mfunction_styled{#1}%
871   \endgroup}
872
873\unexpanded\def\mfunctionlabeltext#1%
874  {\begingroup
875   \math_tags_mfunctionlab{#1}\c_apply_function
876   \math_mfunction_styled{\mathlabeltext{#1}}%
877   \endgroup}
878
879\let\math_tags_mfunctiontxt\gobbletwoarguments
880\let\math_tags_mfunctionlab\gobbletwoarguments
881
882\unexpanded\def\math_tags_mo_indeed#1{\begingroup            \c_attr_mathcategory\plusone                  #1\endgroup}
883\unexpanded\def\math_tags_mi_indeed#1{\begingroup            \c_attr_mathcategory\plustwo                  #1\endgroup}
884\unexpanded\def\math_tags_mn_indeed#1{\begingroup\mathupright\c_attr_mathcategory\plusthree\math_set_o_both#1\endgroup}
885\unexpanded\def\math_tags_ms_indeed#1{\begingroup\mathupright\c_attr_mathcategory\plusfour \math_set_p_both#1\endgroup} % todo: mathoptext
886
887\newconditional\c_apply_function
888
889\unexpanded\def\math_tags_apply#1#2%
890  {\begingroup
891   \settrue\c_apply_function
892   #1%
893   \endgroup
894   \begingroup
895   % todo: auto ()
896   #2%
897   \endgroup}
898
899\appendtoks
900    \let\math_tags_mfunctiontxt\clf_tagmfunctiontxt
901    \let\math_tags_mfunctionlab\clf_tagmfunctionlab
902    \let\math_tags_mo          \math_tags_mo_indeed
903    \let\math_tags_mi          \math_tags_mi_indeed
904    \let\math_tags_mn          \math_tags_mn_indeed
905    \let\math_tags_ms          \math_tags_ms_indeed
906\to \everyenableelements
907
908\appendtoks
909    \let\mo   \math_tags_mo
910    \let\mi   \math_tags_mi
911    \let\mn   \math_tags_mn
912    \let\ms   \math_tags_ms
913    \let\apply\math_tags_apply
914\to\everymathematics
915
916% \def\mlimitsfunction  #1{\mathlimopcomm{{\mr#1}}
917% \def\mnolimitsfunction#1{\mathnolopcomm{{\mr#1}}
918
919% %D Taco posted this solution as response to a mail by Olivier, so let's integrate
920% %D it here.
921%
922% \def\currentmscaledstyle{rm} % will be plugged into the typeface text=ss option
923%
924% \unexpanded\def\math_function_style_opnolimits        #1{\mathop{\mscaledtext{#1}}\nolimits}
925% \unexpanded\def\math_function_style_mfunction         #1{\mscaledtext{\math_tags_function{#1}}}
926% \unexpanded\def\math_function_style_mfunctionlabeltext#1{\mscaledtext{\math_tags_functionlabeltext{#1}}}
927%
928% \unexpanded\def\setmathfunctionstyle#1% rm ss tt (can be made faster if needed)
929%   {\doifsomething{#1}
930%      {\def\currentmscaledstyle{#1}%
931%       \let\mathopnolimits    \math_function_style_opnolimits
932%       \let\mfunction         \math_function_style_mfunction
933%       \let\mfunctionlabeltext\math_function_style_mfunctionlabeltext}}
934
935\def\currentmscaledstyle{rm} % will be plugged into the typeface text=ss option
936
937\unexpanded\def\mscaledtext#1%
938  {\mathchoice
939     {\hbox{\csname\currentmscaledstyle\endcsname\tf  #1}}
940     {\hbox{\csname\currentmscaledstyle\endcsname\tf  #1}}
941     {\hbox{\csname\currentmscaledstyle\endcsname\tfx #1}}
942     {\hbox{\csname\currentmscaledstyle\endcsname\tfxx#1}}}
943
944\unexpanded\def\setmathfunctionstyle#1%
945  {\setupmathematics[\c!functionstyle=#1]} % for old times sake
946
947%D Usage:
948%D
949%D \starttyping
950%D \setmathfunctionstyle\fontstyle % or {rm} or {ss} or ..
951%D \rm test $\sin{(x^{\sin(x^{\sin(x)})})}$ test
952%D \ss test $\sin{(x^{\sin(x^{\sin(x)})})}$ test
953%D \tt test $\sin{(x^{\sin(x^{\sin(x)})})}$ test
954%D \stoptyping
955
956%D \macros
957%D   {nonknuthmode, donknuthmode}
958%D
959%D The underscore is frequently used in manuals but unfortunately \TEX\ prefers
960%D it to be a math specific character. And since computer modern fonts didn't
961%D have an underscore, one had to use commands to fake one. Nowadays we do
962%D have underscores in latin modern, and since all other fonts have them, we
963%D decided to get away from the restriction to use the underscore character in
964%D text mode.
965%D
966%D \starttyping
967%D \def\test#1{#1}
968%D
969%D \nonknuthmode $x_2$ x_2 \test{$x_2$} \test{x_2}
970%D
971%D \donknuthmode $x_2$ x_2 \test{$x_2$} \test{x_2}
972%D \stoptyping
973%D
974%D The result is as expected: the first line typesets ok, while the second
975%D one triggers an error message.
976
977\setnewconstant\activemathcharcode "8000
978
979\newtoks\activatedmathcharacters
980
981\unexpanded\def\activatemathcharacter#1%
982  {\appendtoks
983     \global\mathcode#1=\activemathcharcode
984   \to \activatedmathcharacters}
985
986\def\activatemathcharacters
987  {\the\activatedmathcharacters}
988
989% beware, not runtime, so has to happen at format generation
990
991\activatemathcharacter\circumflexasciicode
992\activatemathcharacter\underscoreasciicode
993\activatemathcharacter\ampersandasciicode
994
995\appendtoks
996    \edef\p_ampersand{\mathematicsparameter\s!ampersand}%
997    \ifx\p_ampersand\v!normal
998        \let\specialmathaligntab\normalmathaligntab
999    \else
1000        \let\specialmathaligntab\mathampersand
1001    \fi
1002\to \everysetupmathematics
1003
1004%D \starttyping
1005%D \setupmathematics[ampersand=normal]
1006%D $\eqalign{a&=a'\cr}$
1007%D \stoptyping
1008
1009%D A simplified version of this code is:
1010%D
1011%D \starttyping
1012%D \catcode"26=12
1013%D
1014%D \bgroup
1015%D     \global\mathcode"26="8000
1016%D
1017%D     \catcode"26=4
1018%D
1019%D     \xdef\normalmathaligntab{&}
1020%D
1021%D     \catcode"26=13
1022%D
1023%D     \global\everymath{\def&{\normalmathaligntab}}
1024%D \egroup
1025%D \stoptyping
1026%D
1027%D The following works okay:
1028%D
1029%D \starttyping
1030%D A & B
1031%D \stoptyping
1032%D
1033%D As does:
1034%D
1035%D \starttyping
1036%D $A \Umathchar"2"0"26 B$
1037%D \stoptyping
1038%D
1039%D But the next code:
1040%D
1041%D \starttyping
1042%D $A \char"26 B$
1043%D \stoptyping
1044%D
1045%D fails with: \type{Misplaced alignment tab character &} and here is the
1046%D reason.
1047%D
1048%D When we have a letter or other category a check happens for an active
1049%D character and when it has one then it gets expanded and fed back into the
1050%D scanner (sort of).
1051%D
1052%D A \type {\char} is also fed back as raw character and again when it's letter
1053%D of other goes through the same process.
1054%D
1055%D This means that we cannot have a definition like:
1056%D
1057%D \starttyping
1058%D \def\AND{\char"26\relax}
1059%D \stoptyping
1060%D
1061%D that can be used in math mode, which is why the cweb macros do:
1062%D
1063%D \starttyping
1064%D \def\AND{\def\AND{\mathchar"2026\relax}\AND}
1065%D \stoptyping
1066%D
1067%D Maybe we need an option to treat chars like chars.
1068
1069% \activatemathcharacter\primeasciicode
1070
1071% not used:
1072%
1073% \mathcode\spaceasciicode\activemathcharcode
1074%
1075% not used:
1076%
1077% \bgroup
1078%     \catcode\underscoreasciicode\activecatcode
1079%     \doglobal\appendtoks
1080%         \mathcode\underscoreasciicode\activemathcharcode
1081%         \let_\activemathunderscore
1082%     \to \everymathematics
1083% \egroup
1084
1085% Here follows some plain legacy: primes.
1086%
1087% The \let\prime\math_prime_indeed might become an obsolete as we have \doubleprime
1088% and \tripleprime and collapsing can nicely handle the script then.
1089%
1090% Collapsing to 0x2033 and 0x2034 happens elsewhere.
1091%
1092% \switchtobodyfont[modern]
1093% \switchtobodyfont[cambria]
1094% \switchtobodyfont[xits]
1095% \switchtobodyfont[minion]
1096% \setupbodyfont[dejavu]
1097%
1098% \startbuffer
1099% \def\SampleLine#1{%
1100%    \NC#1
1101%    \NC\switchtobodyfont[#1]$f^2$                       %  1
1102%    \NC\switchtobodyfont[#1]$f\prime^2$                 %  2
1103%    \NC\switchtobodyfont[#1]$f\prime\prime^2$           %  3
1104%    \NC\switchtobodyfont[#1]$f\prime\prime\prime^2$     %  4
1105%    \NC\switchtobodyfont[#1]$f{\prime}^2$               %  5
1106%    \NC\switchtobodyfont[#1]$f{\prime\prime}^2$         %  6
1107%    \NC\switchtobodyfont[#1]$f{\prime\prime\prime}^2$   %  7
1108%    \NC\switchtobodyfont[#1]$f'(x)$                     %  8
1109%    \NC\switchtobodyfont[#1]$f''(x)$                    %  9
1110%    \NC\switchtobodyfont[#1]$f'''(x)$                   % 10
1111%    \NC\NR
1112% }
1113%
1114% \starttabulate[|Tl|Tc|Tc|Tc|Tc|Tc|Tc|Tc|Tc|Tc|Tc|]
1115%     \NC\NC1\NC2\NC3\NC4\NC5\NC6\NC7\NC8\NC9\NC10\NC\NR
1116%     \SampleLine{modern}
1117%     \SampleLine{cambria}
1118%     \SampleLine{xits}
1119%     \SampleLine{minion}
1120% \stoptabulate
1121% \stopbuffer
1122%
1123% \typebuffer \getbuffer
1124
1125% most math fonts have messed up primes, just test this: $\prime^{\prime^{\prime}}$
1126
1127{ \catcode\circumflexasciicode\othercatcode       \glet\othercircumflextoken      ^ }
1128{ \catcode\circumflexasciicode\superscriptcatcode \glet\superscriptcircumflextoken^ }
1129
1130\ifdefined \prime \else
1131    \Umathchardef\prime "0 "0 "2032
1132\fi
1133
1134% \let\math_prime_indeed_normal\prime
1135%
1136% \appendtoks
1137%     \let\math_prime_indeed_normal\prime    % gets defined later
1138%     \let\mathfontprime\prime               % for tracing
1139%     \let\prime\math_prime_indeed           % so this is needed
1140% \to \everydump
1141%
1142% \unexpanded\def\math_prime_indeed
1143%   {\iffontchar\textfont\zerocount"FE325\relax
1144%     ^\bgroup
1145%      \expandafter\math_prime_indeed_virtual % virtual mess (using funny signal)
1146%    \else
1147%    % \expandafter\math_prime_indeed_normal  % gets collapsed
1148%      \expandafter\math_prime_indeed_crapped  % gets collapsed
1149%    \fi}
1150%
1151% \def\math_prime_indeed_crapped
1152%   {{^{\math_prime_indeed_normal}}}
1153%
1154% % \let\prime\math_prime_indeed
1155%
1156% \def\math_prime_indeed_virtual
1157%   {\math_prime_indeed_normal
1158%    \futurelet\nexttoken\math_prime_indeed_choice}
1159%
1160% \installcorenamespace{mathprime}
1161%
1162% \def\math_prime_indeed_choice
1163%   {\csname\??mathprime
1164%      \ifx                          '\nexttoken a\else
1165%      \ifx  \math_prime_indeed_normal\nexttoken a\else
1166%      \ifx                     \prime\nexttoken a\else
1167%      \ifx\superscriptcircumflextoken\nexttoken b\else
1168%      \ifx\othercircumflextoken      \nexttoken b\else
1169%                                                c\fi\fi\fi\fi\fi
1170%    \endcsname}
1171%
1172% \setvalue{\??mathprime a}#1{\math_prime_indeed_virtual}
1173% \setvalue{\??mathprime b}#1#2{#2\egroup}
1174% \setvalue{\??mathprime c}{\egroup}
1175%
1176% \let\activemathprime\math_prime_indeed
1177%
1178% \bgroup
1179%
1180%     \catcode\primeasciicode\activecatcode
1181%
1182%     \global\everymathematics\expandafter{\the\everymathematics\let'\math_prime_indeed} % todo: do this at the lua end
1183%
1184% \egroup
1185
1186% $\char26$ gives an error because it expands to an active character that
1187% then becomes an & which is then seen as an alignment character; anyway,
1188% even when we switch like this the diufferen tmeaning only happens when
1189% we're in math mode which can be delayed till we're in a cell
1190
1191\bgroup
1192
1193    \catcode\underscoreasciicode\activecatcode
1194    \catcode\circumflexasciicode\activecatcode
1195    \catcode\ampersandasciicode \activecatcode
1196
1197    \glet\specialmathaligntab\normalmathaligntab
1198
1199    \unexpanded\gdef\obeymathcatcodes
1200      {\let _\normalsubscript
1201       \let ^\normalsuperscript
1202       \def &\specialmathaligntab
1203       }
1204
1205    \doglobal \appendtoks
1206        \let _\normalsubscript
1207        \let ^\normalsuperscript
1208        \let &\specialmathaligntab
1209   \to \everymathematics
1210
1211  % \unexpanded\gdef\normalmathampersands
1212  %   {\let\specialmathaligntab\mathampersand}
1213
1214\egroup
1215
1216\newtoks\everydonknuthmode
1217\newtoks\everynonknuthmode
1218
1219\newconditional \knuthmode
1220
1221\let\nonknuthmode\relax % no longer needed in MkIV
1222\let\donknuthmode\relax % no longer needed in MkIV
1223
1224% \def\nonknuthmode
1225%   {\pushcatcodetable
1226%    \setcatcodetable\ctxcatcodes
1227%    \the\everynonknuthmode
1228%    \let\nonknuthmode\relax
1229%    \popcatcodetable}
1230%
1231% \def\donknuthmode
1232%   {\pushcatcodetable
1233%    \setcatcodetable\ctxcatcodes
1234%    \the\everydonknuthmode
1235%    \popcatcodetable}
1236%
1237% \bgroup
1238%
1239%     \catcode\underscoreasciicode\activecatcode
1240%     \catcode\circumflexasciicode\activecatcode
1241%     \catcode\ampersandasciicode \activecatcode
1242%
1243%     \global \everynonknuthmode {\appendtoks
1244%         \let_\normalsubscript
1245%         \let^\normalsuperscript
1246%         \let&\normalmathaligntab % use \def when it's \aligntab
1247%     \to \everymathematics}
1248%
1249% \egroup
1250%
1251% \appendtoks
1252%     \setfalse\knuthmode
1253%     \catcode\underscoreasciicode\othercatcode
1254%     \catcode\circumflexasciicode\othercatcode
1255%     \catcode\ampersandasciicode \othercatcode
1256% \to \everynonknuthmode
1257%
1258% \appendtoks
1259%     \settrue\knuthmode
1260%     \catcode\underscoreasciicode\subscriptcatcode
1261%     \catcode\circumflexasciicode\superscriptcatcode
1262%     \catcode\ampersandasciicode \alignmentcatcode
1263% \to \everydonknuthmode
1264%
1265% \appendtoks
1266%     \startextendcatcodetable\ctxcatcodes
1267%         \catcode\underscoreasciicode\othercatcode
1268%         \catcode\circumflexasciicode\othercatcode
1269%         \catcode\ampersandasciicode \othercatcode
1270%     \stopextendcatcodetable
1271% \to \everynonknuthmode
1272%
1273% \appendtoks
1274%     \startextendcatcodetable\ctxcatcodes
1275%         \catcode\underscoreasciicode\subscriptcatcode
1276%         \catcode\circumflexasciicode\superscriptcatcode
1277%         \catcode\ampersandasciicode \alignmentcatcode
1278%     \stopextendcatcodetable
1279% \to \everydonknuthmode
1280
1281%D Even more drastic (this code will move as nonknuthmode is default now)
1282
1283% \unexpanded\def\enableasciimode
1284%   {\ctxlua{resolvers.macros.enablecomment()}%
1285%    \glet\enableasciimode\relax}
1286%
1287% \unexpanded\def\asciimode
1288%   {\catcodetable\txtcatcodes
1289%    \enableasciimode
1290%    \nonknuthmode}
1291%
1292% \unexpanded\def\startasciimode
1293%   {\pushcatcodetable
1294%    \catcodetable\txtcatcodes
1295%    \enableasciimode
1296%    \nonknuthmode}
1297%
1298% \unexpanded\def\stopasciimode
1299%   {\popcatcodetable
1300%    \ifconditional\knuthmode\else\donknuthmode\fi}
1301
1302\unexpanded\def\enableasciimode
1303  {\clf_enableasciimode} % relaxes itself
1304
1305\unexpanded\def\asciimode
1306  {\catcodetable\txtcatcodes
1307   \clf_enableasciimode}
1308
1309\unexpanded\def\startasciimode
1310  {\pushcatcodetable
1311   \catcodetable\txtcatcodes
1312   \clf_enableasciimode}
1313
1314\unexpanded\def\stopasciimode
1315  {\popcatcodetable}
1316
1317%D Needed for unicode:
1318
1319\def\nulloperator{\mathortext{\mathop{\emptyhbox}}{\emptyhbox}}
1320
1321%D Memory saver:
1322
1323\def\math_basics_check_compact
1324  {\doifelse{\mathematicsparameter\c!compact}\v!yes
1325     \enabledirectives\disabledirectives[math.virtual.optional]}
1326
1327\appendtoks
1328    \ifx\currentmathematics\empty
1329        \math_basics_check_compact % less tracing
1330    \fi
1331\to \everysetupmathematics
1332
1333\setupmathematics
1334  [\c!compact=\v!no]
1335
1336% \enabletrackers[typesetters.directions.math]
1337
1338%D Right||to||left typesetting in math is supported by the \type {align} parameter
1339%D with as option the \type {bidi} parameter. Of course support for special symbols
1340%D like square roots depends on the font as well. We probably need to mirror a few
1341%D more characters.
1342%D
1343%D \startbuffer
1344%D     \removeunwantedspaces
1345%D     \m{   (  1 =   1)   }\quad
1346%D     \m{   (123 = 123)   }\quad
1347%D     \m{ a (  1 =   1) b }\quad
1348%D     \m{ a (123 = 123) b }\quad
1349%D     \m{ x = 123 y + (1 / \sqrt {x}) }
1350%D \stopbuffer
1351%D
1352%D \typebuffer
1353%D
1354%D \starttabulate[|T|T||]
1355%D \HL
1356%D \NC align \NC bidi \NC                                                  \NC \NR
1357%D \HL
1358%D \NC l2r   \NC no   \NC \setupmathematics[bidi=no]            \getbuffer \NC \NR
1359%D \NC l2r   \NC yes  \NC \setupmathematics[bidi=yes]           \getbuffer \NC \NR
1360%D \NC r2l   \NC no   \NC \setupmathematics[align=r2l,bidi=no]  \getbuffer \NC \NR
1361%D \NC r2l   \NC yes  \NC \setupmathematics[align=r2l,bidi=yes] \getbuffer \NC \NR
1362%D \HL
1363%D \stoptabulate
1364
1365% We will use proper constants when we go numbers instead of XXX.
1366
1367\newconditional\c_math_right_to_left
1368
1369\installcorenamespace{mathaligndirection}
1370
1371\setvalue{\??mathaligndirection           r2l}{\settrue\c_math_right_to_left}
1372\setvalue{\??mathaligndirection\v!righttoleft}{\settrue\c_math_right_to_left}
1373
1374\appendtoks
1375    \ifcsname\??mathaligndirection\mathematicsparameter\c!align\endcsname
1376      \lastnamedcs
1377    \else
1378      \setfalse\c_math_right_to_left
1379    \fi
1380\to \everyswitchmathematics
1381
1382\unexpanded\def\math_basics_synchronize_direction
1383  {\mathdirection\ifconditional\c_math_right_to_left\directionrighttoleft\else\directionlefttoright\fi}
1384
1385% Not \everymathematics as it comes too late and I'm not in the mood for a mixed mode
1386% kludge now (should be a property of beginmath nodes and passed to callbacks).
1387
1388\appendtoks
1389    \math_basics_synchronize_direction
1390\to \everyswitchmathematics
1391
1392% experimental (needed for an article)
1393
1394\installcorenamespace {mathbidi}
1395
1396\newcount\c_math_bidi
1397
1398\def\math_bidi_enable {\clf_setmathdirection\plusone  \relax\c_math_bidi\plusone}
1399\def\math_bidi_disable{\clf_setmathdirection\zerocount\relax\c_math_bidi\attributeunsetvalue}
1400
1401\letvalue{\??mathbidi\v!yes}\math_bidi_enable
1402\letvalue{\??mathbidi\v!no }\math_bidi_disable
1403
1404\appendtoks
1405    \edef\p_bidi{\mathematicsparameter\c!bidi}% still needed ?
1406    \ifcsname\??mathbidi\p_bidi\endcsname\lastnamedcs\else\math_bidi_disable\fi
1407\to \everysetupmathematics
1408
1409\appendtoks
1410    \c_attr_mathbidi\ifconditional\c_math_right_to_left\c_math_bidi\else\attributeunsetvalue\fi
1411\to \everyswitchmathematics
1412
1413%D Delayed: greek.
1414%D
1415%D \starttyping
1416%D \usetypescript[cambria]\setupbodyfont[cambria]
1417%D \startTEXpage
1418%D     $\alpha \mathgreekupright \alpha \mathgreekitalic \alpha$
1419%D \stopTEXpage
1420%D \stoptyping
1421
1422% [lc uc] normal (upright) = 2, italic = 3, none = 0/1
1423
1424% We can move the setting to the lua end and use abstract numbers instead
1425% if funny ones here.
1426
1427\installcorenamespace{mathgreek}
1428
1429\newconstant\c_math_greek_attribute
1430
1431\setvalue{\??mathgreek\v!none  }{1}
1432\setvalue{\??mathgreek\v!normal}{2}
1433\setvalue{\??mathgreek\v!italic}{3}
1434
1435% \appendtoks
1436%     \edef\p_sygreek{\mathematicsparameter\s!sygreek}%
1437%     \edef\p_lcgreek{\mathematicsparameter\s!lcgreek}%
1438%     \edef\p_ucgreek{\mathematicsparameter\s!ucgreek}%
1439%     \c_math_greek_attribute"% hex digits
1440%       \csname\??mathgreek\ifcsname\??mathgreek\p_sygreek\endcsname\p_sygreek\else\v!none\fi\endcsname
1441%       \csname\??mathgreek\ifcsname\??mathgreek\p_lcgreek\endcsname\p_lcgreek\else\v!none\fi\endcsname
1442%       \csname\??mathgreek\ifcsname\??mathgreek\p_ucgreek\endcsname\p_ucgreek\else\v!none\fi\endcsname
1443%     \relax
1444%     \ifcase\c_math_greek_attribute
1445%       \c_math_greek_attribute\attributeunsetvalue
1446%     \fi
1447% \to \everyswitchmathematics
1448
1449\appendtoks
1450    \edef\p_sygreek{\mathematicsparameter\s!sygreek}% still needed ?
1451    \edef\p_lcgreek{\mathematicsparameter\s!lcgreek}% still needed ?
1452    \edef\p_ucgreek{\mathematicsparameter\s!ucgreek}% still needed ?
1453    \c_math_greek_attribute"% hex digits
1454      \ifcsname\??mathgreek\p_sygreek\endcsname\lastnamedcs\else1\fi
1455      \ifcsname\??mathgreek\p_lcgreek\endcsname\lastnamedcs\else1\fi
1456      \ifcsname\??mathgreek\p_ucgreek\endcsname\lastnamedcs\else1\fi
1457    \relax
1458    \ifcase\c_math_greek_attribute
1459      \c_math_greek_attribute\attributeunsetvalue
1460    \fi
1461\to \everyswitchmathematics
1462
1463% only used local
1464
1465\unexpanded\def\mathgreekupright{\c_attr_mathgreek"222\relax}
1466\unexpanded\def\mathgreekitalic {\c_attr_mathgreek"333\relax}
1467\unexpanded\def\mathgreekdefault{\c_attr_mathgreek"000\relax}
1468
1469\let\mathgreeknormal\mathgreekupright
1470\let\mathgreeknone  \mathgreekdefault
1471
1472\appendtoks
1473    \c_attr_mathgreek\c_math_greek_attribute
1474\to \everymathematics
1475
1476\setupmathematics
1477  [\s!sygreek=\v!normal,
1478   \s!lcgreek=\v!italic,
1479   \s!ucgreek=\v!normal] % was: none
1480
1481%D Math collapsing (ligatures)
1482
1483\installcorenamespace{mathcollapsing}
1484
1485\setnewconstant\c_math_collapsing_attribute\attributeunsetvalue
1486
1487\letvalue{\??mathcollapsing       1}\plusone              % specials
1488\letvalue{\??mathcollapsing       2}\plustwo              % specials + mathlist
1489\letvalue{\??mathcollapsing       3}\plusthree            % mathlist + specials
1490\letvalue{\??mathcollapsing\v!none }\attributeunsetvalue
1491\letvalue{\??mathcollapsing\v!reset}\attributeunsetvalue
1492
1493\def\math_collapsing_initialize
1494  {\ifnum\c_math_collapsing_attribute=\attributeunsetvalue \else
1495     \clf_initializemathcollapsing % one time
1496     \glet\math_collapsing_initialize\relax
1497   \fi}
1498
1499\appendtoks
1500    \edef\p_collapsing{\mathematicsparameter\s!collapsing}%
1501    \c_math_collapsing_attribute
1502        \ifcsname\??mathcollapsing\p_collapsing\endcsname\lastnamedcs\else\attributeunsetvalue\fi
1503    \relax
1504\to \everyswitchmathematics % only in mathematics
1505
1506\appendtoks
1507    \math_collapsing_initialize
1508    \c_attr_mathcollapsing\c_math_collapsing_attribute
1509\to \everymathematics
1510
1511\setupmathematics
1512  [\s!collapsing=1] % so that we at least do primes
1513
1514%D Math italics (experiment)
1515
1516%D We need keys but what names to use and because we have hardcoded solution
1517%D we can stick to numbers.
1518
1519\installcorenamespace{mathitalics}
1520
1521\setnewconstant\c_math_italics_attribute\attributeunsetvalue
1522
1523\letvalue{\??mathitalics       1}\plusone              % fontitalics
1524\letvalue{\??mathitalics       2}\plustwo              % fontdata
1525\letvalue{\??mathitalics       3}\plusthree            % quad based
1526\letvalue{\??mathitalics       4}\plusfour             % combination of 1 and 3
1527\letvalue{\??mathitalics\v!none }\attributeunsetvalue
1528\letvalue{\??mathitalics\v!reset}\attributeunsetvalue
1529
1530\def\math_italics_initialize
1531  {\ifnum\c_math_italics_attribute=\attributeunsetvalue \else
1532     \clf_initializemathitalics % one time
1533     \glet\math_italics_initialize\relax
1534   \fi}
1535
1536\appendtoks
1537    \edef\p_italics{\mathematicsparameter\s!italics}%
1538    \c_math_italics_attribute
1539        \ifcsname\??mathitalics\p_italics\endcsname\lastnamedcs\else\attributeunsetvalue\fi
1540    \relax
1541  % \math_italics_initialize
1542\to \everyswitchmathematics % only in mathematics
1543
1544\appendtoks
1545    \math_italics_initialize
1546    \c_attr_mathitalics\c_math_italics_attribute
1547\to \everymathematics
1548
1549% \setupmathematics % done later
1550%   [\s!italics=3] % 4 is probably better
1551
1552% looks nicer but can generate bogus csnames
1553%
1554% \setvalue{\??mathitalics1}{\math_italics_initialize\c_math_italics_attribute\plusone  } % fontitalics
1555% \setvalue{\??mathitalics2}{\math_italics_initialize\c_math_italics_attribute\plustwo  } % fontdata
1556% \setvalue{\??mathitalics3}{\math_italics_initialize\c_math_italics_attribute\plusthree} % quad based
1557% \setvalue{\??mathitalics4}{\math_italics_initialize\c_math_italics_attribute\plusfour } % combination of 1 and 3
1558%
1559% \appendtoks
1560%     \c_math_italics_attribute\attributeunsetvalue
1561%     \csname\??mathitalics\mathematicsparameter\s!italics\endcsname
1562% \to \everyswitchmathematics % only in mathematics
1563
1564%D Math kerns (experiment)
1565
1566\installcorenamespace{mathkernpairs}
1567
1568\setnewconstant\c_math_kernpairs_attribute\attributeunsetvalue % no real need for an extra constant
1569
1570\def\math_kernpairs_initialize
1571  {\ifnum\c_math_kernpairs_attribute=\attributeunsetvalue \else
1572     \clf_initializemathkernpairs % one time
1573     \glet\math_kernpairs_initialize\relax
1574   \fi}
1575
1576\appendtoks
1577    \edef\p_kernpairs{\mathematicsparameter\s!kernpairs}%
1578    \c_math_kernpairs_attribute\ifx\p_kernpairs\v!yes\plusone\else\attributeunsetvalue\fi\relax
1579\to \everyswitchmathematics % only in mathematics
1580
1581\appendtoks
1582    \math_kernpairs_initialize
1583    \c_attr_mathkernpairs\c_math_kernpairs_attribute
1584\to \everymathematics
1585
1586\setupmathematics
1587  [\s!kernpairs=\v!no]
1588
1589%D \macros
1590%D   {enablemathpunctuation,disablemathpunctuation}
1591%D
1592%D \startbuffer
1593%D \enablemathpunctuation$(1,2) (1, 2) (1{,}2) \hbox{foo, not bar}$
1594%D \stopbuffer
1595%D
1596%D \typebuffer
1597%D
1598%D \blank{\getbuffer}\blank
1599
1600% \newconditional\automathpunctuation
1601%
1602% \unexpanded\def\enablemathpunctuation {\settrue \automathpunctuation}
1603% \unexpanded\def\disablemathpunctuation{\setfalse\automathpunctuation}
1604%
1605% \appendtoks
1606%     \doifelse{\mathematicsparameter\c!autopunctuation}\v!yes\settrue\setfalse\automathpunctuation
1607% \to \everyswitchmathematics
1608%
1609% \setupmathematics
1610%   [\c!autopunctuation=\v!no]
1611%
1612% \def\math_punctuation_next{\ifx\nexttoken\blankspace\signalcharacter\fi}
1613%
1614% \unexpanded\def\math_punctuation_comma {\textcomma \futurelet\nexttoken\math_punctuation_next}
1615% \unexpanded\def\math_punctuation_period{\textperiod\futurelet\nexttoken\math_punctuation_next}
1616%
1617% \setnewconstant\c_math_comma  "002C
1618% \setnewconstant\c_math_period "002E
1619% \setnewconstant\c_math_special"8000
1620%
1621% \bgroup
1622%
1623%     \catcode\c_math_comma \activecatcode
1624%     \catcode\c_math_period\activecatcode
1625%
1626%     \unexpanded\gdef\math_punctuation_initialize_indeed
1627%       {\mathcode\c_math_comma \c_math_special
1628%        \mathcode\c_math_period\c_math_special
1629%        \let,\math_punctuation_comma
1630%        \let.\math_punctuation_period
1631%        \c_attr_mathpunctuation\plustwo}
1632%
1633%     \unexpanded\gdef\math_punctuation_initialize_yes
1634%       {\c_attr_mathpunctuation\plustwo}
1635%
1636%     \unexpanded\gdef\math_punctuation_initialize_nop
1637%       {\c_attr_mathpunctuation\plusone}
1638%
1639% \egroup
1640%
1641% \appendtoks
1642%     \ifconditional\automathpunctuation
1643%       \math_punctuation_initialize_indeed
1644%       \math_punctuation_initialize_yes
1645%       \let\enablemathpunctuation \math_punctuation_initialize_yes
1646%       \let\disablemathpunctuation\math_punctuation_initialize_nop
1647%     \fi
1648% \to \everymathematics
1649
1650% Later I will look again into a \LUATEX\ based solution. It only makes sense
1651% to delegate to \LUA\ when we have more variants and need analysis (experimental
1652% trickery removed for a while).
1653
1654% \def\math_punctuation_comma_next {\ifx\nexttoken\blankspace\mathpunct\else\mathord\fi{\textcomma }}
1655% \def\math_punctuation_period_next{\ifx\nexttoken\blankspace\mathpunct\else\mathord\fi{\textperiod}}
1656%
1657% \unexpanded\def\math_punctuation_nop_comma {\mathpunct{\textcomma}}
1658% \unexpanded\def\math_punctuation_nop_period{\mathord{\textperiod}}
1659%
1660% \unexpanded\def\math_punctuation_all_comma {\futurelet\nexttoken\math_punctuation_comma_next}
1661% \unexpanded\def\math_punctuation_all_period{\futurelet\nexttoken\math_punctuation_period_next}
1662%
1663%            \let\math_punctuation_yes_comma \math_punctuation_all_comma
1664%            \let\math_punctuation_yes_period\math_punctuation_nop_period
1665%
1666% The next one is more efficient as it produces more flat noad lists for numbers.
1667
1668\setnewconstant\c_math_comma    "002C
1669\setnewconstant\c_math_period   "002E
1670%setnewconstant\c_math_colon    "003A
1671\setnewconstant\c_math_semicolon"003B
1672\setnewconstant\c_math_special  "8000
1673
1674\def\math_set_o_comma    {\Umathcode\c_math_comma    \mathordcode  \zerocount\c_math_comma}
1675\def\math_set_p_comma    {\Umathcode\c_math_comma    \mathpunctcode\zerocount\c_math_comma}
1676\def\math_set_o_period   {\Umathcode\c_math_period   \mathordcode  \zerocount\c_math_period}
1677\def\math_set_p_period   {\Umathcode\c_math_period   \mathpunctcode\zerocount\c_math_period}
1678\def\math_set_o_semicolon{\Umathcode\c_math_semicolon\mathordcode  \zerocount\c_math_semicolon}
1679\def\math_set_p_semicolon{\Umathcode\c_math_semicolon\mathpunctcode\zerocount\c_math_semicolon}
1680
1681\edef\math_set_o_both {\math_set_o_period\math_set_o_comma}
1682\edef\math_set_p_both {\math_set_p_period\math_set_p_comma}
1683
1684\unexpanded\def\math_punctuation_nop_comma    {\begingroup\math_set_p_comma    ,\endgroup}
1685\unexpanded\def\math_punctuation_nop_period   {\begingroup\math_set_o_period   .\endgroup}
1686\unexpanded\def\math_punctuation_nop_semicolon{\begingroup\math_set_p_semicolon;\endgroup}
1687
1688\unexpanded\def\math_punctuation_all_comma    {\futurelet\nexttoken\math_punctuation_comma_next}
1689\unexpanded\def\math_punctuation_all_period   {\futurelet\nexttoken\math_punctuation_period_next}
1690\unexpanded\def\math_punctuation_all_semicolon{\futurelet\nexttoken\math_punctuation_semicolon_next}
1691
1692           \let\math_punctuation_yes_comma    \math_punctuation_all_comma
1693           \let\math_punctuation_yes_period   \math_punctuation_nop_period
1694           \let\math_punctuation_yes_semicolon\math_punctuation_all_semicolon
1695
1696\def\math_punctuation_comma_next    {\begingroup\Umathcode\c_math_comma    \ifx\nexttoken\blankspace\mathpunctcode\else\mathordcode\fi\zerocount\c_math_comma    ,\endgroup}
1697\def\math_punctuation_period_next   {\begingroup\Umathcode\c_math_period   \ifx\nexttoken\blankspace\mathpunctcode\else\mathordcode\fi\zerocount\c_math_period   .\endgroup}
1698\def\math_punctuation_semicolon_next{\begingroup\Umathcode\c_math_semicolon\ifx\nexttoken\blankspace\mathpunctcode\else\mathordcode\fi\zerocount\c_math_semicolon;\endgroup}
1699
1700\installcorenamespace {mathautopunctuation}
1701
1702\bgroup
1703
1704    \catcode\c_math_comma    \activecatcode
1705    \catcode\c_math_period   \activecatcode
1706    \catcode\c_math_semicolon\activecatcode
1707
1708    \setgvalue{\??mathautopunctuation\v!no}%
1709      {\let,\math_punctuation_nop_comma
1710       \let.\math_punctuation_nop_period
1711       \let;\math_punctuation_nop_semicolon}
1712
1713  %  more efficient list:
1714  %
1715  %  \setgvalue{\??mathautopunctuation\v!no}%
1716  %    {\Umathcode\c_math_period\mathordcode  \zerocount\c_math_period
1717  %     \Umathcode\c_math_comma \mathpunctcode\zerocount\c_math_comma }
1718
1719    \setgvalue{\??mathautopunctuation\v!yes}%
1720      {\let,\math_punctuation_yes_comma
1721       \let.\math_punctuation_yes_period
1722       \let;\math_punctuation_nop_semicolon}
1723
1724    \setgvalue{\??mathautopunctuation\v!all}%
1725      {\let,\math_punctuation_all_comma
1726       \let.\math_punctuation_all_period
1727       \let;\math_punctuation_nop_semicolon}
1728
1729    \setgvalue{\??mathautopunctuation comma}%
1730      {\let,\math_punctuation_yes_comma
1731       \let.\math_punctuation_yes_period
1732       \let;\math_punctuation_nop_semicolon}
1733
1734    \setgvalue{\??mathautopunctuation\v!yes\string,semicolon}%
1735      {\let,\math_punctuation_yes_comma
1736       \let.\math_punctuation_yes_period
1737       \let;\math_punctuation_yes_semicolon}
1738
1739    \setgvalue{\??mathautopunctuation comma\string,semicolon}%
1740      {\let,\math_punctuation_yes_comma
1741       \let.\math_punctuation_yes_period
1742       \let;\math_punctuation_yes_semicolon}
1743
1744    \setgvalue{\??mathautopunctuation\v!all\string,semicolon}%
1745      {\let,\math_punctuation_all_comma
1746       \let.\math_punctuation_all_period
1747       \let;\math_punctuation_all_semicolon}
1748
1749\egroup
1750
1751% \appendtoks
1752%     \global\mathcode\c_math_comma    \c_math_special
1753%     \global\mathcode\c_math_period   \c_math_special
1754%     \global\mathcode\c_math_semicolon\c_math_special
1755% \to \everyjob
1756
1757% \activatemathcharacter\c_math_comma
1758% \activatemathcharacter\c_math_period
1759% \activatemathcharacter\c_math_semicolon
1760
1761\appendtoks
1762    \mathcode\c_math_comma    \c_math_special
1763    \mathcode\c_math_period   \c_math_special
1764    \mathcode\c_math_semicolon\c_math_special
1765    \begincsname\??mathautopunctuation\mathematicsparameter\c!autopunctuation\endcsname
1766\to \everymathematics
1767
1768\appendtoks
1769    \ifcsname\??mathautopunctuation\mathematicsparameter\c!autopunctuation\endcsname \else
1770        \letmathematicsparameter\c!autopunctuation\v!no
1771    \fi
1772\to \everysetupmathematics
1773
1774\def\enablemathpunctuation {\csname\??mathautopunctuation\v!no \endcsname}
1775\def\disablemathpunctuation{\csname\??mathautopunctuation\v!yes\endcsname}
1776
1777\setupmathematics
1778  [\c!autopunctuation=\v!no] % no | yes | all | comma | yes,semicolon | all,semicolon
1779
1780%D The consequences of setting this are as follows:
1781%D
1782%D \def\TestA#1#2#3%
1783%D   {\ifnum#1=0 \type{#2}\else\setupmathematics[autopunctuation={#2}]$#3$\fi}
1784%D \def\TestB#1#2%
1785%D   {\NC \TestA{#1}{no}           {#2}
1786%D    \NC \TestA{#1}{yes}          {#2}
1787%D    \NC \TestA{#1}{yes,semicolon}{#2}
1788%D    \NC \TestA{#1}{all}          {#2}
1789%D    \NC \TestA{#1}{all,semicolon}{#2}
1790%D    \NC \NR}
1791%D \starttabulate[|c|c|c|c|c|]
1792%D     \TestB{0}{}
1793%D     \TestB{1}{(1,2)=(1, 2)}
1794%D     \TestB{1}{(1.2)=(1. 2)}
1795%D     \TestB{1}{(1;2)=(1; 2)}
1796%D \stoptabulate
1797
1798%D \macros
1799%D   {mathstyle}
1800%D
1801%D If one want to be sure that something is typeset in the appropriate style, \type
1802%D {\mathstyle} can be used:
1803%D
1804%D \starttyping
1805%D \mathstyle{something}
1806%D \stoptyping
1807
1808% \def\mathstyle#1%
1809%   {\mathchoice
1810%      {\displaystyle     #1}%
1811%      {\textstyle        #1}%
1812%      {\scriptstyle      #1}%
1813%      {\scriptscriptstyle#1}}
1814%
1815% We now have a primitive operation for this. As the macro overloads a new
1816% primitive introduced in \LUATEX, we need to use \type {\normalmathstyle} when we
1817% consult the current math style.
1818%
1819% \let \mathstyle \Ustack % spoils cramped
1820%
1821% \let \mathstyle \firstofoneargument
1822%
1823% 0 = display
1824% 1 = crampeddisplay
1825% 2 = text
1826% 3 = crampedtext
1827% 4 = script
1828% 5 = crampedscript
1829% 6 = scriptscript
1830% 7 = crampedscriptscript
1831
1832\def\uncramped#1%
1833  {{\ifcase\normalmathstyle
1834    \or \displaystyle      \or
1835    \or \textstyle         \or
1836    \or \scriptstyle       \or
1837    \or \scriptscriptstyle \fi
1838    #1}}
1839
1840\def\cramped#1%
1841  {{\ifcase\normalmathstyle
1842    \crampeddisplaystyle      \or \or % 0 -> 1
1843    \crampedtextstyle         \or \or % 2 -> 3
1844    \crampedscriptstyle       \or \or % 4 -> 5
1845    \crampedscriptscriptstyle \fi     % 6 -> 7
1846    #1}}
1847
1848\def\triggermathstyle#1% #1 is number
1849  {\ifcase\numexpr#1\relax
1850     \displaystyle             \or % 0
1851     \crampeddisplaystyle      \or % 1
1852     \textstyle                \or % 2
1853     \crampedtextstyle         \or % 3
1854     \scriptstyle              \or % 4
1855     \crampedscriptstyle       \or % 5
1856     \scriptscriptstyle        \or % 6
1857     \crampedscriptscriptstyle \else
1858     % error
1859   \fi}
1860
1861\let\mathstyletrigger\triggermathstyle
1862
1863\def\triggeredmathstyleparameter#1% to bypass the relax
1864  {\ifcase\numexpr\normalmathstyle\relax
1865     #1\displaystyle             \or % 0
1866     #1\crampeddisplaystyle      \or % 1
1867     #1\textstyle                \or % 2
1868     #1\crampedtextstyle         \or % 3
1869     #1\scriptstyle              \or % 4
1870     #1\crampedscriptstyle       \or % 5
1871     #1\scriptscriptstyle        \or % 6
1872     #1\crampedscriptscriptstyle \else
1873     % error
1874   \fi}
1875
1876\def\mathstylefont#1% #1 is number (\normalmathstyle)
1877  {\ifcase\numexpr#1\relax
1878     \textfont         \or
1879     \textfont         \or
1880     \textfont         \or
1881     \textfont         \or
1882     \scriptfont       \or
1883     \scriptfont       \or
1884     \scriptscriptfont \or
1885     \scriptscriptfont \else
1886     \textfont
1887   \fi\fam} % was \zerocount
1888
1889\def\somemathstylefont#1% #1 is number (\normalmathstyle)
1890  {\ifcase\numexpr#1\relax
1891     \textfont         \or
1892     \textfont         \or
1893     \textfont         \or
1894     \textfont         \or
1895     \scriptfont       \or
1896     \scriptfont       \or
1897     \scriptscriptfont \or
1898     \scriptscriptfont \else
1899     \textfont
1900   \fi}
1901
1902\def\mathsmallstylefont#1% #1 is number (\normalmathstyle)
1903  {\ifcase\numexpr#1\relax
1904     \scriptfont       \or
1905     \scriptfont       \or
1906     \scriptfont       \or
1907     \scriptfont       \or
1908     \scriptscriptfont \or
1909     \scriptscriptfont \or
1910     \scriptscriptfont \or
1911     \scriptscriptfont \else
1912     \scriptfont
1913   \fi\fam} % was \zerocount
1914
1915\def\mathstyleface#1% #1 is number (\normalmathstyle)
1916  {\ifcase\numexpr#1\relax
1917     \textface         \or
1918     \textface         \or
1919     \textface         \or
1920     \textface         \or
1921     \scriptface       \or
1922     \scriptface       \or
1923     \scriptscriptface \or
1924     \scriptscriptface \else
1925     \textface
1926   \fi}
1927
1928\def\mathsmallstyleface#1% #1 is number (\normalmathstyle)
1929  {\ifcase\numexpr#1\relax
1930     \scriptface       \or
1931     \scriptface       \or
1932     \scriptface       \or
1933     \scriptface       \or
1934     \scriptscriptface \or
1935     \scriptscriptface \or
1936     \scriptscriptface \or
1937     \scriptscriptface \else
1938     \scriptface
1939   \fi}
1940
1941\def\mathstylecommand#1#2#3%
1942  {\ifcase\numexpr\normalmathstyle\relax
1943     \expandafter#1\or
1944     \expandafter#1\or
1945     \expandafter#1\or
1946     \expandafter#1\or
1947     \expandafter#2\or
1948     \expandafter#2\or
1949     \expandafter#3\or
1950     \expandafter#3\else
1951     \expandafter#1\fi}
1952
1953% \def\textstyleface#1% #1 is number (\normalmathstyle)
1954%   {\ifcase\numexpr#1\relax
1955%      \tf   \or
1956%      \tf   \or
1957%      \tf   \or
1958%      \tf   \or
1959%      \tfx  \or
1960%      \tfx  \or
1961%      \tfxx \or
1962%      \tfxx \else
1963%      \tf
1964%    \fi}
1965
1966\unexpanded\def\verbosemathstyle#1% #1 is number (\normalmathstyle)
1967  {{\normalexpanded{\relax\darkgray\ttxx[\number#1:\ifcase\numexpr#1\relax
1968                display\or   % 0
1969         crampeddisplay\or   % 1
1970                   text\or   % 2
1971            crampedtext\or   % 3
1972                 script\or   % 4
1973          crampedscript\or   % 5
1974           scriptscript\or   % 6
1975    crampedscriptscript\else % 7
1976                unknown\fi]}}}
1977
1978\unexpanded\def\showmathstyle{\verbosemathstyle\normalmathstyle}
1979
1980%D Handy too:
1981
1982\def\mathcharwd{\fontcharwd\mathstylefont\normalmathstyle}
1983\def\mathcharht{\fontcharht\mathstylefont\normalmathstyle}
1984\def\mathchardp{\fontchardp\mathstylefont\normalmathstyle}
1985
1986%D Some dimension fun:
1987
1988\def\mathexheight
1989  {\fontdimen
1990     \plusfive
1991     \ifcase\numexpr\normalmathstyle\relax
1992       \textfont         \or % 0
1993       \textfont         \or % 1
1994       \textfont         \or % 2
1995       \textfont         \or % 3
1996       \scriptfont       \or % 4
1997       \scriptfont       \or % 5
1998       \scriptscriptfont \or % 6
1999       \scriptscriptfont \else
2000       \textfont
2001     \fi
2002     \zerocount}
2003
2004\def\mathemwidth
2005  {\fontdimen
2006     \plussix
2007     \ifcase\numexpr\normalmathstyle\relax
2008       \textfont         \or % 0
2009       \textfont         \or % 1
2010       \textfont         \or % 2
2011       \textfont         \or % 3
2012       \scriptfont       \or % 4
2013       \scriptfont       \or % 5
2014       \scriptscriptfont \or % 6
2015       \scriptscriptfont \else
2016       \textfont
2017     \fi
2018     \zerocount}
2019
2020%D A plain inheritance:
2021
2022\def\mathpalette#1#2%
2023  {\mathchoice
2024     {#1\displaystyle     {#2}}%
2025     {#1\textstyle        {#2}}%
2026     {#1\scriptstyle      {#2}}%
2027     {#1\scriptscriptstyle{#2}}}
2028
2029%D Often we can use:
2030%D
2031%D \startbuffer
2032%D $x^{\mathstylehbox{x^{\mathstylehbox{x}}}}$
2033%D \stopbuffer
2034%D
2035%D \typebuffer \getbuffer
2036
2037% to be tested: {#1} but it could have side effects
2038
2039% \unexpanded\def\mathstylehbox#1% sensitive for: a \over b => {a\over b} or \frac{a}{b}
2040%   {\normalexpanded{\hbox\bgroup
2041%      \startimath\triggermathstyle\normalmathstyle}\mathsurround\zeropoint#1\stopimath\egroup}
2042
2043\unexpanded\def\mathstylehbox#1#% sensitive for: a \over b => {a\over b} or \frac{a}{b}
2044  {\math_style_hbox{#1}}
2045
2046\unexpanded\def\math_style_hbox#1#2% sensitive for: a \over b => {a\over b} or \frac{a}{b}
2047  {\normalexpanded{\hbox#1\bgroup
2048     \startimath\triggermathstyle\normalmathstyle}\mathsurround\zeropoint#2\stopimath\egroup}
2049
2050\unexpanded\def\mathstylevbox#1%
2051  {\normalexpanded{\vbox\bgroup
2052     \startimath\triggermathstyle\normalmathstyle}\mathsurround\zeropoint#1\stopimath\egroup}
2053
2054\unexpanded\def\mathstylevcenter#1%
2055  {\normalexpanded{\vcenter\bgroup
2056     \startimath\triggermathstyle\normalmathstyle}\mathsurround\zeropoint#1\stopimath\egroup}
2057
2058\unexpanded\def\mathstylevcenteredhbox#1%
2059  {\normalexpanded{\vcenter\bgroup\hbox\bgroup
2060     \startimath\triggermathstyle\normalmathstyle}\mathsurround\zeropoint#1\stopimath\egroup\egroup}
2061
2062\unexpanded\def\mathstylevcenteredvbox#1%
2063  {\normalexpanded{\vcenter\bgroup\vbox\bgroup
2064     \startimath\triggermathstyle\normalmathstyle}\mathsurround\zeropoint#1\stopimath\egroup\egroup}
2065
2066\unexpanded\def\setmathsmalltextbox#1#2#%
2067  {\normalizebodyfontsize\m_math_text_choice_face{\mathsmallstyleface\normalmathstyle}%
2068   \setbox#1#2\bgroup
2069     \font_basics_switchtobodyfont\m_math_text_choice_face
2070     \let\next}
2071
2072\unexpanded\def\setmathtextbox#1#2#%
2073  {\normalizebodyfontsize\m_math_text_choice_face{\mathstyleface\normalmathstyle}%
2074   \setbox#1#2\bgroup
2075     \font_basics_switchtobodyfont\m_math_text_choice_face
2076     \let\next}
2077
2078%D Here is the new mechanism ... it might replace some of the above but we will do
2079%D that stepwise. Keep in mind that cramped only affects superscripts and even then,
2080%D only when in a smaller size than normal.
2081%D
2082%D \def\TestMe#1%
2083%D   {\NC \ttbf #1
2084%D    \NC \ruledhbox{$\setupmathstyle[#1]x + x_j^2 + x_i^{e^2} + \frac{1}{x}$}
2085%D    \NC \ruledhbox{$\setupmathstyle[#1,small]x + x_j^2 + x_i^{e^2} + \frac{1}{x}$}
2086%D    \NC \NR}
2087%D
2088%D \starttabulate[|l|r|l|]
2089%D \HL
2090%D \NC \NC \NC \ttbf ...,small \NC \NR
2091%D \HL
2092%D \TestMe{text}         \TestMe{text,cramped}
2093%D \TestMe{script}       \TestMe{script,cramped}
2094%D \TestMe{scriptscript} \TestMe{scriptscript,cramped}
2095%D \TestMe{display}      \TestMe{display,cramped}
2096%D \HL
2097%D \stoptabulate
2098
2099\def\triggerdisplaystyle
2100  {\ifcase\normalmathstyle\relax
2101     \displaystyle        \or
2102     \crampeddisplaystyle \or
2103     \displaystyle        \or
2104     \crampeddisplaystyle \or
2105     \displaystyle        \or
2106     \crampeddisplaystyle \or
2107     \displaystyle        \or
2108     \crampeddisplaystyle \or
2109   \fi}
2110
2111\def\triggertextstyle
2112  {\ifcase\normalmathstyle\relax
2113     \textstyle        \or
2114     \crampedtextstyle \or
2115     \textstyle        \or
2116     \crampedtextstyle \or
2117     \textstyle        \or
2118     \crampedtextstyle \or
2119     \textstyle        \or
2120     \crampedtextstyle \else
2121   \fi}
2122
2123\def\triggerscriptstyle
2124  {\ifcase\normalmathstyle\relax
2125     \scriptstyle        \or
2126     \crampedscriptstyle \or
2127     \scriptstyle        \or
2128     \crampedscriptstyle \or
2129     \scriptstyle        \or
2130     \crampedscriptstyle \or
2131     \scriptstyle        \or
2132     \crampedscriptstyle \or
2133   \fi}
2134
2135\def\triggerscriptscriptstyle
2136  {\ifcase\normalmathstyle\relax
2137     \scriptscriptstyle        \or
2138     \crampedscriptscriptstyle \or
2139     \scriptscriptstyle        \or
2140     \crampedscriptscriptstyle \or
2141     \scriptscriptstyle        \or
2142     \crampedscriptscriptstyle \or
2143     \scriptscriptstyle        \or
2144     \crampedscriptscriptstyle \or
2145   \fi}
2146
2147\def\triggeruncrampedstyle
2148  {\ifcase\normalmathstyle\relax
2149    \or \displaystyle      \or
2150    \or \textstyle         \or
2151    \or \scriptstyle       \or
2152    \or \scriptscriptstyle \fi}
2153
2154\def\triggercrampedstyle
2155  {\ifcase\normalmathstyle\relax
2156   \crampeddisplaystyle      \or \or
2157   \crampedtextstyle         \or \or
2158   \crampedscriptstyle       \or \or
2159   \crampedscriptscriptstyle \fi}
2160
2161\def\triggersmallstyle
2162  {\ifcase\normalmathstyle\relax
2163     \scriptstyle              \or
2164     \crampedscriptstyle       \or
2165     \scriptstyle              \or
2166     \crampedscriptstyle       \or
2167     \scriptscriptstyle        \or
2168     \crampedscriptscriptstyle \or
2169     \scriptscriptstyle        \or
2170     \crampedscriptscriptstyle \or
2171    \fi}
2172
2173\def\triggeruncrampedsmallstyle
2174  {\ifcase\normalmathstyle\relax
2175     \scriptstyle       \or
2176     \scriptstyle       \or
2177     \scriptstyle       \or
2178     \scriptstyle       \or
2179     \scriptscriptstyle \or
2180     \scriptscriptstyle \or
2181     \scriptscriptstyle \or
2182     \scriptscriptstyle \or
2183    \fi}
2184
2185\def\triggercrampedsmallstyle
2186  {\ifcase\normalmathstyle\relax
2187     \crampedscriptstyle       \or
2188     \crampedscriptstyle       \or
2189     \crampedscriptstyle       \or
2190     \crampedscriptstyle       \or
2191     \crampedscriptscriptstyle \or
2192     \crampedscriptscriptstyle \or
2193     \crampedscriptscriptstyle \or
2194     \crampedscriptscriptstyle \or
2195    \fi}
2196
2197\def\triggerbigstyle
2198  {\ifcase\normalmathstyle\relax
2199     \displaystyle        \or
2200     \crampeddisplaystyle \or
2201     \textstyle           \or
2202     \crampedtextstyle    \or
2203     \textstyle           \or
2204     \crampedtextstyle    \or
2205     \scriptstyle         \or
2206     \crampedscriptstyle  \or
2207    \fi}
2208
2209\def\triggeruncrampedbigstyle
2210  {\ifcase\normalmathstyle\relax
2211     \displaystyle \or
2212     \displaystyle \or
2213     \textstyle    \or
2214     \textstyle    \or
2215     \textstyle    \or
2216     \textstyle    \or
2217     \scriptstyle  \or
2218     \scriptstyle  \or
2219    \fi}
2220
2221\def\triggercrampedbigstyle
2222  {\ifcase\normalmathstyle\relax
2223     \crampeddisplaystyle \or
2224     \crampeddisplaystyle \or
2225     \crampedtextstyle    \or
2226     \crampedtextstyle    \or
2227     \crampedtextstyle    \or
2228     \crampedtextstyle    \or
2229     \crampedscriptstyle  \or
2230     \crampedscriptstyle  \or
2231    \fi}
2232
2233\newcount\c_math_saved_style
2234
2235\unexpanded\def\pushmathstyle % assumes begingroup .. endgroup
2236  {\c_math_saved_style\mathstyle}
2237
2238\unexpanded\def\popmathstyle
2239  {\ifnum\mathstyle=\c_math_saved_style\else
2240     \triggermathstyle\c_math_saved_style
2241   \fi}
2242
2243\installcorenamespace{mathstylecommand}
2244\installcorenamespace{mathstylecache}
2245
2246\newconstant\c_math_styles_state_style
2247\newconstant\c_math_styles_state_cramped
2248\newconstant\c_math_styles_state_size
2249
2250\def\math_style_add_to_cache_choice {%
2251  \ifcase\c_math_styles_state_size
2252    \ifcase\c_math_styles_state_style
2253        \ifcase\c_math_styles_state_cramped
2254        \relax                               \or
2255        \noexpand\triggeruncrampedstyle      \or
2256        \noexpand\triggercrampedstyle        \fi
2257    \or\ifcase\c_math_styles_state_cramped
2258        \noexpand\triggerdisplaystyle        \or
2259        \displaystyle                        \or
2260        \crampeddisplaystyle                 \fi
2261    \or\ifcase\c_math_styles_state_cramped
2262        \noexpand\triggertextstyle           \or
2263        \textstyle                           \or
2264        \crampedtextstyle                    \fi
2265    \or\ifcase\c_math_styles_state_cramped
2266        \noexpand\triggerscriptstyle         \or
2267        \scriptstyle                         \or
2268        \crampedscriptstyle                  \fi
2269    \or\ifcase\c_math_styles_state_cramped
2270        \noexpand\triggerscriptscriptstyle   \or
2271        \scriptscriptstyle                   \or
2272        \crampedscriptscriptstyle            \fi
2273    \fi
2274  \or % small
2275    \ifcase\c_math_styles_state_style
2276        \ifcase\c_math_styles_state_cramped
2277        \noexpand\triggersmallstyle          \or
2278        \noexpand\triggeruncrampedsmallstyle \or
2279        \noexpand\triggercrampedsmallstyle   \fi
2280    \or\ifcase\c_math_styles_state_cramped
2281        \noexpand\triggerscriptstyle         \or
2282        \scriptstyle                         \or
2283        \crampedscriptstyle                  \fi
2284    \or\ifcase\c_math_styles_state_cramped
2285        \noexpand\triggerscriptstyle         \or
2286        \scriptstyle                         \or
2287        \crampedscriptstyle                  \fi
2288    \or\ifcase\c_math_styles_state_cramped
2289        \noexpand\triggerscriptscriptstyle   \or
2290        \scriptscriptstyle                   \or
2291        \crampedscriptscriptstyle            \fi
2292    \or\ifcase\c_math_styles_state_cramped
2293        \noexpand\triggerscriptscriptstyle   \or
2294        \scriptscriptstyle                   \or
2295        \crampedscriptscriptstyle            \fi
2296    \fi
2297  \or % large
2298    \ifcase\c_math_styles_state_style
2299        \ifcase\c_math_styles_state_cramped
2300        \noexpand\triggerbigstyle            \or
2301        \noexpand\triggeruncrampedbigstyle   \or
2302        \noexpand\triggercrampedbigstyle     \fi
2303    \or\ifcase\c_math_styles_state_cramped
2304        \noexpand\triggerdisplaystyle        \or
2305        \displaystyle                        \or
2306        \crampeddisplaystyle                 \fi
2307    \or\ifcase\c_math_styles_state_cramped
2308        \noexpand\triggertextstyle           \or
2309        \textstyle                           \or
2310        \crampedtextstyle                    \fi
2311    \or\ifcase\c_math_styles_state_cramped
2312        \noexpand\triggertextstyle           \or
2313        \textstyle                           \or
2314        \crampedtextstyle                    \fi
2315    \or\ifcase\c_math_styles_state_cramped
2316        \noexpand\triggerscriptstyle         \or
2317        \scriptstyle                         \or
2318        \crampedscriptstyle                  \fi
2319    \fi
2320  \fi
2321}
2322
2323\unexpanded\def\math_style_set#1%
2324  {\edef\m_math_style_asked{#1}%
2325   \ifx\m_math_style_asked\empty \else
2326     \math_style_set_indeed
2327   \fi}
2328
2329\let\setmathstyle\math_style_set
2330
2331\def\installmathstyle#1#2%
2332  {\ifcsname\??mathstylecommand#1\endcsname \else
2333     \setvalue{\??mathstylecommand#1}{#2}%
2334   \fi}
2335
2336\def\math_style_collect#1%
2337  {\csname\??mathstylecommand#1\endcsname}
2338
2339\setvalue{\??mathstylecommand\s!display     }{\c_math_styles_state_style  \plusone}
2340\setvalue{\??mathstylecommand\s!text        }{\c_math_styles_state_style  \plustwo}
2341\setvalue{\??mathstylecommand\s!script      }{\c_math_styles_state_style  \plusthree}
2342\setvalue{\??mathstylecommand\s!scriptscript}{\c_math_styles_state_style  \plusfour}
2343
2344\setvalue{\??mathstylecommand\s!uncramped   }{\c_math_styles_state_cramped\plusone}
2345\setvalue{\??mathstylecommand\s!cramped     }{\c_math_styles_state_cramped\plustwo}
2346\setvalue{\??mathstylecommand\v!normal      }{\c_math_styles_state_cramped\plusone}
2347\setvalue{\??mathstylecommand\v!packed      }{\c_math_styles_state_cramped\plustwo}
2348
2349\setvalue{\??mathstylecommand\v!small       }{\c_math_styles_state_size   \plusone}
2350\setvalue{\??mathstylecommand\v!big         }{\c_math_styles_state_size   \plustwo}
2351
2352\unexpanded\def\setupmathstyle[#1]%
2353  {\edef\m_math_style_asked{#1}%
2354   \ifx\m_math_style_asked\empty \else
2355     \math_style_set_indeed
2356   \fi}
2357
2358\unexpanded\def\usemathstyleparameter#1% faster local variant
2359  {\edef\m_math_style_asked{#1\c!mathstyle}%
2360   \ifx\m_math_style_asked\empty \else
2361     \math_style_set_indeed
2362   \fi}
2363
2364%D \startbuffer
2365%D \definemathstyle[mystyle][scriptscript]
2366%D
2367%D $text\startmathstyle[mystyle]scriptscript\stopmathstyle text$
2368%D \stopbuffer
2369%D
2370%D \typebuffer \blank \start \getbuffer \stop \blank
2371
2372\installcorenamespace {mathstyle}
2373
2374\unexpanded\def\definemathstyle
2375  {\dodoubleargument\math_style_define}
2376
2377\def\math_style_define[#1][#2]%
2378  {\c_math_styles_state_style  \zerocount
2379   \c_math_styles_state_cramped\zerocount
2380   \c_math_styles_state_size   \zerocount
2381   \rawprocesscommacommand[#2]\math_style_collect
2382   \expandafter\let\csname\??mathstyle#1\normalexpanded{\endcsname\math_style_add_to_cache_choice}}
2383
2384% \def\math_style_set_indeed
2385%   {\csname\??mathstyle
2386%      \ifcsname\??mathstyle\m_math_style_asked\endcsname
2387%        \m_math_style_asked
2388%      \else
2389%        \??mathstyle
2390%      \fi
2391%    \endcsname}
2392%
2393% \setvalue{\??mathstyle\??mathstyle}%
2394%   {\csname\??mathstylecache
2395%      \ifcsname\??mathstylecache\m_math_style_asked\endcsname
2396%        \m_math_style_asked
2397%      \else
2398%        \??mathstylecache
2399%      \fi
2400%    \endcsname}
2401%
2402% \setvalue{\??mathstylecache\??mathstylecache}%
2403%   {\c_math_styles_state_style  \zerocount
2404%    \c_math_styles_state_cramped\zerocount
2405%    \c_math_styles_state_size   \zerocount
2406%    \rawprocesscommacommand[\m_math_style_asked]\math_style_collect
2407%    \expandafter\glet\csname\??mathstylecache\m_math_style_asked\normalexpanded{\endcsname\math_style_add_to_cache_choice}%
2408%    \csname\??mathstylecache\m_math_style_asked\endcsname}
2409
2410\def\math_style_set_indeed
2411  {\ifcsname\??mathstyle\m_math_style_asked\endcsname
2412     \lastnamedcs
2413   \else
2414     \math_style_set_mathstyle_mathstyle
2415   \fi}
2416
2417\def\math_style_set_mathstyle_mathstyle
2418  {\ifcsname\??mathstylecache\m_math_style_asked\endcsname
2419     \lastnamedcs
2420   \else
2421     \math_style_set_mathstyle_mathstylecache
2422   \fi}
2423
2424\def\math_style_set_mathstyle_mathstylecache
2425  {\c_math_styles_state_style  \zerocount
2426   \c_math_styles_state_cramped\zerocount
2427   \c_math_styles_state_size   \zerocount
2428   \rawprocesscommacommand[\m_math_style_asked]\math_style_collect
2429   \expandafter\glet\csname\??mathstylecache\m_math_style_asked\normalexpanded{\endcsname\math_style_add_to_cache_choice}%
2430   \csname\??mathstylecache\m_math_style_asked\endcsname}
2431
2432\letvalue{\??mathstyle     \??mathstyle     }\math_style_set_mathstyle_mathstyle      % still needed?
2433\letvalue{\??mathstylecache\??mathstylecache}\math_style_set_mathstyle_mathstylecache % still needed?
2434
2435%D \startbuffer
2436%D $x\begingroup\setupmathstyle[script]x\endgroup x$
2437%D $x{\setupmathstyle[script]x}x$
2438%D $x\startmathstyle[script]x\stopmathstyle x$
2439%D \stopbuffer
2440%D
2441%D \typebuffer \getbuffer
2442
2443\unexpanded\def\startmathstyle[#1]%
2444  {\edef\m_math_style_asked{#1}%
2445   \ifx\m_math_style_asked\empty
2446     \let\stopmathstyle\relax
2447   \else
2448     \bgroup
2449     \math_style_set_indeed
2450     \let\stopmathstyle\egroup
2451   \fi}
2452
2453\let\stopmathstyle\relax
2454
2455\unexpanded\def\startusemathstyleparameter#1%
2456  {\edef\m_math_style_asked{#1\c!mathstyle}%
2457   \ifx\m_math_style_asked\empty
2458     \let\stopusemathstyleparameter\relax
2459   \else
2460     \bgroup
2461     \math_style_set_indeed
2462     \let\stopusemathstyleparameter\egroup
2463   \fi}
2464
2465\let\stopusemathstyleparameter\relax
2466
2467%D Something similar can be used in the (re|)|definition of \type {\text}. This
2468%D version is a variation on the one in the math module (see \type{m-math} and|/|or
2469%D \type {m-newmat}).
2470
2471\let\m_math_text_choice_face\relax
2472
2473% if needed we can get rid of the normalize (predo in font code)
2474
2475% \def\math_text_choice_font#1#2#%
2476%   {\normalizebodyfontsize\m_math_text_choice_face{\mathstyleface\normalmathstyle}%
2477%    \hbox#2\bgroup
2478%    \font_basics_switchtobodyfont\m_math_text_choice_face
2479%    #1%
2480%    \let\next}
2481
2482% \def\math_text_choice_word#1#2#%
2483%   {\normalizebodyfontsize\m_math_text_choice_face{\mathstyleface\normalmathstyle}%
2484%    \hbox#2\bgroup
2485%    \font_basics_switchtobodyfont\m_math_text_choice_face
2486%    #1%
2487%    \nospacing % \normalnospaces\plusone
2488%    \let\next}
2489
2490%D We accept a low level box specification so that one can make helpers:
2491%D
2492%D \startbuffer
2493%D \startformula
2494%D     \startalign[m=2,align={middle}]
2495%D         \NC \text to 6cm{One\hfill}           \NC a = 1 \NR
2496%D         \NC \text to 6cm{One Two\hfill}       \NC b = 2 \NR
2497%D         \NC \text to 6cm{One Two Three\hfill} \NC c = 3 \NR
2498%D     \stopalign
2499%D \stopformula
2500%D \stopbuffer
2501%D
2502%D \typebuffer \getbuffer
2503
2504\def\math_text_choice_font#1#2#%
2505  {\normalizebodyfontsize\m_math_text_choice_face{\mathstyleface\normalmathstyle}%
2506   \hbox#2\bgroup
2507   \bgroup
2508   \aftergroup\hss
2509   \aftergroup\egroup
2510   \hss
2511   \font_basics_switchtobodyfont\m_math_text_choice_face
2512   #1%
2513   \let\next}
2514
2515\def\math_text_choice_word#1#2#%
2516  {\normalizebodyfontsize\m_math_text_choice_face{\mathstyleface\normalmathstyle}%
2517   \hbox#2\bgroup
2518   \bgroup
2519   \aftergroup\hss
2520   \aftergroup\egroup
2521   \hss
2522   \font_basics_switchtobodyfont\m_math_text_choice_face
2523   #1%
2524   \nospacing % \normalnospaces\plusone
2525   \let\next}
2526
2527% \ruledhbox{$\mathtext{abc ffi}$}
2528% \ruledhbox{$\mathword{abc ffi}$}
2529
2530% I need to decide:
2531%
2532%mathscriptboxmode    \zerocount % no kerning
2533%mathscriptboxmode    \plusone   % lists
2534\mathscriptboxmode    \plustwo   % lists and boxes
2535\mathscriptcharmode   \plusone   % lists and boxes
2536%mathscriptboxmode    \plusthree % lists and boxes with \boundary=1 (also for testing and demo)
2537\mathrulethicknessmode\plusone   % adaptive
2538
2539\unexpanded\def\mathtext  {\mathortext{\math_text_choice_font\relax}\hbox}
2540\unexpanded\def\mathword  {\mathortext{\math_text_choice_word\relax}\hbox}
2541
2542\unexpanded\def\mathtexttf{\mathortext{\math_text_choice_font\tf}\hbox}
2543\unexpanded\def\mathtextit{\mathortext{\math_text_choice_font\it}\hbox}
2544\unexpanded\def\mathtextsl{\mathortext{\math_text_choice_font\sl}\hbox}
2545\unexpanded\def\mathtextbf{\mathortext{\math_text_choice_font\bf}\hbox}
2546\unexpanded\def\mathtextbi{\mathortext{\math_text_choice_font\bi}\hbox}
2547\unexpanded\def\mathtextbs{\mathortext{\math_text_choice_font\bs}\hbox}
2548
2549\unexpanded\def\mathwordtf{\mathortext{\math_text_choice_word\tf}\hbox}
2550\unexpanded\def\mathwordit{\mathortext{\math_text_choice_word\it}\hbox}
2551\unexpanded\def\mathwordsl{\mathortext{\math_text_choice_word\sl}\hbox}
2552\unexpanded\def\mathwordbf{\mathortext{\math_text_choice_word\bf}\hbox}
2553\unexpanded\def\mathwordbi{\mathortext{\math_text_choice_word\bi}\hbox}
2554\unexpanded\def\mathwordbs{\mathortext{\math_text_choice_word\bs}\hbox}
2555
2556%D Safeguard against redefinitions:
2557
2558\appendtoks
2559    \let\_\normalunderscore % is textunderscore or fakeunderscore
2560\to \everymathematics
2561
2562%D Because we may overload \type {\text} in other (structuring) macros, we say:
2563
2564\appendtoks \let\text\mathtext \to \everymathematics
2565
2566%D The next code is derived from plain \TEX. The names will change!
2567
2568\newcount\interdisplaylinepenalty \interdisplaylinepenalty\plushundred
2569
2570% Actually, not using an if saves one macro so there is no penalty
2571% for splitting up this macro.
2572%
2573% \newif\ifdt@p
2574%
2575% \def\displ@y
2576%   {\global\dt@ptrue
2577%    \math_openup\displayopenupvalue % was \openup\jot
2578%    \everycr
2579%      {\noalign
2580%         {\ifdt@p
2581%            \global\dt@pfalse
2582%            \ifdim\prevdepth>-\thousandpoint
2583%              \vskip-\lineskiplimit
2584%              \vskip\normallineskiplimit
2585%            \fi
2586%          \else
2587%            \penalty\interdisplaylinepenalty
2588%          \fi}}}
2589
2590\newtoks\mathdisplayaligntweaks
2591
2592% this can become an option:
2593
2594\unexpanded\def\math_display_align_hack % I don't like the global, maybe we should push and pop
2595  {\glet\math_display_align_hack_indeed\math_display_align_hack_remove_skip
2596   \math_openup\displayopenupvalue % was \math_openup\jot
2597   \everycr{\noalign{\math_display_align_hack_indeed}}}
2598
2599\def\math_display_align_hack_remove_skip
2600  {\ifdim\prevdepth>-\thousandpoint
2601     \vskip\dimexpr-\lineskiplimit+\normallineskiplimit\relax
2602   \fi
2603   \glet\math_display_align_hack_indeed\math_display_align_hack_insert_penalty}
2604
2605\def\math_display_align_hack_insert_penalty
2606  {\penalty\interdisplaylinepenalty}
2607
2608\appendtoks
2609    \math_display_align_hack
2610\to \mathdisplayaligntweaks
2611
2612%D Text in math:
2613
2614\unexpanded\def\mathortext
2615  {\ifmmode
2616     \expandafter\firstoftwoarguments
2617   \else
2618     \expandafter\secondoftwoarguments
2619   \fi}
2620
2621% \defineactivecharacter _ {\mathortext{_}{\_}} text_text  $a^2$
2622
2623% force text mode, will be overloaded later
2624
2625\ifdefined\text\else \let\text\hbox \fi
2626
2627% \unexpanded\def\mathoptext#1{\mathop{\text{#1}}}
2628
2629\unexpanded\def\mathoptext
2630  {\normalizebodyfontsize\m_math_text_choice_face{\mathstyleface\normalmathstyle}%
2631  %\showmathstyle
2632   \dowithnextbox
2633     {\mathop{\box\nextbox}}%
2634     \hbox\bgroup\font_basics_switchtobodyfont\m_math_text_choice_face\let\next}
2635
2636% new:
2637
2638% \startsetups math:morespacing
2639%     \Umathordordspacing\textstyle 1mu plus .5mu minus .25mu\relax
2640% \stopsetups
2641%
2642% \setupmathematics
2643%   [setups=math:morespacing]
2644
2645\appendtoks
2646    \edef\p_setups{\mathematicsparameter\c!setups}%
2647    \ifx\p_setups\empty\else
2648        \directsetup\p_setups
2649    \fi
2650\to \everyswitchmathematics
2651
2652% new:
2653
2654\unexpanded\def\smallmathsymbol#1%
2655  {\mathematics{\mathbin{\normalexpanded{\raise.15\exheight\hbox{\normalstartimath
2656     \triggermathstyle{\the\numexpr\normalmathstyle+2\relax}#1%
2657   \normalstopimath}}}}}
2658
2659% this should be a primitive:
2660
2661\def\mathextensiblecode#1#2{\clf_extensiblecode\numexpr#1\relax\numexpr#2\relax}
2662\def\mathhorizontalcode#1#2{\clf_horizontalcode\numexpr#1\relax\numexpr#2\relax}
2663
2664% experimental:
2665
2666%D \starttyping
2667%D \enabletrackers[math.openedup]
2668%D
2669%D \dorecurse{10}{\dorecurse{#1}{whatever }}
2670%D
2671%D \startitemize[packed]
2672%D     \startitem whatever \openedupimath{\frac{1}{2}} whatever
2673%D     \startitem whatever \openedupimath{\frac{1}{2}} whatever
2674%D     \startitem whatever \openedupimath{\frac{1}{2}} whatever
2675%D \stopitemize
2676%D \startitemize[packed,columns]
2677%D     \startitem whatever \openedupimath{\frac{1}{2}} whatever
2678%D     \startitem whatever \openedupimath{\frac{1}{2}} whatever
2679%D     \startitem whatever \openedupimath{\frac{1}{2}} whatever
2680%D     \startitem whatever \openedupimath{\frac{1}{2}} whatever
2681%D     \startitem whatever \openedupimath{\frac{1}{2}} whatever
2682%D     \startitem whatever \openedupimath{\frac{1}{2}} whatever
2683%D \stopitemize
2684%D
2685%D \dorecurse{5}{\dorecurse{#1}{whatever }\openedupimath{\frac{1}{2}} }
2686%D
2687%D \startitemize[packed,columns]
2688%D     \startitem whatever \openedupimath{1+2} whatever
2689%D     \startitem whatever \openedupimath{1+2} whatever
2690%D     \startitem whatever \openedupimath{\frac{1}{2}} whatever
2691%D     \startitem whatever \openedupimath{1+2} whatever
2692%D     \startitem whatever \openedupimath{1+2} whatever
2693%D \stopitemize
2694%D
2695%D \dorecurse{5}{\dorecurse{#1}{whatever }\openedupimath{1+2} }
2696%D
2697%D \startitemize[packed]
2698%D     \startitem whatever \openedupimath{\frac{1}{2}} whatever
2699%D     \startitem whatever \openedupimath{\frac{1}{2}} whatever
2700%D     \startitem whatever \openedupimath{\frac{1}{2}} whatever
2701%D \stopitemize
2702%D
2703%D \dorecurse{10}{whatever }
2704%D \dorecurse {5}{\dorecurse{#1}{whatever }\openedupimath{\frac{1}{2}} }
2705%D \dorecurse{10}{whatever }
2706%D \stoptyping
2707
2708\def\m_math_inline_openup_ht{\dimexpr\ifinsidecolumns\strutdp\else\lineheight\fi/\plusfour\relax}
2709\def\m_math_inline_openup_dp{\dimexpr\ifinsidecolumns\strutdp\else\lineheight\fi/\plusfour\relax}
2710
2711% \def\m_math_inline_openup_ht{\dimexpr\lineheight/\ifinsidecolumns\pluseight\else\plusfour\fi\relax}
2712% \def\m_math_inline_openup_dp{\dimexpr\lineheight/\ifinsidecolumns\pluseight\else\plusfour\fi\relax}
2713
2714\installtextracker
2715  {math.openedup}
2716  {\let\math_inline_openup_start_yes\math_inline_openup_traced_start}
2717  {\let\math_inline_openup_start_yes\math_inline_openup_normal_start}
2718
2719\unexpanded\def\math_inline_openup_normal_start
2720  {\scratchheight\dimexpr\ht\scratchbox+\m_math_inline_openup_ht\relax
2721   \scratchdepth \dimexpr\dp\scratchbox+\m_math_inline_openup_dp\relax
2722   \vrule\s!width\zeropoint\s!height\scratchheight\s!depth\scratchdepth\relax
2723   \begingroup
2724   \let\math_inline_openup_stop\math_inline_openup_normal_stop}
2725
2726\unexpanded\def\math_inline_openup_normal_stop
2727   {\endgroup
2728    \vrule\s!width\zeropoint\s!height\scratchheight\s!depth\scratchdepth\relax}
2729
2730\unexpanded\def\math_inline_openup_traced_start
2731  {\scratchtopoffset   \ht\scratchbox
2732   \scratchbottomoffset\dp\scratchbox
2733   \scratchheight      \dimexpr\scratchtopoffset   +\m_math_inline_openup_ht\relax
2734   \scratchdepth       \dimexpr\scratchbottomoffset+\m_math_inline_openup_dp\relax
2735   \vrule\s!width\zeropoint\s!height\scratchheight\s!depth\scratchdepth\relax
2736   \begingroup
2737     \dofastcoloractivation{darkred}%
2738     \vrule\s!width\emwidth\s!height\scratchheight\s!depth-\scratchtopoffset\relax
2739   \endgroup
2740   \kern-\emwidth
2741   \begingroup
2742   \let\math_inline_openup_stop\math_inline_openup_traced_stop}
2743
2744\unexpanded\def\math_inline_openup_traced_stop
2745  {\endgroup
2746   \kern-\emwidth
2747   \begingroup
2748     \dofastcoloractivation{darkblue}%
2749     \vrule\s!width\emwidth\s!height-\scratchbottomoffset\s!depth\scratchdepth\relax
2750   \endgroup
2751   \vrule\s!width\zeropoint\s!height\scratchheight\s!depth\scratchdepth\relax}
2752
2753\let\math_inline_openup_start_yes\math_inline_openup_normal_start
2754\let\math_inline_openup_stop     \relax
2755
2756\def\math_inline_openup_start_nop
2757  {\let\math_inline_openup_stop\relax}
2758
2759\unexpanded\def\openedupimath
2760  {\dontleavehmode
2761   \begingroup
2762   \ifmmode
2763     \expandafter\openedupimath_math
2764   \else
2765     \expandafter\openedupimath_text
2766   \fi}
2767
2768\unexpanded\def\openedupimath_math#1%
2769  {\setbox\scratchbox\mathstylehbox{#1}%
2770   \ifdim\ht\scratchbox>\strutht
2771     \math_inline_openup_start_yes
2772   \else\ifdim\dp\scratchbox>\strutdp
2773     \math_inline_openup_start_yes
2774   \else
2775     \math_inline_openup_start_nop
2776   \fi\fi
2777   #1%
2778   \math_inline_openup_stop
2779   \endgroup}
2780
2781\unexpanded\def\openedupimath_text#1%
2782  {\setbox\scratchbox\hbox{\startimath#1\stopimath}%
2783   \ifdim\ht\scratchbox>\strutht
2784     \math_inline_openup_start_yes
2785   \else\ifdim\dp\scratchbox>\strutdp
2786     \math_inline_openup_start_yes
2787   \else
2788     \math_inline_openup_start_nop
2789   \fi\fi
2790   \startimath
2791   #1%
2792   \stopimath
2793   \math_inline_openup_stop
2794   \endgroup}
2795
2796% Also handy, especially for units:
2797%
2798% 0x002B=plus 0x2212=minus 0x2013=endash
2799
2800\unexpanded\def\mathplus     {+}
2801\unexpanded\def\mathminus    {\ifmmode \else\iffontchar\font`−−\else \fi\fi}
2802\unexpanded\def\mathplusminus{±}
2803
2804%D The \type {\displaywidth} is only known inside a display formula, so we need to catch
2805%D it when still zero.
2806
2807\def\checkeddisplaywidth % hsize if zero
2808  {\dimexpr
2809     \ifzeropt\displaywidth
2810       \hsize
2811     \else
2812       \displaywidth
2813     \fi
2814   \relax}
2815
2816\def\maximizeddisplaywidth % larger than zero but within hsize
2817  {\dimexpr
2818     \ifzeropt\displaywidth
2819       \hsize
2820     \else\ifdim\displaywidth>\hsize
2821        \hsize
2822     \else
2823       \displaywidth
2824     \fi\fi
2825   \relax}
2826
2827%D Experiment: (todo: same switch as italic, using \type {\everyswitchmathematics}).
2828
2829\newcount\c_math_domain_attribute
2830
2831\def\math_domain_initialize
2832  {\ifnum\c_math_domain_attribute=\attributeunsetvalue \else
2833     \clf_initializemathdomain % one time
2834     \glet\math_domain_initialize\relax
2835   \fi}
2836
2837\appendtoks
2838    \edef\p_domain{\mathematicsparameter\c!domain}%
2839    \ifx\p_domain\empty
2840        \c_math_domain_attribute\attributeunsetvalue
2841    \else
2842        \c_math_domain_attribute\clf_getmathdomain\p_domain\relax
2843        \math_domain_initialize
2844    \fi
2845\to \everyswitchmathematics % only in mathematics
2846
2847\appendtoks
2848    \c_attr_mathdomain\c_math_domain_attribute
2849\to \everymathematics
2850
2851\setupmathematics
2852  [\s!italics=3] % for the moment only this one makes sense .. still experimental
2853
2854%D For special purposed we set this one:
2855
2856\installcorenamespace{mathrules}
2857
2858\unexpanded\def\enablemathrules{\letgvalue{\??mathrules\fontclass}\plusone}
2859
2860\appendtoks
2861    \mathrulesmode\ifcsname\??mathrules\fontclass\endcsname
2862      \lastnamedcs
2863    \else
2864      \zerocount
2865    \fi
2866    \mathrulesfam\zerocount
2867\to \everymathematics
2868
2869%D Maybe:
2870
2871% \starttabulate[|||c|c|]
2872% \BC positive                            \BC negative                               \BC text                           \BC math \NC \NR
2873% \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
2874% \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
2875% \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
2876% \NC \tex {f4} \tex {thickspace}         \NC \tex {b4} \tex {negthickspace}         \NC {\darkred\vl}\f4{\darkblue\vl} \NC ${\darkred\vl}\f4{\darkblue\vl}$ \NC \NR
2877% \NC \tex {f5} \tex {enspace}            \NC \tex {b5}                              \NC {\darkred\vl}\f5{\darkblue\vl} \NC ${\darkred\vl}\f5{\darkblue\vl}$ \NC \NR
2878% \NC \tex {f6} \tex {emspace}            \NC \tex {b6}                              \NC {\darkred\vl}\f6{\darkblue\vl} \NC ${\darkred\vl}\f6{\darkblue\vl}$ \NC \NR
2879% \stoptabulate
2880
2881% \unexpanded\def\negenspace{\kern-.5\emwidth}
2882% \unexpanded\def\negemspace{\kern-  \emwidth}
2883%
2884% \unexpanded\def\math_f#1%
2885%   {\ifcase#1\or
2886%      \hairspace
2887%    \or
2888%      \thinspace
2889%    \or
2890%      \medspace
2891%    \or
2892%      \thickspace
2893%    \or
2894%      \enspace
2895%    \or
2896%      \emspace
2897%    \fi}
2898%
2899% \unexpanded\def\math_b#1%
2900%   {\ifcase#1\or
2901%      \neghairspace
2902%    \or
2903%      \negthinspace
2904%    \or
2905%      \negmedspace
2906%    \or
2907%      \negthickspace
2908%    \or
2909%      \negenspace
2910%    \or
2911%      \negemspace
2912%    \fi}
2913%
2914% \appendtoks
2915%     \let\f\math_f
2916%     \let\b\math_b
2917% \to \everymathematics
2918
2919%D Experiment
2920
2921\unexpanded\def\math_scripts_stack
2922  {\c_attr_mathunstack\attributeunsetvalue}
2923
2924\unexpanded\def\math_scripts_unstack
2925  {\clf_enablescriptunstacking
2926   \c_attr_mathunstack\plusone}
2927
2928\appendtoks
2929    \let\stackscripts  \math_scripts_stack
2930    \let\unstackscripts\math_scripts_unstack
2931\to \everymathematics
2932
2933%D Expensive (tracing and inject) but a primitive (using factors) is tricky as we
2934%D want this frozen support.
2935
2936\def\math_openup_parameter#1#2%
2937  {\ifzeropt#1\displaystyle            \else\ifdim#1\displaystyle            =\maxdimen\else\frozen#1\displaystyle            #2#1\displaystyle            \fi\fi
2938   \ifzeropt#1\crampeddisplaystyle     \else\ifdim#1\crampeddisplaystyle     =\maxdimen\else\frozen#1\crampeddisplaystyle     #2#1\crampeddisplaystyle     \fi\fi
2939   \ifzeropt#1\textstyle               \else\ifdim#1\textstyle               =\maxdimen\else\frozen#1\textstyle               #2#1\textstyle               \fi\fi
2940   \ifzeropt#1\crampedtextstyle        \else\ifdim#1\crampedtextstyle        =\maxdimen\else\frozen#1\crampedtextstyle        #2#1\crampedtextstyle        \fi\fi
2941   \ifzeropt#1\scriptstyle             \else\ifdim#1\scriptstyle             =\maxdimen\else\frozen#1\scriptstyle             #2#1\scriptstyle             \fi\fi
2942   \ifzeropt#1\crampedscriptstyle      \else\ifdim#1\crampedscriptstyle      =\maxdimen\else\frozen#1\crampedscriptstyle      #2#1\crampedscriptstyle      \fi\fi
2943   \ifzeropt#1\scriptscriptstyle       \else\ifdim#1\scriptscriptstyle       =\maxdimen\else\frozen#1\scriptscriptstyle       #2#1\scriptscriptstyle       \fi\fi
2944   \ifzeropt#1\crampedscriptscriptstyle\else\ifdim#1\crampedscriptscriptstyle=\maxdimen\else\frozen#1\crampedscriptscriptstyle#2#1\crampedscriptscriptstyle\fi\fi}
2945
2946\unexpanded\def\mathopenupparameter#1#2%
2947  {\ifdim#2\points=\zeropoint\else
2948     \math_openup_parameter#1{#2}%
2949   \fi}
2950
2951%D For now (needed in asciimath):
2952
2953\def\math_relax_limits{\let\limits\relax}
2954
2955\protect \endinput
2956
2957% % not used (yet)
2958%
2959% \newtoks \everystartimath
2960% \newtoks \everystopimath
2961%
2962% \unexpanded\def\startimath{\Ustartmath\the\everystartimath}
2963% \unexpanded\def\stopimath {\the\everystopimath\Ustopmath}
2964%
2965% \unexpanded\def\m%
2966%   {\relax
2967%    \ifmmode\expandafter\math_m_stay\else\expandafter\math_m_math\fi}
2968%
2969% \unexpanded\def\math_m_math#1%
2970%   {\startimath#1\stopimath}
2971%
2972% \let\math_m_stay\firstofoneargument
2973