luametatex-math.tex /size: 124 Kb    last modification: 2024-01-16 09:02
1% language=us runpath=texruns:manuals/luametatex
2
3\environment luametatex-style
4
5\startcomponent luametatex-math
6
7\startchapter[reference=math,title={Math}]
8
9\startsection[title={Traditional alongside \OPENTYPE}]
10
11\topicindex {math}
12
13Because we started from \LUATEX, by the end of 2021 this chapter started with
14this, even if we already reworked the engine:
15
16\startquotation
17At this point there is no difference between \LUAMETATEX\ and \LUATEX\ with
18respect to math. \footnote {This might no longer be true because we have more
19control options that define default behavior and also have a more extensive
20scaling model. Anyway, it should not look worse, and maybe even a bit better.}
21The handling of mathematics in \LUATEX\ differs quite a bit from how \TEX82 (and
22therefore \PDFTEX) handles math. First, \LUATEX\ adds primitives and extends some
23others so that \UNICODE\ input can be used easily. Second, all of \TEX82's
24internal special values (for example for operator spacing) have been made
25accessible and changeable via control sequences. Third, there are extensions that
26make it easier to use \OPENTYPE\ math fonts. And finally, there are some
27extensions that have been proposed or considered in the past that are now added
28to the engine.
29
30You might be surprised that we don't use all these new control features in
31\CONTEXT\ \LMTX\ but who knows what might happen because users drive it. The main
32reason for adding so much is that I decided it made more sense to be complete now
33than gradually add more and more. At some point we should be able to say \quote
34{This is it}. Also, when looking at these features, you need to keep in mind that
35when it comes to math, \LATEX\ is the dominant macro package and it never needed
36these engine features, so most are probably just here for exploration purposes.
37\stopquotation
38
39Although we still process math as \TEX\ does, there have been some fundamental
40changes to the machinery. Most of that is discussed in documents that come with
41\CONTEXT\ and in Mikael Sundqvist math manual. Together we explored some new ways
42to deal with math spacing, penalties, fencing, operators, fractions, atoms and
43other features of the \TEX\ engine. We started from the way \CONTEXT\ used the
44already present functionality combine with sometimes somewhat dirty (but on the
45average working well) tricks.
46
47It will take a while before this chapter is updated. If you find errors or things
48missing, let me know. A lot of pairwise spacing primitives were dropped but also
49quite a bit of new ones introduced to control matters. Much in \LUAMETATEX\ math
50handling is about micro|-|typography and for us the results are quite visible.
51But, as far as we know, there have never been complaints or demands in the
52direction of the features discussed here. Also, \TEX\ math usage outside
53\CONTEXT\ is rather chiselled in stone (already for nearly three decades) so we
54don't expect other macro packages to use the new features anyway.
55
56\stopsection
57
58\startsection[title=Intermezzo]
59
60It is important to understand a bit how \TEX\ handles math. The math engine
61is a large subsystem and basically can be divided in two parts: convert
62sequential input into a list of nodes where math related ones actually are
63sort of intermediate and therefore called noads.
64
65In text mode entering \type {abc} results in three glyph nodes and \type {a b
66c} in three glyph nodes separated by (spacing) glue. Successive glyphs can be
67transformed in the font engine later on, just as hyphenation directive can
68be added. Eventually one (normally) gets a mix of glyphs, font kerns from
69a sequence of glyphs
70
71In math mode \type {abc} results in three simple ordinary noads and \type {a b c}
72is equivalent to that: three noads. But \type {a bc} results in two ordinary
73noads where the second one has a sublist of two ordinary noads. Because
74characters have class properties, \type {( a + b = c )} results in a simple open
75noad, a simple ordinary, a simple binary, a simple ordinary, a simple relation, a
76simple ordinary and simple close noad. The next samples show a bit of this; in
77order to see the effects of spacing between ordinary atoms set it to \type {9mu}.
78
79\startbuffer
80\typebuffer[sample]
81% \tracingmath1\tracingonline1
82\startlinecorrection
83\setmathspacing\mathordinarycode\mathordinarycode\allmathstyles9mu
84\mathgroupingmode\zerocount
85\scale[scale=2000]{\showmakeup[mathglue]\showboxes\mathspacingmode\plusone\getbuffer[sample]}
86\stoplinecorrection
87\blank[2*line]
88\stopbuffer
89
90\startbuffer[sample]
91$a b c$ \quad $a bc$ \quad $abc$
92\stopbuffer
93
94\getbuffer
95
96With \type {\tracingmath 1} we get this logged:
97
98\starttyping
99> \inlinemath=
100\noad[ord][...]
101.\nucleus
102..\mathchar[ord][...], family "0, character "61
103\noad[ord][...]
104.\nucleus
105..\mathchar[ord][...], family "0, character "62
106\noad[ord][...]
107.\nucleus
108..\mathchar[ord][...], family "0, character "63
109
110> \inlinemath=
111\noad[ord][...]
112.\nucleus
113..\mathchar[ord][...], family "0, character "61
114\noad[ord][...]
115.\nucleus
116..\mathchar[ord][...], family "0, character "62
117\noad[ord][...]
118.\nucleus
119..\mathchar[ord][...], family "0, character "63
120
121> \inlinemath=
122\noad[ord][...]
123.\nucleus
124..\mathchar[ord][...], family "0, character "61
125\noad[ord][...]
126.\nucleus
127..\mathchar[ord][...], family "0, character "62
128\noad[ord][...]
129.\nucleus
130..\mathchar[ord][...], family "0, character "63
131\stoptyping
132
133\startbuffer[sample]
134${a} {b} {c}$ \quad ${a} {bc}$ \quad ${abc}$
135\stopbuffer
136
137\getbuffer
138
139If the previous log surprises you, that might be because in \CONTEXT\ we set up the
140engine differently: curly braces don't create ordinary atoms. However, when we
141set \type {\mathgroupingmode 0} we return to what the engine normally does.
142
143\starttyping
144> \inlinemath=
145\noad[ord][...]
146.\nucleus
147..\mathchar[ord][...], family "0, character "61
148\noad[ord][...]
149.\nucleus
150..\mathchar[ord][...], family "0, character "62
151\noad[ord][...]
152.\nucleus
153..\mathchar[ord][...], family "0, character "63
154
155> \inlinemath=
156\noad[ord][...]
157.\nucleus
158..\mathchar[ord][...], family "0, character "61
159\noad[ord][...]
160.\nucleus
161..\submlist[0][...][tracing depth 5 reached]
162
163> \inlinemath=
164\noad[ord][...]
165.\nucleus
166..\submlist[0][...][tracing depth 5 reached]
167\stoptyping
168
169From the first example you can imagine what these sub lists look like: a list of
170ordinary atoms. The final list that is mix of nodes and yet unprocessed noads get
171fed into the math|-|to|-|hlist function and eventually the noads become glyphs,
172boxes, kerns, glue and whatever makes sense. A lot goes on there: think scripts,
173fractions, fences, accents, radicals, spacing, break control.
174
175An example of more tricky scanning is shown here:
176
177\starttyping
178a +   1 \over 2   + b
179a +  {1}\over{2}  + b
180a + {{1}\over{2}} + b
181\stoptyping
182
183In this case the \type {\over} makes \TEX\ reconsider the last noad, remove if
184from the current list and save it for later, then scan for a following atom a
185single character turned atom or a braced sequence that then is an ordinary noad.
186In the end a fraction noad is made. When that gets processed later specific
187numerator and denominator styles get applied (explicitly entered style nodes of
188course overload this for the content). The fact that this construct is all about
189(implicit) ordinary noads, themselves captured in noads, combined with the wish
190for enforced consistent positioning of numerator and denominator, plus style
191overload, color support and whatever comes to mind means that in practice one
192will use a \type {\frac} macro that provides all that control. \footnote {There
193are now a \prm {Uover} primitives that look ahead and then of course still
194treat curly braces as math lists to be picked up.}
195
196A similar tricky case is this:
197
198\starttyping
199      ( a +       ( b - c        ) + d        )
200\left ( a + \left ( b - c \right ) + d \right )
201\stoptyping
202
203Here the first line creates a list of noads but the second line create a fenced
204structure that is handled as a whole in order to make the fences match. \footnote
205{Actually instead of such a structure there could have been delimiters with
206backlinks but one never knows what happens with these links when processing
207passes are made so that fragility is avoided.} A fence noad will not break across
208lines as it is boxed and that is the reason why macro packages have these \type
209{\bigg} macros: they explicitly force a size using some trickery. In \LUAMETATEX\
210a fence object can actually be unpacked when the class is configured as such. It
211is one of the many extensions we have.
212
213There are some peculiar cases that one can run into but that actually are
214mentioned in the \TEX\ book. Often these reasons for intentional side effects
215become clear when one thinks of the average usage but unless one is willing to
216spend time on the \quote {fine points of math} they can also interfere with
217intentions. The next bits of code are just for the reader to look at. Try to
218predict the outcome. Watch out: in \LMTX\ the outcome is not what one gets by
219default in \LUATEX, \PDFTEX\ or regular \TEX. \footnote {One can set \typ
220{\mathgroupingmode = 0} to get close.}
221
222\starttyping
223$ 1 {\red +} 2$\par
224$ 1 \color[red]{+} 2$\par
225$ 1 \mathbin{\red +} 2$\par
226$ a + - b + {- b} $
227$ a \pm - b - {+ b} $
228$ - b $
229$ {- b} $
230\stoptyping
231
232The message here is that when a user is coding the mindset with respect to
233grouping using curly braces has to be switched to math mode too. And how many
234users really read the relevant chapters of the \TEX\ book a couple of times (as
235much makes only sense after playing with math in \TEX)? Even if one doesn't grasp
236everything it's a worthwhile read. Also consider this: did you really ask for an
237ordinary atom when you uses curly braces where no lists were expected? And what
238would have happened when ordinary related spacing had been set to non|-|zero?
239
240All the above (and plenty more) is why in \CONTEXT\ \LMTX\ we make extensive use
241of some \LUAMETATEX\ features, like: additional atom classes, configurable inter
242atom spacing and penalties, pairwise atom rules that can change classes, class
243based rendering options, more font parameters, configurable style instead of hard
244coded ones in constructs, more granular spacing, etc. That way we get quite
245predictable results but also drop some older (un)expected behavior and side
246effects. It is also why we cannot show many examples in the \LUAMETATEX\ manual:
247it uses \CONTEXT\ and we see no reason to complicate out lives (and spend energy
248on) turning off all the nicely cooperating features (and then for sure forgetting
249one) just for the sake of demos. It also gave us the opportunity to improve
250existing mechanisms and|/|or at least simplify their sometimes complex code.
251
252One last word here about sequences of ordinary atoms: the traditional code path
253feeds ordinary atoms into a ligature and kerning routine and does that when it
254encounters one. However, in \OPENTYPE\ we don't have ligatures not (single) kerns
255so there that doesn't apply. As we're not aware of traditional math fonts with
256ligatures and no one is likely to use these fonts with \LUAMETATEX\ the ligature
257code has been disabled. \footnote {It might show up in a different way if we feel
258the need in which case it's more related to runtime patches to fonts and class
259bases ligature building.} The kerning has been redone a bit so that it permits us
260to fine tune spacing (which in \CONTEXT\ we control with goodie files). The
261mentioned routine can also add italic correction, but that happens selectively
262because it is driven by specifications and circumstances. It is one of the places
263where the approach differs from the original, if only for practical reasons.
264
265\stopsection
266
267\startsection[title={Grouping with \prm {beginmathgroup} and \prm {endmathgroup}}]
268
269These two primitives behave like \prm {begingroup} and \prm {endgroup} but
270restore a style change inside the group. Style changes are actually injecting s
271special style noad which makes them sort of persistent till the next explicit
272change which can be confusing. This additional grouping model compensates for
273that.
274
275\stopsection
276
277\startsection[title={Unicode math characters}]
278
279\topicindex {math+\UNICODE}
280\topicindex {\UNICODE+math}
281
282For various reasons we need to encode a math character in a 32 bit number and
283because we often also need to keep track of families and classes the range of
284characters is limited to 20 bits. There are upto 64 classes (which is a lot more
285than in \LUATEX) and 64 families (less than in \LUATEX). The upper limit of
286characters is less that what \UNICODE\ offers but for math we're okay. If needed
287we can provide less families.
288
289The math primitives from \TEX\ are kept as they are, except for the ones that
290convert from input to math commands: \type {mathcode}, and \type {delcode}. These
291two now allow for the larger character codes argument on the left hand side of
292the equals sign. The number variants of some primitives might be dropped in favor
293of the primitives that read more than one separate value (class, family and
294code), for instance:
295
296\starttyping
297\def\overbrace{\Umathaccent 0 1 "23DE }
298\stoptyping
299
300The altered \TEX82 primitives are:
301
302\starttabulate[|l|l|r|c|l|r|]
303\DB primitive       \BC min \BC max    \BC \kern 2em \BC min \BC max    \NC \NR
304\TB
305\NC \prm {mathcode} \NC 0   \NC 10FFFF \NC =         \NC 0   \NC 8000   \NC \NR
306\NC \prm {delcode}  \NC 0   \NC 10FFFF \NC =         \NC 0   \NC FFFFFF \NC \NR
307\LL
308\stoptabulate
309
310The unaltered ones are:
311
312\starttabulate[|l|l|r|]
313\DB primitive          \BC min \BC max     \NC \NR
314\TB
315\NC \prm {mathchardef} \NC 0   \NC    8000 \NC \NR
316\NC \prm {mathchar}    \NC 0   \NC    7FFF \NC \NR
317\NC \prm {mathaccent}  \NC 0   \NC    7FFF \NC \NR
318\NC \prm {delimiter}   \NC 0   \NC 7FFFFFF \NC \NR
319\NC \prm {radical}     \NC 0   \NC 7FFFFFF \NC \NR
320\LL
321\stoptabulate
322
323% In \LUATEX\ we support the single number primitives *with \type {num} in their
324% name) conforming the \XETEX\ method. For the moment that still works but you need
325% to figure out the number yourself. The split number variants are more future safe
326% with respect to classes and families. We don't document \prm {Umathcharnumdef},
327% \prm {Umathcharnum}, \prm {Umathcodenum} and \prm {Udelcodenum} here any longer.
328
329In \LUATEX\ we support the single number primitives *with \type {num} in their
330name) conforming the \XETEX\ method. These primitives have been dropped in
331\LUAMETATEX\ because we use different ranges and properties, so these numbers
332have no (stable) meaning.
333
334\starttabulate[|l|l|c|c|c|]
335\DB primitive           \BC        \BC class \BC family \BC character \NC \NR
336\TB
337\NC \prm {Umathchardef} \NC csname \NC "40   \NC "40    \NC "FFFFF     \NC \NR
338\NC \prm {Umathcode}    \NC        \NC "40   \NC "40    \NC "FFFFF     \NC \NR
339\NC \prm {Udelcode}     \NC "FFFFF \NC "40   \NC "40    \NC "FFFFF     \NC \NR
340\NC \prm {Umathchar}    \NC        \NC "40   \NC "40    \NC "FFFFF     \NC \NR
341\NC \prm {Umathaccent}  \NC        \NC "40   \NC "40    \NC "FFFFF     \NC \NR
342\NC \prm {Udelimiter}   \NC        \NC "40   \NC "40    \NC "FFFFF     \NC \NR
343\NC \prm {Uradical}     \NC        \NC "40   \NC "40    \NC "FFFFF     \NC \NR
344\LL
345\stoptabulate
346
347So, there are upto 64 classes of which at this moment about 20 are predefined so,
348taking some future usage by the engine into account,you can assume 32 upto 60 to
349be available for any purpose. The number of families has been reduced from 256 to
35064 which is plenty for daily use in an \OPENTYPE\ setup. If we ever need to
351expand the \UNICODE\ range there will be less families or we just go for a larger
352internal record. The values of begin and end classes and the number of classes
353can be fetched from the \LUA\ status table.
354
355Given the above, specifications typically look like:
356
357\starttyping
358\Umathchardef \xx = "1 "0 "456
359\Umathcode    123 = "1 "0 "789
360\stoptyping
361
362The new primitives that deal with delimiter|-|style objects do not set up a
363\quote {large family}. Selecting a suitable size for display purposes is expected
364to be dealt with by the font via the \prm {Umathoperatorsize} parameter. Old
365school fonts can still be handled but you need to set up the engine to do that;
366this can be done per font. In principle we assume that \OPENTYPE\ fonts are used,
367which is no big deal because loading fonts is already under \LUA\ control. At
368that moment the distinction between small and large delimiters will be gone. Of
369course an alternative is to support a specific large size but that is unlikely to
370happen.
371
372This means that future versions of \LUAMETATEX\ might drop for instance the large
373family in delimiters, if only because we assume a coherent setup where
374extensibles come from the same font so that we don't need to worry about clashing
375font parameters. This is a condition that we can easily meet in \CONTEXT, which is
376the reference for \LUAMETATEX.
377
378% Constructor related primitives like \prm {Umathaccent} accepts optional keywords
379% to control various details regarding their treatment and rendering. See for
380% instance \in {section} [mathacc] for details. Some keywords are specific, but
381% some are shared between the math nodes (aka noads).
382
383There are more new primitives and most of these will be explained in following
384sections. For instance these are variants of radicals and delimiters all are
385set the same:
386
387\starttabulate[|l|c|c|c|]
388\DB primitive              \BC class \BC family \NC character \NC \NR
389\TB
390\NC \prm {Uroot}           \NC "40   \NC "40    \NC "FFFFF    \NC \NR
391\NC \prm {Uoverdelimiter}  \NC "40   \NC "40    \NC "FFFFF    \NC \NR
392\NC \prm {Uunderdelimiter} \NC "40   \NC "40    \NC "FFFFF    \NC \NR
393\NC \prm {Udelimiterover}  \NC "40   \NC "40    \NC "FFFFF    \NC \NR
394\NC \prm {Udelimiterunder} \NC "40   \NC "40    \NC "FFFFF    \NC \NR
395\LL
396\stoptabulate
397
398In addition there are \prm {Uvextensible} and \prm {Uoperator} and extended
399versions of fenced: \prm {Uleft}, \prm {Uright} and \prm {Umiddle}. There is also
400\prm {Uover} and similar primitives that expect the numerator and denominator
401after the primitive. In addition to regular scripts there are prescripts and a
402dedicated prime script. Many of these \type {U} primitives can be controlled by
403options and keywords.
404
405\stopsection
406
407\startsection[title=Setting up the engine]
408
409\startsubsection[title={Control}]
410
411\topicindex{math+control}
412
413Rendering math has long been dominated by \TEX\ but that changed when \MICROSOFT\
414came with \OPENTYPE\ math: an implementation as well as a font. Some of that was
415modelled after \TEX\ and some was dictated (we think) by the way word processors
416deal with math. For instance, traditional \TEX\ math has a limited set of glyph
417properties and therefore has a somewhat complex interplay between width and
418italic correction. There are no kerns, contrary to \OPENTYPE\ math fonts that
419provides staircase kerns. Interestingly \TEX\ does have some ligature building
420going on in the engine.
421
422In traditional \TEX\ italic correction gets added to the width and selectively
423removed later (or compensated by some shift and|/|or cheating with the box
424width). When we started with \LUATEX\ we had to gamble quite a bit about how to
425apply parameters and glyph properties which resulted in different code paths,
426heuristics, etc. That worked on the average but fonts are often not perfect and
427when served as an example for another one the bad bits can be inherited. That
428said, over time the descriptions improved and this is what the \OPENTYPE\
429specification has to say about italic correction now \footnote {\type
430{https://docs.microsoft.com/en-us/typography/opentype/spec/math}}:
431
432\startitemize [n]
433    \startitem
434        When a run of slanted characters is followed by a straight character
435        (such as an operator or a delimiter), the italics correction of the last
436        glyph is added to its advance width.
437    \stopitem
438    \startitem
439        When positioning limits on an N-ary operator (e.g., integral sign), the
440        horizontal position of the upper limit is moved to the right by half the
441        italics correction, while the position of the lower limit is moved to the
442        left by the same distance.
443    \stopitem
444    \startitem
445        When positioning superscripts and subscripts, their default horizontal
446        positions are also different by the amount of the italics correction of
447        the preceding glyph.
448    \stopitem
449\stopitemize
450
451The first rule is complicated by the fact that \quote {followed} is vague: in
452\TEX\ the sequence \type {$ a b c def $} results in six separate atoms, separated
453by inter atom spacing. The characters in these atoms are the nucleus and there
454can be a super- and|/|or subscript attached and in \LUAMETATEX\ also a prime,
455superprescript and/or subprescript.
456
457The second rule comes from \TEX\ and one can wonder why the available top accent
458anchor is not used. Maybe because bottom accent anchors are missing? Anyway,
459we're stuck with this now.
460
461The third rule also seems to come from \TEX. Take the \quote {\it f} character:
462in \TEX\ fonts that one has a narrow width and part sticks out (in some even at
463the left edge). That means that when the subscript gets attached it will move
464inwards relative to the real dimensions. Before the superscript an italic
465correction is added so what that correction is non|-|zero the scripts are
466horizontally shifted relative to each other.
467
468Now look at this specification of staircase kerns \footnote {Idem.}:
469
470\startnarrower
471    The \type {MathKernInfo} table provides mathematical kerning values used for
472    kerning of subscript and superscript glyphs relative to a base glyph. Its
473    purpose is to improve spacing in situations such as omega with superscript f
474    or capital V with subscript capital A.
475
476    Mathematical kerning is height dependent; that is, different kerning amounts
477    can be specified for different heights within a glyph’s vertical extent. For
478    any given glyph, different values can be specified for four corner positions,
479    top|-|right, to|-|left, etc., allowing for different kerning adjustments
480    according to whether the glyph occurs as a subscript, a superscript, a base
481    being kerned with a subscript, or a base being kerned with a superscript.
482\stopnarrower
483
484Again we're talking super- and subscripts and should we now look at the italic
485correction or assume that the kerns do the job? This is a mixed bag because
486scripts are not always (single) characters. We have to guess a bit here. After
487years of experimenting we came to the conclusion that it will never be okay so
488that's why we settled on controls and runtime fixes to fonts.
489
490This means that processing math is controlled by \prm {mathfontcontrol}, a
491numeric bitset parameter. The recommended bits are marked with a star but it
492really depends on the macro package to set up the machinery well. Of course one
493can just enable all and see what happens. \footnote {This model was more granular
494and could even be font (and character) specific but that was dropped because
495fonts are too inconsistent and an occasional fit is more robust that a generally
496applied rule.}
497
498\starttabulate[|l|l|c|]
499\DB bit             \BC name                              \NC \NC \NR
500\TB
501\NC \type {0x000001} \NC \type {usefontcontrol}           \NC       \NR
502\NC \type {0x000002} \NC \type {overrule}                 \NC \star \NR
503\NC \type {0x000004} \NC \type {underrule}                \NC \star \NR
504\NC \type {0x000008} \NC \type {radicalrule}              \NC \star \NR
505\NC \type {0x000010} \NC \type {fractionrule}             \NC \star \NR
506\NC \type {0x000020} \NC \type {accentskewhalf}           \NC \star \NR
507\NC \type {0x000040} \NC \type {accentskewapply}          \NC \star \NR
508\NC \type {0x000080} \NC \type {applyordinarykernpair}    \NC \star \NR
509\NC \type {0x000100} \NC \type {applyverticalitalickern}  \NC \star \NR
510\NC \type {0x000200} \NC \type {applyordinaryitalickern}  \NC \star \NR
511\NC \type {0x000400} \NC \type {applycharitalickern}      \NC       \NR
512\NC \type {0x000800} \NC \type {reboxcharitalickern}      \NC       \NR
513\NC \type {0x001000} \NC \type {applyboxeditalickern}     \NC \star \NR
514\NC \type {0x002000} \NC \type {staircasekern}            \NC \star \NR
515\NC \type {0x004000} \NC \type {applytextitalickern}      \NC \star \NR
516\NC \type {0x008000} \NC \type {checktextitalickern}      \NC \star \NR
517\NC \type {0x010000} \NC \type {checkspaceitalickern}     \NC       \NR
518\NC \type {0x020000} \NC \type {applyscriptitalickern}    \NC \star \NR
519\NC \type {0x040000} \NC \type {analysescriptnucleuschar} \NC \star \NR
520\NC \type {0x080000} \NC \type {analysescriptnucleuslist} \NC \star \NR
521\NC \type {0x100000} \NC \type {analysescriptnucleusbox}  \NC \star \NR
522\LL
523\stoptabulate
524
525So, to summarize: the reason for this approach is that traditional and \OPENTYPE\
526fonts have different approaches (especially when it comes to dealing with the
527width and italic corrections) and is even more complicated by the fact that the
528fonts are often inconsistent (within and between). In \CONTEXT\ we deal with this
529by runtime fixes to fonts. In any case the Cambria font is taken as reference.
530
531\stopsubsection
532
533\startsubsection[title={Analyzing the script nucleus}]
534
535\topicindex {math+kerning}
536\topicindex {math+scripts}
537
538The three analyze option relate to staircase kerns for which we need to look into the
539nucleus to get to the first character. In principle we only need to look into simple
540characters and lists but we can also look into boxes.There can be interference with
541other kinds spacing as well as italic corrections, which is why it is an option. These three
542are not bound to fonts because we don't know if have a font involved.
543
544% We keep the next text commented for historic reasons. In \CONTEXT\ we clean up
545% fonts in the font goodie files so the examples would not be honest anyway. But it
546% shows a bit where we come from and what alternatives we tried.
547
548% If you want to typeset text in math macro packages often provide something \type
549% {\text} which obeys the script sizes. As the definition can be anything there is
550% a good chance that the kerning doesn't come out well when used in a script. Given
551% that the first glyph ends up in an \prm {hbox} we have some control over this.
552% And, as a bonus we also added control over the normal sublist kerning. The \prm
553% {mathscriptboxmode} parameter defaults to~1.
554%
555% \starttabulate[|c|l|]
556% \DB value     \BC meaning \NC \NR
557% \TB
558% \NC \type {0} \NC forget about kerning \NC \NR
559% \NC \type {1} \NC kern math sub lists with a valid glyph \NC \NR
560% \NC \type {2} \NC also kern math sub boxes that have a valid glyph \NC \NR
561% \NC \type {3} \NC only kern math sub boxes with a boundary node present\NC \NR
562% \LL
563% \stoptabulate
564%
565% Here we show some examples. Of course this doesn't solve all our problems, if
566% only because some fonts have characters with bounding boxes that compensate for
567% italics, while other fonts can lack kerns.
568%
569% \startbuffer[1]
570%     $T_{\tf fluff}$
571% \stopbuffer
572%
573% \startbuffer[2]
574%     $T_{\text{fluff}}$
575% \stopbuffer
576%
577% \startbuffer[3]
578%     $T_{\text{\boundary1 fluff}}$
579% \stopbuffer
580%
581% \unexpanded\def\Show#1#2#3%
582%   {\doifelsenothing{#3}
583%      {\small\tx\typeinlinebuffer[#1]}
584%      {\doifelse{#3}{-}
585%         {\small\bf\tt mode #2}
586%         {\switchtobodyfont[#3]\showfontkerns\showglyphs\mathscriptboxmode#2\relax\inlinebuffer[#1]}}}
587%
588% \starttabulate[|lBT|c|c|c|c|c|]
589%     \NC          \NC \Show{1}{0}{}         \NC\Show{1}{1}{}         \NC \Show{2}{1}{}         \NC \Show{2}{2}{}         \NC \Show{3}{3}{}         \NC \NR
590%     \NC          \NC \Show{1}{0}{-}        \NC\Show{1}{1}{-}        \NC \Show{2}{1}{-}        \NC \Show{2}{2}{-}        \NC \Show{3}{3}{-}        \NC \NR
591%     \NC modern   \NC \Show{1}{0}{modern}   \NC\Show{1}{1}{modern}   \NC \Show{2}{1}{modern}   \NC \Show{2}{2}{modern}   \NC \Show{3}{3}{modern}   \NC \NR
592%     \NC lucidaot \NC \Show{1}{0}{lucidaot} \NC\Show{1}{1}{lucidaot} \NC \Show{2}{1}{lucidaot} \NC \Show{2}{2}{lucidaot} \NC \Show{3}{3}{lucidaot} \NC \NR
593%     \NC pagella  \NC \Show{1}{0}{pagella}  \NC\Show{1}{1}{pagella}  \NC \Show{2}{1}{pagella}  \NC \Show{2}{2}{pagella}  \NC \Show{3}{3}{pagella}  \NC \NR
594%     \NC cambria  \NC \Show{1}{0}{cambria}  \NC\Show{1}{1}{cambria}  \NC \Show{2}{1}{cambria}  \NC \Show{2}{2}{cambria}  \NC \Show{3}{3}{cambria}  \NC \NR
595%     \NC dejavu   \NC \Show{1}{0}{dejavu}   \NC\Show{1}{1}{dejavu}   \NC \Show{2}{1}{dejavu}   \NC \Show{2}{2}{dejavu}   \NC \Show{3}{3}{dejavu}   \NC \NR
596% \stoptabulate
597%
598% Kerning between a character subscript is controlled by \prm {mathscriptcharmode}
599% which also defaults to~1.
600%
601% Here is another example. Internally we tag kerns as italic kerns or font kerns
602% where font kerns result from the staircase kern tables. In 2018 fonts like Latin
603% Modern and Pagella rely on cheats with the boundingbox, Cambria uses staircase
604% kerns and Lucida a mixture. Depending on how fonts evolve we might add some more
605% control over what one can turn on and off.
606%
607% \def\MathSample#1#2#3%
608%   {\NC
609%    #1 \NC
610%    #2 \NC
611%    \showglyphdata \switchtobodyfont[#2,17.3pt]$#3T_{f}$         \NC
612%    \showglyphdata \switchtobodyfont[#2,17.3pt]$#3\gamma_{e}$    \NC
613%    \showglyphdata \switchtobodyfont[#2,17.3pt]$#3\gamma_{ee}$   \NC
614%    \showglyphdata \switchtobodyfont[#2,17.3pt]$#3T_{\tf fluff}$ \NC
615%    \NR}
616%
617% \starttabulate[|Tl|Tl|l|l|l|l|]
618%     \FL
619%     \MathSample{normal}{modern}  {\mr}
620%     \MathSample{}      {pagella} {\mr}
621%     \MathSample{}      {cambria} {\mr}
622%     \MathSample{}      {lucidaot}{\mr}
623%     \ML
624%     \MathSample{bold}  {modern}  {\mb}
625%     \MathSample{}      {pagella} {\mb}
626%     \MathSample{}      {cambria} {\mb}
627%     \MathSample{}      {lucidaot}{\mb}
628%     \LL
629% \stoptabulate
630
631\stopsubsection
632
633\stopsection
634
635\startsection[title={Math styles}]
636
637\startsubsection[title={\prm {mathstyle}, \prm {mathstackstyle} and \prm {givenmathstyle}}]
638
639\topicindex {math+styles}
640
641It is possible to discover the math style that will be used for a formula in an
642expandable fashion (while the math list is still being read). To make this
643possible, \LUATEX\ adds the new primitive: \prm {mathstyle}. This is a \quote
644{convert command} like e.g. \prm {romannumeral}: its value can only be read,
645not set. Beware that contrary to \LUATEX\ this is now a proper number so you need
646to use \type {\number} or \type {\the} in order to serialize it.
647
648The returned value is between 0 and 7 (in math mode), or $-1$ (all other modes).
649For easy testing, the eight math style commands have been altered so that they can
650be used as numeric values, so you can write code like this:
651
652\starttyping
653\ifnum\mathstyle=\textstyle
654    \message{normal text style}
655\else \ifnum\mathstyle=\crampedtextstyle
656    \message{cramped text style}
657\fi \fi
658\stoptyping
659
660Sometimes you won't get what you expect so a bit of explanation might help to
661understand what happens. When math is parsed and expanded it gets turned into a
662linked list. In a second pass the formula will be build. This has to do with the
663fact that in order to determine the automatically chosen sizes (in for instance
664fractions) following content can influence preceding sizes. A side effect of this
665is for instance that one cannot change the definition of a font family (and
666thereby reusing numbers) because the number that got used is stored and used in
667the second pass (so changing \type {\fam 12} mid|-|formula spoils over to
668preceding use of that family).
669
670The style switching primitives like \prm {textstyle} are turned into nodes so the
671styles set there are frozen. The \prm {mathchoice} primitive results in four
672lists being constructed of which one is used in the second pass. The fact that
673some automatic styles are not yet known also means that the \prm {mathstyle}
674primitive expands to the current style which can of course be different from the
675one really used. It's a snapshot of the first pass state. As a consequence in the
676following example you get a style number (first pass) typeset that can actually
677differ from the used style (second pass). In the case of a math choice used
678ungrouped, the chosen style is used after the choice too, unless you group.
679
680\startbuffer[1]
681    [a:\number\mathstyle]\quad
682    \bgroup
683    \mathchoice
684        {\bf \scriptstyle       (x:d :\number\mathstyle)}
685        {\bf \scriptscriptstyle (x:t :\number\mathstyle)}
686        {\bf \scriptscriptstyle (x:s :\number\mathstyle)}
687        {\bf \scriptscriptstyle (x:ss:\number\mathstyle)}
688    \egroup
689    \quad[b:\number\mathstyle]\quad
690    \mathchoice
691        {\bf \scriptstyle       (y:d :\number\mathstyle)}
692        {\bf \scriptscriptstyle (y:t :\number\mathstyle)}
693        {\bf \scriptscriptstyle (y:s :\number\mathstyle)}
694        {\bf \scriptscriptstyle (y:ss:\number\mathstyle)}
695    \quad[c:\number\mathstyle]\quad
696    \bgroup
697    \mathchoice
698        {\bf \scriptstyle       (z:d :\number\mathstyle)}
699        {\bf \scriptscriptstyle (z:t :\number\mathstyle)}
700        {\bf \scriptscriptstyle (z:s :\number\mathstyle)}
701        {\bf \scriptscriptstyle (z:ss:\number\mathstyle)}
702    \egroup
703    \quad[d:\number\mathstyle]
704\stopbuffer
705
706\startbuffer[2]
707    [a:\number\mathstyle]\quad
708    \begingroup
709    \mathchoice
710        {\bf \scriptstyle       (x:d :\number\mathstyle)}
711        {\bf \scriptscriptstyle (x:t :\number\mathstyle)}
712        {\bf \scriptscriptstyle (x:s :\number\mathstyle)}
713        {\bf \scriptscriptstyle (x:ss:\number\mathstyle)}
714    \endgroup
715    \quad[b:\number\mathstyle]\quad
716    \mathchoice
717        {\bf \scriptstyle       (y:d :\number\mathstyle)}
718        {\bf \scriptscriptstyle (y:t :\number\mathstyle)}
719        {\bf \scriptscriptstyle (y:s :\number\mathstyle)}
720        {\bf \scriptscriptstyle (y:ss:\number\mathstyle)}
721    \quad[c:\number\mathstyle]\quad
722    \begingroup
723    \mathchoice
724        {\bf \scriptstyle       (z:d :\number\mathstyle)}
725        {\bf \scriptscriptstyle (z:t :\number\mathstyle)}
726        {\bf \scriptscriptstyle (z:s :\number\mathstyle)}
727        {\bf \scriptscriptstyle (z:ss:\number\mathstyle)}
728    \endgroup
729    \quad[d:\number\mathstyle]
730\stopbuffer
731
732\typebuffer[1]
733
734% \typebuffer[2]
735
736This gives:
737
738\blank $\displaystyle \getbuffer[1]$ \blank
739\blank $\textstyle    \getbuffer[1]$ \blank
740
741Using \prm {begingroup} \unknown\ \prm {endgroup} instead gives:
742
743\blank $\displaystyle \getbuffer[2]$ \blank
744\blank $\textstyle    \getbuffer[2]$ \blank
745
746This might look wrong but it's just a side effect of \prm {mathstyle} expanding
747to the current (first pass) style and the number being injected in the list that
748gets converted in the second pass. It all makes sense and it illustrates the
749importance of grouping. In fact, the math choice style being effective afterwards
750has advantages. It would be hard to get it otherwise.
751
752So far for the more \LUATEX ish approach. One problem with \prm {mathstyle} is
753that when you got it, and want to act upon it, you need to remap it onto say \prm
754{scriptstyle} which can be done with an eight branched \prm {ifcase}. This is
755why we also have a more efficient alternative that you can use in macros:
756
757\starttyping
758\normalexpand{ ... \givenmathstyle\the\mathstyle      ...}
759\normalexpand{ ... \givenmathstyle\the\mathstackstyle ...}
760\stoptyping
761
762This new primitive \prm {givenmathstyle} accepts a numeric value. The \prm
763{mathstackstyle} primitive is just a bonus (it complements \prm {mathstack}).
764
765The styles that the different math components and their subcomponents start out
766with are no longer hard coded but can be set at runtime:
767
768\starttabulate
769\DB primitive name                        \BC default \NC \NR
770\TB
771\NC \prm {Umathoverlinevariant}           \NC cramped           \NC \NR
772\NC \prm {Umathunderlinevariant}          \NC normal            \NC \NR
773\NC \prm {Umathoverdelimitervariant}      \NC small             \NC \NR
774\NC \prm {Umathunderdelimitervariant}     \NC small             \NC \NR
775\NC \prm {Umathdelimiterovervariant}      \NC normal            \NC \NR
776\NC \prm {Umathdelimiterundervariant}     \NC normal            \NC \NR
777\NC \prm {Umathhextensiblevariant}        \NC normal            \NC \NR
778\NC \prm {Umathvextensiblevariant}        \NC normal            \NC \NR
779\NC \prm {Umathfractionvariant}           \NC cramped           \NC \NR
780\NC \prm {Umathradicalvariant}            \NC cramped           \NC \NR
781\NC \prm {Umathdegreevariant}             \NC doublesuperscript \NC \NR
782\NC \prm {Umathaccentvariant}             \NC cramped           \NC \NR
783\NC \prm {Umathtopaccentvariant}          \NC cramped           \NC \NR
784\NC \prm {Umathbottomaccentvariant}       \NC cramped           \NC \NR
785\NC \prm {Umathoverlayaccentvariant}      \NC cramped           \NC \NR
786\NC \prm {Umathnumeratorvariant}          \NC numerator         \NC \NR
787\NC \prm {Umathdenominatorvariant}        \NC denominator       \NC \NR
788\NC \prm {Umathsuperscriptvariant}        \NC superscript       \NC \NR
789\NC \prm {Umathsubscriptvariant}          \NC subscript         \NC \NR
790\NC \prm {Umathprimevariant}              \NC superscript       \NC \NR
791\NC \prm {Umathstackvariant}              \NC numerator         \NC \NR
792\LL
793\stoptabulate
794
795These defaults remap styles are as follows:
796
797\starttabulate[|Tl|l|l|]
798\DB default           \BC result                    \BC mapping \NC \NR
799\TB
800\NC cramped           \NC cramp the style           \NC D' D' T' T' S'  S'  SS' SS' \NC \NR
801\NC subscript         \NC smaller and cramped       \NC S' S' S' S' SS' SS' SS' SS' \NC \NR
802\NC small             \NC smaller                   \NC S  S  S  S  SS  SS  SS  SS  \NC \NR
803\NC superscript       \NC smaller                   \NC S  S  S  S  SS  SS  SS  SS  \NC \NR
804\NC smaller           \NC smaller unless already SS \NC S  S' S  S' SS  SS' SS  SS' \NC \NR
805\NC numerator         \NC smaller unless already SS \NC S  S' S  S' SS  SS' SS  SS' \NC \NR
806\NC denominator       \NC smaller, all cramped      \NC S' S' S' S' SS' SS' SS' SS' \NC \NR
807\NC doublesuperscript \NC smaller, keep cramped     \NC S  S' S  S' SS  SS' SS  SS' \NC \NR
808\LL
809\stoptabulate
810
811The main reason for opening this up was that it permits experiments and removed
812hard coded internal values. But as these defaults served well for decades there
813are no real reasons to change them.
814
815\stopsubsection
816
817\startsubsection[title={\prm {mathstack}}]
818
819\topicindex {math+stacks}
820
821There are a few math commands in \TEX\ where the style that will be used is not
822known straight from the start. These commands (\prm {over}, \prm {atop},
823\prm {overwithdelims}, \prm {atopwithdelims}) would therefore normally return
824wrong values for \prm {mathstyle}. To fix this, \LUATEX\ introduces a special
825prefix command: \prm {mathstack}:
826
827\starttyping
828$\mathstack {a \over b}$
829\stoptyping
830
831The \prm {mathstack} command will scan the next brace and start a new math group
832with the correct (numerator) math style. The \prm {mathstackstyle} primitive
833relates to this feature.
834
835\stopsubsection
836
837\startsubsection[title={The new \type {\cramped...style} commands}]
838
839\topicindex {math+styles}
840\topicindex {math+spacing}
841\topicindex {math+cramped}
842
843\LUATEX\ has four new primitives to set the cramped math styles directly:
844
845\starttyping
846\crampeddisplaystyle
847\crampedtextstyle
848\crampedscriptstyle
849\crampedscriptscriptstyle
850\stoptyping
851
852These additional commands are not all that valuable on their own, but they come
853in handy as arguments to the math parameter settings that will be added shortly.
854
855Because internally the eight styles are represented as numbers some of the new
856primnitives that relate to them also work with numbers and often you can use them
857mixed. The \prm {tomathstyle} prefix converts a symbolic style into a number so
858\typ {\number \tomathstyle \crampedscriptstyle} gives~\number \tomathstyle
859\crampedscriptstyle.
860
861In Eijkhouts \quotation {\TEX\ by Topic} the rules for handling styles in scripts
862are described as follows:
863
864\startitemize
865\startitem
866    In any style superscripts and subscripts are taken from the next smaller style.
867    Exception: in display style they are in script style.
868\stopitem
869\startitem
870    Subscripts are always in the cramped variant of the style; superscripts are only
871    cramped if the original style was cramped.
872\stopitem
873\startitem
874    In an \type {..\over..} formula in any style the numerator and denominator are
875    taken from the next smaller style.
876\stopitem
877\startitem
878    The denominator is always in cramped style; the numerator is only in cramped
879    style if the original style was cramped.
880\stopitem
881\startitem
882    Formulas under a \type {\sqrt} or \prm {overline} are in cramped style.
883\stopitem
884\stopitemize
885
886In \LUATEX\ one can set the styles in more detail which means that you sometimes
887have to set both normal and cramped styles to get the effect you want. (Even) if
888we force styles in the script using \prm {scriptstyle} and \prm
889{crampedscriptstyle} we get this:
890
891\startbuffer[demo]
892\starttabulate
893\DB style         \BC example \NC \NR
894\TB
895\NC default       \NC $b_{x=xx}^{x=xx}$ \NC \NR
896\NC script        \NC $b_{\scriptstyle x=xx}^{\scriptstyle x=xx}$ \NC \NR
897\NC crampedscript \NC $b_{\crampedscriptstyle x=xx}^{\crampedscriptstyle x=xx}$ \NC \NR
898\LL
899\stoptabulate
900\stopbuffer
901
902\getbuffer[demo]
903
904Now we set the following parameters using \prm {setmathspacing} that accepts two
905class identifier, a style and a value.
906
907\startbuffer[setup]
908\setmathspacing 0 3 \scriptstyle = 30mu
909\setmathspacing 0 3 \scriptstyle = 30mu
910\stopbuffer
911
912\typebuffer[setup]
913
914This gives a different result:
915
916\start\getbuffer[setup,demo]\stop
917
918But, as this is not what is expected (visually) we should say:
919
920\startbuffer[setup]
921\setmathspacing 0 3 \scriptstyle        = 30mu
922\setmathspacing 0 3 \scriptstyle        = 30mu
923\setmathspacing 0 3 \crampedscriptstyle = 30mu
924\setmathspacing 0 3 \crampedscriptstyle = 30mu
925\stopbuffer
926
927\typebuffer[setup]
928
929Now we get:
930
931\start\getbuffer[setup,demo]\stop
932
933\stopsubsection
934
935\stopsection
936
937\startsection[title={Math parameter settings}]
938
939\startsubsection[title={Many new \tex {Umath*} primitives}]
940
941\topicindex {math+parameters}
942
943In \LUATEX, the font dimension parameters that \TEX\ used in math typesetting are
944now accessible via primitive commands. In fact, refactoring of the math engine
945has resulted in turning some hard codes properties into parameters.
946
947{\em The next needs checking ...}
948
949\starttabulate
950\DB primitive name                 \BC description \NC \NR
951\TB
952\NC \prm {Umathquad}               \NC the width of 18 mu's \NC \NR
953\NC \prm {Umathaxis}               \NC height of the vertical center axis of
954                                       the math formula above the baseline \NC \NR
955\NC \prm {Umathoperatorsize}       \NC minimum size of large operators in display mode \NC \NR
956\NC \prm {Umathoverbarkern}        \NC vertical clearance above the rule \NC \NR
957\NC \prm {Umathoverbarrule}        \NC the width of the rule \NC \NR
958\NC \prm {Umathoverbarvgap}        \NC vertical clearance below the rule \NC \NR
959\NC \prm {Umathunderbarkern}       \NC vertical clearance below the rule \NC \NR
960\NC \prm {Umathunderbarrule}       \NC the width of the rule \NC \NR
961\NC \prm {Umathunderbarvgap}       \NC vertical clearance above the rule \NC \NR
962\NC \prm {Umathradicalkern}        \NC vertical clearance above the rule \NC \NR
963\NC \prm {Umathradicalrule}        \NC the width of the rule \NC \NR
964\NC \prm {Umathradicalvgap}        \NC vertical clearance below the rule \NC \NR
965\NC \prm {Umathradicaldegreebefore}\NC the forward kern that takes place before placement of
966                                       the radical degree \NC \NR
967\NC \prm {Umathradicaldegreeafter} \NC the backward kern that takes place after placement of
968                                       the radical degree \NC \NR
969\NC \prm {Umathradicaldegreeraise} \NC this is the percentage of the total height and depth of
970                                       the radical sign that the degree is raised by; it is
971                                       expressed in \type {percents}, so 60\% is expressed as the
972                                       integer $60$ \NC \NR
973\NC \prm {Umathstackvgap}          \NC vertical clearance between the two
974                                       elements in an \prm {atop} stack \NC \NR
975\NC \prm {Umathstacknumup}         \NC numerator shift upward in \prm {atop} stack \NC \NR
976\NC \prm {Umathstackdenomdown}     \NC denominator shift downward in \prm {atop} stack \NC \NR
977\NC \prm {Umathfractionrule}       \NC the width of the rule in a \prm {over} \NC \NR
978\NC \prm {Umathfractionnumvgap}    \NC vertical clearance between the numerator and the rule \NC \NR
979\NC \prm {Umathfractionnumup}      \NC numerator shift upward in \prm {over} \NC \NR
980\NC \prm {Umathfractiondenomvgap}  \NC vertical clearance between the denominator and the rule \NC \NR
981\NC \prm {Umathfractiondenomdown}  \NC denominator shift downward in \prm {over} \NC \NR
982\NC \prm {Umathfractiondelsize}    \NC minimum delimiter size for \type {\...withdelims} \NC \NR
983\NC \prm {Umathlimitabovevgap}     \NC vertical clearance for limits above operators \NC \NR
984\NC \prm {Umathlimitabovebgap}     \NC vertical baseline clearance for limits above operators \NC \NR
985\NC \prm {Umathlimitabovekern}     \NC space reserved at the top of the limit \NC \NR
986\NC \prm {Umathlimitbelowvgap}     \NC vertical clearance for limits below operators \NC \NR
987\NC \prm {Umathlimitbelowbgap}     \NC vertical baseline clearance for limits below operators \NC \NR
988\NC \prm {Umathlimitbelowkern}     \NC space reserved at the bottom of the limit \NC \NR
989\NC \prm {Umathoverdelimitervgap}  \NC vertical clearance for limits above delimiters \NC \NR
990\NC \prm {Umathoverdelimiterbgap}  \NC vertical baseline clearance for limits above delimiters \NC \NR
991\NC \prm {Umathunderdelimitervgap} \NC vertical clearance for limits below delimiters \NC \NR
992\NC \prm {Umathunderdelimiterbgap} \NC vertical baseline clearance for limits below delimiters \NC \NR
993\NC \prm {Umathsubshiftdrop}       \NC subscript drop for boxes and subformulas \NC \NR
994\NC \prm {Umathsubshiftdown}       \NC subscript drop for characters \NC \NR
995\NC \prm {Umathsupshiftdrop}       \NC superscript drop (raise, actually) for boxes and subformulas \NC \NR
996\NC \prm {Umathsupshiftup}         \NC superscript raise for characters \NC \NR
997\NC \prm {Umathsubsupshiftdown}    \NC subscript drop in the presence of a superscript \NC \NR
998\NC \prm {Umathsubtopmax}          \NC the top of standalone subscripts cannot be higher than this
999                                       above the baseline \NC \NR
1000\NC \prm {Umathsupbottommin}       \NC the bottom of standalone superscripts cannot be less than
1001                                       this above the baseline \NC \NR
1002\NC \prm {Umathsupsubbottommax}    \NC the bottom of the superscript of a combined super- and subscript
1003                                       be at least as high as this above the baseline \NC \NR
1004\NC \prm {Umathsubsupvgap}         \NC vertical clearance between super- and subscript \NC \NR
1005\NC \prm {Umathspaceafterscript}   \NC additional space added after a super- or subscript \NC \NR
1006\NC \prm {Umathconnectoroverlapmin}\NC minimum overlap between parts in an extensible recipe \NC \NR
1007\LL
1008\stoptabulate
1009
1010In addition to the above official \OPENTYPE\ font parameters we have these (the
1011undefined will get presets, quite likely zero):
1012
1013\starttabulate
1014\DB primitive name                             \BC description \NC \NR
1015\TB
1016\NC \prm {Umathconnectoroverlapmin}            \NC \NC \NR
1017\NC \prm {Umathsubsupshiftdown}                \NC \NC \NR
1018\NC \prm {Umathfractiondelsize}                \NC \NC \NR
1019\NC \prm {Umathnolimitsupfactor}               \NC a multiplier for the way limits are shifted up and down \NC \NR
1020\NC \prm {Umathnolimitsubfactor}               \NC a multiplier for the way limits are shifted up and down \NC \NR
1021\NC \prm {Umathaccentbasedepth}                \NC the complement of \prm {Umathaccentbaseheight} \NC \NR
1022\NC \prm {Umathflattenedaccentbasedepth}       \NC the complement of \prm {Umathflattenedaccentbaseheight} \NC \NR
1023\NC \prm {Umathspacebeforescript}              \NC \NC \NR
1024\NC \prm {Umathprimeraise}                     \NC \NC \NR
1025\NC \prm {Umathprimeraisecomposed}             \NC \NC \NR
1026\NC \prm {Umathprimeshiftup}                   \NC the prime variant of \prm {Umathsupshiftup} \NC \NR
1027\NC \prm {Umathprimespaceafter}                \NC the prescript variant of \prm {Umathspaceafterscript} \NC \NR
1028\NC \prm {Umathprimeshiftdrop}                 \NC the prime variant of \prm {Umathsupshiftdrop} \NC \NR
1029\NC \prm {Umathprimewidth}                     \NC the percentage of width that gets added \NC \NR
1030\NC \prm {Umathskeweddelimitertolerance}       \NC \NC \NR
1031\NC \prm {Umathaccenttopshiftup}               \NC the amount that a top accent is shifted up \NC \NR
1032\NC \prm {Umathaccentbottomshiftdown}          \NC the amount that a bottom accent is shifted down \NC \NR
1033\NC \prm {Umathaccenttopovershoot}             \NC \NC \NR
1034\NC \prm {Umathaccentbottomovershoot}          \NC \NC \NR
1035\NC \prm {Umathaccentsuperscriptdrop}          \NC \NC \NR
1036\NC \prm {Umathaccentsuperscriptpercent}       \NC \NC \NR
1037\NC \prm {Umathaccentextendmargin}             \NC margins added to automatically extended accents \NC \NR
1038\NC \prm {Umathflattenedaccenttopshiftup}      \NC the amount that a wide top accent is shifted up \NC \NR
1039\NC \prm {Umathflattenedaccentbottomshiftdown} \NC the amount that a wide bottom accent is shifted down \NC \NR
1040\NC \prm {Umathdelimiterpercent}               \NC \NC \NR
1041\NC \prm {Umathdelimitershortfall}             \NC \NC \NR
1042\NC \prm {Umathradicalextensiblebefore}        \NC \NC \NR
1043\NC \prm {Umathradicalextensibleafter}         \NC \NC \NR
1044\stoptabulate
1045
1046These relate to the font parameters and in \CONTEXT\ we assign some different
1047defaults and tweak them in the goodie files:
1048
1049\starttabulate[|T|T|c|]
1050\DB font parameter                    \BC primitive name                             \BC default   \NC \NR
1051\TB
1052\NC MinConnectorOverlap               \NC \prm {Umathconnectoroverlapmin}            \NC 0         \NC \NR
1053\NC SubscriptShiftDownWithSuperscript \NC \prm {Umathsubsupshiftdown}                \NC inherited \NC \NR
1054\NC FractionDelimiterSize             \NC \prm {Umathfractiondelsize}                \NC undefined \NC \NR
1055\NC FractionDelimiterDisplayStyleSize \NC \prm {Umathfractiondelsize}                \NC undefined \NC \NR
1056\NC NoLimitSubFactor                  \NC \prm {Umathnolimitsupfactor}               \NC 0         \NC \NR
1057\NC NoLimitSupFactor                  \NC \prm {Umathnolimitsubfactor}               \NC 0         \NC \NR
1058\NC AccentBaseDepth                   \NC \prm {Umathaccentbasedepth}                \NC reserved  \NC \NR
1059\NC FlattenedAccentBaseDepth          \NC \prm {Umathflattenedaccentbasedepth}       \NC reserved  \NC \NR
1060\NC SpaceBeforeScript                 \NC \prm {Umathspacebeforescript}              \NC 0         \NC \NR
1061\NC PrimeRaisePercent                 \NC \prm {Umathprimeraise}                     \NC 0         \NC \NR
1062\NC PrimeRaiseComposedPercent         \NC \prm {Umathprimeraisecomposed}             \NC 0         \NC \NR
1063\NC PrimeShiftUp                      \NC \prm {Umathprimeshiftup}                   \NC 0         \NC \NR
1064\NC PrimeShiftUpCramped               \NC \prm {Umathprimeshiftup}                   \NC 0         \NC \NR
1065\NC PrimeSpaceAfter                   \NC \prm {Umathprimespaceafter}                \NC 0         \NC \NR
1066\NC PrimeBaselineDropMax              \NC \prm {Umathprimeshiftdrop}                 \NC 0         \NC \NR
1067\NC PrimeWidthPercent                 \NC \prm {Umathprimewidth}                     \NC 0         \NC \NR
1068\NC SkewedDelimiterTolerance          \NC \prm {Umathskeweddelimitertolerance}       \NC 0         \NC \NR
1069\NC AccentTopShiftUp                  \NC \prm {Umathaccenttopshiftup}               \NC undefined \NC \NR
1070\NC AccentBottomShiftDown             \NC \prm {Umathaccentbottomshiftdown}          \NC undefined \NC \NR
1071\NC AccentTopOvershoot                \NC \prm {Umathaccenttopovershoot}             \NC 0         \NC \NR
1072\NC AccentBottomOvershoot             \NC \prm {Umathaccentbottomovershoot}          \NC 0         \NC \NR
1073\NC AccentSuperscriptDrop             \NC \prm {Umathaccentsuperscriptdrop}          \NC 0         \NC \NR
1074\NC AccentSuperscriptPercent          \NC \prm {Umathaccentsuperscriptpercent}       \NC 0         \NC \NR
1075\NC AccentExtendMargin                \NC \prm {Umathaccentextendmargin}             \NC 0         \NC \NR
1076\NC FlattenedAccentTopShiftUp         \NC \prm {Umathflattenedaccenttopshiftup}      \NC undefined \NC \NR
1077\NC FlattenedAccentBottomShiftDown    \NC \prm {Umathflattenedaccentbottomshiftdown} \NC undefined \NC \NR
1078\NC DelimiterPercent                  \NC \prm {Umathdelimiterpercent}               \NC 0         \NC \NR
1079\NC DelimiterShortfall                \NC \prm {Umathdelimitershortfall}             \NC 0         \NC \NR
1080\stoptabulate
1081
1082These parameters not only provide a bit more control over rendering, they also
1083can be used in compensating issues in font, because no font is perfect. Some are
1084the side effects of experiments and they have CamelCase companions in the \type
1085{MathConstants} table. For historical reasons the names are a bit inconsistent as
1086some originate in \TEX\ so we prefer to keep those names. Not many users will
1087mess around with these font parameters anyway. \footnote {I wonder if some names
1088should change, so that decision is pending.}
1089
1090Each of the parameters in this section can be set by a command like this:
1091
1092\starttyping
1093\Umathquad\displaystyle=1em
1094\stoptyping
1095
1096they obey grouping, and you can use \type {\the\Umathquad\displaystyle} if
1097needed.
1098
1099There are quite some parameters that can be set and there are eight styles, which means a lot
1100of keying in. For that reason is is possible to set parameters groupwise:
1101
1102\starttabulate[|l|c|c|c|c|c|c|c|c|]
1103\DB primitive name               \BC D \BC D' \BC T \BC T' \BC S \BC S' \BC SS \BC SS' \NC \NR
1104\TB
1105\NC \prm {alldisplaystyles}      \NC$+$\NC$+ $\NC   \NC    \NC   \NC    \NC    \NC     \NC \NR
1106\NC \prm {alltextstyles}         \NC   \NC    \NC$+$\NC$+ $\NC   \NC    \NC    \NC     \NC \NR
1107\NC \prm {allscriptstyles}       \NC   \NC    \NC   \NC    \NC$+$\NC$+ $\NC    \NC     \NC \NR
1108\NC \prm {allscriptscriptstyles} \NC   \NC    \NC   \NC    \NC   \NC    \NC$+ $\NC$+  $\NC \NR
1109\NC \prm {allmathstyles}         \NC$+$\NC$+ $\NC$+$\NC$+ $\NC$+$\NC$+ $\NC$+ $\NC$+  $\NC \NR
1110\NC \prm {allmainstyles}         \NC   \NC    \NC   \NC    \NC   \NC    \NC    \NC     \NC \NR
1111\NC \prm {allsplitstyles}        \NC$+$\NC$+ $\NC$+$\NC$+ $\NC$-$\NC$- $\NC$- $\NC$-  $\NC \NR
1112\NC \prm {allunsplitstyles}      \NC   \NC    \NC   \NC    \NC$+$\NC$+ $\NC$+ $\NC$+  $\NC \NR
1113\NC \prm {alluncrampedstyles}    \NC$+$\NC    \NC$+$\NC    \NC$+$\NC    \NC$+ $\NC     \NC \NR
1114\NC \prm {allcrampedstyles}      \NC   \NC$+ $\NC   \NC$+ $\NC   \NC$+ $\NC    \NC$+  $\NC \NR
1115\LL
1116\stoptabulate
1117
1118These groups are especially handy when you set up inter atom spacing, pre- and
1119post atom penalties and atom rules.
1120
1121\stopsubsection
1122
1123\startsubsection[title={Font|-|based math parameters}]
1124
1125\topicindex {math+parameters}
1126
1127We already introduced the font specific math parameters but we tell abit more
1128about them and how they relate to the original \TEX\ font dimensions.
1129
1130While it is nice to have these math parameters available for tweaking, it would
1131be tedious to have to set each of them by hand. For this reason, \LUATEX\
1132initializes a bunch of these parameters whenever you assign a font identifier to
1133a math family based on either the traditional math font dimensions in the font
1134(for assignments to math family~2 and~3 using \TFM|-|based fonts like \type
1135{cmsy} and \type {cmex}), or based on the named values in a potential \type
1136{MathConstants} table when the font is loaded via Lua. If there is a \type
1137{MathConstants} table, this takes precedence over font dimensions, and in that
1138case no attention is paid to which family is being assigned to: the \type
1139{MathConstants} tables in the last assigned family sets all parameters.
1140
1141In the table below, the one|-|letter style abbreviations and symbolic tfm font
1142dimension names match those used in the \TeX book. Assignments to \prm
1143{textfont} set the values for the cramped and uncramped display and text styles,
1144\prm {scriptfont} sets the script styles, and \prm {scriptscriptfont} sets the
1145scriptscript styles, so we have eight parameters for three font sizes. In the
1146\TFM\ case, assignments only happen in family~2 and family~3 (and of course only
1147for the parameters for which there are font dimensions).
1148
1149Besides the parameters below, \LUATEX\ also looks at the \quote {space} font
1150dimension parameter. For math fonts, this should be set to zero.
1151
1152\def\MathLine#1#2#3#4#5%
1153  {\TB
1154   \NC \llap{\high{\tx #2\enspace}}\ttbf \prm {#1} \NC \tt #5 \NC \NR
1155   \NC \tx #3 \NC \tt #4 \NC \NR}
1156
1157\starttabulate[|l|l|]
1158\DB variable / style \BC tfm / opentype \NC \NR
1159\MathLine{Umathaxis}                     {}   {}                     {AxisHeight}                              {axis_height}
1160\MathLine{Umathaccentbaseheight}         {}   {}                     {AccentBaseHeight}                        {xheight}
1161\MathLine{Umathflattenedaccentbaseheight}{}   {}                     {FlattenedAccentBaseHeight}               {xheight}
1162\MathLine{Umathoperatorsize}             {6}  {D, D'}                {DisplayOperatorMinHeight}                {\emdash}
1163\MathLine{Umathfractiondelsize}          {9}  {D, D'}                {FractionDelimiterDisplayStyleSize}       {delim1}
1164\MathLine{Umathfractiondelsize}          {9}  {T, T', S, S', SS, SS'}{FractionDelimiterSize}                   {delim2}
1165\MathLine{Umathfractiondenomdown}        {}   {D, D'}                {FractionDenominatorDisplayStyleShiftDown}{denom1}
1166\MathLine{Umathfractiondenomdown}        {}   {T, T', S, S', SS, SS'}{FractionDenominatorShiftDown}            {denom2}
1167\MathLine{Umathfractiondenomvgap}        {}   {D, D'}                {FractionDenominatorDisplayStyleGapMin}   {3*default_rule_thickness}
1168\MathLine{Umathfractiondenomvgap}        {}   {T, T', S, S', SS, SS'}{FractionDenominatorGapMin}               {default_rule_thickness}
1169\MathLine{Umathfractionnumup}            {}   {D, D'}                {FractionNumeratorDisplayStyleShiftUp}    {num1}
1170\MathLine{Umathfractionnumup}            {}   {T, T', S, S', SS, SS'}{FractionNumeratorShiftUp}                {num2}
1171\MathLine{Umathfractionnumvgap}          {}   {D, D'}                {FractionNumeratorDisplayStyleGapMin}     {3*default_rule_thickness}
1172\MathLine{Umathfractionnumvgap}          {}   {T, T', S, S', SS, SS'}{FractionNumeratorGapMin}                 {default_rule_thickness}
1173\MathLine{Umathfractionrule}             {}   {}                     {FractionRuleThickness}                   {default_rule_thickness}
1174\MathLine{Umathskewedfractionhgap}       {}   {}                     {SkewedFractionHorizontalGap}             {math_quad/2}
1175\MathLine{Umathskewedfractionvgap}       {}   {}                     {SkewedFractionVerticalGap}               {math_x_height}
1176\MathLine{Umathlimitabovebgap}           {}   {}                     {UpperLimitBaselineRiseMin}               {big_op_spacing3}
1177\MathLine{Umathlimitabovekern}           {1}  {}                     {0}                                       {big_op_spacing5}
1178\MathLine{Umathlimitabovevgap}           {}   {}                     {UpperLimitGapMin}                        {big_op_spacing1}
1179\MathLine{Umathlimitbelowbgap}           {}   {}                     {LowerLimitBaselineDropMin}               {big_op_spacing4}
1180\MathLine{Umathlimitbelowkern}           {1}  {}                     {0}                                       {big_op_spacing5}
1181\MathLine{Umathlimitbelowvgap}           {}   {}                     {LowerLimitGapMin}                        {big_op_spacing2}
1182\MathLine{Umathoverdelimitervgap}        {}   {}                     {StretchStackGapBelowMin}                 {big_op_spacing1}
1183\MathLine{Umathoverdelimiterbgap}        {}   {}                     {StretchStackTopShiftUp}                  {big_op_spacing3}
1184\MathLine{Umathunderdelimitervgap}       {}   {}                     {StretchStackGapAboveMin}                 {big_op_spacing2}
1185\MathLine{Umathunderdelimiterbgap}       {}   {}                     {StretchStackBottomShiftDown}             {big_op_spacing4}
1186\MathLine{Umathoverbarkern}              {}   {}                     {OverbarExtraAscender}                    {default_rule_thickness}
1187\MathLine{Umathoverbarrule}              {}   {}                     {OverbarRuleThickness}                    {default_rule_thickness}
1188\MathLine{Umathoverbarvgap}              {}   {}                     {OverbarVerticalGap}                      {3*default_rule_thickness}
1189\MathLine{Umathquad}                     {1}  {}                     {<font_size(f)>}                          {math_quad}
1190\MathLine{Umathradicalkern}              {}   {}                     {RadicalExtraAscender}                    {default_rule_thickness}
1191\MathLine{Umathradicalrule}              {2}  {}                     {RadicalRuleThickness}                    {<not set>}
1192\MathLine{Umathradicalvgap}              {3}  {D, D'}                {RadicalDisplayStyleVerticalGap}          {default_rule_thickness+abs(math_x_height)/4}
1193\MathLine{Umathradicalvgap}              {3}  {T, T', S, S', SS, SS'}{RadicalVerticalGap}                      {default_rule_thickness+abs(default_rule_thickness)/4}
1194\MathLine{Umathradicaldegreebefore}      {2}  {}                     {RadicalKernBeforeDegree}                 {<not set>}
1195\MathLine{Umathradicaldegreeafter}       {2}  {}                     {RadicalKernAfterDegree}                  {<not set>}
1196\MathLine{Umathradicaldegreeraise}       {2,7}{}                     {RadicalDegreeBottomRaisePercent}         {<not set>}
1197\MathLine{Umathspaceafterscript}         {4}  {}                     {SpaceAfterScript}                        {script_space}
1198\MathLine{Umathstackdenomdown}           {}   {D, D'}                {StackBottomDisplayStyleShiftDown}        {denom1}
1199\MathLine{Umathstackdenomdown}           {}   {T, T', S, S', SS, SS'}{StackBottomShiftDown}                    {denom2}
1200\MathLine{Umathstacknumup}               {}   {D, D'}                {StackTopDisplayStyleShiftUp}             {num1}
1201\MathLine{Umathstacknumup}               {}   {T, T', S, S', SS, SS'}{StackTopShiftUp}                         {num3}
1202\MathLine{Umathstackvgap}                {}   {D, D'}                {StackDisplayStyleGapMin}                 {7*default_rule_thickness}
1203\MathLine{Umathstackvgap}                {}   {T, T', S, S', SS, SS'}{StackGapMin}                             {3*default_rule_thickness}
1204\MathLine{Umathsubshiftdown}             {}   {}                     {SubscriptShiftDown}                      {sub1}
1205\MathLine{Umathsubshiftdrop}             {}   {}                     {SubscriptBaselineDropMin}                {sub_drop}
1206\MathLine{Umathsubsupshiftdown}          {8}  {}                     {SubscriptShiftDownWithSuperscript}       {\emdash}
1207\MathLine{Umathsubtopmax}                {}   {}                     {SubscriptTopMax}                         {abs(math_x_height*4)/5}
1208\MathLine{Umathsubsupvgap}               {}   {}                     {SubSuperscriptGapMin}                    {4*default_rule_thickness}
1209\MathLine{Umathsupbottommin}             {}   {}                     {SuperscriptBottomMin}                    {abs(math_x_height/4)}
1210\MathLine{Umathsupshiftdrop}             {}   {}                     {SuperscriptBaselineDropMax}              {sup_drop}
1211\MathLine{Umathsupshiftup}               {}   {D}                    {SuperscriptShiftUp}                      {sup1}
1212\MathLine{Umathsupshiftup}               {}   {T, S, SS,}            {SuperscriptShiftUp}                      {sup2}
1213\MathLine{Umathsupshiftup}               {}   {D', T', S', SS'}      {SuperscriptShiftUpCramped}               {sup3}
1214\MathLine{Umathsupsubbottommax}          {}   {}                     {SuperscriptBottomMaxWithSubscript}       {abs(math_x_height*4)/5}
1215\MathLine{Umathunderbarkern}             {}   {}                     {UnderbarExtraDescender}                  {default_rule_thickness}
1216\MathLine{Umathunderbarrule}             {}   {}                     {UnderbarRuleThickness}                   {default_rule_thickness}
1217\MathLine{Umathunderbarvgap}             {}   {}                     {UnderbarVerticalGap}                     {3*default_rule_thickness}
1218\MathLine{Umathconnectoroverlapmin}      {5}  {}                     {MinConnectorOverlap}                     {0}
1219\LL
1220\stoptabulate
1221
1222A few notes:
1223
1224\startitemize[n]
1225
1226\startitem
1227    \OPENTYPE\ fonts set \prm {Umathlimitabovekern} and \prm
1228    {Umathlimitbelowkern} to zero and set \prm {Umathquad} to the font size of
1229    the used font, because these are not supported in the \type {MATH} table.
1230\stopitem
1231
1232\startitem
1233    Traditional \TFM\ fonts do not set \prm {Umathradicalrule} because \TEX82\
1234    uses the height of the radical instead. When this parameter is indeed not set
1235    when \LUATEX\ has to typeset a radical, a backward compatibility mode will
1236    kick in that assumes that an oldstyle \TEX\ font is used. Also, they do not
1237    set \prm {Umathradicaldegreebefore}, \prm {Umathradicaldegreeafter}, and \prm
1238    {Umathradicaldegreeraise}. These are then automatically initialized to
1239    $5/18$quad, $-10/18$quad, and 60.
1240\stopitem
1241
1242\startitem
1243    If \TFM\ fonts are used, then the \prm {Umathradicalvgap} is not set until
1244    the first time \LUATEX\ has to typeset a formula because this needs
1245    parameters from both family~2 and family~3. This provides a partial backward
1246    compatibility with \TEX82, but that compatibility is only partial: once the
1247    \prm {Umathradicalvgap} is set, it will not be recalculated any more.
1248\stopitem
1249
1250\startitem
1251    When \TFM\ fonts are used a similar situation arises with respect to \prm
1252    {Umathspaceafterscript}: it is not set until the first time \LUATEX\ has to
1253    typeset a formula. This provides some backward compatibility with \TEX82. But
1254    once the \prm {Umathspaceafterscript} is set, \prm {scriptspace} will never
1255    be looked at again.
1256\stopitem
1257
1258\startitem
1259    Traditional \TFM\ fonts set \prm {Umathconnectoroverlapmin} to zero because
1260    \TEX82\ always stacks extensibles without any overlap.
1261\stopitem
1262
1263\startitem
1264    The \prm {Umathoperatorsize} is only used in \prm {displaystyle}, and is only
1265    set in \OPENTYPE\ fonts. In \TFM\ font mode, it is artificially set to one
1266    scaled point more than the initial attempt's size, so that always the \quote
1267    {first next} will be tried, just like in \TEX82.
1268\stopitem
1269
1270\startitem
1271    The \prm {Umathradicaldegreeraise} is a special case because it is the only
1272    parameter that is expressed in a percentage instead of a number of scaled
1273    points.
1274\stopitem
1275
1276\startitem
1277    \type {SubscriptShiftDownWithSuperscript} does not actually exist in the
1278    \quote {standard} \OPENTYPE\ math font Cambria, but it is useful enough to be
1279    added.
1280\stopitem
1281
1282\startitem
1283    \type {FractionDelimiterDisplayStyleSize} and \type {FractionDelimiterSize}
1284    do not actually exist in the \quote {standard} \OPENTYPE\ math font Cambria,
1285    but were useful enough to be added.
1286\stopitem
1287
1288\stopitemize
1289
1290As this mostly refers to \LUATEX\ there is more to tell about how \LUAMETATEX\
1291deals with it. However, it is enough to know that much more behavior is
1292configurable.
1293
1294You can let the engine ignore parameter with \prm {setmathignore}, like:
1295
1296\starttyping
1297\setmathignore \Umathspacebeforescript 1
1298\setmathignore \Umathspaceafterscript  1
1299\stoptyping
1300
1301Be aware of the fact that a global setting can get unnoticed by users because
1302there is no warning that some parameter is ignored.
1303
1304\stopsubsection
1305
1306\stopsection
1307
1308\startsection[title={Extra parameters}]
1309
1310\startsubsection[title={Style related parameters}]
1311
1312There are a couple of parameters that don't relate to the font but are more generally
1313influencing the appearances. Some were added for experimenting.
1314
1315\starttabulate[|l|l|]
1316\DB primitive \BC meaning \NC \NR
1317\prm {Umathextrasubpreshift}    \NC \NR
1318\prm {Umathextrasubprespace}    \NC \NR
1319\prm {Umathextrasubshift}       \NC \NR
1320\prm {Umathextrasubspace}       \NC \NR
1321\prm {Umathextrasuppreshift}    \NC \NR
1322\prm {Umathextrasupprespace}    \NC \NR
1323\prm {Umathextrasupshift}       \NC \NR
1324\prm {Umathextrasupspace}       \NC \NR
1325\prm {Umathsubshiftdistance}    \NC \NR
1326\prm {Umathsupshiftdistance}    \NC \NR
1327\prm {Umathpresubshiftdistance} \NC \NR
1328\prm {Umathpresupshiftdistance} \NC \NR
1329\prm {Umathprimeshiftdrop}      \NC \NR
1330\LL
1331\stoptabulate
1332
1333\stopsubsection
1334
1335\startsubsection[title={Math struts}]
1336
1337Todo:
1338
1339\starttabulate[|l|l|]
1340\DB primitive \BC meaning \NC \NR
1341\NC \prm {Umathruleheight} \NC \NR
1342\NC \prm {Umathruledepth}  \NC \NR
1343\LL
1344\stoptabulate
1345
1346\stopsubsection
1347
1348\stopsection
1349
1350\startsection[title={Math spacing}]
1351
1352\startsubsection[reference=spacing:surround,title={Setting inline surrounding space with \prm {mathsurround} and \prm {mathsurroundskip}}]
1353
1354\topicindex {math+spacing}
1355
1356Inline math is surrounded by (optional) \prm {mathsurround} spacing but that is a fixed
1357dimension. There is now an additional parameter \prm {mathsurroundskip}. When set to a
1358non|-|zero value (or zero with some stretch or shrink) this parameter will replace
1359\prm {mathsurround}. By using an additional parameter instead of changing the nature
1360of \prm {mathsurround}, we can remain compatible. In the meantime a bit more
1361control has been added via \prm {mathsurroundmode}. This directive can take 6 values
1362with zero being the default behavior.
1363
1364\start
1365
1366\def\MathHack#1{\mathsurroundmode#1\relax\inlinebuffer}
1367
1368\def\OneLiner#1#2%
1369  {\NC \type{#1}
1370   \NC \dontleavehmode\inframed[align=normal,offset=0pt,frame=off]{\hsize 100pt  x$\MathHack{#1}x$x}
1371   \NC \dontleavehmode\inframed[align=normal,offset=0pt,frame=off]{\hsize 100pt x $\MathHack{#1}x$ x}
1372   \NC #2
1373   \NC \NR}
1374
1375\startbuffer
1376\mathsurround    10pt
1377\mathsurroundskip20pt
1378\stopbuffer
1379
1380\typebuffer
1381
1382\starttabulate[|c|c|c|pl|]
1383\DB mode \BC x\$x\$x \BC x \$x\$ x \BC effect \NC \NR
1384\TB
1385\OneLiner{0}{obey \prm {mathsurround} when \prm {mathsurroundskip} is 0pt}
1386\OneLiner{1}{only add skip to the left}
1387\OneLiner{2}{only add skip to the right}
1388\OneLiner{3}{add skip to the left and right}
1389\OneLiner{4}{ignore the skip setting, obey \prm {mathsurround}}
1390\OneLiner{5}{disable all spacing around math}
1391\OneLiner{6}{only apply \prm {mathsurroundskip} when also spacing}
1392\OneLiner{7}{only apply \prm {mathsurroundskip} when no spacing}
1393\LL
1394\stoptabulate
1395
1396\stop
1397
1398Anything more fancy, like checking the beginning or end of a paragraph (or edges
1399of a box) would not be robust anyway. If you want that you can write a callback
1400that runs over a list and analyzes a paragraph. Actually, in that case you could
1401also inject glue (or set the properties of a math node) explicitly. So, these
1402modes are in practice mostly useful for special purposes and experiments (they
1403originate in a tracker item). Keep in mind that this glue is part of the math
1404node and not always treated as normal glue: it travels with the begin and end
1405math nodes. Also, method 6 and 7 will zero the skip related fields in a node when
1406applicable in the first occasion that checks them (linebreaking or packaging).
1407
1408\stopsubsection
1409
1410\startsubsection[title={Pairwise spacing}]
1411
1412\topicindex {math+spacing}
1413
1414Besides the parameters mentioned in the previous sections, there are also
1415primitives to control the math spacing table (as explained in Chapter~18 of the
1416\TEX book). This happens per class pair. Because we have many possible classes,
1417we no longer have the many primitives that \LUATEX\ has but you can define then
1418using the generic \prm {setmathspacing} primitive:
1419
1420\starttyping
1421\def\Umathordordspacing     {\setmathspacing 0 0 }
1422\def\Umathordordopenspacing {\setmathspacing 0 4 }
1423\stoptyping
1424
1425These parameters are (normally) of type \prm {muskip}, so setting a parameter can
1426be done like this:
1427
1428\starttyping
1429\setmathspacing 1 0 \displaystyle=4mu plus 2mu % op ord Umathopordspacing
1430\stoptyping
1431
1432The atom pairs known by the engine are all initialized by \type {initex} to the
1433values mentioned in the table in Chapter~18 of the \TEX book.
1434
1435For ease of use as well as for backward compatibility, \prm {thinmuskip}, \prm
1436{medmuskip} and \prm {thickmuskip} are treated specially. In their case a pointer
1437to the corresponding internal parameter is saved, not the actual \prm {muskip}
1438value. This means that any later changes to one of these three parameters will be
1439taken into account. As a bonus we also introduced the \prm {tinymuskip} and \prm
1440{pettymuskip} primitives, just because we consider these fundamental, but they
1441are not assigned internally to atom spacing combinations.
1442
1443In \LUAMETATEX\ we go a bit further. Any named dimension, glue and mu glue
1444register as well as the constants with these properties can be bound to a pair by
1445prefixing \prm {setmathspacing} by \prm {inherited}.
1446
1447Careful readers will realize that there are also primitives for the items marked
1448\type {*} in the \TEX book. These will actually be used because we pose no
1449restrictions. However, you can enforce the remapping rules to conform to the
1450rules of \TEX\ (or yourself).
1451
1452Every class has a set of spacing parameters and the more classes you define the more
1453pairwise spacing you need to define. However, you can default to an existing class.
1454By default all spacing is zero and you can get rid of the defaults inherited from
1455good old \TEX\ with \prm {resetmathspacing}. You can alias class spacing to an exiting
1456class with \prm {letmathspacing}:
1457
1458\starttyping
1459\letmathspacing class displayclass textclass scriptclass scriptscriptclass
1460\stoptyping
1461
1462Instead you can copy spacing with \prm {copymathspacing}:
1463
1464\starttyping
1465\copymathspacing class parentclass
1466\stoptyping
1467
1468Specific paring happens with \prm {setmathspacing}:
1469
1470\starttyping
1471\setmathspacing leftclass rightclass style value
1472\stoptyping
1473
1474Unless we have a frozen parameter, the prefix \prm {inherited} makes it possible
1475to have a more dynamic relationship: the used value resolves to the current value
1476of the given register. Possible values are the usual mu skip register, a regular
1477skip or dimension register, or just some mu skip value.
1478
1479A similar set of primitives deals with rules. These remap pairs onto other pairs, so
1480\prm {setmathatomrule} looks like:
1481
1482\starttyping
1483\setmathatomrule oldleftclass oldrightclass newleftclass newrightclass
1484\stoptyping
1485
1486The \prm {letmathatomrule} and \prm {copymathatomrule} primitives take two
1487classes where the second is the parent.
1488
1489Some primitives are still experimental and might evolve, like \prm
1490{letmathparent} and \prm {copymathparent} that take numbers as in:
1491
1492\starttyping
1493\letmathatomrule class spacingclass prepenaltyclass postpenaltyclass options reserved
1494\stoptyping
1495
1496Primitives like this were used when experimenting and when re use them in \CONTEXT\
1497eventually they will become stable.
1498
1499The \prm {setmathprepenalty} and \prm {setmathpostpenalty} primitives take a
1500class and penalty (integer) value. These are injected before and after atoms with
1501the given class where a penalty of 10000 is a signal to ignore it.
1502
1503The engine control options for a class can be set with \prm {setmathoptions}. The
1504possible options are discussed elsewhere. This primitive takes a class number and
1505an integer (bitset). For all these setters the \CONTEXT\ math setup gives examples.
1506
1507\stopsubsection
1508
1509% \setdefaultmathcodes
1510% \setmathignore        parameter
1511
1512\startsubsection[title={Local \prm {frozen} settings with}]
1513
1514Math is processed in two passes. The first pass is needed to intercept for
1515instance \type {\over}, one of the few \TEX\ commands that actually has a
1516preceding argument. There are often lots of curly braces used in math and these
1517can result in a nested run of the math sub engine. However, you need to be aware
1518of the fact that some properties are kind of global to a formula and the last
1519setting (for instance a family switch) wins. This also means that a change (or
1520again, the last one) in math parameters affects the whole formula. In
1521\LUAMETATEX\ we have changed this model a bit. One can argue that this introduces
1522an incompatibility but it's hard to imagine a reason for setting the parameters
1523at the end of a formula run and assume that they also influence what goes in
1524front.
1525
1526\startbuffer
1527$
1528                                               x \subscript  {-}
1529     \frozen\Umathsubshiftdown\textstyle  0pt  x \subscript  {0}
1530    {\frozen\Umathsubshiftdown\textstyle  5pt  x \subscript  {5}}
1531                                               x \subscript  {0}
1532    {\frozen\Umathsubshiftdown\textstyle 15pt  x \subscript {15}}
1533                                               x \subscript  {0}
1534    {\frozen\Umathsubshiftdown\textstyle 20pt  x \subscript {20}}
1535                                               x \subscript  {0}
1536     \frozen\Umathsubshiftdown\textstyle 10pt  x \subscript {10}
1537                                               x \subscript  {0}
1538$
1539\stopbuffer
1540
1541\typebuffer
1542
1543The \type {\frozen} prefix does the magic: it injects information in the
1544math list about the set parameter.
1545
1546In \LUATEX\ 1.10+ the last setting, the \type {10pt} drop wins, but in
1547\LUAMETATEX\ you will see each local setting taking effect. The implementation
1548uses a new node type, parameters nodes, so you might encounter these in an
1549unprocessed math list. The result looks as follows:
1550
1551\blank \getbuffer \blank
1552
1553\stopsubsection
1554
1555\startsubsection[title={Arbitrary atoms with \prm {mathatom} etc.}]
1556
1557The original \TEX\ engine has primitives like \prm {mathord} and a limited set of
1558possible atoms. In \LUAMETATEX\ we have many more built in and you can add more.
1559It will take a while before we have documented all the new math features and more
1560details can be found in the manuals that come with \CONTEXT\ for which all this
1561was implemented. In addition to \prm {mathordinary} (aka \prm {mathord}), \prm
1562{mathoperator} (aka \prm {mathop}), \prm {mathbinary} (aka \prm {mathbin}), \prm
1563{mathrelation} (aka \prm {mathrel}), \prm {mathopen}, \prm {mathclose}, \prm
1564{mathpunctuation} (aka {mathpunct}) and \prm {mathinner} we have \prm
1565{mathfraction}, \prm {mathradical}, \prm {mathmiddle}, \prm {mathaccent}, \prm
1566{mathfenced}, \prm {mathghost} and the existing \prm {mathunderline} (aka \prm
1567{underline}) and \prm {mathoverline} (aka \prm {overline}) class driven atoms.
1568
1569The \prm {mathatom} primitive is the generic one and it accepts a couple of
1570keywords:
1571
1572\starttabulate[|lT|l|l|]
1573\DB keyword    \BC argument \NC meaning \NC \NR
1574\TB
1575\NC attr       \NC int int \NC attributes to be applied to this atom \NC \NR
1576\NC leftclass  \NC class   \NC the left edge class that determines spacing etc \NC \NR
1577\NC rightclass \NC class   \NC the right edge class that determines spacing etc \NC \NR
1578\NC class      \NC class   \NC the general class \NC \NR
1579\NC unpack     \NC         \NC unpack this atom in inline math \NC \NR
1580\NC source     \NC int     \NC a symbolic index of the resulting box \NC \NR
1581\NC textfont   \NC         \NC use the current text font \NC \NR
1582\NC mathfont   \NC         \NC use the current math font \NC \NR
1583\NC limits     \NC         \NC put scripts on top and below \NC \NR
1584\NC nolimits   \NC         \NC force scripts to be postscripts \NC \NR
1585\NC nooverflow \NC         \NC keep (extensible) within target dimensions \NC \NR
1586\NC options    \NC int     \NC bitset with options \NC \NR
1587\NC void       \NC         \NC discard content and ignore dimensions \NC \NR
1588\NC phantom    \NC         \NC discard content but retain dimensions \NC \NR
1589\LL
1590\stoptabulate
1591
1592To what extend the options kick in depends on the class as well where and how the
1593atom is used.
1594
1595The original \TEX\ engines has three atom modifiers: \prm {displaylimits}, \prm
1596{limits}, and \prm {nolimits}. These look back to the last atom and set a limit
1597related signal. Just to be consistent we have some more of that: \prm
1598{Umathadapttoleft}, \prm {Umathadapttoright}, \prm {Umathuseaxis}, \prm
1599{Umathnoaxis}, \prm {Umathphantom}, \prm {Umathvoid}, \prm {Umathsource}, \prm
1600{Umathopenupheight}, \prm {Umathopenupdepth}, \prm {Umathlimits}, \prm
1601{Umathnolimits}. The last two are equivalent to the lowercase ones with the
1602similar names. Al these modifiers are cheap primitives and one can wonder if they
1603are needed but that also now also applies to the original three. We could stick
1604to one modifier that takes an integer but let's not diverge too much from the
1605original concept.
1606
1607The \prm {nonscript} primitive injects a glue node that signals that the next
1608glue is to be ignored when we are in script or scriptscript mode. The \prm
1609{noatomruling} does the same but this time the signal is that no inter|-|atom
1610rules need to be applied.
1611
1612\stopsubsection
1613
1614\startsubsection[title={Checking a state with \prm {ifmathparameter}}]
1615
1616When you adapt math parameters it might make sense to see if they are set at all.
1617When a parameter is unset its value has the maximum dimension value and you might
1618for instance mistakenly multiply that value to open up things a bit, which gives
1619unexpected side effects. For that reason there is a convenient checker: \prm
1620{ifmathparameter}. This test primitive behaves like an \prm {ifcase}, with:
1621
1622\starttabulate[|c|l|]
1623\DB value \BC meaning \NC \NR
1624\TB
1625\NC 0 \NC the parameter value is zero \NC \NR
1626\NC 1 \NC the parameter is set \NC \NR
1627\NC 2 \NC the parameter is unset \NC \NR
1628\LL
1629\stoptabulate
1630
1631\stopsubsection
1632
1633\startsubsection[title={Forcing fixed scripts with \prm {mathscriptsmode}}]
1634
1635We have three parameters that are used for this fixed anchoring:
1636
1637\starttabulate[|c|l|]
1638\DB parameter \BC register \NC \NR
1639\NC $d$ \NC \prm {Umathsubshiftdown}    \NC \NR
1640\NC $u$ \NC \prm {Umathsupshiftup}      \NC \NR
1641\NC $s$ \NC \prm {Umathsubsupshiftdown} \NC \NR
1642\LL
1643\stoptabulate
1644
1645When we set \prm {mathscriptsmode} to a value other than zero these are used
1646for calculating fixed positions. This is something that is needed for instance
1647for chemistry. You can manipulate the mentioned variables to achieve different
1648effects.
1649
1650\def\SampleMath#1%
1651  {$\mathscriptsmode#1\mathupright CH_2 + CH^+_2 + CH^2_2$}
1652
1653\starttabulate[|c|c|c|p|]
1654\DB mode \BC down          \BC up            \BC example        \NC \NR
1655\TB
1656\NC 0    \NC dynamic       \NC dynamic       \NC \SampleMath{0} \NC \NR
1657\NC 1    \NC $d$           \NC $u$           \NC \SampleMath{1} \NC \NR
1658\NC 2    \NC $s$           \NC $u$           \NC \SampleMath{2} \NC \NR
1659%
1660% In \LUATEX\ but dropped in \LUAMETATEX:
1661%
1662%NC 3    \NC $s$           \NC $u + s - d$   \NC \SampleMath{3} \NC \NR
1663%NC 4    \NC $d + (s-d)/2$ \NC $u + (s-d)/2$ \NC \SampleMath{4} \NC \NR
1664%NC 5    \NC $d$           \NC $u + s - d$   \NC \SampleMath{5} \NC \NR
1665\LL
1666\stoptabulate
1667
1668The value of this parameter obeys grouping and is applied to character atoms only
1669(but that might evolve as we go).
1670
1671\stopsubsection
1672
1673\startsubsection[title={Penalties: \prm {mathpenaltiesmode}}]
1674
1675\topicindex {math+penalties}
1676
1677Only in inline math penalties will be added in a math list. You can force
1678penalties (also in display math) by setting:
1679
1680\starttyping
1681\mathpenaltiesmode = 1
1682\stoptyping
1683
1684This primnitive is not really needed in \LUATEX\ because you can use the callback
1685\cbk {mlist_to_hlist} to force penalties by just calling the regular routine
1686with forced penalties. However, as part of opening up and control this primitive
1687makes sense. As a bonus we also provide two extra penalties:
1688
1689\starttyping
1690\prebinoppenalty = -100 % example value
1691\prerelpenalty   =  900 % example value
1692\stoptyping
1693
1694They default to inifinite which signals that they don't need to be inserted. When
1695set they are injected before a binop or rel noad. This is an experimental feature.
1696
1697\stopsubsection
1698
1699\startsubsection[title={Equation spacing: \prm {matheqnogapstep}}]
1700
1701By default \TEX\ will add one quad between the equation and the number. This is
1702hard coded. A new primitive can control this:
1703
1704\startsyntax
1705\matheqnogapstep = 1000
1706\stopsyntax
1707
1708Because a math quad from the math text font is used instead of a dimension, we
1709use a step to control the size. A value of zero will suppress the gap. The step
1710is divided by 1000 which is the usual way to mimmick floating point factors in
1711\TEX.
1712
1713\stopsubsection
1714
1715\stopsection
1716
1717\startsection[title={Math constructs}]
1718
1719\startsubsection[title={Cheating with fences}]
1720
1721\topicindex {math+fences}
1722
1723Sometimes you might want to act upon the size of a delimiter, something that is
1724not really possible because of the fact that they are calculated {\em after} most
1725has been typeset already. For this we have two keyword: \type {phantom} and
1726\type {void}. In both cases the symbol is replaced by an empty rule, in the first
1727case all three dimensions are preserved in the last case only the height and depth.
1728
1729\startbuffer
1730\startformula
1731    x\mathlimop{\Uvextensible         \Udelimiter 5 0 "222B}_1^2 x
1732\stopformula
1733\vskip-9ex
1734\startformula \red
1735    x\mathlimop{\Uvextensible phantom \Udelimiter 5 0 "222B}_1^2 x
1736\stopformula
1737\vskip-9ex
1738\startformula \blue
1739    x\mathlimop{\Uvextensible void    \Udelimiter 5 0 "222B}_1^2 x
1740\stopformula
1741\stopbuffer
1742
1743\typebuffer
1744
1745In typeset form this looks like:
1746
1747\getbuffer
1748
1749Normally fences need to be matched, that is: when a left fence is seen, there has
1750to be a right fence. When you set \prm {mathcheckfencesmode} to non|-|zero the
1751scanner silently recovers from this.
1752
1753\stopsubsection
1754
1755\startsubsection[title={Accent handling with \prm {Umathaccent}},reference=mathacc]
1756
1757\topicindex {math+accents}
1758
1759\LUATEX\ supports both top accents and bottom accents in math mode, and math
1760accents stretch automatically (if this is supported by the font the accent comes
1761from, of course). Bottom and combined accents as well as fixed-width math accents
1762are controlled by optional keywords following \prm {Umathaccent}.
1763
1764The keyword \type {bottom} after \prm {Umathaccent} signals that a bottom accent
1765is needed, and the keyword \type {both} signals that both a top and a bottom
1766accent are needed (in this case two accents need to be specified, of course).
1767
1768Then the set of three integers defining the accent is read. This set of integers
1769can be prefixed by the \type {fixed} keyword to indicate that a non-stretching
1770variant is requested (in case of both accents, this step is repeated).
1771
1772A simple example:
1773
1774\starttyping
1775\Umathaccent both fixed 0 0 "20D7 fixed 0 0 "20D7 {example}
1776\stoptyping
1777
1778If a math top accent has to be placed and the accentee is a character and has a
1779non-zero \type {top_accent} value, then this value will be used to place the
1780accent instead of the \prm {skewchar} kern used by \TEX82.
1781
1782The \type {top_accent} value represents a vertical line somewhere in the
1783accentee. The accent will be shifted horizontally such that its own \type
1784{top_accent} line coincides with the one from the accentee. If the \type
1785{top_accent} value of the accent is zero, then half the width of the accent
1786followed by its italic correction is used instead.
1787
1788The vertical placement of a top accent depends on the \type {x_height} of the
1789font of the accentee (as explained in the \TEX book), but if a value turns out
1790to be zero and the font had a \type {MathConstants} table, then \type
1791{AccentBaseHeight} is used instead.
1792
1793The vertical placement of a bottom accent is straight below the accentee, no
1794correction takes place.
1795
1796Possible locations are \type {top}, \type {bottom}, \type {both} and \type
1797{center}. When no location is given \type {top} is assumed. An additional
1798parameter \nod {fraction} can be specified followed by a number; a value of for
1799instance 1200 means that the criterium is 1.2 times the width of the nucleus. The
1800fraction only applies to the stepwise selected shapes and is mostly meant for the
1801\type {overlay} location. It also works for the other locations but then it
1802concerns the width.
1803
1804\stopsubsection
1805
1806\startsubsection[title={Building radicals with \prm {Uradical}, \prm {Uroot} and \prm {Urooted}}]
1807
1808\topicindex {math+radicals}
1809\topicindex {math+roots}
1810
1811The new primitive \prm {Uroot} allows the construction of a radical noad
1812including a degree field. Its syntax is an extension of \prm {Uradical}:
1813
1814\starttyping
1815\Uradical
1816    <fam integer> <left char integer>
1817    <content>
1818\Uroot
1819    <fam integer> <left char integer>
1820    <degree>
1821    <content>
1822\Urooted
1823    <fam integer> <left char integer>
1824    <fam integer> <right char integer>
1825    <degree>
1826    <content>
1827\stoptyping
1828
1829The placement of the degree is controlled by the math parameters \prm
1830{Umathradicaldegreebefore}, \prm {Umathradicaldegreeafter}, and \prm
1831{Umathradicaldegreeraise}. The degree will be typeset in \prm
1832{scriptscriptstyle}.
1833
1834In \CONTEXT\ we use \prm {Urooted} to wrap something in an \quote {annuity}
1835umbrella where there is a symbol at the end that has to behave like the radical
1836does at the left end: adapt its size. In order to support variants this primitive
1837supports two delimiters.
1838
1839{\em todo: mention optional keywords}
1840
1841\stopsubsection
1842
1843\startsubsection[title={Tight delimiters with \prm {Udelimited}}]
1844
1845\topicindex {math+radicals}
1846\topicindex {math+delimiters}
1847
1848This new primitive is like \prm {Urooted} in that it takes two delimiters but it
1849takes no degree and no rule is drawn.
1850
1851\starttyping
1852\Udelimited
1853    <fam integer> <left char integer>
1854    <fam integer> <right char integer>
1855    <content>
1856\stoptyping
1857
1858In \CONTEXT\ we use it for fourier notations in which case there is only a right
1859symbol (like a hat).
1860
1861{\em todo: mention optional keywords}
1862
1863\stopsubsection
1864
1865\startsubsection[title={Super- and subscripts}]
1866
1867The character fields in a \LUA|-|loaded \OPENTYPE\ math font can have a \quote
1868{mathkern} table. The format of this table is the same as the \quote {mathkern}
1869table that is returned by the \type {fontloader} library, except that all height
1870and kern values have to be specified in actual scaled points.
1871
1872When a super- or subscript has to be placed next to a math item, \LUATEX\ checks
1873whether the super- or subscript and the nucleus are both simple character items.
1874If they are, and if the fonts of both character items are \OPENTYPE\ fonts (as
1875opposed to legacy \TEX\ fonts), then \LUATEX\ will use the \OPENTYPE\ math
1876algorithm for deciding on the horizontal placement of the super- or subscript.
1877
1878This works as follows:
1879
1880\startitemize
1881    \startitem
1882        The vertical position of the script is calculated.
1883    \stopitem
1884    \startitem
1885        The default horizontal position is flat next to the base character.
1886    \stopitem
1887    \startitem
1888        For superscripts, the italic correction of the base character is added.
1889    \stopitem
1890    \startitem
1891        For a superscript, two vertical values are calculated: the bottom of the
1892        script (after shifting up), and the top of the base. For a subscript, the two
1893        values are the top of the (shifted down) script, and the bottom of the base.
1894    \stopitem
1895    \startitem
1896        For each of these two locations:
1897        \startitemize
1898            \startitem
1899                find the math kern value at this height for the base (for a subscript
1900                placement, this is the bottom_right corner, for a superscript
1901                placement the top_right corner)
1902            \stopitem
1903            \startitem
1904                find the math kern value at this height for the script (for a
1905                subscript placement, this is the top_left corner, for a superscript
1906                placement the bottom_left corner)
1907            \stopitem
1908            \startitem
1909                add the found values together to get a preliminary result.
1910            \stopitem
1911        \stopitemize
1912    \stopitem
1913    \startitem
1914        The horizontal kern to be applied is the smallest of the two results from
1915        previous step.
1916    \stopitem
1917\stopitemize
1918
1919The math kern value at a specific height is the kern value that is specified by the
1920next higher height and kern pair, or the highest one in the character (if there is no
1921value high enough in the character), or simply zero (if the character has no math kern
1922pairs at all).
1923
1924\stopsubsection
1925
1926\startsubsection[title={Scripts on extensibles: \prm {Uunderdelimiter}, \prm {Uoverdelimiter},
1927\prm {Udelimiterover}, \prm {Udelimiterunder} and \prm {Uhextensible}}]
1928
1929\topicindex {math+scripts}
1930\topicindex {math+delimiters}
1931\topicindex {math+extensibles}
1932
1933The primitives \prm {Uunderdelimiter} and \prm {Uoverdelimiter} allow the
1934placement of a subscript or superscript on an automatically extensible item and
1935\prm {Udelimiterunder} and \prm {Udelimiterover} allow the placement of an
1936automatically extensible item as a subscript or superscript on a nucleus. The
1937input:
1938
1939% these produce radical noads .. in fact the code base has the numbers wrong for
1940% quite a while, so no one seems to use this
1941
1942\startbuffer
1943$\Uoverdelimiter  0 "2194 {\hbox{\strut  overdelimiter}}$
1944$\Uunderdelimiter 0 "2194 {\hbox{\strut underdelimiter}}$
1945$\Udelimiterover  0 "2194 {\hbox{\strut  delimiterover}}$
1946$\Udelimiterunder 0 "2194 {\hbox{\strut delimiterunder}}$
1947\stopbuffer
1948
1949\typebuffer will render this:
1950
1951\blank \startnarrower \getbuffer \stopnarrower \blank
1952
1953The vertical placements are controlled by \prm {Umathunderdelimiterbgap}, \prm
1954{Umathunderdelimitervgap}, \prm {Umathoverdelimiterbgap}, and \prm
1955{Umathoverdelimitervgap} in a similar way as limit placements on large operators.
1956The superscript in \prm {Uoverdelimiter} is typeset in a suitable scripted style,
1957the subscript in \prm {Uunderdelimiter} is cramped as well.
1958
1959These primitives accepts an optional \type {width} specification. When used the
1960also optional keywords \type {left}, \type {middle} and \type {right} will
1961determine what happens when a requested size can't be met (which can happen when
1962we step to successive larger variants).
1963
1964An extra primitive \prm {Uhextensible} is available that can be used like this:
1965
1966\startbuffer
1967$\Uhextensible width 10cm 0 "2194$
1968\stopbuffer
1969
1970\typebuffer This will render this:
1971
1972\blank \startnarrower \getbuffer \stopnarrower \blank
1973
1974Here you can also pass options, like:
1975
1976\startbuffer
1977$\Uhextensible width 1pt middle 0 "2194$
1978\stopbuffer
1979
1980\typebuffer This gives:
1981
1982\blank \startnarrower \getbuffer \stopnarrower \blank
1983
1984\LUATEX\ internally uses a structure that supports \OPENTYPE\ \quote
1985{MathVariants} as well as \TFM\ \quote {extensible recipes}. In most cases where
1986font metrics are involved we have a different code path for traditional fonts end
1987\OPENTYPE\ fonts.
1988
1989\stopsubsection
1990
1991\startsubsection[title={Fractions and the new \prm {Ustretched} and \prm {Ustretchedwithdelims}}]
1992
1993\topicindex {math+fractions}
1994
1995These commands are similar the regular rule separated fractions but expect a delimiter
1996that then will be used instead. This permits for instance the use of horizontal
1997extensible arrows. When no extensible is possible (this is a font property) the given
1998glyph is centered.
1999
2000Normally one will pass a specific delimiter and not a character, if only because
2001these come from the non \ASCII\ ranges:
2002
2003\starttyping
2004{ \Ustretched <delimiter> <options> {1} {2} }
2005{ \Ustretchedwithdelims <delimiter> () <options> {1} {2} }
2006\stoptyping
2007
2008\stopsubsection
2009
2010\startsubsection[title={Fractions and the new \prm {Uskewed} and \prm {Uskewedwithdelims}}]
2011
2012\topicindex {math+fractions}
2013
2014The \prm {abovewithdelims} command accepts a keyword \type {exact}. When issued
2015the extra space relative to the rule thickness is not added. One can of course
2016use the \type {\Umathfraction..gap} commands to influence the spacing. Also the
2017rule is still positioned around the math axis.
2018
2019\starttyping
2020$$ { {a} \abovewithdelims() exact 4pt {b} }$$
2021\stoptyping
2022
2023The math parameter table contains some parameters that specify a horizontal and
2024vertical gap for skewed fractions. Of course some guessing is needed in order to
2025implement something that uses them. And so we now provide a primitive similar to the
2026other fraction related ones but with a few options so that one can influence the
2027rendering. Of course a user can also mess around a bit with the parameters
2028\prm {Umathskewedfractionhgap} and \prm {Umathskewedfractionvgap}.
2029
2030The syntax used here is:
2031
2032\starttyping
2033{ \Uskewed / <options> {1} {2} }
2034{ \Uskewedwithdelims / () <options> {1} {2} }
2035\stoptyping
2036
2037where the options can be \type {noaxis} and \type {exact}. By default we add half
2038the axis to the shifts and by default we zero the width of the middle character.
2039For Latin Modern the result looks as follows:
2040
2041\def\ShowA#1#2#3{$x + { \Uskewed           /    #3 {#1} {#2} } + x$}
2042\def\ShowB#1#2#3{$x + { \Uskewedwithdelims / () #3 {#1} {#2} } + x$}
2043
2044\start
2045    \switchtobodyfont[modern]
2046    \starttabulate[||||||]
2047        \NC \NC
2048            \ShowA{a}{b}{} \NC
2049            \ShowA{1}{2}{} \NC
2050            \ShowB{a}{b}{} \NC
2051            \ShowB{1}{2}{} \NC
2052        \NR
2053        \NC \type{exact} \NC
2054            \ShowA{a}{b}{exact} \NC
2055            \ShowA{1}{2}{exact} \NC
2056            \ShowB{a}{b}{exact} \NC
2057            \ShowB{1}{2}{exact} \NC
2058        \NR
2059        \NC \type{noaxis} \NC
2060            \ShowA{a}{b}{noaxis} \NC
2061            \ShowA{1}{2}{noaxis} \NC
2062            \ShowB{a}{b}{noaxis} \NC
2063            \ShowB{1}{2}{noaxis} \NC
2064        \NR
2065        \NC \type{exact noaxis} \NC
2066            \ShowA{a}{b}{exact noaxis} \NC
2067            \ShowA{1}{2}{exact noaxis} \NC
2068            \ShowB{a}{b}{exact noaxis} \NC
2069            \ShowB{1}{2}{exact noaxis} \NC
2070        \NR
2071    \stoptabulate
2072\stop
2073
2074The \type {\over} and related primitives have the form:
2075
2076\starttyping
2077{{top}\over{bottom}}
2078\stoptyping
2079
2080For convenience, which also avoids some of the trickery that makes this
2081\quote {looking back} possible, the \LUAMETATEX\ also provides this variant:
2082
2083\starttyping
2084\Uover{top}{bottom}
2085\stoptyping
2086
2087The optional arguments are also supported but we have one extra option: \type
2088{style}. The style is applied to the numerator and denominator.
2089
2090\starttyping
2091\Uover style \scriptstyle {top} {bottom}
2092\stoptyping
2093
2094The complete list of these commands is: \prm {Uabove}, \prm {Uatop}, \prm
2095{Uover}, \prm {Uabovewithdelims}, \prm {Uatopwithdelims}, \prm {Uoverwithdelims},
2096\prm {Uskewed}, \prm {Uskewedwithdelims}. As with other extensions we use a
2097leading \type {U}. Here are a few examples:
2098
2099\startbuffer
2100$\Uover {                   1234} {                   5678} $\quad
2101$\Uover {\textstyle         1234} {\textstyle         5678} $\quad
2102$\Uover {\scriptstyle       1234} {\scriptstyle       5678} $\quad
2103$\Uover {\scriptscriptstyle 1234} {\scriptscriptstyle 5678} $\blank
2104
2105$\Uover                          {1234} {5678} $\quad
2106$\Uover style \textstyle         {1234} {5678} $\quad
2107$\Uover style \scriptstyle       {1234} {5678} $\quad
2108$\Uover style \scriptscriptstyle {1234} {5678} $\blank
2109\stopbuffer
2110
2111\typebuffer
2112
2113These render as: \getbuffer
2114
2115\stopsubsection
2116
2117\startsubsection[title={Math styles: \prm {givenmathstyle}}]
2118
2119This primitive accepts a style identifier:
2120
2121\starttyping
2122\givenmathstyle \displaystyle
2123\stoptyping
2124
2125This in itself is not spectacular because it is equivalent to
2126
2127\starttyping
2128\displaystyle
2129\stoptyping
2130
2131Both commands inject a style node and change the current style. However, as in other
2132places where \LUAMETATEX\ expects a style you can also pass a number in the range
2133zero upto seven (like the ones reported by the primitive \prm {mathstyle}). So, the
2134next few lines give identical results:
2135
2136\startbuffer
2137$\givenmathstyle0                         \number\mathstyle
2138 \givenmathstyle7                         \number\mathstyle$
2139$\givenmathstyle\displaystyle             \number\mathstyle
2140 \givenmathstyle\crampedscriptscriptstyle \number\mathstyle$
2141$\displaystyle                            \number\mathstyle
2142 \crampedscriptscriptstyle                \number\mathstyle$
2143\stopbuffer
2144
2145Like: \inlinebuffer . Values outside the valid range are ignored.
2146
2147There is an extra option \type {norule} that can be used to suppress the rule while
2148keeping the spacing compatible.
2149
2150\stopsubsection
2151
2152\startsubsection[title={Delimiters: \prm {Uleft}, \prm {Umiddle} and \prm {Uright}}]
2153
2154\topicindex {math+delimiters}
2155
2156Normally you will force delimiters to certain sizes by putting an empty box or
2157rule next to it. The resulting delimiter will either be a character from the
2158stepwise size range or an extensible. The latter can be quite differently
2159positioned than the characters as it depends on the fit as well as the fact
2160whether the used characters in the font have depth or height. Commands like
2161(plain \TEX s) \type {\big} need to use this feature. In \LUATEX\ we provide a bit
2162more control by three variants that support optional parameters \type {height},
2163\type {depth} and \type {axis}. The following example uses this:
2164
2165\startbuffer
2166\Uleft   height 30pt depth 10pt      \Udelimiter "0 "0 "000028
2167\quad x\quad
2168\Umiddle height 40pt depth 15pt      \Udelimiter "0 "0 "002016
2169\quad x\quad
2170\Uright  height 30pt depth 10pt      \Udelimiter "0 "0 "000029
2171\quad \quad \quad
2172\Uleft   height 30pt depth 10pt axis \Udelimiter "0 "0 "000028
2173\quad x\quad
2174\Umiddle height 40pt depth 15pt axis \Udelimiter "0 "0 "002016
2175\quad x\quad
2176\Uright  height 30pt depth 10pt axis \Udelimiter "0 "0 "000029
2177\stopbuffer
2178
2179\typebuffer
2180
2181\startlinecorrection
2182\ruledhbox{\mathematics{\getbuffer}}
2183\stoplinecorrection
2184
2185The keyword \type {exact} can be used as directive that the real dimensions
2186should be applied when the criteria can't be met which can happen when we're
2187still stepping through the successively larger variants. When no dimensions are
2188given the \type {noaxis} command can be used to prevent shifting over the axis.
2189
2190You can influence the final class with the keyword \type {class} which will
2191influence the spacing. The numbers are the same as for character classes.
2192
2193\stopsubsection
2194
2195\stopsection
2196
2197\startsection[title={Extracting values}]
2198
2199\startsubsection[title={Codes and using \prm {Umathcode}, \prm {mathcharclass}, \prm
2200{Umathcharfam} and \prm {Umathcharslot}}]
2201
2202\topicindex {math+codes}
2203
2204You should not really depend on the number that comes from \prm {Umathcode} because
2205the engine can (at some point) use a different amount of families and classes. Given this,
2206you can extract the components of a math character. Say that we have defined:
2207
2208\starttyping
2209\Umathcode 1 2 3 4
2210\stoptyping
2211
2212then
2213
2214\starttyping
2215[\mathcharclass\Umathcode1] [\Umathcharfam\Umathcode1] [\Umathcharslot\Umathcode1]
2216\stoptyping
2217
2218which will return:
2219
2220\starttyping
2221[2] [3] [4]
2222\stoptyping
2223
2224You can of course store the code in for instance a register and use that as
2225argument. The three commands also accept a specification (and maybe more in the
2226future).
2227
2228These commands are provided as convenience. Before they became available you
2229could do the following:
2230
2231\starttyping
2232\def\mathcharclass{\numexpr
2233    \directlua{tex.print(tex.getmathcode(token.scan_int())[1])}
2234\relax}
2235\def\Umathcharfam{\numexpr
2236    \directlua{tex.print(tex.getmathcode(token.scan_int())[2])}
2237\relax}
2238\def\Umathcharslot{\numexpr
2239    \directlua{tex.print(tex.getmathcode(token.scan_int())[3])}
2240\relax}
2241\stoptyping
2242
2243\stopsubsection
2244
2245\startsubsection[title={Last lines and \prm{predisplaygapfactor}}]
2246
2247\topicindex {math+last line}
2248
2249There is a new primitive to control the overshoot in the calculation of the
2250previous line in mid|-|paragraph display math. The default value is 2 times
2251the em width of the current font:
2252
2253\starttyping
2254\predisplaygapfactor=2000
2255\stoptyping
2256
2257If you want to have the length of the last line independent of math i.e.\ you don't
2258want to revert to a hack where you insert a fake display math formula in order to
2259get the length of the last line, the following will often work too:
2260
2261\starttyping
2262\def\lastlinelength{\dimexpr
2263    \directlua {tex.sprint (
2264        (nodes.dimensions(node.tail(tex.lists.page_head).list))
2265    )}sp
2266\relax}
2267\stoptyping
2268
2269\stopsubsection
2270
2271\stopsection
2272
2273\startsection[title={Math mode and scripts}]
2274
2275\startsubsection[title={Entering and leaving math mode with \prm {Ustartmathmode}
2276and \prm {Ustopmathmode}}]
2277
2278These commands are variants on the single and double (usually) dollar signs that
2279make us enter math mode and later leave it. The start command expects a style
2280identifier that determines in what style we end up in.
2281
2282\stopsubsection
2283
2284\startsubsection[title={Verbose versions of single|-|character math commands like \prm {superscript}
2285and \prm {subscript}}]
2286
2287\topicindex {math+styles}
2288
2289\LUATEX\ defines six new primitives that have the same function as
2290\type {^}, \type {_}, \type {$}, and \type {$$}:
2291
2292\starttabulate[|l|l|]
2293\DB primitive                \BC explanation \NC \NR
2294\TB
2295\NC \prm {superscript}      \NC duplicates the functionality of \type {^} \NC \NR
2296\NC \prm {subscript}        \NC duplicates the functionality of \type {_} \NC \NR
2297\NC \prm {Ustartmath}        \NC duplicates the functionality of \type {$}, % $
2298                                   when used in non-math mode. \NC \NR
2299\NC \prm {Ustopmath}         \NC duplicates the functionality of \type {$}, % $
2300                                   when used in inline math mode. \NC \NR
2301\NC \prm {Ustartdisplaymath} \NC duplicates the functionality of \type {$$}, % $$
2302                                   when used in non-math mode. \NC \NR
2303\NC \prm {Ustopdisplaymath}  \NC duplicates the functionality of \type {$$}, % $$
2304                                   when used in display math mode. \NC \NR
2305\LL
2306\stoptabulate
2307
2308The \prm {Ustopmath} and \prm {Ustopdisplaymath} primitives check if the current
2309math mode is the correct one (inline vs.\ displayed), but you can freely intermix
2310the four mathon|/|mathoff commands with explicit dollar sign(s).
2311
2312\stopsubsection
2313
2314\startsubsection[title={Script commands \prm {Unosuperscript}, \prm {Unosubscript}, \prm {Unosuperprescript} and \prm {Unosubprescript}}]
2315
2316\topicindex {math+styles}
2317\topicindex {math+scripts}
2318
2319These commands result in super- and subscripts but with the current style (at the
2320time of rendering). So,
2321
2322\startbuffer[script]
2323$
2324    x\superscript  {1}\subscript  {2} =
2325    x\nosuperscript{1}\nosubscript{2} =
2326    x\superscript  {1}\nosubscript{2} =
2327    x\nosuperscript{1}\subscript  {2}
2328$
2329\stopbuffer
2330
2331\typebuffer[script]
2332
2333results in \inlinebuffer[script].
2334
2335\stopsubsection
2336
2337\startsubsection[title={Script commands \prm {Ushiftedsuperscript}, \prm {Ushiftedsubscript}, \prm {Ushiftedsuperprescript} and \prm {Ushiftedsubprescript}}]
2338
2339\topicindex {math+styles}
2340\topicindex {math+scripts}
2341\topicindex {math+indices}
2342
2343Sometimes a script acts as an index in which case is should be anchored
2344differently. For that we have four extra primitives. Here the shifted postscripts
2345are shown:
2346
2347\startbuffer[script]
2348$
2349    x\superscript       {1}\subscript       {2} =
2350    x\shiftedsuperscript{1}\shiftedsubscript{2} =
2351    x\superscript       {1}\shiftedsubscript{2} =
2352    x\shiftedsuperscript{1}\subscript       {2}
2353$
2354\stopbuffer
2355
2356\typebuffer[script]
2357
2358results in \inlinebuffer[script].
2359
2360\stopsubsection
2361
2362\startsubsection[title={Injecting primes with \prm {Uprimescript}}]
2363
2364This one is a bit special. In \LUAMETATEX\ a prime is a native element of a
2365nucleus, alongside the two prescript and two postscripts. The most confusing
2366combination of primes and postscripts is the case where we have a prime and
2367superscript. In that case we assume that in order to avoid confusion parenthesis
2368are applied so we don't covert it. That leaves three cases:
2369
2370\startbuffer[script]
2371$
2372    a \primescript{1} \superscript{2} \subscript {3} +
2373    b \subscript  {3} \primescript{1} +
2374    c \primescript{1} \subscript  {3} = d
2375$
2376\stopbuffer
2377
2378\typebuffer[script]
2379
2380This gets rendered as: \inlinebuffer[script]. In this case a subscript is handled as if
2381it were an index.
2382
2383\stopsubsection
2384
2385\startsubsection[title={Prescripts with \prm {Usuperprescript} and \prm {Usubprescript}}]
2386
2387\startbuffer
2388\hbox{$
2389    {\tf X}^1_2^^3__4 \quad
2390    {\tf X}^1  ^^3    \quad
2391    {\tf X}  _1   __4 \quad
2392    {\tf X}    ^^3    \quad
2393    {\tf X}       __4 \quad
2394    {\tf X}^^3    __4
2395$}
2396\stopbuffer
2397
2398\typebuffer
2399
2400The problem with the circumflex is that it is also used for escaping character
2401input. Normally that only happens in a format file so you can safely disable
2402that. Alternatives are using active characters that adapt. In \CONTEXT\ we make
2403them regular (other) characters in text mode and set \prm {supmarkmode} to~1 to
2404disable the normal multiple \type {^} treatment (a value larger than 1 will also
2405disable that in text mode). In math mode we make them active and behave as
2406expected.
2407
2408\blank \getbuffer \blank
2409
2410The more explicit commands are:
2411
2412\startbuffer
2413\hbox{$
2414{\tf X}\superscript{1}                                               \quad
2415{\tf X}               \subscript{2}                                  \quad
2416{\tf X}\superscript{1}\subscript{2}                                  \quad
2417{\tf X}\superscript{1}             \superprescript{3}                \quad
2418{\tf X}               \subscript{2}                  \subprescript{4}\quad
2419{\tf X}\superscript{1}\subscript{2}\superprescript{3}\subprescript{4}\quad
2420{\tf X}                            \superprescript{3}                \quad
2421{\tf X}                                              \subprescript{4}\quad
2422{\tf X}                            \superprescript{3}\subprescript{4}
2423$}
2424\stopbuffer
2425
2426\typebuffer
2427
2428These more verbose triggers can be used to build interfaces:
2429
2430\blank \getbuffer \blank
2431
2432\stopsubsection
2433
2434\startsubsection[title={Allowed math commands in non|-|math modes}]
2435
2436\topicindex {math+text}
2437\topicindex {text+math}
2438
2439The commands \prm {mathchar}, and \prm {Umathchar} and control sequences that are
2440the result of \prm {mathchardef} or \prm {Umathchardef} are also acceptable in
2441the horizontal and vertical modes. In those cases, the \prm {textfont} from the
2442requested math family is used.
2443
2444\stopsubsection
2445
2446\stopsection
2447
2448% \startsection[title={Flattening: \prm {mathflattenmode}}]
2449%
2450% \topicindex {math+flattening}
2451%
2452% The \TEX\ math engine collapses \type {ord} noads without sub- and superscripts
2453% and a character as nucleus, which has the side effect that in \OPENTYPE\ mode
2454% italic corrections are applied (given that they are enabled).
2455%
2456% \startbuffer[sample]
2457% \switchtobodyfont[modern]
2458% $V \mathbin{\mathbin{v}} V$\par
2459% $V \mathord{\mathord{v}} V$\par
2460% \stopbuffer
2461%
2462% \typebuffer[sample]
2463%
2464% This renders as:
2465%
2466% \blank \start \mathflattenmode\plusone \getbuffer[sample] \stop \blank
2467%
2468% When we set \prm {mathflattenmode} to 31 we get:
2469%
2470% \blank \start \mathflattenmode\numexpr1+2+4+8+16\relax \getbuffer[sample] \stop \blank
2471%
2472% When you see no difference, then the font probably has the proper character
2473% dimensions and no italic correction is needed. For Latin Modern (at least till
2474% 2018) there was a visual difference. In that respect this parameter is not always
2475% needed unless of course you want efficient math lists anyway.
2476%
2477% You can influence flattening by adding the appropriate number to the value of the
2478% mode parameter. The default value is~1.
2479%
2480% \starttabulate[|Tc|c|]
2481% \DB mode \BC class \NC \NR
2482% \TB
2483% \NC  1   \NC ord   \NC \NR
2484% \NC  2   \NC bin   \NC \NR
2485% \NC  4   \NC rel   \NC \NR
2486% \NC  8   \NC punct \NC \NR
2487% \NC 16   \NC inner \NC \NR
2488% \LL
2489% \stoptabulate
2490%
2491% \stopsubsection
2492
2493
2494\startsection[title={Tracing}]
2495
2496\topicindex {math+tracing}
2497
2498\startsubsection[title={Assignments}]
2499
2500Because there are quite some math related parameters and values, it is possible
2501to limit tracing. Only when \type {tracingassigns} and|/|or \type
2502{tracingrestores} are set to~2 or more they will be traced.
2503
2504\stopsubsection
2505
2506\startsubsection[title={\prm{tracingmath}}]
2507
2508The \TEX\ engine has a of places where tracing information can be generated so
2509one can see what gets read and what comes out, but the math machinery is a black
2510box. In \LUAMETATEX\ the math engine has been extended with tracing too.
2511
2512A value of one shows only the initial list, but a value of two also shows the
2513intermediate lists as well as applied rules, injected spacing, injected penalties
2514and parameter initialization. A value of three shows the result and larger values
2515will do so with maximum breadth and depth.
2516
2517If you also want to see something on the console make sure to set \prm
2518{tracingonline} to more than one.
2519
2520\stopsubsection
2521
2522\stopsection
2523
2524\startsection[title={Classes}]
2525
2526\startsubsection[title={Forcing classes with \prm {Umathclass}}]
2527
2528You can change the class of a math character on the fly:
2529
2530\startbuffer
2531$x\mathopen   {!}+123+\mathclose   {!}x$
2532$x\mathclass4 `! +123+\mathclass5 `! x$
2533$x             ! +123+             ! x$
2534$x\mathclose  {!}+123+\mathopen   {!}x$
2535$x\mathclass5 `! +123+\mathclass4 `! x$
2536\stopbuffer
2537
2538\typebuffer
2539
2540Watch how the spacing changes:
2541
2542\startlines
2543\getbuffer
2544\stoplines
2545
2546The \TEX\ engines deal with active characters in math differently as in text.
2547When a character has class~8 it will be fed back into the machinery with an
2548active catcode which of course assumes that there is some meaning attached.
2549
2550A variant on this is the use of \prm {amcode}. A character that has that code set
2551and that is active when we are in math mode, will be fed back with that code as
2552catcode which can be one of alignment tab, superscript, subscript, letter, other
2553char, or active. This feature is still experimental. Watch out: when an already
2554active character remains active we get a loop. Also, math characters are checked
2555for this property too, which can then turn them active.
2556
2557\stopsubsection
2558
2559\startsubsection[title={Checking class states}]
2560
2561When a formula is typeset it starts out with a begin class and finishes with an end class.
2562This is done by adding two \quote {fake} atoms.  here are two global state variables that tell
2563what the most recent edge classes are and two variables that act like registers and are
2564local. There are also two registers that can be set to values that will force begin and end
2565classes.
2566
2567The values of \prm {mathbeginclass} and \prm {mathendclass} are used when a
2568formula starts and afterwards they are reset. Afterwards \prm {mathleftclass} and
2569\prm {mathrightclass} have the effective edge classes. The global \prm
2570{lastleftclass} and \prm {lastrightclass} variables also have the last edge
2571classes but them being global they might not always reflect what you expect.
2572
2573\stopsubsection
2574
2575\startsubsection[title={Getting class spacing}]
2576
2577You can query the pairwise spacing of atoms with \prm {mathatomglue} and inject it with
2578\prm {mathatomskip}, as in:
2579
2580\startbuffer
2581\the\mathatomglue 5 4 \displaystyle : $[\mathatomskip 5 4 \displaystyle]$
2582\stopbuffer
2583
2584\typebuffer
2585
2586and get: \inlinebuffer.
2587
2588\stopsubsection
2589
2590\startsubsection[title={Default math codes}]
2591
2592The probably not that useful primitive (but who knows) \prm {setdefaultmathcodes}
2593initializes the mathcodes of digits to family zero and the lowercase and
2594uppercase letters to family one, just as standard \TEX\ does. Don't do this in in
2595\CONTEXT.
2596
2597\stopsubsection
2598
2599\stopsection
2600
2601\startsection[title={Modes}]
2602
2603\startsubsection[title={Introduction}]
2604
2605For most cases the math engine acts the same as in regular \TEX, apart of course
2606from some font specific features that need to be supported out of the box. There
2607are however ways to divert, which we do in \CONTEXT. The following paragraphs are
2608therefore rather \CONTEXT\ driven and not that relevant otherwise. Some modes have
2609been removed and became default and|/|ro were replaced by more granular options.
2610
2611\stopsubsection
2612
2613\startsubsection[title={Controlling display math with \prm {mathdisplaymode}}]
2614
2615By setting \prm {mathdisplaymode} larger than zero double math shift characters
2616(normally the dollar sign) are disabled. The reason for this feature is rather
2617\CONTEXT\ specific: we pay a lot attention to spacing and the build in heuristics
2618don't work well with that. We also need to initialize display math as well as
2619deal with whatever has to be done with respect to finalizing. Because users use
2620the high level commands anyway, disabling is okay for \CONTEXT\ and less likely
2621to be done for other macro packages, so be careful with this one.
2622
2623\stopsubsection
2624
2625\startsubsection[title={Skips around display math and \prm {mathdisplayskipmode}}]
2626
2627\topicindex {math+spacing}
2628
2629The injection of \prm {abovedisplayskip} and \prm {belowdisplayskip} is not
2630symmetrical. An above one is always inserted, also when zero, but the below is
2631only inserted when larger than zero. Especially the latter makes it sometimes hard
2632to fully control spacing. Therefore \LUATEX\ comes with a new directive: \prm
2633{mathdisplayskipmode}. The following values apply:
2634
2635\starttabulate[|c|l|]
2636\DB value \BC meaning \NC \NR
2637\TB
2638\NC 0 \NC normal \TEX\ behavior \NC \NR
2639\NC 1 \NC always (same as 0) \NC \NR
2640\NC 2 \NC only when not zero \NC \NR
2641\NC 3 \NC never, not even when not zero \NC \NR
2642\LL
2643\stoptabulate
2644
2645\stopsubsection
2646
2647\startsubsection[title={Scripts}]
2648
2649The regular superscript trigger \type {^} and subscript trigger \type {_} are
2650quite convenient and although we do have verbose aliases in regular text these
2651two will be used. A multiple superscript character sequence is used for accessing
2652characters by number unless you disable that via catcode manipulations. In
2653\CONTEXT\ the super- and subscript characters are regular characters and only in
2654math mode they have a special meaning. We can have upto for script characters and
2655they indicate pre- and postscripts.
2656
2657\starttabulate[|c|c|c|c|]
2658\NC \type {^}    \NC         \NC super \NC post \NC \NR
2659\NC \type {_}    \NC         \NC sub   \NC post \NC \NR
2660\NC \type {^^}   \NC         \NC super \NC pre  \NC \NR
2661\NC \type {__}   \NC         \NC sub   \NC pre  \NC \NR
2662\NC \type {^^^}  \NC shifted \NC super \NC post \NC \NR
2663\NC \type {___}  \NC shifted \NC sub   \NC post \NC \NR
2664\NC \type {^^^^} \NC shifted \NC super \NC pre  \NC \NR
2665\NC \type {____} \NC shifted \NC sub   \NC pre  \NC \NR
2666\stoptabulate
2667
2668The shifted variants force a script to be an index and thereby make the other
2669script move. This multiple character features used to be optional but is now always
2670active.
2671
2672Related to this is the issue of double scripts. The regular \TEX\ is to issue
2673an error message, inject an ordinary node and carry on when asked to. Here we have
2674\prm {mathdoublescriptmode} as escape: when set to a zero or positive value it will
2675also inject an atom but with class properties determined by its value. There will
2676be no error message.
2677
2678\starttyping
2679\mathdoublescriptmode"MMLLRR % main left right
2680\stoptyping
2681
2682% Another variable that influences rendering is \prm {mathscriptcharmode} that in
2683% \CONTEXT\ we default to~1. The \prm {mathscriptboxmode} parameter determines if a
2684% boxed nucleus is analyzed and is also set to~1 in \CONTEXT. Both parameters are a
2685% left|-|over from the split code path approach and might still be handy for
2686% experiments. They might go away some day of replaced by a different control
2687% option. Older versions if \LUAMETATEX\ had optional behavior for different values
2688% but that code was removed.
2689
2690\stopsubsection
2691
2692\startsubsection[title={Grouping}]
2693
2694When set to non zero \prm {mathgroupingmode} will make stand alone \quote {list}
2695as in \typ {a {bc} d} behave like grouping instead of creating composite atoms.
2696In \CONTEXT\ indeed we set it to a positive value. Although it was ot strictly
2697necessary it is nicer when users don't get side effects if they revert to low
2698level source coding.
2699
2700\stopsubsection
2701
2702\startsubsection[title={Slack}]
2703
2704The \prm {mathslackmode} parameters controls removal of accidental left and|/|or
2705right space added to a formula. Of course we enable this in \CONTEXT. There is
2706more detailed control possible at the atom label as well as with class options.
2707
2708\stopsubsection
2709
2710\startsubsection[title={Limit fitting \prm {mathlimitsmode}}]
2711
2712\topicindex {math+limits}
2713
2714When set, this parameter avoids too wide limits to stick out too much by sort of
2715centering them.
2716
2717\stopsubsection
2718
2719\startsubsection[title={Nolimit correction with \prm {mathnolimitsmode}}]
2720
2721\topicindex {math+limits}
2722
2723There are two extra math parameters \prm {Umathnolimitsupfactor} and \prm
2724{Umathnolimitsubfactor} that were added to provide some control over how limits
2725are spaced (for example the position of super and subscripts after integral
2726operators). They relate to an extra parameter \prm {mathnolimitsmode}. The half
2727corrections are what happens when scripts are placed above and below. The
2728problem with italic corrections is that officially that correction italic is used
2729for above|/|below placement while advanced kerns are used for placement at the
2730right end. The question is: how often is this implemented, and if so, do the
2731kerns assume correction too. Anyway, with this parameter one can control it.
2732
2733\starttabulate[|l|ck1|ck1|ck1|ck1|ck1|ck1|]
2734    \NC
2735        \NC \mathnolimitsmode0    $\displaystyle\int\nolimits^0_1$
2736        \NC \mathnolimitsmode1    $\displaystyle\int\nolimits^0_1$
2737        \NC \mathnolimitsmode2    $\displaystyle\int\nolimits^0_1$
2738        \NC \mathnolimitsmode3    $\displaystyle\int\nolimits^0_1$
2739        \NC \mathnolimitsmode4    $\displaystyle\int\nolimits^0_1$
2740        \NC \mathnolimitsmode8000 $\displaystyle\int\nolimits^0_1$
2741    \NC \NR
2742    \TB
2743    \BC mode
2744        \NC \tttf 0
2745        \NC \tttf 1
2746        \NC \tttf 2
2747        \NC \tttf 3
2748        \NC \tttf 4
2749        \NC \tttf 8000
2750    \NC \NR
2751    \BC superscript
2752        \NC 0
2753        \NC font
2754        \NC 0
2755        \NC 0
2756        \NC +ic/2
2757        \NC 0
2758    \NC \NR
2759    \BC subscript
2760        \NC -ic
2761        \NC font
2762        \NC 0
2763        \NC -ic/2
2764        \NC -ic/2
2765        \NC 8000ic/1000
2766    \NC \NR
2767\stoptabulate
2768
2769When the mode is set to one, the math parameters are used. This way a macro
2770package writer can decide what looks best. Given the current state of fonts in
2771\CONTEXT\ we currently use mode 1 with factor 0 for the superscript and 750 for
2772the subscripts. Positive values are used for both parameters but the subscript
2773shifts to the left. A \prm {mathnolimitsmode} larger that 15 is considered to
2774be a factor for the subscript correction. This feature can be handy when
2775experimenting.
2776
2777\stopsubsection
2778
2779\startsubsection[title={Some spacing control with \prm {mathsurroundmode}, \prm {mathspacingmode} and \prm {mathgluemode}}]
2780
2781See \in {section} [spacing:surround] for more about inline spacing. The \prm
2782{mathsurroundmode} parameter just permits the glue variant to kick in and indeed
2783we enable it in \CONTEXT.
2784
2785The \prm {mathspacingmode} parameter is for tracing: normally zero inter atom
2786glue is not injected but when this parameter is set to non|-|zero even zero
2787spacing will show up. This permits us to check the applied inter atom spacing.
2788
2789The \prm {mathgluemode} bitset controls if glue can stretch and|/|or shrink. It
2790is used in some of the upgraded \CONTEXT\ high level math alignment command so
2791probably more qualifies as a feature specific for that usage.
2792
2793\starttabulate[|c|l|]
2794\DB value \BC meaning \NC \NR
2795\TB
2796\NC 0x01  \NC obey stretch component \NC \NR
2797\NC 0x02  \NC obey shrink  component \NC \NR
2798\LL
2799\stoptabulate
2800
2801\stopsubsection
2802
2803\stopsection
2804
2805\startsection[title={Experiments}]
2806
2807There are a couple of experimental features. They will stay but details might
2808change, for instance more control over spacing. We just show some examples and
2809let your imagination work it out.
2810
2811\startsubsection[title={Scaling spacing with \prm {Umathxscale} and  \prm {Umathyscale}}]
2812
2813These two primitives scale the horizontal and vertical scaling related
2814parameters. They are set by style. There is no combined scaling primitive.
2815
2816\startbuffer
2817$\Umathxscale\textstyle  800 a + b + x + d + e = f $\par
2818$\Umathxscale\textstyle 1000 a + b + x + d + e = f $\par
2819$\Umathxscale\textstyle 1200 a + b + x + d + e = f $\blank
2820
2821$\Umathyscale\textstyle  800 \sqrt[2]{x+1}$\quad
2822$\Umathyscale\textstyle 1000 \sqrt[2]{x+1}$\quad
2823$\Umathyscale\textstyle 1200 \sqrt[2]{x+1}$\blank
2824\stopbuffer
2825
2826\typebuffer
2827
2828Normally only small deviations from 1000 make sense but here we want to show the
2829effect and use a 20\percent\ scaling:
2830
2831\getbuffer
2832
2833\startsubsection[title={Scaling with \prm {scaledmathstyle}}]
2834
2835Because styles put a style switching node in the stream we have a
2836scaling primitive that uses such a style node to signal dynamic
2837scaling. Thisis still somewhat experimental.
2838
2839\startbuffer
2840$
2841    {\scaledmathstyle  500 x + x}\quad
2842    {\scaledmathstyle 1000 x + x}\quad
2843    {\scaledmathstyle 1500 x + x}
2844$
2845\stopbuffer
2846
2847\typebuffer
2848
2849You get differently sized math but of course you then probably also need to
2850handle spacing differently, although for small deviations from 1000 is should
2851come out acceptable.
2852
2853\stopsubsection
2854
2855\startsubsection[title={Spreading math with \prm {maththreshold}}]
2856
2857Small formulas that don't get unpacked can be made to act like glue, that is,
2858they become a sort of leader and permit the par builder to prevent excessive
2859spacing because the embedded inter atom glue can now participate in the
2860calculations. The \prm {maththreshold} primitive is a regular glue parameter.
2861
2862\stopsubsection
2863
2864\startsubsection[title={\prm {everymathatom} and \prm {lastatomclass}}]
2865
2866Just for completeness we have \prm {everymathatom} as companion for \prm {everyhbox}
2867and friends and it is probably just as useful. The next example shows how it works:
2868
2869\startbuffer
2870\everymathatom
2871  {\begingroup
2872   \scratchcounter\lastatomclass
2873   \everymathatom{}%
2874   \mathghost{\hbox to 0pt yoffset -1ex{\smallinfofont \setstrut\strut \the\scratchcounter\hss}}%
2875   \endgroup}
2876
2877$ a = \mathatom class 4 {b} + \mathatom class 5 {c} $
2878\stopbuffer
2879
2880\typebuffer
2881
2882We get a formula with open- and close atom spacing applied to~$b$ and~$c$:
2883
2884{\getbuffer}
2885
2886This example shows bit of all: we want the number to be invisible to the math
2887machinery so we ghost it. So, we need to make sure we don't get recursion due to
2888nested injection and expansion of \prm {everymathatom} and of course we need to
2889store the number. The \prm {lastatomclass} state variable is only meaningful
2890inside an explicit atom wrapper like \prm {mathatom} and \prm {mathatom}.
2891
2892\stopsubsection
2893
2894\startsubsection[title={\prm {postinlinepenalty} and \prm {preinlinepenalty}}]
2895
2896In horizontal lists math is embedded in a begin and end math node. These nodes
2897also carry information about the surrounding space, and the in \LUAMETATEX\
2898optional glue. We also store a penalty so that we can let that play a role in the
2899decisions to be made; these two internal integer registers control this. Just
2900like the mentioned spacing they are not visible as nodes in the list.
2901
2902\stopsubsection
2903
2904\startsubsection[title={\prm {mathforwardpenalties} and \prm {mathbackwardpenalties}}]
2905
2906These penalties are experimental and deltas added to the regular penalties
2907between atoms. Here is an example, as with other primitives that take more
2908arguments the first number indicates how much follows.
2909
2910\startbuffer
2911$ a + b + c + d + e + f + g + h = x $\par
2912\mathforwardpenalties  3 300 200 100
2913\mathbackwardpenalties 3 250 150  50
2914$ a + b + c + d + e + f + g + h = x $\par
2915\stopbuffer
2916
2917\typebuffer
2918
2919You'll notice that we apply more severe penalties at the edges:
2920
2921{\showmakeup[penalty]\multiply\glyphscale\plustwo \getbuffer}
2922
2923\stopsubsection
2924
2925\startsubsection[title={\prm {Umathdiscretionary} and \prm {hmcode}}]
2926
2927\topicindex {math+discretionaries}
2928
2929The usual \prm {discretionary} command is supported in math mode but it has the
2930disadvantage that one needs to make sure that the content triplet does the math
2931right (especially the style). This command takes an optional class specification.
2932
2933\starttyping
2934\Umathdiscretionary [class n] {+} {+} {+}
2935\stoptyping
2936
2937It uses the same logic as \prm {mathchoice} but in this case we handle three
2938snippets in the current style.
2939
2940A fully automatic mechanism kicks in when a character has a \prm {hmcode} set:
2941
2942\starttabulate[|c|l|p|]
2943\DB bit \BC meaning \BC explanation \NC \NR
2944\TB
2945\NC 1   \NC normal  \NC a discretionary is created with the same components \NC \NR
2946\NC 2   \NC italic  \NC following italic correction is kept with the component \NC \NR
2947\LL
2948\stoptabulate
2949
2950So we can say:
2951
2952\starttyping
2953\hmcode `+ 3
2954\stoptyping
2955
2956When the \type {italic} bit is set italic correction is kept at a linebreak.
2957\stopsubsection
2958
2959\stopsection
2960
2961\stopchapter
2962
2963\stopcomponent
2964