summaryrefslogtreecommitdiff
path: root/tex/context/base/mkiv/math-stc.mkvi
diff options
context:
space:
mode:
Diffstat (limited to 'tex/context/base/mkiv/math-stc.mkvi')
-rw-r--r--tex/context/base/mkiv/math-stc.mkvi1293
1 files changed, 1293 insertions, 0 deletions
diff --git a/tex/context/base/mkiv/math-stc.mkvi b/tex/context/base/mkiv/math-stc.mkvi
new file mode 100644
index 000000000..96e1738db
--- /dev/null
+++ b/tex/context/base/mkiv/math-stc.mkvi
@@ -0,0 +1,1293 @@
+%D \module
+%D [ file=math-stc,
+%D version=2012.12.29,
+%D title=\CONTEXT\ Math Macros,
+%D subtitle=Stackers,
+%D comment=This replaces math-arr and friends,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\writestatus{loading}{ConTeXt Math Macros / Stackers}
+
+\unprotect
+
+%D WARNING: If the code here changes, the export needs to be checked! Stackers are rather
+%D special because the order in mathml matters, so we flush in [base under over] order. We
+%D also do some analysis at the \TEX\ end (passing the right variant). It's easy in the
+%D export to deal with it but in the pdf stream less trivial as we don't actually analyze
+%D there.
+
+%D At some point the \MKII\ arrow mechanism has been converted to \MKIV, but we kept
+%D most of the logic. We now have a more generic variant dealing with extensibles.
+%D There are a few demands than we need to meet:
+%D
+%D \startitemize
+%D \startitem The width of the extensible need to adapt itself automatically. \stopitem
+%D \startitem We need to be able to control horizontal and vertical offsets. \stopitem
+%D \startitem We best have a math as well as a text variant (which is handy for chemistry). \stopitem
+%D \startitem For historic reasons we need to deal with optional arguments in a special (reverse) way. \stopitem
+%D \startitem We need alternatives for extensibles on top, in the middle and at the bottom. \stopitem
+%D \stopitemize
+%D
+%D After I had experimented a bit with virtual characters for two headed arrows I
+%D discussed the issue with the Gyre folks and we came to the conclusion that it
+%D made sense to have real extensibles instead of constructing them out of snippets.
+%D After all, \OPENTYPE\ math provides for it. So, in December 2013 beta versions of
+%D Latin Modern and Gyre fonts came available that had these! Because we still want
+%D to support the traditional Latin Modern Virtual math font those were extended
+%D with a couple of virtual extensibles as well.
+%D
+%D {\em For the moment we still have some mess here: we can deal with known dimensions, but
+%D fillers (like \type {\rightarrowfil} don't work with \OPENTYPE\ extensibles yet
+%D because there is no way to let them stretch like leaders. At some point \LUATEX\
+%D might provide a auto||fit||to||encapsulated||box and if not I will cook up a \LUA\
+%D based variant.}
+%D
+%D We could mess with something like \type {$mid\limits^{top}_{bottom}$} but we like
+%D a bit more control. At some point we need to add some hacks to get exports
+%D working well.
+%D
+%D In the end we have a more flexible mechanism which also handles text variants.
+
+%D When wrapping up some math developments I decided to add mp support here
+%D as well. A nice evening job with Joe Bonamassa performing live on the big
+%D screen (real nice bluray's). See meta-imp-mat.mkiv for examples.
+
+% possible improvements:
+%
+% - we could skip the left/right offsets when offset=normal, this saves some access time
+% at the lua end and some checking: use \mathhorizontalcode or \mathextensiblecode
+% but in practice arrows etc are not used that often
+
+\installcorenamespace {mathextensiblefallbacks}
+
+% currently no italic correction ... problem is that we don't know yet if we have an italic
+% below so we we need to postpone
+
+\def\math_stackers_fallback
+ {\hbox to \scratchwidth{\csname\??mathextensiblefallbacks\ifcsname\??mathextensiblefallbacks\number\scratchunicode\endcsname\number\scratchunicode\fi\endcsname}}
+ %{\csname\??mathextensiblefallbacks\ifcsname\??mathextensiblefallbacks\number\scratchunicode\endcsname\number\scratchunicode\fi\endcsname }
+
+% \def\math_stackers_regular
+% {\mathstylehbox{\Umathaccent\fam\zerocount\scratchunicode{\hskip\scratchwidth}}}
+
+\def\math_stackers_regular
+ {\mathstylehbox{\usemathstackerscolorparameter\c!color
+ \Umathaccent\fam\zerocount\scratchunicode{\hskip\scratchwidth}}}
+
+\def\math_stackers_stretch % we don't have that one yet
+ {\mathstylehbox{\usemathstackerscolorparameter\c!color
+ \Umathaccent\fam\zerocount\scratchunicode{\hskip\hsize}}}
+
+% these delimiters are a unuseable as they don't center for small arguments:
+%
+% $\Umathaccent 0 0 "2190{x}$ \par $\Umathaccent 0 0 "27F8{x}$\par
+% $\Udelimiterunder 0 "2190{x}$ \par $\Udelimiterunder 0 "27F8{x}$\par
+
+\setvalue{\??mathextensiblefallbacks}{\hbox{\vrule\!!width\scratchwidth\!!height.1\exheight\!!depth\zeropoint}}
+
+% \def\math_stackers_with_fallback#codepoint%
+% {\begingroup
+% \scratchunicode#codepoint\relax
+% \ifcase\mathextensiblecode\fam\scratchunicode\relax
+% \math_stackers_fallback
+% \else
+% \math_stackers_stretch
+% \fi
+% \endgroup}
+
+%D We don't really need this because we can assume that fonts have the right
+%D extensibles. If needed I will make a general virtual extender for \OPENTYPE\
+%D fonts.
+%D
+%D Because we have quite some control over positioning, we have somewhat extensive
+%D tracing built in.
+
+\let\math_stackers_top \relax
+\let\math_stackers_middle\relax
+\let\math_stackers_bottom\relax
+\let\math_stackers_skip \hskip
+
+\installtextracker
+ {math.stackers.texts}
+ {\let\math_stackers_top \filledhboxb
+ \let\math_stackers_middle\filledhboxr
+ \let\math_stackers_bottom\filledhboxg
+ \let\math_stackers_skip \math_stackers_skip_indeed}
+ {\let\math_stackers_top \relax
+ \let\math_stackers_middle\relax
+ \let\math_stackers_bottom\relax
+ \let\math_stackers_skip \hskip}
+
+\def\math_stackers_skip_indeed#amount%
+ {\filledhboxk{\unsetteststrut\strut\hskip#amount}} % \dontshowstruts
+
+\let\math_stackers_start_tagged_mid\relax
+\let\math_stackers_start_tagged_top\relax
+\let\math_stackers_start_tagged_bot\relax
+\let\math_stackers_stop_tagged \relax
+
+\appendtoks
+ \def\math_stackers_start_tagged_mid{\dostarttagged\t!mathstackermid\empty\hbox\bgroup}%
+ \def\math_stackers_start_tagged_top{\dostarttagged\t!mathstackertop\empty\hbox\bgroup}%
+ \def\math_stackers_start_tagged_bot{\dostarttagged\t!mathstackerbot\empty\hbox\bgroup}%
+ \def\math_stackers_stop_tagged {\egroup\dostoptagged}%
+\to \everysetuptagging
+
+%D We define a full featured command handler.
+
+\installcorenamespace {mathstackers}
+
+\installcommandhandler \??mathstackers {mathstackers} \??mathstackers
+
+\setupmathstackers
+ [%c!alternative=\v!text, % text | mathematics
+ \c!left=,
+ \c!right=,
+ \c!mathclass=\s!rel,
+ \c!alternative=\v!normal,
+ \c!mp=math:stacker:\number\scratchunicode,
+ \c!mpheight=\exheight,
+ \c!mpdepth=\exheight,
+ \c!mpoffset=.25\exheight,
+ \c!voffset=.25\exheight,
+ \c!hoffset=.5\emwidth,
+ \c!distance=\mathstackersparameter\c!voffset, % distance between symbol and base (can be different from voffset)
+ \c!minheight=\exheight,
+ \c!mindepth=\zeropoint,
+ \c!minwidth=.5\emwidth,
+ \c!order=\v!normal,
+ \c!strut=,
+ \c!color=, % todo: when I need it
+ \c!topcommand=,
+ \c!middlecommand=,
+ \c!bottomcommand=,
+ \c!offset=\v!normal, % normal | min | max
+ \c!location=\v!top] % none | normal | small | medium | big
+
+%D We assume that the middle characters (that can be an extensible) to sit on
+%D top of the baseline by default.
+
+\installcorenamespace {mathstackerslocation}
+\installcorenamespace {mathstackersalternative}
+
+\letvalue{\??mathstackerslocation\v!top }\plusone % on top of baseline
+\letvalue{\??mathstackerslocation\v!high }\plustwo % 25 % down
+\letvalue{\??mathstackerslocation\v!middle }\plusthree % centered
+\letvalue{\??mathstackerslocation\v!low }\plusfour % 75 % down
+\letvalue{\??mathstackerslocation\v!bottom }\plusfive % below baseline
+\letvalue{\??mathstackerslocation }\zerocount
+
+%D First we implement the helper that deals with an extensible in the middle and
+%D top and|/|or bottom texts:
+
+\let\m_math_stackers_text_top \empty
+\let\m_math_stackers_text_bottom\empty
+\let\m_math_stackers_text_middle\empty
+
+\def\math_stackers_flushtext#command#text%
+ {\ifdim\scratchleftoffset >\zeropoint\math_stackers_skip\scratchleftoffset \fi
+ \ifx\p_strut\v!no \else
+ \strut
+ \fi
+ \mathstackersparameter#command#text%
+ \ifdim\scratchrightoffset>\zeropoint\math_stackers_skip\scratchrightoffset\fi}
+
+\def\math_stackers_toptext {\math_stackers_flushtext\c!topcommand \m_math_stackers_text_top }
+\def\math_stackers_bottomtext{\math_stackers_flushtext\c!bottomcommand\m_math_stackers_text_bottom}
+\def\math_stackers_middletext{\math_stackers_flushtext\c!middlecommand\m_math_stackers_text_middle}
+
+\def\math_stackers_content
+ {\ifcase\scratchcounter
+ \math_stackers_fallback
+ \or % left
+ \math_stackers_regular
+ \or % right
+ \math_stackers_regular
+ \or % horizontal
+ \math_stackers_regular
+ \else
+ \math_stackers_fallback
+ \fi}
+
+% no checking, we assume sane use
+
+\letvalue{\??mathstackersalternative\v!normal }\math_stackers_content
+\letvalue{\??mathstackersalternative\v!default}\math_stackers_content
+
+\setvalue{\??mathstackersalternative\v!mp}%
+ {\hbox\bgroup % todo: add code key + tag
+ \d_overlay_width \scratchwidth
+ \d_overlay_height \dimexpr\mathstackersparameter\c!mpheight
+ \d_overlay_depth \dimexpr\mathstackersparameter\c!mpdepth
+ \d_overlay_offset \dimexpr\mathstackersparameter\c!mpoffset
+ \d_overlay_linewidth\linewidth
+ \edef\overlaylinecolor{\mathstackersparameter\c!color}%
+ \edef\p_mp{\mathstackersparameter\c!mp}%
+ \uniqueMPgraphic{\p_mp}%
+ \egroup}
+
+\def\math_stackers_check_unicode#codepoint%
+ {\scratchunicode#codepoint\relax
+ \scratchhoffset\mathstackersparameter\c!hoffset\relax
+ \scratchvoffset\mathstackersparameter\c!voffset\relax
+ \scratchcounter\mathhorizontalcode\fam\scratchunicode\relax % also sets \leftscratchoffset and \rightscratchoffset
+ \ifx\p_offset\v!max
+ % heads/tails + hoffset
+ \else\ifx\p_offset\v!min
+ % heads/tails - hoffset
+ \advance\scratchleftoffset-\scratchhoffset
+ \advance\scratchrightoffset-\scratchhoffset
+ \else % \v!normal
+ % hoffset
+ \scratchleftoffset\zeropoint
+ \scratchrightoffset\zeropoint
+ \fi\fi
+ \ifdim\scratchleftoffset<\zeropoint
+ \scratchleftoffset\zeropoint
+ \fi
+ \ifdim\scratchrightoffset<\zeropoint
+ \scratchrightoffset\zeropoint
+ \fi}
+
+\def\math_stackers_normalize_three
+ {\scratchheight\ht\scratchboxthree
+ \scratchdepth \dp\scratchboxthree
+ \scratchtopoffset \scratchheight
+ \scratchbottomoffset\scratchdepth
+ \scratchdimen\mathstackersparameter\c!minheight\relax
+ \ifdim\scratchheight<\scratchdimen
+ \scratchheight\scratchdimen
+ \ht\scratchboxthree\scratchheight
+ \fi
+ \scratchdimen\mathstackersparameter\c!mindepth\relax
+ \ifdim\scratchdepth<\scratchdimen
+ \scratchdepth\scratchdimen
+ \dp\scratchboxthree\scratchdepth
+ \fi
+ \advance\scratchtopoffset -\scratchheight
+ \advance\scratchbottomoffset-\scratchdepth
+ \ifdim\scratchtopoffset<\zeropoint
+ \scratchtopoffset\zeropoint
+ \fi
+ \ifdim\scratchbottomoffset<\zeropoint
+ \scratchbottomoffset\zeropoint
+ \fi}
+
+\unexpanded\def\math_stackers_triplet#method#category#codepoint#toptext#bottomtext%
+ %{\math_stackers_start_group{#category}%
+ {\begingroup
+ \edef\currentmathstackers{#category}%
+ \mathstackersparameter\c!left\relax
+ \dostarttagged\t!mathstacker\currentmathstackers
+ \ifmmode\math_class_by_parameter\mathstackersparameter\else\dontleavehmode\fi
+ {\edef\p_offset {\mathstackersparameter\c!offset}%
+ \edef\p_location {\mathstackersparameter\c!location}%
+ \edef\p_order {\mathstackersparameter\c!order}%
+ \edef\p_strut {\mathstackersparameter\c!strut}%
+ \edef\p_alternative{\mathstackersparameter\c!alternative}%
+ \ifx\p_order\v!reverse
+ \edef\m_math_stackers_text_top {#bottomtext}%
+ \edef\m_math_stackers_text_bottom{#toptext}%
+ \else
+ \edef\m_math_stackers_text_top {#toptext}%
+ \edef\m_math_stackers_text_bottom{#bottomtext}%
+ \fi
+ \scratchleftoffset \zeropoint
+ \scratchrightoffset\zeropoint
+ \ifcase#method\relax
+ \math_stackers_check_unicode{#codepoint}%
+ \else
+ \edef\m_math_stackers_text_middle{#codepoint}%
+ \fi
+ \ifx\m_math_stackers_text_top\empty
+ \setbox\scratchboxone\emptyhbox
+ \else
+ \setmathsmalltextbox\scratchboxone\hbox{\math_stackers_toptext}%
+ \fi
+ \ifx\m_math_stackers_text_bottom\empty
+ \setbox\scratchboxtwo\emptyhbox
+ \else
+ \setmathsmalltextbox\scratchboxtwo\hbox{\math_stackers_bottomtext}%
+ \fi
+ %
+ \ifcase#method\relax
+ \scratchwidth\wd
+ \ifdim\wd\scratchboxone>\wd\scratchboxtwo
+ \scratchboxone
+ \else
+ \scratchboxtwo
+ \fi
+ \relax
+ \else
+ \ifx\m_math_stackers_text_middle\empty
+ \setbox\scratchboxthree\emptyhbox
+ \else
+ \setmathtextbox\scratchboxthree\hbox{\math_stackers_middletext}%
+ \fi
+ \scratchwidth\wd
+ \ifdim\wd\scratchboxone>\wd\scratchboxtwo
+ \ifdim\wd\scratchboxone>\wd\scratchboxthree
+ \scratchboxone
+ \else
+ \scratchboxthree
+ \fi
+ \else\ifdim\wd\scratchboxtwo>\wd\scratchboxthree
+ \scratchboxtwo
+ \else
+ \scratchboxthree
+ \fi\fi
+ \relax
+ \fi
+ %
+ \scratchdimen\mathstackersparameter\c!minwidth\relax
+ \ifdim\scratchwidth<\scratchdimen
+ \scratchwidth\scratchdimen
+ \fi
+ \advance\scratchwidth2\scratchhoffset
+ %
+ \ifcase#method\relax
+ \dostarttagged\t!mathstackermid\empty
+ \setbox\scratchboxthree\csname\??mathstackersalternative\p_alternative\endcsname
+ \dostoptagged
+ \fi
+ %
+ \ifdim\wd\scratchboxone<\scratchwidth
+ \setbox\scratchboxone\hbox to \scratchwidth{\hss\unhbox\scratchboxone\hss}% unhboxing makes leaders work
+ \fi
+ \ifdim\wd\scratchboxtwo<\scratchwidth
+ \setbox\scratchboxtwo\hbox to \scratchwidth{\hss\unhbox\scratchboxtwo\hss}%
+ \fi
+ \ifdim\wd\scratchboxthree<\scratchwidth
+ \setbox\scratchboxthree\hbox to \scratchwidth{\hss\unhbox\scratchboxthree\hss}%
+ \fi
+ %
+ \ifcsname\??mathstackerslocation\p_location\endcsname
+ \ifcase\csname\??mathstackerslocation\p_location\endcsname\relax
+ \scratchdistance\zeropoint
+ \or
+ % top
+ \scratchdistance\zeropoint
+ \or
+ % high
+ \scratchdistance.25\htdp\scratchboxthree
+ \or
+ % centered
+ \scratchdistance.5\htdp\scratchboxthree
+ \or
+ % low
+ \scratchdistance.75\htdp\scratchboxthree
+ \or
+ % bottom
+ \scratchdistance\htdp\scratchboxthree
+ \else
+ \scratchdistance\zeropoint
+ \fi
+ \else
+ \scratchdistance\p_location\htdp\scratchboxthree
+ \fi
+ %
+ \ifzeropt\scratchdistance\else
+ \setbox\scratchboxthree\hbox{\lower\scratchdistance\box\scratchboxthree}%
+ \fi
+ %
+ \math_stackers_normalize_three
+ % analysis
+ \ifdim\htdp\scratchboxtwo>\zeropoint
+ \ifdim\htdp\scratchboxone>\zeropoint
+ \dosettagproperty\s!subtype\t!munderover
+ \else
+ \dosettagproperty\s!subtype\t!munder
+ \fi
+ \else
+ \ifdim\htdp\scratchboxone>\zeropoint
+ \dosettagproperty\s!subtype\t!mover
+ \else
+ % brrr
+ \fi
+ \fi
+ % base
+ \math_stackers_start_tagged_mid
+ \math_stackers_middle\bgroup
+ \box\scratchboxthree
+ \egroup
+ \math_stackers_stop_tagged
+ % under
+ \ifdim\htdp\scratchboxtwo>\zeropoint
+ \math_stackers_start_tagged_bot
+ \scratchoffset\scratchvoffset
+ \kern-\scratchwidth
+ \math_stackers_bottom\bgroup
+ \lower\dimexpr\ht\scratchboxtwo+\scratchdepth+\scratchoffset+\scratchbottomoffset\relax
+ \box\scratchboxtwo
+ \egroup
+ \math_stackers_stop_tagged
+ \fi
+ % over
+ \ifdim\htdp\scratchboxone>\zeropoint
+ \math_stackers_start_tagged_top
+ \scratchoffset\scratchvoffset
+ \kern-\scratchwidth
+ \math_stackers_top\bgroup
+ \raise\dimexpr\dp\scratchboxone+\scratchheight+\scratchoffset+\scratchtopoffset\relax
+ \box\scratchboxone
+ \egroup
+ \math_stackers_stop_tagged
+ \fi
+ %
+ }%
+ \dostoptagged
+ \mathstackersparameter\c!right\relax
+ \endgroup}
+ %\math_stackers_start_group}
+
+\unexpanded\def\definemathextensible
+ {\dotripleempty\math_stackers_define_normal}
+
+\def\math_stackers_define_normal[#1][#2][#3]% category name unicode
+ {\ifthirdargument
+ \setuevalue{#2}{\math_stackers_auto_normal{#1}{\number#3}}%
+ \else
+ \setuevalue{#1}{\math_stackers_auto_normal\noexpand\currentmathstackers{\number#2}}%
+ \fi}
+
+\unexpanded\def\math_stackers_auto_normal#category#codepoint%
+ {\begingroup
+ \edef\currentmathstackers{#category}%
+ \scratchcounter#codepoint\relax
+ \dosingleempty\math_stackers_auto_normal_first}
+
+\unexpanded\def\math_stackers_auto_normal_first[#category]% [#2]% #2 gobble spaces
+ {\iffirstargument\edef\currentmathstackers{#category}\fi
+ \permitspacesbetweengroups
+ \dodoublegroupempty\math_stackers_auto_normal_second}
+
+\def\math_stackers_auto_normal_second#toptext#bottomtext%
+ {\math_stackers_triplet\zerocount\currentmathstackers\scratchcounter{#toptext}{#bottomtext}%
+ \endgroup}
+
+%D A few direct accessors:
+
+\unexpanded\def\mathextensible{\begingroup\dosingleempty\math_stackers_handle_math}
+\unexpanded\def\textextensible{\begingroup\dosingleempty\math_stackers_handle_text}
+
+\unexpanded\def\math_stackers_handle_math[#category]%
+ {\math_stackers_handle_extensible{\iffirstargument#category\else\v!mathematics\fi}} % will be defined later on
+
+\unexpanded\def\math_stackers_handle_text[#category]%
+ {\math_stackers_handle_extensible{\iffirstargument#category\else\v!text \fi}} % will be defined later on
+
+\def\math_stackers_handle_extensible#category#codepoint#toptext#bottomtext%
+ {\math_stackers_triplet\zerocount{#category}{#codepoint}{#toptext}{#bottomtext}%
+ \endgroup}
+
+%D The next one deals with under and over extensibles (arrows mostly):
+
+\installcorenamespace {mathclasses}
+
+\letvalue{\??mathclasses }\mathord
+\letvalue{\??mathclasses rel}\mathrel
+\letvalue{\??mathclasses ord}\mathord
+
+\def\math_class_by_parameter#1%
+ {\normalexpanded{\noexpand\math_class_by_parameter_indeed{#1\c!mathclass}}}
+
+\def\math_class_by_parameter_indeed#1%
+ {\csname\??mathclasses\ifcsname\??mathclasses#1\endcsname#1\fi\endcsname}
+
+% 1 0 name n 0 | 0 1 name n 0 | 1 1 name n n
+
+\unexpanded\def\math_stackers_start_group#category%
+ {\begingroup
+ \edef\currentmathstackers{#category}%
+ \edef\p_limits{\mathstackersparameter\c!mathlimits}%
+ \ifx\p_limits\v!yes
+ \def\math_stackers_stop_group{\egroup\endgroup\limits}%
+ \mathop\bgroup
+ \else
+ \let\math_stackers_stop_group\endgroup
+ \fi}
+
+\unexpanded\def\math_stackers_make_double#top#bottom#category#codepoint#codeextra#text%
+ {\math_stackers_start_group{#category}%
+ \mathstackersparameter\c!left\relax
+ \dostarttagged\t!mathstacker\currentmathstackers
+ \ifmmode\math_class_by_parameter\mathstackersparameter\else\dontleavehmode\fi
+ {\edef\m_math_stackers_text_middle {#text}%
+ %
+ \edef\p_offset {\mathstackersparameter\c!offset}%
+ \edef\p_location {\mathstackersparameter\c!location}%
+ \edef\p_strut {\mathstackersparameter\c!strut}%
+ \edef\p_alternative{\mathstackersparameter\c!alternative}%
+ %
+ \scratchleftoffset \zeropoint
+ \scratchrightoffset\zeropoint
+ %
+ \math_stackers_check_unicode{#codepoint}%
+ %
+ \ifx\math_stackers_middle\empty
+ \setbox\scratchboxthree\emptyhbox
+ \else
+ \setmathtextbox\scratchboxthree\hbox{\math_stackers_middletext}%
+ \fi
+ \scratchwidth\wd\scratchboxthree
+ %
+ \scratchdimen\mathstackersparameter\c!minwidth\relax
+ \ifdim\scratchwidth<\scratchdimen
+ \scratchwidth\scratchdimen
+ \fi
+ \advance\scratchwidth2\scratchhoffset
+ %
+ \setbox\scratchboxtwo\csname\??mathstackersalternative\p_alternative\endcsname
+ \setbox\scratchboxthree\hbox to \scratchwidth{\hss\box\scratchboxthree\hss}%
+ %
+ \scratchunicode#codeextra\relax
+ \ifcase\scratchunicode\else
+ \setbox\scratchboxone\csname\??mathstackersalternative\p_alternative\endcsname
+ \fi
+ %
+ \math_stackers_normalize_three
+ % analysis
+ \ifcase#bottom\relax
+ \ifcase#top\relax
+ \dosettagproperty\s!subtype\t!munderover
+ \else
+ \dosettagproperty\s!subtype\t!mover
+ \fi
+ \else
+ \ifcase#top\relax
+ \dosettagproperty\s!subtype\t!munder
+ \else
+ % brrr
+ \fi
+ \fi
+ % base
+ \math_stackers_start_tagged_mid
+ \math_stackers_middle\bgroup
+ \box\scratchboxthree
+ \egroup
+ \math_stackers_stop_tagged
+ %
+ \ifdim\htdp\scratchboxtwo>\zeropoint
+ \ifcase#bottom\else
+ \kern-\scratchwidth
+ % under
+ \math_stackers_start_tagged_bot
+ \math_stackers_bottom\bgroup
+ \lower\dimexpr
+ \scratchdepth
+ +\ht\scratchboxtwo
+ +\mathstackersparameter\c!distance % was \c!voffset
+ \relax
+ \ifcase#top\relax
+ \box\scratchboxtwo
+ \else
+ \box\scratchboxone
+ \fi
+ \egroup
+ \math_stackers_stop_tagged
+ \fi
+ \ifcase#top\else
+ \kern-\scratchwidth
+ % over
+ \math_stackers_start_tagged_top
+ \math_stackers_top\bgroup
+ \raise\dimexpr
+ \scratchheight
+ +\dp\scratchboxtwo % new
+ +\mathstackersparameter\c!distance % was \c!voffset
+ \relax
+ \box\scratchboxtwo
+ \egroup
+ \math_stackers_stop_tagged
+ \fi
+ %
+ \fi}%
+ \dostoptagged
+ \mathstackersparameter\c!right\relax
+ \math_stackers_stop_group}
+
+\unexpanded\def\definemathoverextensible {\dotripleempty \math_extensibles_define_over }
+\unexpanded\def\definemathunderextensible {\dotripleempty \math_extensibles_define_under}
+\unexpanded\def\definemathdoubleextensible{\doquadrupleempty\math_extensibles_define_double}
+
+\def\math_extensibles_define_over[#1][#2][#3]%
+ {\ifthirdargument
+ \setuevalue{#2}{\math_stackers_make_double\plusone \zerocount{#1}{\number#3}{0}}%
+ \else
+ \setuevalue{#1}{\math_stackers_make_double\plusone \zerocount\noexpand\currentmathstackers{\number#2}{0}}%
+ \fi}
+
+\def\math_extensibles_define_under[#1][#2][#3]%
+ {\ifthirdargument
+ \setuevalue{#2}{\math_stackers_make_double\zerocount\plusone{#1}{\number#3}{0}}%
+ \else
+ \setuevalue{#1}{\math_stackers_make_double\zerocount\plusone\noexpand\currentmathstackers{\number#2}{0}}%
+ \fi}
+
+\def\math_extensibles_define_double[#1][#2][#3][#4]%
+ {\iffourthargument
+ \setuevalue{#2}{\math_stackers_make_double\plusone \plusone{#1}{\number#3}{\number#4}}%
+ \else
+ \setuevalue{#1}{\math_stackers_make_double\plusone \plusone\noexpand\currentmathstackers{\number#2}{\number#3}}%
+ \fi}
+
+\unexpanded\def\mathover {\begingroup\dosingleempty\math_stackers_handle_over }
+\unexpanded\def\mathunder {\begingroup\dosingleempty\math_stackers_handle_under }
+\unexpanded\def\mathdouble{\begingroup\dodoubleempty\math_stackers_handle_double}
+
+\def\math_stackers_handle_over[#category]%
+ {\math_stackers_direct_double\plusone\zerocount
+ {\iffirstargument#category\else\v!top \fi}} % will be defined later on
+
+\def\math_stackers_handle_under[#category]%
+ {\math_stackers_direct_double\zerocount\plusone
+ {\iffirstargument#category\else\v!bottom\fi}} % will be defined later on
+
+\def\math_stackers_handle_double[#topcategory][#bottomcategory]%
+ {\math_stackers_direct_double\plusone\plusone
+ {\iffirstargument #topcategory\else\v!top \fi}%
+ {\ifsecondargument#bottomcategory\else\v!bottom\fi}}
+
+\def\math_stackers_direct_double#top#bottom#category#codepoint#text%
+ {\math_stackers_make_double#top#bottom{#category}{#codepoint}{0}{#text}%
+ \endgroup}
+
+%D A relative new one is a combination of accents and text (as needed in mathml):
+
+\unexpanded\def\math_stackers_make_double_text#where#category#codepoint#text#extra%
+ {\math_stackers_start_group{#category}%
+ \mathstackersparameter\c!left\relax
+ \dostarttagged\t!mathstacker\currentmathstackers
+ \ifmmode\math_class_by_parameter\mathstackersparameter\else\dontleavehmode\fi
+ {\edef\currentmathstackers{#category}%
+ %
+ \edef\p_offset {\mathstackersparameter\c!offset}%
+ \edef\p_location {\mathstackersparameter\c!location}%
+ \edef\p_strut {\mathstackersparameter\c!strut}%
+ \edef\p_alternative{\mathstackersparameter\c!alternative}%
+ %
+ \scratchleftoffset \zeropoint
+ \scratchrightoffset\zeropoint
+ %
+ \edef\m_math_stackers_text_middle{#text}%
+ \math_stackers_check_unicode{#codepoint}%
+ \scratchunicode#codepoint\relax
+ %
+ \ifx\math_stackers_middle\empty
+ \setbox\scratchboxthree\emptyhbox
+ \else
+ \setmathtextbox\scratchboxthree\hbox{\math_stackers_middletext}%
+ \fi
+ %
+ \ifcase#where\relax
+ \edef\m_math_stackers_text_top{#extra}%
+ \ifx\math_stackers_top\empty
+ \setbox\scratchboxone\emptyhbox
+ \else
+ \setmathsmalltextbox\scratchboxone\hbox{\math_stackers_toptext}%
+ \fi
+ \else
+ \edef\m_math_stackers_text_bottom{#extra}%
+ \ifx\math_stackers_bottom\empty
+ \setbox\scratchboxone\emptyhbox
+ \else
+ \setmathsmalltextbox\scratchboxone\hbox{\math_stackers_bottomtext}%
+ \fi
+ \fi
+ %
+ \scratchwidth\wd
+ \ifdim\wd\scratchboxone>\wd\scratchboxthree
+ \scratchboxone
+ \else
+ \scratchboxthree
+ \fi
+ \relax
+ \scratchdimen\mathstackersparameter\c!minwidth\relax
+ \ifdim\scratchwidth<\scratchdimen
+ \scratchwidth\scratchdimen
+ \fi
+ \advance\scratchwidth2\scratchhoffset
+ %
+ \ifdim\wd\scratchboxone<\scratchwidth
+ \setbox\scratchboxone\hbox to \scratchwidth{\hss\unhbox\scratchboxone\hss}%
+ \fi
+ \ifdim\wd\scratchboxthree<\scratchwidth
+ \setbox\scratchboxthree\hbox to \scratchwidth{\hss\unhbox\scratchboxthree\hss}%
+ \fi
+ %
+ \math_stackers_normalize_three
+ % analysis
+ \dosettagproperty\s!subtype\t!munderover
+ % base
+ \math_stackers_start_tagged_mid
+ \math_stackers_middle\bgroup
+ \box\scratchboxthree
+ \egroup
+ \math_stackers_stop_tagged
+ %
+ \setbox\scratchboxtwo\csname\??mathstackersalternative\p_alternative\endcsname
+ \kern-\scratchwidth
+ \ifcase#where\relax
+ % under
+ \math_stackers_start_tagged_bot
+ \math_stackers_bottom\bgroup
+ \lower\dimexpr
+ \scratchdepth
+ +\ht\scratchboxtwo
+ +\mathstackersparameter\c!distance
+ \relax
+ \box\scratchboxtwo % accent
+ \egroup
+ \math_stackers_stop_tagged
+ \kern-\scratchwidth
+ % over
+ \math_stackers_start_tagged_top
+ \math_stackers_top\bgroup
+ \raise\dimexpr
+ \scratchheight
+ +\dp\scratchboxone
+ +\mathstackersparameter\c!voffset
+ \relax
+ \box\scratchboxone % toptext
+ \egroup
+ \math_stackers_stop_tagged
+ \else
+ % under
+ \math_stackers_start_tagged_bot
+ \math_stackers_bottom\bgroup
+ \lower\dimexpr
+ \scratchdepth
+ +\ht\scratchboxone
+ +\mathstackersparameter\c!voffset
+ \relax
+ \box\scratchboxone % bottext
+ \egroup
+ \math_stackers_stop_tagged
+ \kern-\scratchwidth
+ % over
+ \math_stackers_start_tagged_top
+ \math_stackers_top\bgroup
+ \raise\dimexpr
+ \scratchheight
+ +\dp\scratchboxtwo % new
+ +\mathstackersparameter\c!distance
+ \relax
+ \box\scratchboxtwo % accent
+ \egroup
+ \math_stackers_stop_tagged
+ \fi
+ }%
+ \dostoptagged
+ \mathstackersparameter\c!right\relax
+ \math_stackers_stop_group}
+
+\unexpanded\def\definemathovertextextensible {\dotripleempty\math_extensibles_define_over_text }
+\unexpanded\def\definemathundertextextensible{\dotripleempty\math_extensibles_define_under_text}
+
+\def\math_extensibles_define_over_text[#1][#2][#3]%
+ {\ifthirdargument
+ \setuevalue{#2}{\math_stackers_make_double_text\plusone {#1}{\number#3}}%
+ \else
+ \setuevalue{#1}{\math_stackers_make_double_text\plusone \noexpand\currentmathstackers{\number#2}}%
+ \fi}
+
+\def\math_extensibles_define_under_text[#1][#2][#3]%
+ {\ifthirdargument
+ \setuevalue{#2}{\math_stackers_make_double_text\zerocount{#1}{\number#3}}%
+ \else
+ \setuevalue{#1}{\math_stackers_make_double_text\zerocount\noexpand\currentmathstackers{\number#2}}%
+ \fi}
+
+\unexpanded\def\mathovertext {\begingroup\dosingleempty\math_stackers_handle_over_text }
+\unexpanded\def\mathundertext{\begingroup\dosingleempty\math_stackers_handle_under_text }
+
+\def\math_stackers_handle_over_text[#category]%
+ {\math_stackers_direct_double_text\plusone {\iffirstargument#category\else\v!top \fi}} % will be defined later on
+
+\def\math_stackers_handle_under_text[#category]%
+ {\math_stackers_direct_double_text\zerocount{\iffirstargument#category\else\v!bottom\fi}} % will be defined later on
+
+\def\math_stackers_direct_double_text#where#category#codepoint#text#extra%%
+ {\math_stackers_make_double_text#where{#category}{#codepoint}{#text}{#extra}%
+ \endgroup}
+
+%D Here is a bonus macro that takes three texts. It can be used to get consistent
+%D mixed usage.
+
+\unexpanded\def\mathtriplet
+ {\begingroup
+ \dosingleempty\math_stackers_handle_triplet}
+
+\def\math_stackers_handle_triplet[#category]#middletext#toptext#bottomtext%
+ {\math_stackers_triplet\plusone{\iffirstargument#category\else\currentmathstackers\fi}{#middletext}{#toptext}{#bottomtext}%
+ \endgroup}
+
+\unexpanded\def\definemathtriplet
+ {\dotripleempty\math_stackers_define_triplet}
+
+\def\math_stackers_define_triplet[#1][#2][#3]% category name default
+ {\ifthirdargument
+ \setuevalue{#2}{\math_stackers_auto_triplet_yes{#1}{#3}}%
+ \else\ifsecondargument
+ \setuevalue{#2}{\math_stackers_auto_triplet_nop{#1}}%
+ \else
+ \setuevalue{#1}{\math_stackers_auto_triplet_nop\noexpand\currentmathstackers}%
+ \fi\fi}
+
+\unexpanded\def\math_stackers_auto_triplet_yes#category#middletext%
+ {\begingroup
+ \edef\currentmathstackers {#category}%
+ \def \m_math_stackers_text_middle{#middletext}%
+ \dosingleempty\math_stackers_auto_triplet_yes_first}
+
+\unexpanded\def\math_stackers_auto_triplet_yes_first[#category]% [#2]% #2 gobble spaces
+ {\iffirstargument\edef\currentmathstackers{#category}\fi
+ \permitspacesbetweengroups
+ \dodoublegroupempty\math_stackers_auto_triplet_yes_second}
+
+\def\math_stackers_auto_triplet_yes_second#toptext#bottomtext%
+ {\math_stackers_triplet\plusone\currentmathstackers\m_math_stackers_text_middle{#toptext}{#bottomtext}%
+ \endgroup}
+
+\unexpanded\def\math_stackers_auto_triplet_nop#category%
+ {\begingroup
+ \edef\currentmathstackers{#category}%
+ \dosingleempty\math_stackers_auto_triplet_nop_first}
+
+\unexpanded\def\math_stackers_auto_triplet_nop_first[#category]% [#2]% #2 gobble spaces
+ {\iffirstargument\edef\currentmathstackers{#category}\fi
+ \permitspacesbetweengroups
+ \dotriplegroupempty\math_stackers_auto_triplet_nop_second}
+
+\def\math_stackers_auto_triplet_nop_second#middletext#toptext#bottomtext%
+ {\math_stackers_triplet\plusone\currentmathstackers{#middletext}{#toptext}{#bottomtext}%
+ \endgroup}
+
+%D Definitions:
+
+\definemathstackers
+ [\v!mathematics]
+ [\c!topcommand=\mathematics,
+ \c!middlecommand=\mathematics,
+ \c!bottomcommand=\mathematics]
+
+\definemathstackers
+ [\s!math]
+ [\v!mathematics]
+
+\definemathstackers
+ [\v!text]
+ [\v!mathematics]
+ [\c!topcommand=,
+ \c!middlecommand=\mathematics,
+ \c!bottomcommand=]
+
+\definemathstackers
+ [\v!reverse]
+ [\v!mathematics]
+ [\c!order=\v!reverse]
+
+\definemathstackers
+ [\v!both]
+ [\v!mathematics]
+ [\c!location=\v!top, % ?
+ \c!strut=\v!no,
+ \c!middlecommand=\mathematics,
+ \c!hoffset=\zeropoint]
+
+\definemathstackers
+ [\v!top]
+ [\v!both]
+
+\definemathstackers
+ [\v!bottom]
+ [\v!both]
+
+\definemathstackers
+ [\v!vfenced]
+ [\v!both]
+ [\c!mathclass=\s!ord,
+ \c!mathlimits=\v!yes]
+
+% these are needed for mathml:
+
+% \setupmathstackers
+% [\v!both]
+% [\c!hoffset=1pt,
+% \c!voffset=1pt]
+
+\definemathstackers
+ [\v!bothtext]
+ [\v!both]
+ [\c!strut=\v!yes]
+
+% These are compatibity definitions, math only.
+
+% todo: top= bottom= middle= is nicer (compare math-fen)
+
+%D We save a few definitions that we automatically got from the \type {char-def.lua}
+%D database.
+
+% Be careful in choosing what accents you take (the code below uses a
+% combining one):
+%
+% \startbuffer
+% % $\Umathaccent top 0 0 "20D7 {example}$
+% % $\Umathaccent top fixed 0 0 "20D7 {example}$
+% $\Umathaccent 0 0 "20D7 {example}$
+% $\Umathaccent fixed 0 0 "20D7 {example}$
+% $\Umathaccent bottom 0 0 "20D7 {example}$
+% $\Umathaccent bottom fixed 0 0 "20D7 {example}$
+% $\Umathaccent both 0 0 "20D7
+% 0 0 "20D7 {example}$
+% $\Umathaccent both fixed 0 0 "20D7
+% fixed 0 0 "20D7 {example}$
+% $\Umathaccent both 0 0 "20D7
+% fixed 0 0 "20D7 {example}$
+% $\Umathaccent both fixed 0 0 "20D7
+% 0 0 "20D7 {example}$
+% \stopbuffer
+%
+% \setupbodyfont[modern] \getbuffer
+% \setupbodyfont[xits] \getbuffer
+% \setupbodyfont[cambria] \getbuffer
+
+\unexpanded\def\normaldoublebrace {\Umathaccents 0 \defaultmathfamily "23DE 0 \defaultmathfamily "23DF }
+\unexpanded\def\normaldoubleparent{\Umathaccents 0 \defaultmathfamily "23DC 0 \defaultmathfamily "23DD }
+
+% let's keep this
+
+\let\normaloverbrace \overbrace
+\let\normalunderbrace \underbrace
+\let\normaloverparent \overparent
+\let\normalunderparent \underparent
+\let\normaloverbracket \overbracket
+\let\normalunderbracket \underbracket
+\let\normalunderleftarrow \underleftarrow
+\let\normaloverleftarrow \overleftarrow
+\let\normalunderrightarrow\underrightarrow
+\let\normaloverrightarrow \overrightarrow
+
+%D Here come the new ones:
+
+\definemathstackers [\v!none] [\v!mathematics] [\c!hoffset=\zeropoint]
+\definemathstackers [\v!normal] [\v!mathematics] [\c!hoffset=0.5\emwidth] % the default
+\definemathstackers [\v!small] [\v!mathematics] [\c!hoffset=1\emwidth]
+\definemathstackers [\v!medium] [\v!mathematics] [\c!hoffset=1.5\emwidth]
+\definemathstackers [\v!big] [\v!mathematics] [\c!hoffset=2\emwidth]
+
+\definemathextensible [\v!reverse] [xrel] ["002D]
+\definemathextensible [\v!reverse] [xequal] ["003D]
+\definemathextensible [\v!reverse] [xleftarrow] ["2190] % ["27F5]
+\definemathextensible [\v!reverse] [xrightarrow] ["2192] % ["27F6]
+\definemathextensible [\v!reverse] [xleftrightarrow] ["27F7]
+\definemathextensible [\v!reverse] [xLeftarrow] ["27F8]
+\definemathextensible [\v!reverse] [xRightarrow] ["27F9]
+\definemathextensible [\v!reverse] [xLeftrightarrow] ["27FA]
+\definemathextensible [\v!reverse] [xtwoheadleftarrow] ["219E]
+\definemathextensible [\v!reverse] [xtwoheadrightarrow] ["21A0]
+\definemathextensible [\v!reverse] [xmapsto] ["21A6]
+\definemathextensible [\v!reverse] [xhookleftarrow] ["21A9]
+\definemathextensible [\v!reverse] [xhookrightarrow] ["21AA]
+\definemathextensible [\v!reverse] [xleftharpoondown] ["21BD]
+\definemathextensible [\v!reverse] [xleftharpoonup] ["21BC]
+\definemathextensible [\v!reverse] [xrightharpoondown] ["21C1]
+\definemathextensible [\v!reverse] [xrightharpoonup] ["21C0]
+\definemathextensible [\v!reverse] [xrightoverleftarrow] ["21C4]
+\definemathextensible [\v!reverse] [xleftrightharpoons] ["21CB]
+\definemathextensible [\v!reverse] [xrightleftharpoons] ["21CC]
+\definemathextensible [\v!reverse] [xtriplerel] ["2261]
+
+\definemathextensible [\v!mathematics] [mrel] ["002D]
+\definemathextensible [\v!mathematics] [mequal] ["003D]
+\definemathextensible [\v!mathematics] [mleftarrow] ["2190] % ["27F5]
+\definemathextensible [\v!mathematics] [mrightarrow] ["2192] % ["27F6]
+\definemathextensible [\v!mathematics] [mleftrightarrow] ["27F7]
+\definemathextensible [\v!mathematics] [mLeftarrow] ["27F8]
+\definemathextensible [\v!mathematics] [mRightarrow] ["27F9]
+\definemathextensible [\v!mathematics] [mLeftrightarrow] ["27FA]
+\definemathextensible [\v!mathematics] [mtwoheadleftarrow] ["219E]
+\definemathextensible [\v!mathematics] [mtwoheadrightarrow] ["21A0]
+\definemathextensible [\v!mathematics] [mmapsto] ["21A6]
+\definemathextensible [\v!mathematics] [mhookleftarrow] ["21A9]
+\definemathextensible [\v!mathematics] [mhookrightarrow] ["21AA]
+\definemathextensible [\v!mathematics] [mleftharpoondown] ["21BD]
+\definemathextensible [\v!mathematics] [mleftharpoonup] ["21BC]
+\definemathextensible [\v!mathematics] [mrightharpoondown] ["21C1]
+\definemathextensible [\v!mathematics] [mrightharpoonup] ["21C0]
+\definemathextensible [\v!mathematics] [mrightoverleftarrow] ["21C4]
+\definemathextensible [\v!mathematics] [mleftrightharpoons] ["21CB]
+\definemathextensible [\v!mathematics] [mrightleftharpoons] ["21CC]
+\definemathextensible [\v!mathematics] [mtriplerel] ["2261]
+
+\definemathextensible [\v!mathematics] [eleftarrowfill] ["2190] % ["27F5]
+\definemathextensible [\v!mathematics] [erightarrowfill] ["2192] % ["27F6]
+\definemathextensible [\v!mathematics] [eleftrightarrowfill] ["27F7]
+\definemathextensible [\v!mathematics] [etwoheadrightarrowfill] ["27F9]
+\definemathextensible [\v!mathematics] [eleftharpoondownfill] ["21BD]
+\definemathextensible [\v!mathematics] [eleftharpoonupfill] ["21BC]
+\definemathextensible [\v!mathematics] [erightharpoondownfill] ["21C1]
+\definemathextensible [\v!mathematics] [erightharpoonupfill] ["21C0]
+
+\definemathextensible [\v!mathematics] [eoverbarfill] ["FE33E]
+\definemathextensible [\v!mathematics] [eunderbarfill] ["FE33F]
+\definemathextensible [\v!mathematics] [eoverbracefill] ["FE3DE]
+\definemathextensible [\v!mathematics] [eunderbracefill] ["FE3DF]
+\definemathextensible [\v!mathematics] [eoverparentfill] ["FE3DC]
+\definemathextensible [\v!mathematics] [eunderparentfill] ["FE3DD]
+\definemathextensible [\v!mathematics] [eoverbracketfill] ["FE3B4]
+\definemathextensible [\v!mathematics] [eunderbracketfill] ["FE3B5]
+
+\definemathextensible [\v!text] [trel] ["002D]
+\definemathextensible [\v!text] [tequal] ["003D]
+\definemathextensible [\v!text] [tmapsto] ["21A6]
+\definemathextensible [\v!text] [tleftarrow] ["2190] % ["27F5]
+\definemathextensible [\v!text] [trightarrow] ["2192] % ["27F6]
+\definemathextensible [\v!text] [tleftrightarrow] ["27F7]
+\definemathextensible [\v!text] [tLeftarrow] ["27F8]
+\definemathextensible [\v!text] [tRightarrow] ["27F9]
+\definemathextensible [\v!text] [tLeftrightarrow] ["27FA]
+\definemathextensible [\v!text] [ttwoheadleftarrow] ["219E]
+\definemathextensible [\v!text] [ttwoheadrightarrow] ["21A0]
+\definemathextensible [\v!text] [thookleftarrow] ["21A9]
+\definemathextensible [\v!text] [thookrightarrow] ["21AA]
+\definemathextensible [\v!text] [tleftharpoondown] ["21BD]
+\definemathextensible [\v!text] [tleftharpoonup] ["21BC]
+\definemathextensible [\v!text] [trightharpoondown] ["21C1]
+\definemathextensible [\v!text] [trightharpoonup] ["21C0]
+\definemathextensible [\v!text] [trightoverleftarrow] ["21C4]
+\definemathextensible [\v!text] [tleftrightharpoons] ["21CB]
+\definemathextensible [\v!text] [trightleftharpoons] ["21CC]
+\definemathextensible [\v!text] [ttriplerel] ["2261]
+
+\definemathoverextensible [\v!top] [overleftarrow] ["2190] % ["27F5]
+\definemathoverextensible [\v!top] [overrightarrow] ["2192] % ["27F6]
+\definemathoverextensible [\v!top] [overleftrightarrow] ["27F7]
+\definemathoverextensible [\v!top] [overtwoheadleftarrow] ["27F8]
+\definemathoverextensible [\v!top] [overtwoheadrightarrow] ["27F9]
+\definemathoverextensible [\v!top] [overleftharpoondown] ["21BD]
+\definemathoverextensible [\v!top] [overleftharpoonup] ["21BC]
+\definemathoverextensible [\v!top] [overrightharpoondown] ["21C1]
+\definemathoverextensible [\v!top] [overrightharpoonup] ["21C0]
+
+\definemathunderextensible [\v!bottom] [underleftarrow] ["2190] % ["27F5]
+\definemathunderextensible [\v!bottom] [underrightarrow] ["2192] % ["27F6]
+\definemathunderextensible [\v!bottom] [underleftrightarrow] ["27F7]
+\definemathunderextensible [\v!bottom] [undertwoheadleftarrow] ["27F8]
+\definemathunderextensible [\v!bottom] [undertwoheadrightarrow] ["27F9]
+\definemathunderextensible [\v!bottom] [underleftharpoondown] ["21BD]
+\definemathunderextensible [\v!bottom] [underleftharpoonup] ["21BC]
+\definemathunderextensible [\v!bottom] [underrightharpoondown] ["21C1]
+\definemathunderextensible [\v!bottom] [underrightharpoonup] ["21C0]
+
+% We don't use overline and underline. This is one of the overlooked aspects of
+% unicode cq. opentype math: why treat rules different than e.g. arrows and
+% accents. It is a bit unfortunate that the opportunity to move math to new
+% technologies happened outside the tex domain (and/or some aspects were kept
+% while in fact they were side effects of limitations of traditional fonts).
+% From the unicode aware tex engines' implementation point of view things
+% could have been done a bit nicer but then: the community didn't seem to care
+% too much and just has to follow now.
+%
+% Anyhow, we use a character based approach so that at least we get unicode
+% stuff in the backend (okay, we still need to deal with some cut and paste
+% issues but at least we now know what we deal with.
+
+% alternatively we can move the original to FE*
+
+\definemathoverextensible [vfenced] [overbar] ["FE33E] % ["203E]
+\definemathunderextensible [vfenced] [underbar] ["FE33F] % ["203E]
+\definemathdoubleextensible [vfenced] [doublebar] ["FE33E] ["FE33F]
+
+\definemathoverextensible [vfenced] [overbrace] ["FE3DE] % ["023DE]
+\definemathunderextensible [vfenced] [underbrace] ["FE3DF] % ["023DF]
+\definemathdoubleextensible [vfenced] [doublebrace] ["FE3DE] ["FE3DF]
+
+\definemathoverextensible [vfenced] [overparent] ["FE3DC] % ["023DC]
+\definemathunderextensible [vfenced] [underparent] ["FE3DD] % ["023DD]
+\definemathdoubleextensible [vfenced] [doubleparent] ["FE3DC] ["FE3DD]
+
+\definemathoverextensible [vfenced] [overbracket] ["FE3B4] % ["023B4]
+\definemathunderextensible [vfenced] [underbracket] ["FE3B5] % ["023B5]
+\definemathdoubleextensible [vfenced] [doublebracket] ["FE3B4] ["FE3B5]
+
+% \unexpanded\def\mathopwithlimits#1#2{\mathop{#1{#2}}\limits}
+
+%D For mathml:
+
+\definemathdoubleextensible [both] [overbarunderbar] ["FE33E] ["FE33F]
+\definemathdoubleextensible [both] [overbraceunderbrace] ["FE3DE] ["FE3DF]
+\definemathdoubleextensible [both] [overparentunderparent] ["FE3DC] ["FE3DD]
+\definemathdoubleextensible [both] [overbracketunderbracket] ["FE3B4] ["FE3B5]
+
+\definemathovertextextensible [bothtext] [overbartext] ["FE33E]
+\definemathundertextextensible [bothtext] [underbartext] ["FE33F]
+\definemathovertextextensible [bothtext] [overbracetext] ["FE3DE]
+\definemathundertextextensible [bothtext] [underbracetext] ["FE3DF]
+\definemathovertextextensible [bothtext] [overparenttext] ["FE3DC]
+\definemathundertextextensible [bothtext] [underparenttext] ["FE3DD]
+\definemathovertextextensible [bothtext] [overbrackettext] ["FE3B4]
+\definemathundertextextensible [bothtext] [underbrackettext] ["FE3B5]
+
+%D Some bonus ones (for the moment here):
+
+\definemathstackers
+ [\v!chemistry]
+ [\c!offset=\v!max,
+ \c!left=\enspace,
+ \c!right=\enspace,
+ \c!hoffset=.5\emwidth]
+
+\definemathextensible [\v!chemistry] [cleftarrow] ["2190]
+\definemathextensible [\v!chemistry] [crightarrow] ["2192]
+\definemathextensible [\v!chemistry] [crightoverleftarrow] ["21C4]
+
+% for the moment:
+
+\def\math_stackers_hacked_fill#1#2#3%
+ {\mathematics
+ {\begingroup
+ \mathsurround\zeropoint
+ \thickmuskip \zeromuskip
+ \medmuskip \zeromuskip
+ \thinmuskip \zeromuskip
+ #1%
+ \mkern-7\onemuskip
+ \cleaders\mathstylehbox{\mkern-2\onemuskip#2\mkern-2\onemuskip}\hfill
+ \mkern-7\onemuskip
+ #3%
+ \endgroup}}
+
+% These will be defined in char-def as well once we have \leaders<number>
+
+\unexpanded\def\rightarrowfill {\math_stackers_hacked_fill \relbar \relbar \rightarrow}
+\unexpanded\def\leftarrowfill {\math_stackers_hacked_fill \leftarrow \relbar \relbar }
+\unexpanded\def\rightoverleftarrowfill{\math_stackers_hacked_fill \ctxdoublearrowfillleftend\ctxdoublearrowfillmiddlepart\ctxdoublearrowfillrightend}
+\unexpanded\def\equalfill {\math_stackers_hacked_fill \Relbar \Relbar \Relbar}
+\unexpanded\def\Rightarrowfill {\math_stackers_hacked_fill \Relbar \Relbar \Rightarrow}
+\unexpanded\def\Leftarrowfill {\math_stackers_hacked_fill \Leftarrow \Relbar \Relbar}
+\unexpanded\def\Leftrightarrowfill {\math_stackers_hacked_fill \Leftarrow \Relbar \Rightarrow}
+\unexpanded\def\leftrightarrowfill {\math_stackers_hacked_fill \leftarrow \relbar \rightarrow}
+\unexpanded\def\mapstofill {\math_stackers_hacked_fill{\mapstochar\relbar} \relbar \rightarrow}
+\unexpanded\def\twoheadrightarrowfill {\math_stackers_hacked_fill \relbar \relbar \twoheadrightarrow}
+\unexpanded\def\twoheadleftarrowfill {\math_stackers_hacked_fill \twoheadleftarrow \relbar \relbar}
+\unexpanded\def\rightharpoondownfill {\math_stackers_hacked_fill \relbar \relbar \rightharpoondown}
+\unexpanded\def\rightharpoonupfill {\math_stackers_hacked_fill \relbar \relbar \rightharpoonup}
+\unexpanded\def\leftharpoondownfill {\math_stackers_hacked_fill \leftharpoondown \relbar \relbar}
+\unexpanded\def\leftharpoonupfill {\math_stackers_hacked_fill \leftharpoonup \relbar \relbar}
+\unexpanded\def\hookleftfill {\math_stackers_hacked_fill \leftarrow \relbar {\relbar\joinrel\rhook}}
+\unexpanded\def\hookrightfill {\math_stackers_hacked_fill{\lhook\joinrel\relbar} \relbar \rightarrow}
+\unexpanded\def\relfill {\math_stackers_hacked_fill \relbar \relbar \relbar}
+\unexpanded\def\triplerelfill {\math_stackers_hacked_fill \equiv \equiv \equiv}
+
+\unexpanded\def\singlebond {{\xrel}} % or \def\singlebond{{\xrel[2]}}
+\unexpanded\def\doublebond {{\xequal}}
+\unexpanded\def\triplebond {{\xtriplerel}}
+
+\unexpanded\def\defineextensiblefiller
+ {\dodoubleargument\math_stackers_define_filler}
+
+\def\math_stackers_define_filler[#1][#2]%
+ {\setuevalue{#1}{\leaders\number#2\hfill}}
+
+%D For the moment:
+
+\def\math_stackers_define_filler[#1][#2]%
+ {\expandafter\let\csname\??mathextensiblefallbacks\number#2\expandafter\endcsname\csname#1\endcsname
+ \expandafter\let\csname #1\expandafter\endcsname\csname#1\endcsname}
+
+\defineextensiblefiller [barfill] ["203E]
+\defineextensiblefiller [relfill] ["002D]
+\defineextensiblefiller [equalfill] ["003D]
+\defineextensiblefiller [leftarrowfill] ["2190]
+\defineextensiblefiller [rightarrowfill] ["2192]
+\defineextensiblefiller [twoheadleftarrowfill] ["219E]
+\defineextensiblefiller [twoheadrightarrowfill] ["21A0]
+\defineextensiblefiller [mapstofill] ["21A6]
+\defineextensiblefiller [hookleftarrowfill] ["21A9]
+\defineextensiblefiller [hookrightarrowfill] ["21AA]
+\defineextensiblefiller [leftharpoondownfill] ["21BD]
+\defineextensiblefiller [leftharpoonupfill] ["21BC]
+\defineextensiblefiller [rightharpoondownfill] ["21C1]
+\defineextensiblefiller [rightharpoonupfill] ["21C0]
+\defineextensiblefiller [rightoverleftarrowfill] ["21C4]
+\defineextensiblefiller [leftrightharpoonsfill] ["21CB]
+\defineextensiblefiller [rightleftharpoonsfill] ["21CC]
+\defineextensiblefiller [triplerelfill] ["2261]
+\defineextensiblefiller [leftrightarrowfill] ["27F7]
+\defineextensiblefiller [Leftarrowfill] ["27F8]
+\defineextensiblefiller [Rightarrowfill] ["27F9]
+\defineextensiblefiller [Leftrightarrowfill] ["27FA]
+\defineextensiblefiller [Leftrightarrowfill] ["27FA]
+
+%defineextensiblefiller [overbarfill] ["FE33E] % untested
+%defineextensiblefiller [underbarfill] ["FE33F] % untested
+\defineextensiblefiller [overbracefill] ["FE3DE] % untested
+\defineextensiblefiller [underbracefill] ["FE3DF] % untested
+\defineextensiblefiller [overparentfill] ["FE3DC] % untested
+\defineextensiblefiller [underparentfill] ["FE3DD] % untested
+\defineextensiblefiller [overbracketfill] ["FE3B4] % untested
+\defineextensiblefiller [underbracketfill] ["FE3B5] % untested
+
+%D Extra:
+
+\unexpanded\edef\singlebond{\mathematics{\mathsurround\zeropoint\char\number"002D\relax}}
+\unexpanded\edef\doublebond{\mathematics{\mathsurround\zeropoint\char\number"003D\relax}}
+\unexpanded\edef\triplebond{\mathematics{\mathsurround\zeropoint\char\number"2261\relax}}
+
+% \mathchardef\singlebond"002D
+% \mathchardef\doublebond"003D
+% \mathchardef\triplebond"2261
+
+%D Also handy:
+
+\unexpanded\def\definemathunstacked
+ {\dotripleempty\math_stackers_define_unstacked_normal}
+
+\def\math_stackers_define_unstacked_normal[#1][#2][#3]% category name unicode
+ {\ifthirdargument
+ \setuevalue{#2}{\math_stackers_unstacked_normal{#1}{\number#3}}%
+ \else
+ \setuevalue{#1}{\math_stackers_unstacked_normal\noexpand\currentmathstackers{\number#2}}%
+ \fi}
+
+\unexpanded\def\math_stackers_unstacked_normal#category#codepoint%
+ {\begingroup
+ \edef\currentmathstackers{#category}%
+ \edef\p_moffset{\mathstackersparameter\c!moffset}%
+ \ifx\p_moffset\empty \else
+ \mskip\p_moffset\relax
+ \fi
+ \ifmmode\math_class_by_parameter\mathstackersparameter\else\dontleavehmode\fi
+ {\usemathstackerscolorparameter\c!color
+ \Umathchar\zerocount\defaultmathfamily#codepoint}%
+ \ifx\p_moffset\empty \else
+ \mskip\p_moffset\relax
+ \fi
+ \endgroup}
+
+\definemathstackers [\v!wide] [\c!moffset=\thickmuskip,\c!mathclass=\s!rel]
+
+\definemathunstacked [\v!wide] [And] ["0026] % \mathrel{\;&\;}
+\definemathunstacked [\v!wide] [impliedby] ["27F8] % \mathrel{\;\Longleftarrow\;}
+\definemathunstacked [\v!wide] [implies] ["27F9] % \mathrel{\;\Longrightarrow\;}
+\definemathunstacked [\v!wide] [iff] ["27FA] % \mathrel{\;\Longleftrightarrow\;}
+
+\protect \endinput
+
+% \mathrel{\mathop{\hbox to \dimen0{\hss\copy4\hss}}
+% \limits\normalsuperscript{\box0}\normalsubscript{\box2}}%
+
+% $\Uoverdelimiter \defaultmathfamily "2194 {xxxx}$
+% $\Uunderdelimiter\defaultmathfamily "2194 {xxxx}$
+% $\Udelimiterover \defaultmathfamily "2194 {xxxx}$
+% $\Udelimiterunder\defaultmathfamily "2194 {xxxx}$
+% $\Udelimiterover \defaultmathfamily "219A {\Udelimiterunder \defaultmathfamily "219B {xxxx}}$
+
+% $a \mathrel{\mathop{\filledhboxr{mid}}}\limits^{\filledhboxg{\strut top}}_{\filledhboxb{\strut bottom}} b$