%D \module %D [ file=math-ext, %D version=2006.01.14, %D title=\CONTEXT\ Math Macros, %D subtitle=Extra Macros, %D author={Hans Hagen \& Taco Hoekwater \& Aditya Mahajan}, %D date=\currentdate, %D copyright=\PRAGMA] %C %C This module is part of the \CONTEXT\ macro||package and is %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. \unprotect %D These will be generalized! \def\exmthfont#1{\symbolicsizedfont#1\plusone{MathExtension}} \def\domthfrac#1#2#3#4#5#6#7% {\begingroup \mathsurround\zeropoint \setbox0\hbox{$#1 #6$}% \setbox2\hbox{$#1 #7$}% \dimen0\wd0 \ifdim\wd2>\dimen0 \dimen0\wd2 \fi \setbox4\hbox to \dimen0{\exmthfont#2#3\leaders\hbox{#4}\hss#5}% \mathord{\vcenter{{\offinterlineskip \hbox to \dimen0{\hss\box0\hss}% \kern \ht4% \hbox to \dimen0{\hss\copy4\hss}% \kern \ht4% \hbox to \dimen0{\hss\box2\hss}}}}% \endgroup} \def\domthsqrt#1#2#3#4#5% {\begingroup \mathsurround\zeropoint \setbox0\hbox{$#1 #5$}% \dimen0=1.05\ht0 \advance\dimen0 1pt \ht0 \dimen0 \dimen0=1.05\dp0 \advance\dimen0 1pt \dp0 \dimen0 \dimen0\wd0 \setbox4\hbox to \dimen0{\exmthfont#2\leaders\hbox{#3}\hfill#4}% \delimitershortfall=0pt \nulldelimiterspace=0pt \setbox2\hbox{$\left\delimiter"0270370 \vrule height\ht0 depth \dp0 width0pt \right.$}% \mathord{\vcenter{\hbox{\copy2 \rlap{\raise\dimexpr\ht2-\ht4\relax\copy4}\copy0}}}% \endgroup} \def\mthfrac#1#2#3#4#5{\mathchoice {\domthfrac\displaystyle \textface {#1}{#2}{#3}{#4}{#5}} {\domthfrac\textstyle \textface {#1}{#2}{#3}{#4}{#5}} {\domthfrac\scriptstyle \scriptface {#1}{#2}{#3}{#4}{#5}} {\domthfrac\scriptscriptstyle\scriptscriptface{#1}{#2}{#3}{#4}{#5}}} \def\mthsqrt#1#2#3{\mathchoice {\domthsqrt\displaystyle \textface {#1}{#2}{#3}} {\domthsqrt\textstyle \textface {#1}{#2}{#3}} {\domthsqrt\scriptstyle \textface {#1}{#2}{#3}} {\domthsqrt\scriptscriptstyle\textface {#1}{#2}{#3}}} % temp here %D We next define extensible arrows. Extensible arrows are arrows that change %D their length accoding to the width of the text to be placed above and below %D the arrow. Since we need to define a lot of arrows, we first define some %D helper macros. The basic idea is to measure the width of the box to be %D placed above and below the arrow, and make the \quotation{body} of the %D arrow as long as the bigger of the 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}% \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}% \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.22ex\relax \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 Macro for defining new arrows. We can define two types of arrows|<|single %D arrows and double arrows. Single arrows are defined as %D \starttyping %D \definematharrow [xrightarrow] [0359] [\rightarrowfill] %D \stoptyping %D The first argument is the name of the arrow (\tex{xrightarrow} in this case.) %D The second argument consists of a set of 4 numbers and specify the spacing %D correction in math units~\type{mu}. These numbers define: %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 %D is optional when the arrow is redefined later (this is useful for font %D specific tweaking of the skips.) For example, %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 \starttyping %D \definematharrow [xrightleftharpoons] [3095,0359] %D [\rightharpoonupfill,\leftharpoondownfill] %D \stoptyping %D The second and the third set of arguments consist of comma separated %D values. The first element of the second argument (\type{3095}) corresponds %D to the spacing correction of top arrow fill (\tex{rightarrowupfill}). %D Similarly, \type{0359} corresponds to bottom arrow fill %D \tex{leftharpoondownfill}). Stacking them on top of each other we get %D $\xrightleftharpoons[big]{above}{below}$. %D The following math arrows are defined %D \midaligned{\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 To extend the arrows we need to define a \quotation{math arrow fill}. This %D command takes 7 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. \tex{defaultmtharrowfill} has values tweaked to %D match latin modern fonts. For fonts that are significantly different (e.g. %D cows) a different set of values need to be determined. \def\mtharrowfill#1#2#3#4#5#6#7% {$\mathsurround 0pt \thickmuskip0mu\medmuskip\thickmuskip\thinmuskip\thickmuskip \relax#5% \mkern-#1mu \cleaders\hbox{$\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 arrows. %D \tex{leftarrowfill} and \tex{rightarrowfill} are redefined using \tex{defaultmtharrowfill}. \def\rightarrowfill {\defaultmtharrowfill \relbar \relbar \rightarrow } \def\leftarrowfill {\defaultmtharrowfill \leftarrow \relbar \relbar } \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} %D Now we define most commonly used arrows. These include arrows defined in %D \filename{amsmath.sty}, \filename{extarrows.sty}, \filename{extpfel.sty} %D and mathtools.sty packages for \LATEX. \definematharrow [xrightarrow] [0359] [\rightarrowfill] \definematharrow [xleftarrow] [3095] [\leftarrowfill] \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 [xleftrightharpoons] [3399,3399] [\leftharpoonupfill,\rightharpoondownfill] \definematharrow [xrightleftharpoons] [3399,3399] [\rightharpoonupfill,\leftharpoondownfill] \definematharrow [xhookleftarrow] [3095] [\hookleftfill] \definematharrow [xhookrightarrow] [0395] [\hookrightfill] %D These arrows can be used as folows: %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 \typebuffer which gives \getbuffer \protect \endinput