1
2
3\environment luametatexstyle
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
14
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 dont 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 \TEXs 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, htdp) 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 youll 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 wont 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 {shiftamount} \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 {glueorder} \NC the calculated order of glue stretch of shrink \NC \NR
172\NC \type {gluesign} \NC the determined sign of glue stretch of shrink \NC \NR
173\NC \type {glueset} \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 {woffset} \NC used in horizontal movement calculations \NC \NR
178\NC \type {hoffset} \NC used in vertical movement calculations \NC \NR
179\NC \type {doffset} \NC used in vertical movement calculations \NC \NR
180\NC \type {xoffset} \NC a horizontal shift independent of dimensions \NC \NR
181\NC \type {yoffset} \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 {packagestate} \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 {premigrated} \NC content bound to the box that eventually will be injected \NC \NR
189\NC \type {postmigrated} \NC idem \NC \NR
190\NC \type {preadjusted} \NC idem \NC \NR
191\NC \type {postadjusted} \NC idem \NC \NR
192\ML
193\NC \type {sourceanchor} \NC an identifier bound to the box \NC \NR
194\NC \type {targetanchor} \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
226
227
228
229
230
231
232
233
234
235
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: prepost supersub 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 ( wd3,ht6dp4) shifted (0,dp ) ;
264 path presubscript ; presubscript := fullsquare xyscaled ( wd, ht2dp2) shifted (0,dp2) ;
265 path presuperscript ; presuperscript := fullsquare xyscaled ( wd, ht2dp2) shifted (0,dp2) ;
266 path postsubscript ; postsubscript := fullsquare xyscaled ( wd, ht2dp2) shifted (0,dp2) ;
267 path postsuperscript ; postsuperscript := fullsquare xyscaled ( wd, ht2dp2) shifted (0,dp2) ;
268 path primescript ; primescript := fullsquare xyscaled ( wd2,ht2dp2) shifted (0,dp2) ;
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 45 xheight \NC \NR
359
360\NC superscriptshiftdrop \NC post \NC SuperscriptBaselineDropMax \NC supdrop \NC \NR
361\NC superscriptbottommin \NC post \NC SuperscriptBottomMin \NC 14 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 45 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\ were 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 multiscripts 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,(hsds)) -- (ws,(hsds)) ;
435 path numerator ; numerator := unitsquare xyscaled (wd, htdp) 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, ax2) ;
442 denominator := anchored.rt (denominator, center slash) shifted ( 3.5ws,ax2) ;
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" ;
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 dont 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{x2} {x3} \mathaxisbelow }}} {}
475 {\scale [s=3] {\showglyphs\im { \vfrac{(x1)}{(x2)} \mathaxisbelow }}} {}
476 {\scale [s=3] {\showglyphs\im { \vfrac{x1} {x2} \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, htdp) shifted (0,dp) && ((0,0) -- (wd,0)) ;
520 path denominator ; denominator := numerator ;
521 path fraction ; fraction := (wd2ax,0) -- (wd2ax,0) ;
522
523 numerator := numerator shifted center numerator ;
524 denominator := denominator shifted center denominator ;
525
526 numerator := numerator shifted (0, (htdp)ay) ;
527 denominator := denominator shifted (0,(htdp)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 (20bbwidth(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: theres 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,rh3) -- (-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, htdp) shifted (0,dp) && ((0,0) -- (wd,0)) ;
589 path degree ; degree := unitsquare xyscaled (dw, dhdd) shifted (0,dd) && ((0,0) -- (dw,0)) ;
590
591 degree := degree shifted (-3rw-2,rh3dd+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
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786 |