%D \module %D [ file=math-ext, %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. \writestatus{loading}{ConTeXt Math Macros / Arrows} \unprotect %D These will be generalized! Is it still needed in \MKIV? %D We next define extensible arrows. Extensible arrows are arrows that %D change their length according to the width of the text to be placed %D above and below the arrow. Since we need to define a lot of arrows, %D we first define some helper macros. The basic idea is to measure %D the width of the box to be placed above and below the arrow, and %D make the \quotation{body} of the arrow as long as the bigger of the %D two widths. \def\mtharrfactor{1} \def\mtharrextra {0} \def\domthxarr#1#2#3#4#5% hm, looks like we do a double mathrel {\begingroup \def\mtharrfactor{1}% \def\mtharrextra {0}% \processaction[#1] % will be sped up [ \v!none=>\def\mtharrfactor{0}, \v!small=>\def\mtharrextra{10}, \v!medium=>\def\mtharrextra{15}, \v!big=>\def\mtharrextra{20}, \v!normal=>, \v!default=>, \v!unknown=>\doifnumberelse{#1}{\def\mtharrextra{#1}}\donothing]% \mathsurround\zeropoint \muskip0=\thirdoffourarguments #2mu \muskip2=\fourthoffourarguments #2mu \muskip4=\firstoffourarguments #2mu \muskip6=\secondoffourarguments #2mu \muskip0=\mtharrfactor\muskip0 \advance\muskip0 \mtharrextra mu \muskip2=\mtharrfactor\muskip2 \advance\muskip2 \mtharrextra mu \setbox0\hbox{$\scriptstyle \mkern\muskip4\relax \mkern\muskip0\relax #5\relax \mkern\muskip2\relax \mkern\muskip6\relax $}% \setbox4\hbox{#3\displaystyle}% \dimen0\wd0 \ifdim\wd4>\dimen0 \dimen0\wd4 \fi \setbox2\hbox{$\scriptstyle \mkern\muskip4\relax \mkern\muskip0\relax #4\relax \mkern\muskip2\relax \mkern\muskip6\relax $}% \ifdim\wd2>\dimen0 \dimen0\wd2 \fi \setbox4\hbox to \dimen0{#3\displaystyle}% \mathrel{\mathop{\hbox to \dimen0{\hss\copy4\hss}}\limits^{\box0}_{\box2}} \endgroup} \let\domthxarrsingle\domthxarr %D There are some arrows which are created by stacking two arrows. The next %D macro helps in defining such \quotation{double arrows}. \def\domthxarrdouble#1#2#3#4#5#6#7% opt l r sp rs top bot {\mathrel {\scratchdimen.32ex\relax % was .22, todo: make configurable \setbox0\hbox{$\domthxarr{#1}{#2}{#4}{\phantom{#6}}{#7}$}% \setbox2\hbox{$\domthxarr{#1}{#3}{#5}{#6}{\phantom{#7}}$}% \raise\scratchdimen\box0 \kern-\wd2 \lower\scratchdimen\box2}} %D \macros{definematharrow} %D %D Macro for defining new arrows. We can define two types of %D arrows|<|single arrows and double arrows. Single arrows are defined %D 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 %D this case.) The second argument consists of a set of 4 numbers and %D specify the spacing correction in math units~\type{mu}. These %D 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 %D argument is optional when the arrow is redefined later (this is %D useful for font specific tweaking of the 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 %D separated values. The first element of the second argument %D (\type{3095}) corresponds to the spacing correction of top arrow %D fill (\tex{rightarrowupfill}). Similarly, \type{0359} corresponds %D to bottom arrow fill \tex{leftharpoondownfill}). Stacking them on %D top of each other we get $\xrightleftharpoons[big]{above}{below}$. %D The 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} \def\definematharrow {\doquadrupleargument\dodefinematharrow} \def\dodefinematharrow[#1][#2][#3][#4]% name type[none|both] template command {\iffourthargument \executeifdefined{dodefine#2arrow}\gobblethreearguments{#1}{#3}{#4}% \else\ifthirdargument \dodefinebotharrow{#1}{#2}{#3}% \else\ifsecondargument \redefinebotharrow{#1}{#2}{#3}% \fi\fi\fi} \def\redefinebotharrow#1#2#3% real dirty, this overload! {\doifdefined{#1} {\pushmacro\dohandlemtharrow \def\dohandlemtharrow[##1][##2]{\setvalue{#1}{\dohandlemtharrow[#2][##2]}}% % == \def\dohandlemtharrow[##1][##2]{\dodefinebotharrow{#1}{#2}{##2}}% \getvalue{#1}% \popmacro\dohandlemtharrow}} \def\dodefinebotharrow#1#2#3% {\setvalue{#1}{\dohandlemtharrow[#2][#3]}} \def\dohandlemtharrow {\dotripleempty\doxmtharrow} \def\doxmtharrow[#1][#2][#3]% #3 == optional arg {\def\dodoxmtharrow{\dododoxmtharrow[#1,\empty,\empty][#2,\empty,\empty][#3]}% {##1}{##2} \dodoublegroupempty\dodoxmtharrow} \def\dododoxmtharrow[#1,#2,#3][#4,#5,#6][#7]#8#9% [3] is the optional arg {\edef\!!stringa{#2}% \ifx\!!stringa\empty \ifsecondargument \mathrel{\domthxarrsingle{#7}{#1}{#4}{#8}{#9}}% \else \mathrel{\domthxarrsingle{#7}{#1}{#4}{}{#8}}% \fi \else \ifsecondargument \mathrel{\domthxarrdouble{#7}{#1}{#2}{#4}{#5}{#8}{#9}}% \else \mathrel{\domthxarrdouble{#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 %D fill}. This command takes 8 arguments: the first four correspond %D the second argument of \tex{definematharrow} explained above. The %D other three specify the tail, body and head of the arrow. The last %D argument specifies the math-mode in which the arrow is drawn. %D \tex{defaultmtharrowfill} has values tweaked to match Latin Modern %D 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% {$\mathsurround 0pt \thickmuskip0mu\medmuskip\thickmuskip\thinmuskip\thickmuskip \relax#8#5% \mkern-#1mu \cleaders\hbox{$#8\mkern -#2mu#6\mkern -#3mu$}\hfill \mkern-#4mu#7$} \def\defaultmtharrowfill{\mtharrowfill 7227} %D We now define some arrow fills that will be used for defining the %D arrows. Plain \TEX\ already defines \tex{leftarrowfill} and %D \tex{rightarrowfill}. The \tex{defaultmtharrowfill} command defines an %D arrowfill that takes an argument (so that it can also be used %D with over and under arrows). However the Plain \TEX\ definitions of %D \tex{leftarrowfill} and \tex{rightarrowfill} do not take this extra %D argument. To be backward compatible with Plain \TEX, we define two %D arrowfills: \tex{specrightarrowfill} which takes an extra argument, and %D \tex{rightarrowfill} which does not. \def\specrightarrowfill {\defaultmtharrowfill \relbar \relbar \rightarrow} \def\specleftarrowfill {\defaultmtharrowfill \leftarrow \relbar \relbar} \def\rightarrowfill {\specrightarrowfill \textstyle} \def\leftarrowfill {\specleftarrowfill \textstyle} \def\equalfill {\defaultmtharrowfill \Relbar \Relbar \Relbar} \def\Rightarrowfill {\defaultmtharrowfill \Relbar \Relbar \Rightarrow} \def\Leftarrowfill {\defaultmtharrowfill \Leftarrow \Relbar \Relbar} \def\Leftrightarrowfill {\defaultmtharrowfill \Leftarrow \Relbar \Rightarrow} \def\leftrightarrowfill {\defaultmtharrowfill \leftarrow \relbar \rightarrow} \def\mapstofill {\defaultmtharrowfill{\mapstochar\relbar} \relbar \rightarrow} \def\twoheadrightarrowfill{\defaultmtharrowfill \relbar \relbar \twoheadrightarrow} \def\twoheadleftarrowfill {\defaultmtharrowfill \twoheadleftarrow \relbar \relbar} \def\rightharpoondownfill {\defaultmtharrowfill \relbar \relbar \rightharpoondown} \def\rightharpoonupfill {\defaultmtharrowfill \relbar \relbar \rightharpoonup} \def\leftharpoondownfill {\defaultmtharrowfill \leftharpoondown \relbar \relbar} \def\leftharpoonupfill {\defaultmtharrowfill \leftharpoonup \relbar \relbar} \def\hookleftfill {\defaultmtharrowfill \leftarrow \relbar{\relbar\joinrel\rhook}} \def\hookrightfill {\defaultmtharrowfill{\lhook\joinrel\relbar}\relbar \rightarrow} \def\relfill {\defaultmtharrowfill \relbar \relbar \relbar} \def\triplerelbar {\mathrel\equiv} \def\triplerelfill{\defaultmtharrowfill\triplerelbar\triplerelbar\triplerelbar} \def\singlebond{{\xrel}} % or \def\singlebond{{\xrel[2]}} \def\doublebond{{\xequal}} \def\triplebond{{\xtriplerel}} %D Now we define most commonly used arrows. These include arrows %D defined in \filename{amsmath.sty}, \filename{extarrows.sty}, %D \filename{extpfel.sty} and \filename{mathtools.sty} packages for %D \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 %D \filename{amsmath.sty} \def\definemathoverarrow {\dotripleargument\dodefinemathoverarrow} \def\dodefinemathoverarrow[#1][#2][#3]% {\ifthirdargument \setvalue{#1}{\dohandlemathoverarrow[#2][#3]}% \else \setvalue{#1}{\dohandlemathoverarrow[\zeropoint][#2]}% \fi} \def\dohandlemathoverarrow[#1][#2]% {\mathpalette{\dodohandlemathoverarrow{#1}{#2}}} %D Note: \filename{math-pln.tex} has \type{\kern-\onepoint} and %D \filename{amsmath.sty} does not. We keep the kern amount %D configurable. This is useful for harpoons. \def\dodohandlemathoverarrow#1#2#3#4% {\vbox{\ialign{##\crcr #2#3\crcr \noalign{\kern#1\nointerlineskip}% $\mathsurround\zeropoint\hfil#3#4\hfil$\crcr}}} %D Now the under arrows \def\definemathunderarrow {\dotripleargument\dodefinemathunderarrow} %D For underarrows the default kern is 0.3ex \def\dodefinemathunderarrow[#1][#2][#3]% {\ifthirdargument \setvalue{#1}{\dohandlemathunderarrow[#2][#3]}% \else \setvalue{#1}{\dohandlemathunderarrow[0.3ex][#2]}% \fi} \def\dohandlemathunderarrow[#1][#2]% {\mathpalette{\dodohandlemathunderarrow{#1}{#2}}} \def\dodohandlemathunderarrow#1#2#3#4% {\vtop{\ialign{##\crcr $\mathsurround\zeropoint\hfil#3#4\hfil$\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