% language=us runpath=texruns:manuals/luametatex

\environment luametatex-style

\startdocument[title=Constructions]

\startluacode
local styles     = tex.getmathstylevalues    () styles     = table.swapped(styles,styles)
local parameters = tex.getmathparametervalues() parameters = table.swapped(parameters,parameters)
local variants   = tex.getmathvariantvalues  () variants   = table.swapped(variants,variants)
local presets    = tex.getmathvariantpresets () presets    = table.swapped(presets,presets)

-- inspect(presets)
-- inspect(presets)

function document.printmathpresets()
    context.starttabulate { "||||" }
    context.FL()
    context.BC() context("construct")
    context.BC() context("value")
    context.BC() context("preset name")
    context.BC() context.NR()
    context.TL()
    for parameter=parameters.overlinevariant,parameters.stackvariant do
        local value  = tex.getmath(parameter,"display")
        local preset = variants[presets[value]]
        context.NC() context.type("\\Umath"..parameters[parameter])
        context.NC() context("0x%08X",value)
        context.NC() context(preset)
        context.NC() context.NR()
    end
    context.LL()
    context.stoptabulate()
end

function document.printmathvariants()
    for parameter=parameters.overlinevariant,parameters.stackvariant do
        for style=styles.display,styles.crampedscriptscript do
            local p, s = tex.getmathstylevariant(style,parameter)
            if p and s then
                 logs.report("mathvariants","%-24s %-20s %-18s %-20s",parameters[parameter],styles[style],variants[p],styles[s])
            end
        end
    end
end

function document.showmathvariant(variant)
    local parameter = type(variant) == "string" and parameters[variant] or variant
    context.startsubsubsubject { title = variant }
    context.starttabulate { "||T||" }
    context.BC() context("current style")
    context.BC() context("mapping")
    context.BC() context("used style")
    context.BC() context.NR()
    context.ML()
    for style=styles.display,styles.crampedscriptscript do
        local p, s = tex.getmathstylevariant(style,parameter)
        if p and s then
            context.NC() context(styles[style])
            context.NC() context("0x%08X",p)
            context.NC() context(styles[s])
            context.NC() context.NR()
        end
    end
    context.stoptabulate()
    context.stopsubsubsubject()
end
\stopluacode

\startsubject[title=Contents]
    \setups[sectioncontents]
\stopsubject

\startsection[title={Introduction}]

This is more a discussion of the way some constructs in for instance math work.
It will never be exhausting and mostly is for our own usage. We don't discuss all
the options but many are interfaced in higher level macros in \CONTEXT. This
chapter will gradually grow, depending on time and mood.

\stopsection

\startsection[title=Boxes]

Boxes are very important in \TEX. We have horizontal boxes and vertical boxes.
When you look at a page of text, the page itself is a vertical box, and among
other things it packs lines that are themselves horizontal boxes. The lines that
make a paragraph are the result of breaking a long horizontal box in smaller
pieces.

\startlinecorrection
\ruledvbox \bgroup \hsize 20em \showmakeup[line] \showboxes
    This is a vertical box. It has a few lines of text that started out as
    one long line but has been broken in pieces. Doing this as good as possible
    is one of \TEX's virtues.
\egroup
\stoplinecorrection

There is a low level manual on boxes so here we can limit the discussion to
basics. A box is in \TEX\ speak a node. In traditional \TEX\ it has a
width, height, depth and shift.

\startlinecorrection
\startMPcode
    numeric wd ; wd := 24 ;
    numeric ht ; ht :=  7 ;
    numeric dp ; dp :=  3 ;

    path body ; body := unitsquare xyscaled (wd, ht+dp) shifted (0,-dp) ;
    path line ; line := (0,0) -- (wd,0) ;

    draw line withcolor "middlegray" ;
    draw body withcolor "darkred" ;

    currentpicture := currentpicture scaled 5 ;
\stopMPcode
\stoplinecorrection

Here we see a box and the gray line is called the baseline, the height goes up
and the depth goes down. Normally the height and depth are determined by what
goes in the box but they can be changed as we like.

\startbuffer
\setbox\scratchboxone\ruledhpack{SHIFT 1}
\setbox\scratchboxtwo\ruledhpack{SHIFT 2}

\boxshift\scratchboxtwo 1ex \dontleavehmode \box\scratchboxone\box\scratchboxtwo

\setbox\scratchboxone\ruledvpack{SHIFT 3}
\setbox\scratchboxtwo\ruledvpack{SHIFT 4}

\boxshift\scratchboxtwo 1ex \box\scratchboxone\box\scratchboxtwo
\stopbuffer

\typebuffer

In this example you'll notice that the shift depends on the box being horizontal
or vertical. The primitives \type {\raise}, \type {\lower}, \type {\moveleft} and
\type {\moveright} can be used to shift a box.

\startlinecorrection
\getbuffer
\stoplinecorrection

The reason why we have the shift property is that it is more efficient than
wrapping a box in another box and shifting with kerns. In that case we also have
to go via a box register so that we can manipulate the final dimensions. Another
advantage is that the engine can use shifts to position for instance elements in
a math formula and even the par builder used shifts to deal with positioning the
lines according to shape and margin. In \LUAMETATEX\ the later is no longer the
case.

Inside a box there can be mark (think running headers), insert (think footnotes)
and adjust (think injecting something before or after the current line) nodes. The
par builder will move this from inside the box to between the lines but when boxes
are nested too deeply this won't happen and they get lost. In \LUAMETATEX\ these
objects do bubble up because we make them box properties. So, in addition to
the dimensions and shift a box also has migration fields.

In the low level manuals you can find examples of accessing various properties of
boxes so here we stick to a short description. The reason for mentioning them is
that it gives you an idea of what goes on in the engine.

\starttabulate
\FL
\BC field                 \BC usage \NC \NR
\TL
\NC \type {width}         \NC the (used) width \NC \NR
\NC \type {height}        \NC the (used) height \NC \NR
\NC \type {depth}         \NC the (used) depth \NC \NR
\NC \type {shift_amount}  \NC the shift (right or down) \NC \NR
\ML
\NC \type {list}          \NC pointer to the content \NC \NR
\ML
\NC \type {glue_order}    \NC the calculated order of glue stretch of shrink \NC \NR
\NC \type {glue_sign}     \NC the determined sign of glue stretch of shrink \NC \NR
\NC \type {glue_set}      \NC the calculated multiplier for glue stretch or shrink \NC \NR
\ML
\NC \type {geometry}      \NC a bit set registering manipulations \NC \NR
\NC \type {orientation}   \NC positional manipulations \NC \NR
\NC \type {w_offset}      \NC used in horizontal movement calculations \NC \NR
\NC \type {h_offset}      \NC used in vertical movement calculations \NC \NR
\NC \type {d_offset}      \NC used in vertical movement calculations \NC \NR
\NC \type {x_offset}      \NC a horizontal shift independent of dimensions \NC \NR
\NC \type {y_offset}      \NC a vertical shift independent of dimensions  \NC \NR
\NC \type {axis}          \NC the math axis \NC \NR
\ML
\NC \type {dir}           \NC the direction the box goes to (l2r or r2l) \NC \NR
\NC \type {package_state} \NC a bitset indicating how the box came to be as it is \NC \NR
\NC \type {index}         \NC a (system dependent) identifier \NC \NR
\ML
\NC \type {pre_migrated}  \NC content bound to the box that eventually will be injected \NC \NR
\NC \type {post_migrated} \NC idem \NC \NR
\NC \type {pre_adjusted}  \NC idem \NC \NR
\NC \type {post_adjusted} \NC idem \NC \NR
\ML
\NC \type {source_anchor} \NC an identifier bound to the box \NC \NR
\NC \type {target_anchor} \NC idem \NC \NR
\NC \type {anchor}        \NC a bitset indicating where and how to anchor \NC \NR
\ML
\NC \type {except}        \NC carried information about additional virtual depth \NC \NR
\NC \type {exdepth}       \NC additional virtual depth taken into account in the page builder \NC \NR
\LL
\stoptabulate

We have the usual dimension but also extra ones that relate to \typ {\boxxoffset}
and \typ {\boxyoffset} (these are virtual) as well as \typ {\boxxmove} and \typ
{\boxymove} (these influence dimensions). The \typ {\boxorientation} also gets
registered. The state fields carry information that is used in various places,
the pre and post fields relate to the mentioned embedded content. Anchors are
just there so that a macro package can play with this and excepts refer to an
additional dimensions that is looked at in the page builder, for instance in
order to prevent a page break at an unlucky spot. It all gives an indication of
what we are dealing with.

\stopsection

\startsection[title=Math style variants]

The \LUAMETATEX\ math engine is a follow up on the one in \LUATEX. That one
gradually became more configurable in order to deal with both traditional fonts
and \OPENTYPE\ fonts. In \LUAMETATEX\ much has been redone, opened up and
extended. New mechanisms and constructs have been added. In the process hard
coded heuristics with regards to math styles inside constructions were made
configurable, a feature that is probably not used much, apart from experimenting.
A side effect is that we can show how the engine is set up, so we do that when
applicable.

% \starttabulate
% \NC normal            \NC \tohexa8 \mathnormalstylepreset            \NC \NR
% \NC cramped           \NC \tohexa8 \mathcrampedstylepreset           \NC \NR
% \NC subscript         \NC \tohexa8 \mathsubscriptstylepreset         \NC \NR
% \NC superscript       \NC \tohexa8 \mathsuperscriptstylepreset       \NC \NR
% \NC small             \NC \tohexa8 \mathsmallstylepreset             \NC \NR
% \NC smaller           \NC \tohexa8 \mathsmallerstylepreset           \NC \NR
% \NC numerator         \NC \tohexa8 \mathnumeratorstylepreset         \NC \NR
% \NC denominator       \NC \tohexa8 \mathdenominatorstylepreset       \NC \NR
% \NC doublesuperscript \NC \tohexa8 \mathdoublesuperscriptstylepreset \NC \NR
% \stoptabulate

\ctxlua{document.printmathpresets()}

\stopsection

\startsection[title=Math scripts]

The basic components in a math formula are characters, accents, fractions,
radicals and fences. They are represented in the to be processed node list as
noads and eventually are converted in glyph, kern, glue and list nodes. Each noad
carries similar but also specific information about its purpose and intended
rendering. In \LUAMETATEX\ that is quite a bit more than in traditional \TEX.

These noads are often called atoms. The center piece in a noad is called the
nucleus. The fact that these noads also can have scripts attached makes them more
like molecules. Scripts can be attached to the left and right, high or low. That
makes fours of them: pre|/|post super|/|sub scripts. In \LUAMETATEX\ we also have
a prime script, which comes on its own, above a post subscript or after the post
superscript, if given.

\startlinecorrection
\startMPcode
    numeric wd ; wd := 10 ;
    numeric ht ; ht :=  8 ;
    numeric dp ; dp :=  2 ;

    path nucleus         ; nucleus         := fullsquare xyscaled (2wd,  ht  +dp  ) shifted (0,-dp  ) ;
    path follower        ; follower        := fullsquare xyscaled ( wd/3,ht/6+dp/4) shifted (0,-dp  ) ;
    path presubscript    ; presubscript    := fullsquare xyscaled ( wd,  ht/2+dp/2) shifted (0,-dp/2) ;
    path presuperscript  ; presuperscript  := fullsquare xyscaled ( wd,  ht/2+dp/2) shifted (0,-dp/2) ;
    path postsubscript   ; postsubscript   := fullsquare xyscaled ( wd,  ht/2+dp/2) shifted (0,-dp/2) ;
    path postsuperscript ; postsuperscript := fullsquare xyscaled ( wd,  ht/2+dp/2) shifted (0,-dp/2) ;
    path primescript     ; primescript     := fullsquare xyscaled ( wd/2,ht/2+dp/2) shifted (0,-dp/2) ;

    presubscript    := anchored.lrt  (presubscript,    llcorner nucleus) shifted (-1,0) ;
    presuperscript  := anchored.lrt  (presuperscript,  ulcorner nucleus) shifted (-1,0) ;
    postsubscript   := anchored.llft (postsubscript,   lrcorner nucleus) shifted ( 1,0) ;
    postsuperscript := anchored.llft (postsuperscript, urcorner nucleus) shifted ( 1,0) ;
    primescript     := anchored.llft (primescript,     urcorner nucleus) shifted (bbwidth postsuperscript + 2,0) ;

    draw nucleus         withcolor "darkgray"   ;
    draw presubscript    withcolor "darkred"    ;
    draw presuperscript  withcolor "darkgreen"  ;
    draw postsubscript   withcolor "darkblue"   ;
    draw postsuperscript withcolor "darkyellow" ;
    draw primescript     withcolor "darkorange" ;

    draw follower        shifted (  .5bbwidth nucleus + bbwidth postsuperscript + bbwidth primescript + 3,0) withcolor "darkgray"   ;
    draw follower        shifted (- .5bbwidth nucleus - bbwidth presuperscript                        - 1,0) withcolor "darkgray"   ;
    draw presubscript    shifted (                    - bbwidth presubscript                          - 1,0) withcolor "darkred"    ;
    draw presuperscript  shifted (                    - bbwidth presuperscript                        - 1,0) withcolor "darkgreen"  ;
    draw postsubscript   shifted (                      bbwidth postsubscript   + bbwidth primescript + 2,0) withcolor "darkblue"   ;
    draw postsuperscript shifted (                      bbwidth postsuperscript + bbwidth primescript + 2,0) withcolor "darkyellow" ;

    currentpicture := currentpicture scaled 5 ;
\stopMPcode
\stoplinecorrection

Here the raised rectangle represents the prime. The large center piece is the
nucleus. Four scripts are attached to the nucleus. The two smaller center pieces
indicate follow up atoms. They make it possible to have multiple pre- and
postscripts. For single scripts we get combinations like these:

\startlinecorrection
\startcombination[nx=3,ny=2,distance=4em]
    {\scale [s=3] {\showglyphs\im { X   ^{\tt a} _{\tt b} ^^^{\tt c} ___{\tt d} \mathaxisbelow }}} {}
    {\scale [s=3] {\showglyphs\im { X            _{\tt b}            ___{\tt d} \mathaxisbelow }}} {}
    {\scale [s=3] {\showglyphs\im { X   ^{\tt a}          ^^^{\tt c}            \mathaxisbelow }}} {}
    {\scale [s=3] {\showglyphs\im { X ' ^{\tt a} _{\tt b} ^^^{\tt c} ___{\tt d} \mathaxisbelow }}} {}
    {\scale [s=3] {\showglyphs\im { X '          _{\tt b}            ___{\tt d} \mathaxisbelow }}} {}
    {\scale [s=3] {\showglyphs\im { X ' ^{\tt a}          ^^^{\tt c}            \mathaxisbelow }}} {}
\stopcombination
\stoplinecorrection

And for multiple (there can be more that two) we get this assembly:

\startlinecorrection
\startcombination[nx=3,ny=2,distance=4em]
    {\scale [s=3] {\showglyphs\im { X   ^{\tt a} _{\tt b} ^^^{\tt c} ___{\tt d}  ^{\tt A} _{\tt B} ^^^{\tt C} ___{\tt D} \mathaxisbelow }}} {}
    {\scale [s=3] {\showglyphs\im { X            _{\tt b}            ___{\tt d}           _{\tt B}            ___{\tt D} \mathaxisbelow }}} {}
    {\scale [s=3] {\showglyphs\im { X   ^{\tt a}          ^^^{\tt c}             ^{\tt A}          ^^^{\tt C}            \mathaxisbelow }}} {}
    {\scale [s=3] {\showglyphs\im { X ' ^{\tt a} _{\tt b} ^^^{\tt c} ___{\tt d}  ^{\tt A} _{\tt B} ^^^{\tt C} ___{\tt D} \mathaxisbelow }}} {}
    {\scale [s=3] {\showglyphs\im { X '          _{\tt b}            ___{\tt d}           _{\tt B}            ___{\tt D} \mathaxisbelow }}} {}
    {\scale [s=3] {\showglyphs\im { X ' ^{\tt a}          ^^^{\tt c}             ^{\tt A}          ^^^{\tt C}            \mathaxisbelow }}} {}
\stopcombination
\stoplinecorrection

It will be clear that there is quite a bit of code involved in dealing with this
because these scripts are not only to be anchored relative to the nucleus but
also to each other. The dimensions of the scripts determine for instance how
close a combined super and subscript are positioned.

\startlinecorrection
\startcombination[nx=3,ny=1,distance=2em]
    {\scale [s=5] {\showglyphs\im { X          _{\tt p} \mathaxisbelow }}} {}
    {\scale [s=5] {\showglyphs\im { X ^{\tt p} _{\tt p} \mathaxisbelow }}} {}
    {\scale [s=5] {\showglyphs\im { X ^{\tt p}          \mathaxisbelow }}} {}
\stopcombination
\stoplinecorrection

The rendering of scripts involves several parameters, of which some relate to
font parameters. In \LUAMETATEX\ we have a few more variables and we also
overload font parameters, if only because only a few make sense and it looks like
font designers just copy values from the first available fonts so in the end we
can as well use our own preferred values.

The following parameters play a role in rendering the shown assembly, The
traditional \TEX\ engine expects a math font to set quite some parameters for
positioning the scripts but has no concept of prescripts and neither has
\OPENTYPE. This is why we have extra parameters (and for completeness we also
have them for the post scripts). One can wonder of font parameters make sense
here because in the end we can decide for a better visual result with different
ones. After all, assembling scripts is not really what fonts are about.

\starttabulate[|||||]
\FL
\BC engine parameter                                \BC target \BC open type font                      \BC tex font            \BC \NR
\TL
\NC                   subscriptshiftdrop            \NC post   \NC SubscriptBaselineDropMin            \NC subdrop             \NC \NR
\NC                   subscriptshiftdown            \NC post   \NC SubscriptShiftDown                  \NC sub1                \NC \NR
\NC                   subscriptsuperscriptshiftdown \NC post   \NC SubscriptShiftDown[WithSuperscript] \NC sub2                \NC \NR
\NC                   subscriptsuperscriptvgap      \NC post   \NC SubSuperscriptGapMin                \NC 4   rulethickness   \NC \NR
\NC                   subscripttopmax               \NC post   \NC SubscriptTopMax                     \NC 4/5 xheight         \NC \NR

\NC                   superscriptshiftdrop          \NC post   \NC SuperscriptBaselineDropMax          \NC supdrop             \NC \NR
\NC                   superscriptbottommin          \NC post   \NC SuperscriptBottomMin                \NC 1/4 xheight         \NC \NR
\NC                   superscriptshiftup            \NC post   \NC SuperscriptShiftUp[Cramped]         \NC sup1 sup2 sup3      \NC \NR
\NC                   superscriptsubscriptbottommax \NC post   \NC SuperscriptBottomMaxWithSubscript   \NC 4/5 xheight         \NC \NR

\NC \llap{\star\space}primeraise                    \NC prime  \NC PrimeRaisePercent                   \NC                     \NC \NR
\NC \llap{\star\space}primeraisecomposed            \NC prime  \NC PrimeRaiseComposedPercent           \NC                     \NC \NR
\NC \llap{\star\space}primeshiftup                  \NC prime  \NC PrimeShiftUp[Cramped]               \NC                     \NC \NR
\NC \llap{\star\space}primeshiftdrop                \NC prime  \NC PrimeBaselineDropMax                \NC                     \NC \NR
\NC \llap{\star\space}primespaceafter               \NC prime  \NC PrimeSpaceAfter                     \NC                     \NC \NR

\NC                   spaceafterscript              \NC post   \NC SpaceAfterScript                    \NC \typ {\scriptspace} \NC \NR
\NC \llap{\star\space}spacebeforescript             \NC post   \NC SpaceBeforeScript                   \NC                     \NC \NR
\NC \llap{\star\space}spacebetweenscript            \NC multi  \NC SpaceBetweenScript                  \NC                     \NC \NR

\NC \llap{\star\space}extrasuperscriptshift         \NC pre    \NC                                     \NC                     \NC \NR
\NC \llap{\star\space}extrasuperprescriptshift      \NC pre    \NC                                     \NC                     \NC \NR
\NC \llap{\star\space}extrasubscriptshift           \NC pre    \NC                                     \NC                     \NC \NR
\NC \llap{\star\space}extrasubprescriptshift        \NC pre    \NC                                     \NC                     \NC \NR

\NC \llap{\star\space}extrasuperscriptspace         \NC post   \NC                                     \NC                     \NC \NR
\NC \llap{\star\space}extrasubscriptspace           \NC post   \NC                                     \NC                     \NC \NR
\NC \llap{\star\space}extrasuperprescriptspace      \NC pre    \NC                                     \NC                     \NC \NR
\NC \llap{\star\space}extrasubprescriptspace        \NC pre    \NC                                     \NC                     \NC \NR
\LL
\stoptabulate

The parameters marked by a \star\ are \LUAMETATEX\ specific. Some have an
associated font parameter but that is not official \OPENTYPE. For a very long
time we had only a few math fonts but even today most of these fonts seem to
use values that are similar to the ones \TEX\ uses. In that respect one can
as well turn them into rendering specific ones. After all, changes are slim that
a formula rendered by \TEX\ or e.g.\ \MSWORD\ are metric compatible and with
the advanced spacing options in \LUAMETATEX\ we're even further off. Also keep
in mind that the \TEX\ font parameters could be overloaded at the \TEX\ end.

The spacing after a (combination of) postscript(s) is determined by \quote {space
after script} and the spacing before a (combination of) prescript(s) by \quote
{space before script}. If we have multi-scripts the \quote {space between script}
kicks in and the space after the script is subtracted from it. The given space
between is scaled with the \type {\scriptspacebetweenfactor} parameter.

The default style mapping that we use are the same as those (hard coded) in
regular \TEX\ and those for prime scripts are the same as for superscripts.

\startluacode
document.showmathvariant("subscriptvariant")
document.showmathvariant("superscriptvariant")
document.showmathvariant("primevariant")
\stopluacode

\stopsection

\startsection[title=Skewed fractions]

Skewed fractions are native in \LUAMETATEX. Such a fraction is a horizontal
construct with the numerator and denominator shifted up and down a bit. It looks
like this:

\startlinecorrection
\startMPcode
    vardef baseline expr p =
        (xpart llcorner p, 0) -- (xpart lrcorner p,0)
    enddef ;

    numeric wd ; wd := 12 ;
    numeric ht ; ht :=  7 ;
    numeric dp ; dp :=  3 ;

    numeric ax ; ax :=  4 ;
    numeric ws ; ws :=  5 ;
    numeric hs ; hs :=  6 ;
    numeric ds ; ds :=  3 ;

    path slash       ; slash       := (-ws,-(hs+ds)) -- (ws,(hs+ds))  ;
    path numerator   ; numerator   := unitsquare xyscaled (wd, ht+dp) shifted (0,-dp) && ((0,0) -- (wd,0)) ;
    path denominator ; denominator := numerator ;

    numerator   := numerator   shifted - center numerator ;
    denominator := denominator shifted - center denominator ;

    numerator   := anchored.lft (numerator,   center slash) shifted (-3.5ws, ax/2) ;
    denominator := anchored.rt  (denominator, center slash) shifted ( 3.5ws,-ax/2) ;

    draw slash       withcolor "darkgray" withpen pencircle scaled 1 ;
    draw numerator   withcolor "darkred"  ;
    draw denominator withcolor "darkblue" ;

    path line ; line := (baseline currentpicture) leftenlarged 1 rightenlarged 1 ;

    draw line                withstacking -1 withcolor "middlegray" ;
    draw line shifted (0,ax) withstacking -1 withcolor "darkgreen"  ; % axis

    currentpicture := currentpicture scaled 5 ;
\stopMPcode
\stoplinecorrection

The rendering is driven by some parameters that determine the horizontal and
vertically shifts but we found that the ones given by the font make no sense (and
are not that well defined in the standard either). The horizontal shift relates
to the width (and angle) of the slash and the vertical relates to the math axis.
We don't listen to \quote {skewed fraction hgap} nor to \quote {skewed fraction
vgap} but use the width of the middle character, normally a slash, that can grow
on demand and multiply that with a \type {hfactor} that can be passed with the
fraction command. A \type {vfactor} is used a multiplier for the vertical shift
over the axis. Examples of (more)) control can be found in the \CONTEXT\ math
manual. Here we just show a few examples that use \type {\vfrac} with its
default values.

\startlinecorrection
\startcombination[nx=3,ny=2,distance=4em]
    {\scale [s=3] {\showglyphs\im { \vfrac{1}    {2}     \mathaxisbelow }}} {}
    {\scale [s=3] {\showglyphs\im { \vfrac{a}    {b}     \mathaxisbelow }}} {}
    {\scale [s=3] {\showglyphs\im { \vfrac{b}    {a}     \mathaxisbelow }}} {}
    {\scale [s=3] {\showglyphs\im { \vfrac{x^2}  {x^3}   \mathaxisbelow }}} {}
    {\scale [s=3] {\showglyphs\im { \vfrac{(x+1)}{(x+2)} \mathaxisbelow }}} {}
    {\scale [s=3] {\showglyphs\im { \vfrac{x+1}  {x+2}   \mathaxisbelow }}} {}
\stopcombination
\stoplinecorrection

The quality of the slashes differs per font, some lack granularity in sizes,
others have inconsistent angles between the base character and larger variants.

The following commands are used:

\starttyping
\Uskewed
\Uskewedwithdelims
\stoptyping

There are some parameter involved:

\starttyping
\Umathskeweddelimitertolerance
\Umathskewedfractionhgap
\Umathskewedfractionvgap
\stoptyping

\stopsection

\startsection[title=Math fractions]

Fractions in \TEX\ come in variants: with or without rule in the middle and with
or without fences. The reason for the fenced ones is that they are not spaced
like open and close class symbols. So, instead of open, fraction, close being
three things, we have one thing. In \LUAMETATEX\ we can also use an extensible
instead of the rule.

\startlinecorrection
\startMPcode
    def Example (expr showbar) =
        numeric wd ; wd := 20 ;
        numeric ht ; ht :=  7 ;
        numeric dp ; dp :=  3 ;

        numeric ax ; ax :=  2 ;
        numeric ay ; ay := -2 ;
        numeric ab ; ab :=  2 ;

        path numerator   ; numerator   := unitsquare xyscaled ( wd, ht+dp) shifted (0,-dp) && ((0,0) -- (wd,0)) ;
        path denominator ; denominator := numerator ;
        path fraction    ; fraction    := (-wd/2-ax,0) -- (wd/2+ax,0) ;

        numerator   := numerator   shifted - center numerator ;
        denominator := denominator shifted - center denominator ;

        numerator   := numerator   shifted (0, (ht+dp)+ay) ;
        denominator := denominator shifted (0,-(ht+dp)-ay) ;

        if showbar :
            draw fraction    withcolor "darkgray" withpen pencircle scaled 1 ;
        fi ;
        draw numerator   withcolor "darkred"  ;
        draw denominator withcolor "darkblue" ;

        path leftbar  ; leftbar  := (leftboundary  currentpicture topenlarged 2 bottomenlarged 2) shifted (-ab,0) ;
        path rightbar ; rightbar := (rightboundary currentpicture topenlarged 2 bottomenlarged 2) shifted ( ab,0) ;

        draw leftbar  withcolor "darkgray" withpen pencircle scaled 1 ;
        draw rightbar withcolor "darkgray" withpen pencircle scaled 1 ;

        currentpicture := currentpicture scaled 5 ;
    enddef ;

    draw image (Example(true)) ;

    draw image (Example(false)) shifted (20+bbwidth(currentpicture) ,0) ;

\stopMPcode
\stoplinecorrection

Because the rule is optional, we can have the following, which represents a so
called binom construct.

Involved commands:

\starttyping
\Uabove
\Uatop
\Uover
\Ustretched
\Uabovewithdelims
\Uatopwithdelims
\Uoverwithdelims
\Ustretchedwithdelims
\stoptyping

Relevant parameters:

\starttyping
\Umathfractionrule
\Umathfractionnumvgap
\Umathfractionnumup
\Umathfractiondenomvgap
\Umathfractiondenomdown
\Umathfractiondelsize
\stoptyping

The values that come with the fonts often are sub-optimal so in \CONTEXT\ we
adapt them. We also use different means for spacing, like struts. But it will
always be a compromise. We'll try to show what happens but assume that you're
familiar with \TEX, read: are able to read a macro. If not, just forget about
messing with these parameters.

\startbuffer
\starttexdefinition TestRun #1#2
    \dontleavehmode
    \scale[width=1tw] \bgroup \pushoverloadmode
        \def\TestA{$ \maincolor \showglyphs \Uover              {\darkgray #1}{\darkgray #2} $}
        \def\TestB{$ \maincolor \showglyphs \Uover vfactor  100 {\darkgray #1}{\darkgray #2} $}
        \def\TestC{$ \maincolor \showglyphs \Uover vfactor 2000 {\darkgray #1}{\darkgray #2} $}
        \def\TestD{$ \maincolor \showglyphs \Uover vfactor    0 {\darkgray #1}{\darkgray #2} $}
        \everymath{\fam\zerocount}%
        \Umathfractionnumup    \allmathstyles\zeropoint
        \Umathfractiondenomdown\allmathstyles\zeropoint
        \Umathfractionnumvgap  \allmathstyles\zeropoint
        \Umathfractiondenomvgap\allmathstyles\zeropoint
        \start
            \TestA
        \stop \thinspace \start
            \Umathfractionnumvgap  \allmathstyles 2pt
            \TestA
        \stop \thinspace \start
            \Umathfractiondenomvgap\allmathstyles 2pt
            \TestA
        \stop \thinspace \start
            \Umathfractionnumup    \allmathstyles 2pt
            \TestA \TestB \TestC \TestD
        \stop \thinspace \start
            \Umathfractionnumup    \allmathstyles 1.1ex
            \TestA \TestB \TestC \TestD
        \stop \thinspace \start
            \Umathfractiondenomdown\allmathstyles 2pt
            \TestA \TestB \TestC \TestD
        \stop \thinspace \start
            \Umathfractiondenomdown\allmathstyles 1.1ex
            \TestA \TestB \TestC \TestD
      % \stop \thinspace \start
      %     \Umathfractionnumvgap\allmathstyles -2pt
      %     \Umathfractionnumup  \allmathstyles  2pt
      %     \TestA
      % \stop \thinspace \start
      %     \Umathfractiondenomvgap\allmathstyles -2pt
      %     \Umathfractiondenomdown\allmathstyles  2pt
      %     \TestA
        \stop
    \egroup
\stoptexdefinition
\stopbuffer

\typebuffer[option=TEX] \getbuffer

We now apply this macro to two different characters, first the often used \im
{x}:

\startlinecorrection
    \TestRun{𝑥}{𝑥}
\stoplinecorrection

Next we use a character with a descender:

\startlinecorrection
    \TestRun{𝑔}{𝑔}
\stoplinecorrection

The displacement logic that gets applied in the engine is as follows:

\starttyping[option=LUA]
factor_up   = num_up     * vfactor
factor_down = denom_down * vfactor

delta_up    = num_vgap   - (factor_up   - num_depth   ) - (axis + rule/2)
delta_down  = denom_vgap - (factor_down - denom_height) + (axis - rule/2)

shift_up    = factor_up   + max(0,delta_up)
shift_down  = factor_down + max(0,delta_down)
\stoptyping

In \CONTEXT\ we only tweak the gaps, so there we effectively have:

\starttyping[option=LUA]
delta_up    = num_vgap   + num_depth    - (axis + rule/2)
delta_down  = denom_vgap + denom_height + (axis - rule/2)

shift_up    = max(0,delta_up)
shift_down  = max(0,delta_down)
\stoptyping

\definecolor[tdarkblue][b=.6,t=.5,a=1]
\definecolor[tdarkred] [r=.6,t=.5,a=1]

Here, in blue we see what \CONTEXT\ does by default, while in red we see the
engine (and font) defaults in action:

\startlinecorrection
    \scale [width=.25tw] \bgroup
        \startoverlay
            \bgroup \color[tdarkblue]\bgroup
                \vrule height 1.25sh depth 1.25sd
                \im {\frac{𝑥}{𝑥} + \frac{𝑔}{𝑔}}%
            \egroup \egroup
            \bgroup \color[tdarkred]\bgroup
                \vrule height 1.25sh depth 1.25sd
                \pushoverloadmode
                \everymath{\fam\zerocount}%
                $\Uover{𝑥}{𝑥} + \Uover{𝑔}{𝑔} $%
            \egroup \egroup
        \stopoverlay
    \egroup
\stoplinecorrection

\stopsection

\startsection[title=Math radicals]

Radicals indeed look like roots. But the radical mechanism basically is a
wrapping construct: there's something at the left that in traditional \TEX\ gets
a rule appended. The left piece is an extensible, so it first grow with variant
glyphs and when we run out if these we get an upward extensible with a repeated
upward rule like symbol that then connect with the horizontal rule. In
\LUAMETATEX\ the horizontal rule can be an extensible (repeated symbol) and we
can also have a symbol at the right, which indeed can be a vertical extensible
too.

\startlinecorrection
\startMPcode
    vardef baseline expr p =
        (xpart llcorner p, 0) -- (xpart lrcorner p,0)
    enddef ;

    numeric wd ; wd := 24 ;
    numeric ht ; ht :=  7 ;
    numeric dp ; dp :=  3 ;

    numeric dw ; dw :=  3 ;
    numeric dh ; dh :=  3 ;
    numeric dd ; dd :=  1 ;

    numeric rw ; rw :=  2 ;
    numeric rh ; rh :=  2 + ht ;
    numeric rd ; rd :=  2 + dp ;

    path rleft   ; rleft   := (-3rw,rh/3) -- (-2rw,-rd) -- (-rw,rh) ;
    path rright  ; rright  := (wd+2,rh) -- (wd+2,rh-2);
    path rmiddle ; rmiddle := (-rw,rh) -- (wd+2,rh);
    path body    ; body    := unitsquare xyscaled (wd, ht+dp) shifted (0,-dp) && ((0,0) -- (wd,0)) ;
    path degree  ; degree  := unitsquare xyscaled (dw, dh+dd) shifted (0,-dd) && ((0,0) -- (dw,0)) ;

    degree := degree shifted (-3rw-2,rh/3+dd+2) ;

    draw rleft   withcolor "darkblue"  ;
    draw rmiddle withcolor "darkgray"  ;
    draw rright  withcolor "darkblue"  ;
    draw body    withcolor "darkred"  ;
    draw degree  withcolor "darkgreen"  ;

    path line ; line := (baseline currentpicture) leftenlarged 1 rightenlarged 1 ;

    draw line withstacking -1 withcolor "middlegray" ;

    currentpicture := currentpicture scaled 5 ;
\stopMPcode
\stoplinecorrection

Here are some aspects to take care of when rendering a radical like this:

\startitemize[packed]
\startitem The radical symbol goes below the baseline of what it contains. \stopitem
\startitem There is some distance between the left symbol and the body. \stopitem
\startitem There is some distance between the top symbol and the body. \stopitem
\startitem There is some distance between the right symbol and the body. \stopitem
\startitem The degree has to be anchored properly and possibly can stick out left. \stopitem
\startitem The (upto) three elements have to overlap a little to avoid artifacts. \stopitem
\startitem Multiple radicals might have to be made consistent with respect to heights and depths. \stopitem
\stopitemize

Involved commands:

\starttyping
\Uradical
\Uroot
\Urooted
\stoptyping

Relevant parameters:

\starttyping
\Umathradicaldegreeafter
\Umathradicaldegreebefore
\Umathradicaldegreeraise
\Umathradicalextensibleafter
\Umathradicalextensiblebefore
\Umathradicalkern
\Umathradicalrule
\Umathradicalvariant
\Umathradicalvgap
\stoptyping

\stopsection

\startsection[title=Math accents]

Math accents a bit of a mess. We have for instance \type {\overline} and \type
{\underline}which actually can be seen as an accent but is a rule because that
was easier. It also saved a set of glyph variants and an extensible in a time
where the number of slots in a font was a limiting factor. Of course a square
rule doesn't match well with shapes that have rounded corners but given the small
sizes that often goes unnoticed. Rules are important in \TEX\ anyway: between
fractions and as extender for a radical. In \LUAMETATEX\ we can instead fall back
on what a font provides (or what we can fake using virtual assemblies).

Accents, or symbols that go on top or below, can be of a fixed size, go wider in
steps or eventually stretch. A hat for instance comes in sizes and has no
stretch variant (that is, no extensible because in \LUAMETATEX\ we actually can
stretch); the shape is not that suited for it. A brace on the other hand can at
some point be constructed from pieces. Unfortunately fonts are often inconsistent
or incomplete, which is likely a side effect of the repertoire that \TEX\ came
with.

\startlinecorrection
\startMPcode
    numeric wd ; wd := 12 ;
    numeric ht ; ht :=  7 ;
    numeric dp ; dp :=  3 ;
    numeric at ; at :=  2 ;
    numeric ab ; ab :=  2 ;
    numeric af ; af :=  1 ;
    numeric dd ; dd :=  1 ;

    path abot ; abot := unitsquare xyscaled (  wd/2, at)    shifted (0,-dd-ab) ;
    path atop ; atop := unitsquare xyscaled (5*wd/4, ab)    shifted (0, dd) ;
    path flat ; flat := unitsquare xyscaled (3*wd/4, af)    shifted (0, dd) ;
    path body ; body := unitsquare xyscaled (  wd,   ht+dp) shifted (0,-dp) ;
    path line ; line := (0,0) -- (wd,0) ;

    draw line shifted (0, 0)        withcolor "middlegray" ;
    draw body shifted (0, 0)        withcolor "darkred" ;
    draw atop shifted (-1*wd/8, ht) withcolor "darkblue" ;
    draw abot shifted (3,-dp)       withcolor "darkblue" ;

    draw line shifted (20, 0)         withcolor "middlegray" ;
    draw body shifted (20, 0)         withcolor "darkred" ;
    draw flat shifted (20+1*wd/8, ht) withcolor "darkblue" ;

    currentpicture := currentpicture scaled 5 ;
\stopMPcode
\stoplinecorrection

In \OPENTYPE\ we also have accents but for some reason we only have top anchors.
Maybe it is because \TEX\ had no real anchors, only a so called skew character
from which we used a kern between that one and an accent as shift: a pseudo
anchor so to say. In \LUAMETATEX\ we do support bottom anchors and also provide
more control over placement. Of course one has to use math font that supports
this, which is what we do in \CONTEXT, after all we wanted this and had to test
it. In \OPENTYPE\ fonts we also have so called flat accents, so we have ways to
choose those variants when needed. They prevent a formula becoming too high.

\startbuffer[1]
\im {\Umathaccent           "0 "0 "20D7             {xxx}}
\im {\Umathaccent top       "0 "0 "20D7             {xxx}}
\im {\Umathaccent bottom    "0 "0 "20D7             {xxx}}
\im {\Umathaccent both      "0 "0 "20D7 "1 "0 "20D7 {xxx}}
\im {\Umathaccent top fixed "0 "0 "20D7             {xxx}}
\stopbuffer

\startbuffer[21]
\im {\Umathaccent         top "0 "0 "0302 {xxxxxxxx}}
\im {\Umathaccent exact   top "0 "0 "0302 {xxxxxxxx}}
\im {\Umathaccent stretch top "0 "0 "0302 {xxxxxxxx}}
\im {\Umathaccent shrink  top "0 "0 "0302 {xxxxxxxx}}
\im {\Umathaccent center  top "0 "0 "0302 {xxxxxxxx}}
\im {\Umathaccent single  top "0 "0 "0302 {xxxxxxxx}}
\stopbuffer

\startbuffer[22]
\im {\Umathaccent         top "0 "0 `x    {\blue x}}
\im {\Umathaccent shrink  top "0 "0 `x    {\blue x}}
\im {\Umathaccent         top "0 "0 "0302 {\red x}}
\im {\Umathaccent shrink  top "0 "0 "0302 {\red x}}
\stopbuffer

\startbuffer[3]
\im {\Umathaccent top "0 "0 "0302 {x}}
\im {\Umathaccent top "0 "0 "0302 {xx}}
\im {\Umathaccent top "0 "0 "0302 {xxx}}
\im {\Umathaccent top "0 "0 "0302 {xxxx}}
\im {\Umathaccent top "0 "0 "0302 {xxxxx}}
\im {\Umathaccent top "0 "0 "0302 {xxxxxx}}
\stopbuffer

\startbuffer[4]
\im {\Umathaccent fraction 100 top "0 "0 "0302 {xxxxx}}
\im {\Umathaccent fraction 200 top "0 "0 "0302 {xxxxx}}
\im {\Umathaccent fraction 300 top "0 "0 "0302 {xxxxx}}
\im {\Umathaccent fraction 400 top "0 "0 "0302 {xxxxx}}
\im {\Umathaccent fraction 500 top "0 "0 "0302 {xxxxx}}
\im {\Umathaccent fraction 600 top "0 "0 "0302 {xxxxx}}
\stopbuffer

\startbuffer[5]
\im {\Umathaccent overlay      "0 "0 `a {xxxxxxxx}}
\im {\Umathaccent base overlay "0 "0 `a {xxxxxxxx}}
\stopbuffer

In its simplest form, the accent constructor takes a single math character
specification but you can control the location with a keyword. Given the
availability of wider variants and/or an extensible the accent will cover the
body. The fixed keyword will force the smallest variant.

\typebuffer[1][option=TEX]

\start \switchtobodyfont[pagella-nt] \getbuffer[1] \par \stop
\start \switchtobodyfont[pagella]    \getbuffer[1] \par \stop

To what extend the accent will stretch is controlled by keywords. As above, we
show what happens with a font-as-is and with one set up by \CONTEXT. The later
will always stretch or shrink to fit.

\typebuffer[21][option=TEX]

\start \switchtobodyfont[pagella-nt] \getbuffer[2] \par \stop
\start \switchtobodyfont[pagella]    \getbuffer[2] \par \stop

It's not so easy to come up with an example for shrink because it will only
happen when there is a reason to do so. Also, it's kind of hard to see because
accents can be shifted based on the italic correction (or kern). The good news is
that the macro package will set up things. Also good news is that some of these
options are just there as left-over from experiments, so you might find no real
reason to apply them.

\typebuffer[22][option=TEX]

\start \switchtobodyfont[pagella-nt] \getbuffer[2] \par \stop
\start \switchtobodyfont[pagella]    \getbuffer[2] \par \stop

The reason why you see a difference between \CONTEXT\ and the non-tuned variant
is that the rendering is controlled by a lot of options. After this mechanism is
set up according to circumstances, font parameters, math font options, class
options and available glyphs, we eventually end up at the following steps:

\startitemize[n]
\startitem
    When the glyph involved has option \number\noitaliccorrectionclassoptioncode\
    the italic correction will be set to zero. In \CONTEXT\ we always have zero
    italic corrections anyway.
\stopitem
\startitem
    When we don't stretch or shrink and still have italic correction and
    italic correction is actually to be dealt with, we apply it to the accent
    if \type {\mathfontcontrol} has \number\applycharitalickernmathcontrolcode\
    set. When italic has been applied we need to position and fall through,
    otherwise we continue.
\stopitem
\startitem
    We assume we have an accent with some width, otherwise we quit. The two
    previous steps are not applied in \CONTEXT.
\stopitem
\startitem
    When \type {\mathfontcontrol} has the \number\extendaccentsmathcontrolcode\
    bit set and when we have an extensible, it will stretch when to narrow or
    shrink when too wide. In that case we will subtract \typ
    {\Umathaccentextendmargin} at both ends before checking. Independent of
    scaling being applied we then quit further actions. In \CONTEXT\ we end up
    here, so we're done.
\stopitem
\startitem
    If the control option is not set, we will do a simple check for under- or
    overfull and just scale. We don't reposition, at least not currently, after
    all we don't use this branch so we can't decide on this.
\stopitem
\stopitemize

We now carry on with some more examples. We can add an \typ {nooverflow}
directive just to be compatible with other mechanisms and to be prepared for
future extensions, but as you see, accent placement is not overflowing due to
constraints.

\typebuffer[3][option=TEX]

\start \switchtobodyfont[pagella-nt] \getbuffer[3] \par \stop
\start \switchtobodyfont[pagella]    \getbuffer[3] \par \stop

The \type {fraction} applied to the target width.

\typebuffer[4][option=TEX]

\start \switchtobodyfont[pagella-nt] \getbuffer[4] \par \stop
\start \switchtobodyfont[pagella]    \getbuffer[4] \par \stop

The \type {overlay} keyword can be used for special effects. The \typ {base}
keyword shown here doesn't do much: it compensate the fonts' accent base height
with the depth of an accent. It's there to catch suboptional dimensions.

\typebuffer[5][option=TEX]

\start \switchtobodyfont[pagella-nt] \getbuffer[5] \par \stop
\start \switchtobodyfont[pagella]    \getbuffer[5] \par \stop

This only part of the story because accent placement is not just a matter of size
but also of shifting to the (normally) right so that it looks beter over the
(normally) sloped glyph. Because we started from \OPENTYPE\ font parameters
combined with \TEX\ existing algorithm the code involved it kind of messy. We
might eventually decide to just remove what we don't need to do a proper job.

The shift to the right is in \TEX\ speak called skew. In traditional \TEX\ that
value is defined by a kern between the accent and a bogus skew character, in
\OPENTYPE\ we have a top accent value. In \LUAMETATEX\ we also have a bottom
accent value. In \LUAMETATEX\ we also have kerns in all corners. These are used
when we anchor scripts. We can set an permitted overshoot for a character which
again is a \LUAMETATEX\ feature.

Before the steps above take place we need to resolve the character. The result of
the search can be a single glyph or an assembly made from extensibles. When that
is done we can trigger a callback which makes it possible for the macro package
to mess with the result, for instance turn it into a \TYPETHREE\ character.

We also have to deal with so called flat accents, unless that font option is
disabled. As more, it's driven by font parameters and of course an accent that
qualifies should have such a variant. Anyway, there are all kind of optimizations
going on.

We can control the styles applied with \prm {Umathtopaccentvariant}, \prm
{Umathbottomaccentvariant} and \prm {Umathoverlayaccentvariant}. Spacing is
influenced by the font parameters \prm {Umathconnectoroverlapmin}, \prm
{Umathaccentbaseheight}, \prm {Umathaccenttopshiftup}, \prm
{Umathflattenedaccentbaseheight}, \prm {Umathflattenedaccenttopshiftup}, \prm
{Umathflattenedaccentbottomshiftdown}, \prm {Umathaccentbottomshiftdown}. There
is actually no need for these and we can let the engine to a nice job without
them. Given the number of times that we find ourselves adapting them indicates
their uselessness. One reason is that for consistent spacing one will use
different interfaces.

% \Umathfractionrule (callback)

How we deal with specific situations is also driven by the \prm {mathfontcontrol}
options \quote {accent top skew with offset}, \quote {accent skew half} and
\quote {ignore flat accents}. The skew comes from the top accent anchor value or
just is the middle of the accent. We already mentioned left and right margins and
overshoot properties of glyphs. The character can have so called tag bits set:
\quote {keep base}, \quote {extensible} and \quote {inner bottom}. We only
mention them as something that the font loaded needs to set.

We can place accents above (top), below (bottom) and overlay, and we can let them
stretch or shrink as well as play visually safe with a bit of scaling (this
factor). We have to deal with attaching scripts which can be controlled with
corner kerns as well as class options \quote {left bottom kern} and \quote {right
bottom kern}.

We could have hard coded the way \CONTEXT\ likes it with just the control
features that we need which makes a description easier. But for now we keep what
we have.

\stopsection

\startsection[title=Math fences]

Fences are glyphs that adapts itself to what if surrounds. In original \TEX\
there were only left and right fences that always come in pairs, although one can
\quote {hide} one by using a bogus fence (often a period is used for that). The
height and depth normally are at least those of the content but it also depends
on what a font provides. A font can provide sizes (in steps) and eventually
provide an extensible although that can only be used when the shape permits it.
Although technically not a fence, an integral can be seen as a left fence and
indeed this is why in \LUAMETATEX\ we implement such a fencing operator.

\startlinecorrection
\startMPcode
    numeric wd ; wd := 12 ;
    numeric ht ; ht :=  7 ;
    numeric dp ; dp :=  3 ;

    path fence ; fence := unitsquare xyscaled (wd/2, 5*(ht+dp)/4) shifted (0,-5*dp/4) ;
    path body  ; body  := unitsquare xyscaled (wd,      ht+dp   ) shifted (0,-dp) ;
    path line  ; line  := (0,0) -- (wd,0) ;

    draw fence shifted ( 0,0) withcolor "darkblue" ;
    draw line  shifted (10,0) withcolor "middlegray" ;
    draw body  shifted (10,0) withcolor "darkred" ;
    draw fence shifted (24,0) withcolor "darkgreen" ;
    draw line  shifted (32,0) withcolor "middlegray" ;
    draw body  shifted (32,0) withcolor "darkred" ;
    draw fence shifted (48,0) withcolor "darkblue" ;

    currentpicture := currentpicture scaled 5 ;
\stopMPcode
\stoplinecorrection

Here we also visualize a middle fence, something that \ETEX\ introduced. In
\LUAMETATEX\ we are a bit more tolerant with respect to fences, and we try to
compensate for missing ones, which is not always possible. Fences can have super-
and subscripts on the right fence and in \LUAMETATEX\ prescripts on the left
fence. Here the fences are kind of wide but depending on the shape that can
actually be the case: it the base character is rather curved, the larger sizes
also need to follow that design. Font also differ in the depth of these fencing
characters. When we implemented some new features related to these fences in
\CONTEXT\ we also decided to add companion fonts that not only provided more
steps but also did so consistently for various glyphs (parentheses, braces,
brackets, etc) and we made sure that the height and depths were consistently
distributed. In case we couldn't come up with a companion we tweak dimensions and
other properties runtime.

In order to determine the dimensions the content (subformula) has to be processed
first. In traditional \TEX\ we therefore have two passes but in \LUAMETATEX\ we
do more and therefore have more passes. There are a lot of subtle details, for
instance we support specific kerning for scripts attached to fences. We also have
a dedicated middle class so that we can do proper spacing.

One of the more tricky fences is the bar because it serves different purposes and
\UNICODE\ doesn't deal with that. Of course there should have been a left and
right bar and maybe even a middle bar but alas, this is something that we need to
deal with in the macro package.

Involved commands:

\starttyping
\Uleft
\Uright
\Umiddle
\Uoperator
\Uvextensible
\stoptyping

Relevant parameters:

\starttyping
\Umathfractionrule
\Umathoperatorsize
\Umathdelimitershortfall
\Umathdelimiterpercent
\stoptyping

\stopsection

\stopdocument

% \tohexa8 \mathnormalstylepreset            \par
% \tohexa8 \mathcrampedstylepreset           \par
% \tohexa8 \mathsubscriptstylepreset         \par
% \tohexa8 \mathsuperscriptstylepreset       \par
% \tohexa8 \mathsmallstylepreset             \par
% \tohexa8 \mathsmallerstylepreset           \par
% \tohexa8 \mathnumeratorstylepreset         \par
% \tohexa8 \mathdenominatorstylepreset       \par
% \tohexa8 \mathdoublesuperscriptstylepreset \par

% \tohexa8 \Umathoverlayaccentvariant \displaystyle\par
% \tohexa8 \Umathradicalvariant       \displaystyle\par
% \tohexa8 \Umathradicalvariant       \textstyle   \par
% \tohexa8 \Umathunderlinevariant     \displaystyle\par

% $2x^{2^2}$
% $\sqrt{x-\frac{1}{\sqrt{2}}}$
% $\Umathradicalvariant \allmathstyles 0 \sqrt{x-\frac{1}{\sqrt{2}}}$
% $2\frac{1}{2}$

% An alternative description:
%
% \def\blob#1{\mathord{\ruledhbox{\strut\tttf #1}}}
%
% The most common cases of scripts attached to a nucleus are the following where
% vertical spacing depends on the dimensions and combinations:
%
% \startlinecorrection
% \im { \blob{nuc}
%     \superscript   {\blob{sup 1}}
% }
% \quad
% \im { \blob{nuc}
%     \subscript     {\blob{sub 1}}
% }
% \quad
% \im { \blob{nuc}
%     \superscript   {\blob{sup 1}}
%     \subscript     {\blob{sub 1}}
% }
% \stoplinecorrection
%
% We also have primes. These have always been somewhat messy in \TEX\ (macro
% packages) because they are on the one hand already raised (in text they also
% serve as minutes) but because they are supposed to be anchored as super script
% the non raised variant us used. Another complication is that, especially in
% \UNICODE\ the multiple primes are single characters. In \LUAMETATEX\ primes are
% an additional script which makes for better positioning, definitely when we also
% have a superscript. Multiple primes are collected and can be collapsed into a
% single character. \footnote {In \CONTEXT\ \MKIV\ primes are handles at the \LUA\
% end and become scripts. In \MKIV\ as well as in \MKXL\ collapsing is still a
% \LUA\ task, but it is much simpler in \MKXL.}
%
% \startlinecorrection
% \im { \blob{nuc}
%     \primescript   {\blob{pri}}
% }
% \quad
% \im { \blob{nuc}
%     \primescript   {\blob{pri}}
%     \subscript     {\blob{sub 1}}
% }
% \quad
% \im { \blob{nuc}
%     \primescript   {\blob{pri}}
%     \superscript   {\blob{sup 1}}
% }
% \quad
% \im { \blob{nuc}
%     \primescript   {\blob{pri}}
%     \superscript   {\blob{sup 1}}
%     \subscript     {\blob{sub 1}}
% }
% \stoplinecorrection
%
% We also have prescripts and these have to align properly with postscripts
% when present. Combinations of super- and subscripts make for different spacing
% compared to single scripts and you can imagine that looking at four possible
% scripts in various combinations have to obey to the same rules.
%
% \startlinecorrection
% \im { \blob{nuc}
%     \superscript   {\blob{sup 1}}
%     \superprescript{\blob{sup 1}}
% }
% \quad
% \im { \blob{nuc}
%     \subscript   {\blob{sup 1}}
%     \subprescript{\blob{sup 1}}
% }
% \quad
% \im { \blob{nuc}
%     \superscript {\blob{sup 1}}
%     \subprescript{\blob{sup 1}}
% }
% \stoplinecorrection
%
% Finally there can be multiscripts and often we then talk in terms of index. One
% can explicitly mark an index. A single \type {^} means super (post) script (or
% more verbose \typ {\superscript}), while \type {^^} means indexed super (post)
% script (\typ {\indexedsuperscript}). The threesome \type {^^^} makes a super pre
% script and likewise the quadruple \type {^^^^} is an indexed super pre script.
%
% \startlinecorrection
% \im { \blob{nuc}
%     \primescript   {\blob{pri}}
%     \superscript   {\blob{sup 1}}
%     \subscript     {\blob{sub 1}}
%     \superprescript{\blob{presup 1}}
%     \subprescript  {\blob{presub 1}}
%     \superscript   {\blob{sup 2}}
%     \subscript     {\blob{sub 2}}
%     \superprescript{\blob{presup 2}}
%     \subprescript  {\blob{presub 2}}
% }
% \stoplinecorrection
%
% We can move to the next multiscript assembly with \typ {\noscript} so we have some
% control over positioning.
%
% \startlinecorrection
% \im { \blob{nuc}
%     \superscript   {\blob{sup 1}}
%     \noscript
%     \subscript     {\blob{sub 1}}
%     \noscript
%     \superscript   {\blob{sup 2}}
% }
% \stoplinecorrection
