diff options
author | Context Git Mirror Bot <phg42.2a@gmail.com> | 2016-01-12 17:15:07 +0100 |
---|---|---|
committer | Context Git Mirror Bot <phg42.2a@gmail.com> | 2016-01-12 17:15:07 +0100 |
commit | 8d8d528d2ad52599f11250cfc567fea4f37f2a8b (patch) | |
tree | 94286bc131ef7d994f9432febaf03fe23d10eef8 /tex/context/base/mkiv/math-stc.mkvi | |
parent | f5aed2e51223c36c84c5f25a6cad238b2af59087 (diff) | |
download | context-8d8d528d2ad52599f11250cfc567fea4f37f2a8b.tar.gz |
2016-01-12 16:26:00
Diffstat (limited to 'tex/context/base/mkiv/math-stc.mkvi')
-rw-r--r-- | tex/context/base/mkiv/math-stc.mkvi | 1293 |
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$ |