luametatex-constructions.tex /size: 33 Kb    last modification: 2025-02-21 11:03
1% language=us runpath=texruns:manuals/luametatex
2
3\environment luametatex-style
4
5\startdocument[title=Constructions]
6
7\startluacode
8local styles     = tex.getmathstylevalues    () styles     = table.swapped(styles,styles)
9local parameters = tex.getmathparametervalues() parameters = table.swapped(parameters,parameters)
10local variants   = tex.getmathvariantvalues  () variants   = table.swapped(variants,variants)
11local presets    = tex.getmathvariantpresets () presets    = table.swapped(presets,presets)
12
13-- inspect(presets)
14-- inspect(presets)
15
16function document.printmathpresets()
17    context.starttabulate { "||||" }
18    context.FL()
19    context.BC() context("construct")
20    context.BC() context("value")
21    context.BC() context("preset name")
22    context.BC() context.NR()
23    context.TL()
24    for parameter=parameters.overlinevariant,parameters.stackvariant do
25        local value  = tex.getmath(parameter,"display")
26        local preset = variants[presets[value]]
27        context.NC() context.type("\\Umath"..parameters[parameter])
28        context.NC() context("0x%08X",value)
29        context.NC() context(preset)
30        context.NC() context.NR()
31    end
32    context.LL()
33    context.stoptabulate()
34end
35
36function document.printmathvariants()
37    for parameter=parameters.overlinevariant,parameters.stackvariant do
38        for style=styles.display,styles.crampedscriptscript do
39            local p, s = tex.getmathstylevariant(style,parameter)
40            if p and s then
41                 logs.report("mathvariants","%-24s %-20s %-18s %-20s",parameters[parameter],styles[style],variants[p],styles[s])
42            end
43        end
44    end
45end
46
47function document.showmathvariant(variant)
48    local parameter = type(variant) == "string" and parameters[variant] or variant
49    context.startsubsubsubject { title = variant }
50    context.starttabulate { "||T||" }
51    context.BC() context("current style")
52    context.BC() context("mapping")
53    context.BC() context("used style")
54    context.BC() context.NR()
55    context.ML()
56    for style=styles.display,styles.crampedscriptscript do
57        local p, s = tex.getmathstylevariant(style,parameter)
58        if p and s then
59            context.NC() context(styles[style])
60            context.NC() context("0x%08X",p)
61            context.NC() context(styles[s])
62            context.NC() context.NR()
63        end
64    end
65    context.stoptabulate()
66    context.stopsubsubsubject()
67end
68\stopluacode
69
70\startsection[title={Introduction}]
71
72This is more a discussion of the way some constructs in for instance math work.
73It will never be exhausting and mostly is for our own usage. We don't discuss all
74the options bit many are interfaced in higher level macros in \CONTEXT. This
75chapter will gradually grow, depending on time and mood.
76
77\stopsection
78
79\startsection[title=Boxes]
80
81Boxes are very important in \TEX. We have horizontal boxes and vertical boxes.
82When you look at a page of text, the page itself is a vertical box, and among
83other things it packs lines that are themselves horizontal boxes. The lines that
84make a paragraph are the result of breaking a long horizontal box in smaller
85pieces.
86
87\startlinecorrection
88\ruledvbox \bgroup \hsize 20em \showmakeup[line] \showboxes
89    This is a vertical box. It has a few lines of text that started out as
90    one long line but has been broken in pieces. Doing this as good as possible
91    is one of \TEX's virtues.
92\egroup
93\stoplinecorrection
94
95There is a low level manual on boxes so here we can limit the discussion to
96basics. A box is in \TEX\ speak a node. In traditional \TEX\ it has a
97width, height, depth and shift.
98
99\startlinecorrection
100\startMPcode
101    numeric wd ; wd := 24 ;
102    numeric ht ; ht :=  7 ;
103    numeric dp ; dp :=  3 ;
104
105    path body ; body := unitsquare xyscaled (wd, ht+dp) shifted (0,-dp) ;
106    path line ; line := (0,0) -- (wd,0) ;
107
108    draw line withcolor "middlegray" ;
109    draw body withcolor "darkred" ;
110
111    currentpicture := currentpicture scaled 5 ;
112\stopMPcode
113\stoplinecorrection
114
115Here we see a box and the gray line is called the baseline, the height goes up
116and the depth goes down. Normally the height and depth are determined by what
117goes in the box but they can be changed as we like.
118
119\startbuffer
120\setbox\scratchboxone\ruledhpack{SHIFT 1}
121\setbox\scratchboxtwo\ruledhpack{SHIFT 2}
122
123\boxshift\scratchboxtwo 1ex \dontleavehmode \box\scratchboxone\box\scratchboxtwo
124
125\setbox\scratchboxone\ruledvpack{SHIFT 3}
126\setbox\scratchboxtwo\ruledvpack{SHIFT 4}
127
128\boxshift\scratchboxtwo 1ex \box\scratchboxone\box\scratchboxtwo
129\stopbuffer
130
131\typebuffer
132
133In this example you'll notice that the shift depends on the box being horizontal
134or vertical. The primitives \type {\raise}, \type {\lower}, \type {\moveleft} and
135\type {\moveright} can be used to shift a box.
136
137\startlinecorrection
138\getbuffer
139\stoplinecorrection
140
141The reason why we have the shift property is that it is more efficient than
142wrapping a box in another box and shifting with kerns. In that case we also have
143to go via a box register so that we can manipulate the final dimensions. Another
144advantage is that the engine can use shifts to position for instance elements in
145a math formula and even the par builder used shifts to deal with positioning the
146lines according to shape and margin. In \LUAMETATEX\ the later is no longer the
147case.
148
149Inside a box there can be mark (think running headers), insert (think footnotes)
150and adjust (think injecting something before or after the current line) nodes. The
151par builder will move this from inside the box to between the lines but when boxes
152are nested too deeply this won't happen and they get lost. In \LUAMETATEX\ these
153objects do bubble up because we make them box properties. So, in addition to
154the dimensions and shift a box also has migration fields.
155
156In the low level manuals you can find examples of accessing various properties of
157boxes so here we stick to a short description. The reason for mentioning them is
158that it gives you an idea of what goes on in the engine.
159
160\starttabulate
161\FL
162\BC field                 \BC usage \NC \NR
163\TL
164\NC \type {width}         \NC the (used) width \NC \NR
165\NC \type {height}        \NC the (used) height \NC \NR
166\NC \type {depth}         \NC the (used) depth \NC \NR
167\NC \type {shift_amount}  \NC the shift (right or down) \NC \NR
168\ML
169\NC \type {list}          \NC pointer to the content \NC \NR
170\ML
171\NC \type {glue_order}    \NC the calculated order of glue stretch of shrink \NC \NR
172\NC \type {glue_sign}     \NC the determined sign of glue stretch of shrink \NC \NR
173\NC \type {glue_set}      \NC the calculated multiplier for glue stretch or shrink \NC \NR
174\ML
175\NC \type {geometry}      \NC a bit set registering manipulations \NC \NR
176\NC \type {orientation}   \NC positional manipulations \NC \NR
177\NC \type {w_offset}      \NC used in horizontal movement calculations \NC \NR
178\NC \type {h_offset}      \NC used in vertical movement calculations \NC \NR
179\NC \type {d_offset}      \NC used in vertical movement calculations \NC \NR
180\NC \type {x_offset}      \NC a horizontal shift independent of dimensions \NC \NR
181\NC \type {y_offset}      \NC a vertical shift independent of dimensions  \NC \NR
182\NC \type {axis}          \NC the math axis \NC \NR
183\ML
184\NC \type {dir}           \NC the direction the box goes to (l2r or r2l) \NC \NR
185\NC \type {package_state} \NC a bitset indicating how the box came to be as it is \NC \NR
186\NC \type {index}         \NC a (system dependent) identifier \NC \NR
187\ML
188\NC \type {pre_migrated}  \NC content bound to the box that eventually will be injected \NC \NR
189\NC \type {post_migrated} \NC idem \NC \NR
190\NC \type {pre_adjusted}  \NC idem \NC \NR
191\NC \type {post_adjusted} \NC idem \NC \NR
192\ML
193\NC \type {source_anchor} \NC an identifier bound to the box \NC \NR
194\NC \type {target_anchor} \NC idem \NC \NR
195\NC \type {anchor}        \NC a bitset indicating where and how to anchor \NC \NR
196\ML
197\NC \type {except}        \NC carried information about additional virtual depth \NC \NR
198\NC \type {exdepth}       \NC additional virtual depth taken into account in the page builder \NC \NR
199\LL
200\stoptabulate
201
202We have the usual dimension but also extra ones that relate to \typ {\boxxoffset}
203and \typ {\boxyoffset} (these are virtual) as well as \typ {\boxxmove} and \typ
204{\boxymove} (these influence dimensions). The \typ {\boxorientation} also gets
205registered. The state fields carry information that is used in various places,
206the pre and post fields relate to the mentioned embedded content. Anchors are
207just there so that a macro package can play with this and excepts refer to an
208additional dimensions that is looked at in the page builder, for instance in
209order to prevent a page break at an unlucky spot. It all gives an indication of
210what we are dealing with.
211
212\stopsection
213
214\startsection[title=Math style variants]
215
216The \LUAMETATEX\ math engine is a follow up on the one in \LUATEX. That one
217gradually became more configurable in order to deal with both traditional fonts
218and \OPENTYPE\ fonts. In \LUAMETATEX\ much has been redone, opened up and
219extended. New mechanisms and constructs have been added. In the process hard
220coded heuristics with regards to math styles inside constructions were made
221configurable, a feature that is probably not used much, apart from experimenting.
222A side effect is that we can show how the engine is set up, so we do that when
223applicable.
224
225% \starttabulate
226% \NC normal            \NC \tohexa8 \mathnormalstylepreset            \NC \NR
227% \NC cramped           \NC \tohexa8 \mathcrampedstylepreset           \NC \NR
228% \NC subscript         \NC \tohexa8 \mathsubscriptstylepreset         \NC \NR
229% \NC superscript       \NC \tohexa8 \mathsuperscriptstylepreset       \NC \NR
230% \NC small             \NC \tohexa8 \mathsmallstylepreset             \NC \NR
231% \NC smaller           \NC \tohexa8 \mathsmallerstylepreset           \NC \NR
232% \NC numerator         \NC \tohexa8 \mathnumeratorstylepreset         \NC \NR
233% \NC denominator       \NC \tohexa8 \mathdenominatorstylepreset       \NC \NR
234% \NC doublesuperscript \NC \tohexa8 \mathdoublesuperscriptstylepreset \NC \NR
235% \stoptabulate
236
237\ctxlua{document.printmathpresets()}
238
239\stopsection
240
241\startsection[title=Math scripts]
242
243The basic components in a math formula are characters, accents, fractions,
244radicals and fences. They are represented in the to be processed node list as
245noads and eventually are converted in glyph, kern, glue and list nodes. Each noad
246carries similar but also specific information about its purpose and intended
247rendering. In \LUAMETATEX\ that is quite a bit more than in traditional \TEX.
248
249These noads are often called atoms. The center piece in a noad is called the
250nucleus. The fact that these noads also can have scripts attached makes them more
251like molecules. Scripts can be attached to the left and right, high or low. That
252makes fours of them: pre|/|post super|/|sub scripts. In \LUAMETATEX\ we also have
253a prime script, which comes on its own, above a post subscript or after the post
254superscript, if given.
255
256\startlinecorrection
257\startMPcode
258    numeric wd ; wd := 10 ;
259    numeric ht ; ht :=  8 ;
260    numeric dp ; dp :=  2 ;
261
262    path nucleus         ; nucleus         := fullsquare xyscaled (2wd,  ht  +dp  ) shifted (0,-dp  ) ;
263    path follower        ; follower        := fullsquare xyscaled ( wd/3,ht/6+dp/4) shifted (0,-dp  ) ;
264    path presubscript    ; presubscript    := fullsquare xyscaled ( wd,  ht/2+dp/2) shifted (0,-dp/2) ;
265    path presuperscript  ; presuperscript  := fullsquare xyscaled ( wd,  ht/2+dp/2) shifted (0,-dp/2) ;
266    path postsubscript   ; postsubscript   := fullsquare xyscaled ( wd,  ht/2+dp/2) shifted (0,-dp/2) ;
267    path postsuperscript ; postsuperscript := fullsquare xyscaled ( wd,  ht/2+dp/2) shifted (0,-dp/2) ;
268    path primescript     ; primescript     := fullsquare xyscaled ( wd/2,ht/2+dp/2) shifted (0,-dp/2) ;
269
270    presubscript    := anchored.lrt  (presubscript,    llcorner nucleus) shifted (-1,0) ;
271    presuperscript  := anchored.lrt  (presuperscript,  ulcorner nucleus) shifted (-1,0) ;
272    postsubscript   := anchored.llft (postsubscript,   lrcorner nucleus) shifted ( 1,0) ;
273    postsuperscript := anchored.llft (postsuperscript, urcorner nucleus) shifted ( 1,0) ;
274    primescript     := anchored.llft (primescript,     urcorner nucleus) shifted (bbwidth postsuperscript + 2,0) ;
275
276    draw nucleus         withcolor "darkgray"   ;
277    draw presubscript    withcolor "darkred"    ;
278    draw presuperscript  withcolor "darkgreen"  ;
279    draw postsubscript   withcolor "darkblue"   ;
280    draw postsuperscript withcolor "darkyellow" ;
281    draw primescript     withcolor "darkorange" ;
282
283    draw follower        shifted (  .5bbwidth nucleus + bbwidth postsuperscript + bbwidth primescript + 3,0) withcolor "darkgray"   ;
284    draw follower        shifted (- .5bbwidth nucleus - bbwidth presuperscript                        - 1,0) withcolor "darkgray"   ;
285    draw presubscript    shifted (                    - bbwidth presubscript                          - 1,0) withcolor "darkred"    ;
286    draw presuperscript  shifted (                    - bbwidth presuperscript                        - 1,0) withcolor "darkgreen"  ;
287    draw postsubscript   shifted (                      bbwidth postsubscript   + bbwidth primescript + 2,0) withcolor "darkblue"   ;
288    draw postsuperscript shifted (                      bbwidth postsuperscript + bbwidth primescript + 2,0) withcolor "darkyellow" ;
289
290    currentpicture := currentpicture scaled 5 ;
291\stopMPcode
292\stoplinecorrection
293
294Here the raised rectangle represents the prime. The large center piece is the
295nucleus. Four scripts are attached to the nucleus. The two smaller center pieces
296indicate follow up atoms. They make it possible to have multiple pre- and
297postscripts. For single scripts we get combinations like these:
298
299\startlinecorrection
300\startcombination[nx=3,ny=2,distance=4em]
301    {\scale [s=3] {\showglyphs\im { X   ^{\tt a} _{\tt b} ^^^{\tt c} ___{\tt d} \mathaxisbelow }}} {}
302    {\scale [s=3] {\showglyphs\im { X            _{\tt b}            ___{\tt d} \mathaxisbelow }}} {}
303    {\scale [s=3] {\showglyphs\im { X   ^{\tt a}          ^^^{\tt c}            \mathaxisbelow }}} {}
304    {\scale [s=3] {\showglyphs\im { X ' ^{\tt a} _{\tt b} ^^^{\tt c} ___{\tt d} \mathaxisbelow }}} {}
305    {\scale [s=3] {\showglyphs\im { X '          _{\tt b}            ___{\tt d} \mathaxisbelow }}} {}
306    {\scale [s=3] {\showglyphs\im { X ' ^{\tt a}          ^^^{\tt c}            \mathaxisbelow }}} {}
307\stopcombination
308\stoplinecorrection
309
310And for multiple (there can be more that two) we get this assembly:
311
312\startlinecorrection
313\startcombination[nx=3,ny=2,distance=4em]
314    {\scale [s=3] {\showglyphs\im { X   ^{\tt a} _{\tt b} ^^^{\tt c} ___{\tt d}  ^{\tt A} _{\tt B} ^^^{\tt C} ___{\tt D} \mathaxisbelow }}} {}
315    {\scale [s=3] {\showglyphs\im { X            _{\tt b}            ___{\tt d}           _{\tt B}            ___{\tt D} \mathaxisbelow }}} {}
316    {\scale [s=3] {\showglyphs\im { X   ^{\tt a}          ^^^{\tt c}             ^{\tt A}          ^^^{\tt C}            \mathaxisbelow }}} {}
317    {\scale [s=3] {\showglyphs\im { X ' ^{\tt a} _{\tt b} ^^^{\tt c} ___{\tt d}  ^{\tt A} _{\tt B} ^^^{\tt C} ___{\tt D} \mathaxisbelow }}} {}
318    {\scale [s=3] {\showglyphs\im { X '          _{\tt b}            ___{\tt d}           _{\tt B}            ___{\tt D} \mathaxisbelow }}} {}
319    {\scale [s=3] {\showglyphs\im { X ' ^{\tt a}          ^^^{\tt c}             ^{\tt A}          ^^^{\tt C}            \mathaxisbelow }}} {}
320\stopcombination
321\stoplinecorrection
322
323It will be clear that there is quite a bit of code involved in dealing with this
324because these scripts are not only to be anchored relative to the nucleus but
325also to each other. The dimensions of the scripts determine for instance how
326close a combined super and subscript are positioned.
327
328\startlinecorrection
329\startcombination[nx=3,ny=1,distance=2em]
330    {\scale [s=5] {\showglyphs\im { X          _{\tt p} \mathaxisbelow }}} {}
331    {\scale [s=5] {\showglyphs\im { X ^{\tt p} _{\tt p} \mathaxisbelow }}} {}
332    {\scale [s=5] {\showglyphs\im { X ^{\tt p}          \mathaxisbelow }}} {}
333\stopcombination
334\stoplinecorrection
335
336The rendering of scripts involves several parameters, of which some relate to
337font parameters. In \LUAMETATEX\ we have a few more variables and we also
338overload font parameters, if only because only a few make sense and it looks like
339font designers just copy values from the first available fonts so in the end we
340can as well use our own preferred values.
341
342The following parameters play a role in rendering the shown assembly, The
343traditional \TEX\ engine expects a math font to set quite some parameters for
344positioning the scripts but has no concept of prescripts and neither has
345\OPENTYPE. This is why we have extra parameters (and for completeness we also
346have them for the post scripts). One can wonder of font parameters make sense
347here because in the end we can decide for a better visual result with different
348ones. After all, assembling scripts is not really what fonts are about.
349
350\starttabulate[||||||]
351\FL
352\BC engine parameter                                \BC target \BC open type font                      \BC tex font            \BC \NR
353\TL
354\NC                   subscriptshiftdrop            \NC post   \NC SubscriptBaselineDropMin            \NC subdrop             \NC \NR
355\NC                   subscriptshiftdown            \NC post   \NC SubscriptShiftDown                  \NC sub1                \NC \NR
356\NC                   subscriptsuperscriptshiftdown \NC post   \NC SubscriptShiftDown[WithSuperscript] \NC sub2                \NC \NR
357\NC                   subscriptsuperscriptvgap      \NC post   \NC SubSuperscriptGapMin                \NC 4   rulethickness   \NC \NR
358\NC                   subscripttopmax               \NC post   \NC SubscriptTopMax                     \NC 4/5 xheight         \NC \NR
359
360\NC                   superscriptshiftdrop          \NC post   \NC SuperscriptBaselineDropMax          \NC supdrop             \NC \NR
361\NC                   superscriptbottommin          \NC post   \NC SuperscriptBottomMin                \NC 1/4 xheight         \NC \NR
362\NC                   superscriptshiftup            \NC post   \NC SuperscriptShiftUp[Cramped]         \NC sup1 sup2 sup3      \NC \NR
363\NC                   superscriptsubscriptbottommax \NC post   \NC SuperscriptBottomMaxWithSubscript   \NC 4/5 xheight         \NC \NR
364
365\NC \llap{\star\space}primeraise                    \NC prime  \NC PrimeRaisePercent                   \NC                     \NC \NR
366\NC \llap{\star\space}primeraisecomposed            \NC prime  \NC PrimeRaiseComposedPercent           \NC                     \NC \NR
367\NC \llap{\star\space}primeshiftup                  \NC prime  \NC PrimeShiftUp[Cramped]               \NC                     \NC \NR
368\NC \llap{\star\space}primeshiftdrop                \NC prime  \NC PrimeBaselineDropMax                \NC                     \NC \NR
369\NC \llap{\star\space}primespaceafter               \NC prime  \NC PrimeSpaceAfter                     \NC                     \NC \NR
370
371\NC                   spaceafterscript              \NC post   \NC SpaceAfterScript                    \NC \typ {\scriptspace} \NC \NR
372\NC \llap{\star\space}spacebeforescript             \NC post   \NC SpaceBeforeScript                   \NC                     \NC \NR
373\NC \llap{\star\space}spacebetweenscript            \NC multi  \NC SpaceBetweenScript                  \NC                     \NC \NR
374
375\NC \llap{\star\space}extrasuperscriptshift         \NC pre    \NC                                     \NC                     \NC \NR
376\NC \llap{\star\space}extrasuperprescriptshift      \NC pre    \NC                                     \NC                     \NC \NR
377\NC \llap{\star\space}extrasubscriptshift           \NC pre    \NC                                     \NC                     \NC \NR
378\NC \llap{\star\space}extrasubprescriptshift        \NC pre    \NC                                     \NC                     \NC \NR
379
380\NC \llap{\star\space}extrasuperscriptspace         \NC post   \NC                                     \NC                     \NC \NR
381\NC \llap{\star\space}extrasubscriptspace           \NC post   \NC                                     \NC                     \NC \NR
382\NC \llap{\star\space}extrasuperprescriptspace      \NC pre    \NC                                     \NC                     \NC \NR
383\NC \llap{\star\space}extrasubprescriptspace        \NC pre    \NC                                     \NC                     \NC \NR
384\LL
385\stoptabulate
386
387The parameters marked by a \star\ are \LUAMETATEX\ specific. Some have an
388associated font parameter but that is not official \OPENTYPE. For a very long
389time we had only a few math fonts but even today most of these fonts seem to
390use values that are similar to the ones \TEX\ uses. In that respect one can
391as well turn them into rendering specific ones. After all, changes are slim that
392a formula rendered by \TEX\ or e.g.\ \MSWORD\ are metric compatible and with
393the advanced spacing options in \LUAMETATEX\ we're even further off. Also keep
394in mind that the \TEX\ font parameters could be overloaded at the \TEX\ end.
395
396The spacing after a (combination of) postscript(s) is determined by \quote {space
397after script} and the spacing before a (combination of) prescript(s) by \quote
398{space before script}. If we have multi-scripts the \quote {space between script}
399kicks in and the space after the script is subtracted from it. The given space
400between is scaled with the \type {\scriptspacebetweenfactor} parameter.
401
402The default style mapping that we use are the same as those (hard coded) in
403regular \TEX\ and those for prime scripts are the same as for superscripts.
404
405\startluacode
406document.showmathvariant("subscriptvariant")
407document.showmathvariant("superscriptvariant")
408document.showmathvariant("primevariant")
409\stopluacode
410
411\stopsection
412
413\startsection[title=Skewed fractions]
414
415Skewed fractions are native in \LUAMETATEX. Such a fraction is a horizontal
416construct with the numerator and denominator shifted up and down a bit. It looks
417like this:
418
419\startlinecorrection
420\startMPcode
421    vardef baseline expr p =
422        (xpart llcorner p, 0) -- (xpart lrcorner p,0)
423    enddef ;
424
425    numeric wd ; wd := 12 ;
426    numeric ht ; ht :=  7 ;
427    numeric dp ; dp :=  3 ;
428
429    numeric ax ; ax :=  4 ;
430    numeric ws ; ws :=  5 ;
431    numeric hs ; hs :=  6 ;
432    numeric ds ; ds :=  3 ;
433
434    path slash       ; slash       := (-ws,-(hs+ds)) -- (ws,(hs+ds))  ;
435    path numerator   ; numerator   := unitsquare xyscaled (wd, ht+dp) shifted (0,-dp) && ((0,0) -- (wd,0)) ;
436    path denominator ; denominator := numerator ;
437
438    numerator   := numerator   shifted - center numerator ;
439    denominator := denominator shifted - center denominator ;
440
441    numerator   := anchored.lft (numerator,   center slash) shifted (-3.5ws, ax/2) ;
442    denominator := anchored.rt  (denominator, center slash) shifted ( 3.5ws,-ax/2) ;
443
444    draw slash       withcolor "darkgray" withpen pencircle scaled 1 ;
445    draw numerator   withcolor "darkred"  ;
446    draw denominator withcolor "darkblue" ;
447
448    path line ; line := (baseline currentpicture) leftenlarged 1 rightenlarged 1 ;
449
450    draw line                withstacking -1 withcolor "middlegray" ;
451    draw line shifted (0,ax) withstacking -1 withcolor "darkgreen"  ; % axis
452
453    currentpicture := currentpicture scaled 5 ;
454\stopMPcode
455\stoplinecorrection
456
457The rendering is driven by some parameters that determine the horizontal and
458vertically shifts but we found that the ones given by the font make no sense (and
459are not that well defined in the standard either). The horizontal shift relates
460to the width (and angle) of the slash and the vertical relates to the math axis.
461We don't listen to \quote {skewed fraction hgap} nor to \quote {skewed fraction
462vgap} but use the width of the middle character, normally a slash, that can grow
463on demand and multiply that with a \type {hfactor} that can be passed with the
464fraction command. A \type {vfactor} is used a multiplier for the vertical shift
465over the axis. Examples of (more)) control can be found in the \CONTEXT\ math
466manual. Here we just show a few examples that use \type {\vfrac} with its
467default values.
468
469\startlinecorrection
470\startcombination[nx=3,ny=2,distance=4em]
471    {\scale [s=3] {\showglyphs\im { \vfrac{1}    {2}     \mathaxisbelow }}} {}
472    {\scale [s=3] {\showglyphs\im { \vfrac{a}    {b}     \mathaxisbelow }}} {}
473    {\scale [s=3] {\showglyphs\im { \vfrac{b}    {a}     \mathaxisbelow }}} {}
474    {\scale [s=3] {\showglyphs\im { \vfrac{x^2}  {x^3}   \mathaxisbelow }}} {}
475    {\scale [s=3] {\showglyphs\im { \vfrac{(x+1)}{(x+2)} \mathaxisbelow }}} {}
476    {\scale [s=3] {\showglyphs\im { \vfrac{x+1}  {x+2}   \mathaxisbelow }}} {}
477\stopcombination
478\stoplinecorrection
479
480The quality of the slashes differs per font, some lack granularity in sizes,
481others have inconsistent angles between the base character and larger variants.
482
483The following commands are used:
484
485\starttyping
486\Uskewed
487\Uskewedwithdelims
488\stoptyping
489
490There are some parameter involved:
491
492\starttyping
493\Umathskeweddelimitertolerance
494\Umathskewedfractionhgap
495\Umathskewedfractionvgap
496\stoptyping
497
498\stopsection
499
500\startsection[title=Math fractions]
501
502Fractions in \TEX\ come in variants: with or without rule in the middle and with
503or without fences. The reason for the fenced ones is that they are not spaced
504like open and close class symbols. So, instead of open, fraction, close being
505three things, we have one thing. In \LUAMETATEX\ we can also use an extensible
506instead of the rule.
507
508\startlinecorrection
509\startMPcode
510    def Example (expr showbar) =
511        numeric wd ; wd := 20 ;
512        numeric ht ; ht :=  7 ;
513        numeric dp ; dp :=  3 ;
514
515        numeric ax ; ax :=  2 ;
516        numeric ay ; ay := -2 ;
517        numeric ab ; ab :=  2 ;
518
519        path numerator   ; numerator   := unitsquare xyscaled ( wd, ht+dp) shifted (0,-dp) && ((0,0) -- (wd,0)) ;
520        path denominator ; denominator := numerator ;
521        path fraction    ; fraction    := (-wd/2-ax,0) -- (wd/2+ax,0) ;
522
523        numerator   := numerator   shifted - center numerator ;
524        denominator := denominator shifted - center denominator ;
525
526        numerator   := numerator   shifted (0, (ht+dp)+ay) ;
527        denominator := denominator shifted (0,-(ht+dp)-ay) ;
528
529        if showbar :
530            draw fraction    withcolor "darkgray" withpen pencircle scaled 1 ;
531        fi ;
532        draw numerator   withcolor "darkred"  ;
533        draw denominator withcolor "darkblue" ;
534
535        path leftbar  ; leftbar  := (leftboundary  currentpicture topenlarged 2 bottomenlarged 2) shifted (-ab,0) ;
536        path rightbar ; rightbar := (rightboundary currentpicture topenlarged 2 bottomenlarged 2) shifted ( ab,0) ;
537
538        draw leftbar  withcolor "darkgray" withpen pencircle scaled 1 ;
539        draw rightbar withcolor "darkgray" withpen pencircle scaled 1 ;
540
541        currentpicture := currentpicture scaled 5 ;
542    enddef ;
543
544    draw image (Example(true)) ;
545
546    draw image (Example(false)) shifted (20+bbwidth(currentpicture) ,0) ;
547
548\stopMPcode
549\stoplinecorrection
550
551Because the rule is optional, we can have the following, which represents a so
552called binom construct.
553
554\stopsection
555
556\startsection[title=Math radicals]
557
558Radicals indeed look like roots. But the radical mechanism basically is a
559wrapping construct: there's something at the left that in traditional \TEX\ gets
560a rule appended. The left piece is an extensible, so it first grow with variant
561glyphs and when we run out if these we get an upward extensible with a repeated
562upward rule like symbol that then connect with the horizontal rule. In
563\LUAMETATEX\ the horizontal rule can be an extensible (repeated symbol) and we
564can also have a symbol at the right, which indeed can be a vertical extensible
565too.
566
567\startlinecorrection
568\startMPcode
569    vardef baseline expr p =
570        (xpart llcorner p, 0) -- (xpart lrcorner p,0)
571    enddef ;
572
573    numeric wd ; wd := 24 ;
574    numeric ht ; ht :=  7 ;
575    numeric dp ; dp :=  3 ;
576
577    numeric dw ; dw :=  3 ;
578    numeric dh ; dh :=  3 ;
579    numeric dd ; dd :=  1 ;
580
581    numeric rw ; rw :=  2 ;
582    numeric rh ; rh :=  2 + ht ;
583    numeric rd ; rd :=  2 + dp ;
584
585    path rleft   ; rleft   := (-3rw,rh/3) -- (-2rw,-rd) -- (-rw,rh) ;
586    path rright  ; rright  := (wd+2,rh) -- (wd+2,rh-2);
587    path rmiddle ; rmiddle := (-rw,rh) -- (wd+2,rh);
588    path body    ; body    := unitsquare xyscaled (wd, ht+dp) shifted (0,-dp) && ((0,0) -- (wd,0)) ;
589    path degree  ; degree  := unitsquare xyscaled (dw, dh+dd) shifted (0,-dd) && ((0,0) -- (dw,0)) ;
590
591    degree := degree shifted (-3rw-2,rh/3+dd+2) ;
592
593    draw rleft   withcolor "darkblue"  ;
594    draw rmiddle withcolor "darkgray"  ;
595    draw rright  withcolor "darkblue"  ;
596    draw body    withcolor "darkred"  ;
597    draw degree  withcolor "darkgreen"  ;
598
599    path line ; line := (baseline currentpicture) leftenlarged 1 rightenlarged 1 ;
600
601    draw line withstacking -1 withcolor "middlegray" ;
602
603    currentpicture := currentpicture scaled 5 ;
604\stopMPcode
605\stoplinecorrection
606
607Here are some aspects to take care of when rendering a radical like this:
608
609\startitemize[packed]
610\startitem The radical symbol goes below the baseline of what it contains. \stopitem
611\startitem There is some distance between the left symbol and the body. \stopitem
612\startitem There is some distance between the top symbol and the body. \stopitem
613\startitem There is some distance between the right symbol and the body. \stopitem
614\startitem The degree has to be anchored properly and possibly can stick out left. \stopitem
615\startitem The (upto) three elements have to overlap a little to avoid artifacts. \stopitem
616\startitem Multiple radicals might have to be made consistent with respect to heights and depths. \stopitem
617\stopitemize
618
619Involved commands:
620
621\starttyping
622\Uradical
623\Uroot
624\Urooted
625\stoptyping
626
627Relevant parameters:
628
629\starttyping
630\Umathradicaldegreeafter
631\Umathradicaldegreebefore
632\Umathradicaldegreeraise
633\Umathradicalextensibleafter
634\Umathradicalextensiblebefore
635\Umathradicalkern
636\Umathradicalrule
637\Umathradicalvariant
638\Umathradicalvgap
639\stoptyping
640
641\stopsection
642
643\startsection[title=Math accents]
644
645todo
646
647\stopsection
648
649\startsection[title=Math fences]
650
651todo
652
653\stopsection
654
655\stopdocument
656
657% \tohexa8 \mathnormalstylepreset            \par
658% \tohexa8 \mathcrampedstylepreset           \par
659% \tohexa8 \mathsubscriptstylepreset         \par
660% \tohexa8 \mathsuperscriptstylepreset       \par
661% \tohexa8 \mathsmallstylepreset             \par
662% \tohexa8 \mathsmallerstylepreset           \par
663% \tohexa8 \mathnumeratorstylepreset         \par
664% \tohexa8 \mathdenominatorstylepreset       \par
665% \tohexa8 \mathdoublesuperscriptstylepreset \par
666
667% \tohexa8 \Umathoverlayaccentvariant \displaystyle\par
668% \tohexa8 \Umathradicalvariant       \displaystyle\par
669% \tohexa8 \Umathradicalvariant       \textstyle   \par
670% \tohexa8 \Umathunderlinevariant     \displaystyle\par
671
672% $2x^{2^2}$
673% $\sqrt{x-\frac{1}{\sqrt{2}}}$
674% $\Umathradicalvariant \allmathstyles 0 \sqrt{x-\frac{1}{\sqrt{2}}}$
675% $2\frac{1}{2}$
676
677% An alternative description:
678%
679% \def\blob#1{\mathord{\ruledhbox{\strut\tttf #1}}}
680%
681% The most common cases of scripts attached to a nucleus are the following where
682% vertical spacing depends on the dimensions and combinations:
683%
684% \startlinecorrection
685% \im { \blob{nuc}
686%     \superscript   {\blob{sup 1}}
687% }
688% \quad
689% \im { \blob{nuc}
690%     \subscript     {\blob{sub 1}}
691% }
692% \quad
693% \im { \blob{nuc}
694%     \superscript   {\blob{sup 1}}
695%     \subscript     {\blob{sub 1}}
696% }
697% \stoplinecorrection
698%
699% We also have primes. These have always been somewhat messy in \TEX\ (macro
700% packages) because they are on the one hand already raised (in text they also
701% serve as minutes) but because they are supposed to be anchored as super script
702% the non raised variant us used. Another complication is that, especially in
703% \UNICODE\ the multiple primes are single characters. In \LUAMETATEX\ primes are
704% an additional script which makes for better positioning, definitely when we also
705% have a superscript. Multiple primes are collected and can be collapsed into a
706% single character. \footnote {In \CONTEXT\ \MKIV\ primes are handles at the \LUA\
707% end and become scripts. In \MKIV\ as well as in \MKXL\ collapsing is still a
708% \LUA\ task, but it is much simpler in \MKXL.}
709%
710% \startlinecorrection
711% \im { \blob{nuc}
712%     \primescript   {\blob{pri}}
713% }
714% \quad
715% \im { \blob{nuc}
716%     \primescript   {\blob{pri}}
717%     \subscript     {\blob{sub 1}}
718% }
719% \quad
720% \im { \blob{nuc}
721%     \primescript   {\blob{pri}}
722%     \superscript   {\blob{sup 1}}
723% }
724% \quad
725% \im { \blob{nuc}
726%     \primescript   {\blob{pri}}
727%     \superscript   {\blob{sup 1}}
728%     \subscript     {\blob{sub 1}}
729% }
730% \stoplinecorrection
731%
732% We also have prescripts and these have to align properly with postscripts
733% when present. Combinations of super- and subscripts make for different spacing
734% compared to single scripts and you can imagine that looking at four possible
735% scripts in various combinations have to obey to the same rules.
736%
737% \startlinecorrection
738% \im { \blob{nuc}
739%     \superscript   {\blob{sup 1}}
740%     \superprescript{\blob{sup 1}}
741% }
742% \quad
743% \im { \blob{nuc}
744%     \subscript   {\blob{sup 1}}
745%     \subprescript{\blob{sup 1}}
746% }
747% \quad
748% \im { \blob{nuc}
749%     \superscript {\blob{sup 1}}
750%     \subprescript{\blob{sup 1}}
751% }
752% \stoplinecorrection
753%
754% Finally there can be multiscripts and often we then talk in terms of index. One
755% can explicitly mark an index. A single \type {^} means super (post) script (or
756% more verbose \typ {\superscript}), while \type {^^} means indexed super (post)
757% script (\typ {\indexedsuperscript}). The threesome \type {^^^} makes a super pre
758% script and likewise the quadruple \type {^^^^} is an indexed super pre script.
759%
760% \startlinecorrection
761% \im { \blob{nuc}
762%     \primescript   {\blob{pri}}
763%     \superscript   {\blob{sup 1}}
764%     \subscript     {\blob{sub 1}}
765%     \superprescript{\blob{presup 1}}
766%     \subprescript  {\blob{presub 1}}
767%     \superscript   {\blob{sup 2}}
768%     \subscript     {\blob{sub 2}}
769%     \superprescript{\blob{presup 2}}
770%     \subprescript  {\blob{presub 2}}
771% }
772% \stoplinecorrection
773%
774% We can move to the next multiscript assembly with \typ {\noscript} so we have some
775% control over positioning.
776%
777% \startlinecorrection
778% \im { \blob{nuc}
779%     \superscript   {\blob{sup 1}}
780%     \noscript
781%     \subscript     {\blob{sub 1}}
782%     \noscript
783%     \superscript   {\blob{sup 2}}
784% }
785% \stoplinecorrection
786