%D \module %D [ file=math-arr, %D version=2007.07.19, %D title=\CONTEXT\ Math Macros, %D subtitle=Arrows, %D author={Hans Hagen \& Taco Hoekwater \& Aditya Mahajan}, %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. %D We keep this file around as reference of his things were done in the %D past. You can still load this module but it has been replaced by more %D modern code. \writestatus{loading}{ConTeXt Math Macros / Arrows} \unprotect %D These will be generalized! Is it still needed in \MKIV? Also, we need to %D to it using regular opentype math! % Plain code: % % \def\rightarrowfill % {$% % \mathsurround\zeropoint % \smash-% % \mkern-7mu% % \cleaders\hbox{$\mkern-2mu\smash-\mkern-2mu$}\hfill % \mkern-7mu% % \mathord\rightarrow % $} % % \def\leftarrowfill % brrr no longer in luatex % {$% % \mathsurround\zeropoint % \mathord\leftarrow % \mkern-7mu% % \cleaders\hbox{$\mkern-2mu\smash-\mkern-2mu$}\hfill % \mkern-7mu % \smash-% % $} %D Extensible arrows are arrows that change their length according to the width of %D the text to be placed above and below the arrow. %D %D Since we need to define a lot of arrows, we first define some helper macros. The %D basic idea is to measure the width of the box to be placed above and below the %D arrow, and make the \quote {body} of the arrow as long as the bigger of the two %D widths. \installcorenamespace{matharrowsettings} \def\m_math_arrows_factor{1} \def\m_math_arrows_extra {0} \setvalue{\??matharrowsettings\v!none }{\def\m_math_arrows_factor{0}} \setvalue{\??matharrowsettings\v!small }{\def\m_math_arrows_extra{10}} \setvalue{\??matharrowsettings\v!medium }{\def\m_math_arrows_extra{15}} \setvalue{\??matharrowsettings\v!big }{\def\m_math_arrows_extra{20}} \setvalue{\??matharrowsettings\v!normal }{} \setvalue{\??matharrowsettings }{} \setvalue{\??matharrowsettings\s!unknown}{\doifelsenumber\p_math_spacing{\let\m_math_arrows_extra\p_math_spacing}\donothing} \def\math_arrows_construct#1#2#3#4#5% hm, looks like we do a double mathrel (a bit cleaned up .. needs checking) {\begingroup \let\m_math_arrows_factor\!!plusone \let\m_math_arrows_extra \!!zerocount \edef\p_math_spacing{#1}% \csname\??matharrowsettings \ifcsname\??matharrowsettings\p_math_spacing\endcsname\p_math_spacing\else\s!unknown\fi \endcsname \mathsurround\zeropoint \scratchmuskipone\muexpr\m_math_arrows_factor\muexpr\thirdoffourarguments #2\onemuskip\relax+\m_math_arrows_extra\onemuskip+\firstoffourarguments #2\onemuskip\relax \scratchmuskiptwo\muexpr\m_math_arrows_factor\muexpr\fourthoffourarguments#2\onemuskip\relax+\m_math_arrows_extra\onemuskip+\secondoffourarguments#2\onemuskip\relax \setbox\scratchboxone\hbox {\normalstartimath \scriptstyle \mkern\scratchmuskipone\relax #5\relax \mkern\scratchmuskiptwo\relax \normalstopimath}% \setbox\scratchboxtwo\hbox {\normalstartimath \scriptstyle \mkern\scratchmuskipone\relax #4\relax \mkern\scratchmuskiptwo\relax \normalstopimath}% \setbox\scratchboxthree\hbox{#3\displaystyle}% \scratchdimenone\wd\scratchboxone\relax \ifdim\wd\scratchboxtwo>\scratchdimenone \scratchdimenone\wd\scratchboxtwo\relax \fi \ifdim\wd\scratchboxthree>\scratchdimenone \scratchdimenone\wd\scratchboxthree\relax \fi \ifdim\wd\scratchboxthree=\scratchdimenone\else \setbox\scratchboxthree\hbox to \scratchdimenone{#3\displaystyle}% \fi \mathrel {\mathop {\hpack to \scratchdimenone{\hss\box\scratchboxthree\hss}}% pack ? copy ? \limits \normalsuperscript{\box\scratchboxone}% \normalsubscript {\box\scratchboxtwo}}% \endgroup} \let\math_arrows_construct_single\math_arrows_construct %D There are some arrows which are created by stacking two arrows. The next %D macro helps in defining such \quotation{double arrows}. % weird, we get a shift with the double ... but will become core luatex anyway % % \startchemicalformula % \chemical{S} % \chemical{+} % \chemical{O_2} % \chemical{EQUILIBRIUM}{boven}{onder} % \chemical{SO_2} % \stopchemicalformula \def\math_arrows_construct_double#1#2#3#4#5#6#7% opt l r sp rs top bot {\mathrel {\scratchdimen.32\exheight\relax % was .22, todo: make configurable \setbox\scratchboxone\hbox{\normalstartimath\math_arrows_construct{#1}{#2}{#4}{\phantom{#6}}{#7}\normalstopimath}% \setbox\scratchboxtwo\hbox{\normalstartimath\math_arrows_construct{#1}{#3}{#5}{#6}{\phantom{#7}}\normalstopimath}% \raise\scratchdimen\box\scratchboxone \kern-\wd\scratchboxtwo \lower\scratchdimen\box\scratchboxtwo}} %D \macros{definematharrow} %D %D Macro for defining new arrows. We can define two types of arrows|<|single arrows %D and double arrows. Single arrows are defined as %D %D \starttyping %D \definematharrow [xrightarrow] [0359] [\rightarrowfill] %D \stoptyping %D %D The first argument is the name of the arrow (\tex {xrightarrow} in this case.) The %D second argument consists of a set of 4 numbers and specify the spacing correction %D in math units~\type {mu}. These numbers define: %D %D \startlines %D 1st number: arrow||tip correction %D 2nd number: arrow||tip correction %D 3rd number: space (multiplied by \tex{matharrfactor} and advanced by \tex{matharrextra}) %D 4th number: space (multiplied by \tex{matharrfactor} and advanced by \tex{matharrextra}) %D \stoplines %D %D The third argument is the name of the extensible fill. The third argument is optional %D when the arrow is redefined later (this is useful for font specific tweaking of the %D skips.) For example, %D %D \startbuffer %D \math{\xrightarrow{above}} %D \definematharrow[xrightarrow][0000] %D \math{\xrightarrow{above}} %D \definematharrow[xrightarrow][55{50}{50}] %D \math{\xrightarrow{above}} %D \stopbuffer %D \typebuffer gives {\getbuffer} %D %D The double arrows are defined as follows %D %D \starttyping %D \definematharrow [xrightleftharpoons] [3095,0359] %D [\rightharpoonupfill,\leftharpoondownfill] %D \stoptyping %D %D The second and the third set of arguments consist of comma separated values. The %D first element of the second argument (\type {3095}) corresponds to the spacing %D correction of top arrow fill (\tex{rightarrowupfill}). Similarly, \type {0359} %D corresponds to bottom arrow fill \tex {leftharpoondownfill}). Stacking them on %D top of each other we get $\xrightleftharpoons [big] {above} {below}$. The %D following math arrows are defined %D %D \placetable[none]{}{\starttable[|l|m|] %D \NC \tex{xrightarrow} \NC \xrightarrow [big] \NC \NR %D \NC \tex{xleftarrow} \NC \xleftarrow [big] \NC \NR %D \NC \tex{xequal} \NC \xequal [big] \NC \NR %D \NC \tex{xRightarrow} \NC \xRightarrow [big] \NC \NR %D \NC \tex{xLeftarrow} \NC \xLeftarrow [big] \NC \NR %D \NC \tex{xLeftrightarrow} \NC \xLeftrightarrow [big] \NC \NR %D \NC \tex{xleftrightarrow} \NC \xleftrightarrow [big] \NC \NR %D \NC \tex{xmapsto} \NC \xmapsto [big] \NC \NR %D \NC \tex{xtwoheadrightarrow} \NC \xtwoheadrightarrow [big] \NC \NR %D \NC \tex{xtwoheadleftarrow} \NC \xtwoheadleftarrow [big] \NC \NR %D \NC \tex{xrightharpoondown} \NC \xrightharpoondown [big] \NC \NR %D \NC \tex{xrightharpoonup} \NC \xrightharpoonup [big] \NC \NR %D \NC \tex{xleftharpoondown} \NC \xleftharpoondown [big] \NC \NR %D \NC \tex{xleftharpoonup} \NC \xleftharpoonup [big] \NC \NR %D \NC \tex{xhookleftarrow} \NC \xhookleftarrow [big] \NC \NR %D \NC \tex{xhookrightarrow} \NC \xhookrightarrow [big] \NC \NR %D \NC \tex{xleftrightharpoons} \NC \xleftrightharpoons [big] \NC \NR %D \NC \tex{xrightleftharpoons} \NC \xrightleftharpoons [big] \NC \NR %D \stoptable} %D If needed this can be optimized (i.e. we can preexpand using \type %D {\docheckedpair}). \unexpanded\def\definematharrow {\doquadrupleargument\math_arrows_define} \def\math_arrows_define[#1][#2][#3][#4]% name type[none|both] template command {\iffourthargument \executeifdefined{math_arrows_define_#2}\gobblethreearguments{#1}{#3}{#4}% \else\ifthirdargument \math_arrows_define_both{#1}{#2}{#3}% \else\ifsecondargument \math_arrows_define_both_again{#1}{#2}{#3}% \fi\fi\fi} \def\math_arrows_define_both_again#1#2#3% real dirty, this overload! {\ifcsname#1\endcsname \pushmacro\math_arrows_do \def\math_arrows_do[##1][##2]{\setuvalue{#1}{\math_arrows_do[#2][##2]}}% \csname#1\endcsname \popmacro\math_arrows_do \fi} \def\math_arrows_define_both#1#2#3% {\setuvalue{#1}{\math_arrows_do[#2][#3]}} \unexpanded\def\math_arrows_do {\doquadrupleempty\math_arrows_handle} \def\math_arrows_handle[#1][#2][#3][#4]% #3 == optional arg .. \empty can be just 'empty' [#4] gobbles spaces {\def\math_arrows_handle_indeed{\math_arrows_handle_finalize[#1,\empty,\empty][#2,\empty,\empty][#3]}% {##1}{##2} \dodoublegroupempty\math_arrows_handle_indeed} \def\math_arrows_handle_finalize[#1,#2,#3][#4,#5,#6][#7]#8#9% [#7] is the optional arg {\edef\!!stringa{#2}% \ifx\!!stringa\empty \ifsecondargument \mathrel{\math_arrows_construct_single{#7}{#1}{#4}{#8}{#9}}% \else \mathrel{\math_arrows_construct_single{#7}{#1}{#4}{}{#8}}% \fi \else \ifsecondargument \mathrel{\math_arrows_construct_double{#7}{#1}{#2}{#4}{#5}{#8}{#9}}% \else \mathrel{\math_arrows_construct_double{#7}{#1}{#2}{#4}{#5}{}{#8}}% \fi \fi} % Adapted from amsmath. %D \macros{mtharrowfill,defaultmtharrowfill} %D %D To extend the arrows we need to define a \quotation {math arrow fill}. This %D command takes 8 arguments: the first four correspond the second argument of %D \tex {definematharrow} explained above. The other three specify the tail, %D body and head of the arrow. The last argument specifies the math-mode in which %D the arrow is drawn. \tex {defaultmtharrowfill} has values tweaked to match %D Latin Modern fonts. For fonts that are significantly different (e.g. cows) a %D different set of values need to be determined. \def\mtharrowfill#1#2#3#4#5#6#7#8% {\normalstartimath \mathsurround\zeropoint \thickmuskip\zeromuskip\medmuskip\thickmuskip\thinmuskip\thickmuskip \relax#8#5% \mkern-#1\onemuskip \cleaders\hbox{\normalstartimath#8\mkern-#2\onemuskip#6\mkern-#3\onemuskip\normalstopimath}\hfill \mkern-#4\onemuskip#7% \normalstopimath} \def\defaultmtharrowfill{\mtharrowfill 7227} %D We now define some arrow fills that will be used for defining the arrows. Plain %D \TEX\ already defines \tex {leftarrowfill} and \tex {rightarrowfill}. The \tex %D {defaultmtharrowfill} command defines an arrowfill that takes an argument (so %D that it can also be used with over and under arrows). However the Plain \TEX\ %D definitions of \tex {leftarrowfill} and \tex {rightarrowfill} do not take this %D extra argument. To be backward compatible with Plain \TEX, we define two %D arrowfills: \tex {specrightarrowfill} which takes an extra argument, and \tex %D {rightarrowfill} which does not. \unexpanded\def\specrightarrowfill {\defaultmtharrowfill \relbar \relbar \rightarrow} \unexpanded\def\specleftarrowfill {\defaultmtharrowfill \leftarrow \relbar \relbar} \unexpanded\def\rightarrowfill {\specrightarrowfill\textstyle} \unexpanded\def\leftarrowfill {\specleftarrowfill \textstyle} \unexpanded\def\equalfill {\defaultmtharrowfill \Relbar \Relbar \Relbar} \unexpanded\def\Rightarrowfill {\defaultmtharrowfill \Relbar \Relbar \Rightarrow} \unexpanded\def\Leftarrowfill {\defaultmtharrowfill \Leftarrow \Relbar \Relbar} \unexpanded\def\Leftrightarrowfill {\defaultmtharrowfill \Leftarrow \Relbar \Rightarrow} \unexpanded\def\leftrightarrowfill {\defaultmtharrowfill \leftarrow \relbar \rightarrow} \unexpanded\def\mapstofill {\defaultmtharrowfill{\mapstochar\relbar} \relbar \rightarrow} \unexpanded\def\twoheadrightarrowfill{\defaultmtharrowfill \relbar \relbar \twoheadrightarrow} \unexpanded\def\twoheadleftarrowfill {\defaultmtharrowfill \twoheadleftarrow \relbar \relbar} \unexpanded\def\rightharpoondownfill {\defaultmtharrowfill \relbar \relbar \rightharpoondown} \unexpanded\def\rightharpoonupfill {\defaultmtharrowfill \relbar \relbar \rightharpoonup} \unexpanded\def\leftharpoondownfill {\defaultmtharrowfill \leftharpoondown \relbar \relbar} \unexpanded\def\leftharpoonupfill {\defaultmtharrowfill \leftharpoonup \relbar \relbar} \unexpanded\def\hookleftfill {\defaultmtharrowfill \leftarrow \relbar{\relbar\joinrel\rhook}} \unexpanded\def\hookrightfill {\defaultmtharrowfill{\lhook\joinrel\relbar}\relbar \rightarrow} \unexpanded\def\relfill {\defaultmtharrowfill \relbar \relbar \relbar} \unexpanded\def\triplerelbar {\mathrel\equiv} \unexpanded\def\triplerelfill{\defaultmtharrowfill\triplerelbar\triplerelbar\triplerelbar} \unexpanded\def\singlebond{{\xrel}} % or \def\singlebond{{\xrel[2]}} \unexpanded\def\doublebond{{\xequal}} \unexpanded\def\triplebond{{\xtriplerel}} %D A bit or arrow juggling: %D %D \startbuffer %D \hbox to \hsize{\rightoverleftarrowfill} %D \stopbuffer %D %D \typebuffer \blank \getbuffer \blank \unexpanded\def\rightoverleftarrowfill {\specrightoverleftarrowfill} \unexpanded\def\specrightoverleftarrowfill {\defaultmtharrowfill \ctxdoublearrowfillleftend \ctxdoublearrowfillmiddlepart \ctxdoublearrowfillrightend \textstyle} %D Now we define most commonly used arrows. These include arrows defined in \filename %D {amsmath.sty}, \filename {extarrows.sty}, \filename {extpfel.sty} and \filename %D {mathtools.sty} packages for \LATEX\ (plus a few more). \definematharrow [xrightarrow] [0359] [\specrightarrowfill] \definematharrow [xleftarrow] [3095] [\specleftarrowfill] \definematharrow [xequal] [0099] [\equalfill] \definematharrow [xRightarrow] [0359] [\Rightarrowfill] \definematharrow [xLeftarrow] [3095] [\Leftarrowfill] \definematharrow [xLeftrightarrow] [0099] [\Leftrightarrowfill] \definematharrow [xleftrightarrow] [0099] [\leftrightarrowfill] \definematharrow [xmapsto] [3599] [\mapstofill] \definematharrow [xtwoheadrightarrow] [5009] [\twoheadrightarrowfill] \definematharrow [xtwoheadleftarrow] [0590] [\twoheadleftarrowfill] \definematharrow [xrightharpoondown] [0359] [\rightharpoondownfill] \definematharrow [xrightharpoonup] [0359] [\rightharpoonupfill] \definematharrow [xleftharpoondown] [3095] [\leftharpoondownfill] \definematharrow [xleftharpoonup] [3095] [\leftharpoonupfill] \definematharrow [xhookleftarrow] [3095] [\hookleftfill] \definematharrow [xhookrightarrow] [0395] [\hookrightfill] \definematharrow [xrel] [0099] [\relfill] \definematharrow [xtriplerel] [0099] [\triplerelfill] \definematharrow [xrightoverleftarrow] [0359,3095] [\specrightarrowfill,\specleftarrowfill] \definematharrow [xleftrightharpoons] [3399,3399] [\leftharpoonupfill,\rightharpoondownfill] \definematharrow [xrightleftharpoons] [3399,3399] [\rightharpoonupfill,\leftharpoondownfill] %D These arrows can be used as follows: %D %D \startbuffer %D \startformula \xrightarrow{stuff on top}\stopformula %D \startformula \xrightarrow{}{stuff on top}\stopformula %D \startformula \xrightarrow{stuff below}{}\stopformula %D \startformula \xrightarrow{stuff below}{stuff on top}\stopformula %D %D \startformula \xleftarrow [none]{stuff below}{stuff on top}\stopformula %D \startformula \xleftarrow [small]{stuff below}{stuff on top}\stopformula %D \startformula \xleftarrow [medium]{stuff below}{stuff on top}\stopformula %D \startformula \xleftarrow [big]{stuff below}{stuff on top}\stopformula %D \stopbuffer %D %D \typebuffer which gives \getbuffer %D \macros{definemathoverarrow,defineunderarrow} %D %D These macros for define math-overarrows are adapted from \filename {amsmath.sty} \unexpanded\def\definemathoverarrow {\dotripleargument\math_arrows_define_over} \def\math_arrows_define_over[#1][#2][#3]% {\ifthirdargument \setuvalue{#1}{\math_arrows_over_handle[#2][#3]}% \else \setuvalue{#1}{\math_arrows_over_handle[\zeropoint][#2]}% \fi} \def\math_arrows_over_handle[#1][#2]% {\mathpalette{\math_arrows_over_handle_indeed{#1}{#2}}} %D Note: \filename {math-pln.tex} has \type {\kern-\onepoint} and \filename %D {amsmath.sty} does not. We keep the kern amount configurable. This is useful %D for harpoons. \def\math_arrows_over_handle_indeed#1#2#3#4% {\vbox{\ialign{% \alignmark\alignmark \crcr #2#3% \crcr \noalign{\kern#1\nointerlineskip}% \normalstartimath \mathsurround\zeropoint\hfil#3#4\hfil \normalstopimath \crcr }}} %D Now the under arrows \unexpanded\def\definemathunderarrow {\dotripleargument\math_arrows_define_under} %D For underarrows the default kern is 0.3ex \def\math_arrows_define_under[#1][#2][#3]% {\ifthirdargument \setuvalue{#1}{\math_arrows_under_handle[#2][#3]}% \else \setuvalue{#1}{\math_arrows_under_handle[0.3ex][#2]}% \fi} \def\math_arrows_under_handle[#1][#2]% {\mathpalette{\math_arrows_under_handle_indeed{#1}{#2}}} \def\math_arrows_under_handle_indeed#1#2#3#4% {\vtop{\ialign{% \alignmark\alignmark \crcr \normalstartimath\mathsurround\zeropoint\hfil#3#4\hfil\normalstopimath \crcr \noalign{\nointerlineskip\kern#1}% #2#3% \crcr }}} %D Now we define the arrows \definemathoverarrow [overleftarrow] [\specleftarrowfill] \definemathoverarrow [overrightarrow] [\specrightarrowfill] \definemathoverarrow [overleftrightarrow] [\leftrightarrowfill] \definemathoverarrow [overtwoheadrightarrow] [\twoheadrightarrowfill] \definemathoverarrow [overtwoheadleftarrow] [\twoheadleftarrowfill] \definemathoverarrow [overrightharpoondown] [1pt] [\rightharpoondownfill] \definemathoverarrow [overrightharpoonup] [\rightharpoonupfill] \definemathoverarrow [overleftharpoondown] [1pt] [\leftharpoondownfill] \definemathoverarrow [overleftharpoonup] [\leftharpoonupfill] \definemathunderarrow [underleftarrow] [\specleftarrowfill] \definemathunderarrow [underrightarrow] [\specrightarrowfill] \definemathunderarrow [underleftrightarrow] [\leftrightarrowfill] \definemathunderarrow [undertwoheadrightarrow][\twoheadrightarrowfill] \definemathunderarrow [undertwoheadleftarrow] [\twoheadleftarrowfill] \definemathunderarrow [underrightharpoondown] [\rightharpoondownfill] \definemathunderarrow [underrightharpoonup] [\rightharpoonupfill] \definemathunderarrow [underleftharpoondown] [\leftharpoondownfill] \definemathunderarrow [underleftharpoonup] [\leftharpoonupfill] %D These can be used as follows: %D %D \startbuffer %D $\overleftarrow{A}$ $\overleftarrow{ABC}$ %D $a_{\overleftarrow{A}}$ $b_{\overleftarrow{ABC}}$ %D \stopbuffer %D \typebuffer which gives \getbuffer %D TODO: Possibly have a single arrow command define all the arrows. \protect \endinput