diff options
Diffstat (limited to 'tex/context/base/mkiv/math-arr.mkiv')
-rw-r--r-- | tex/context/base/mkiv/math-arr.mkiv | 446 |
1 files changed, 446 insertions, 0 deletions
diff --git a/tex/context/base/mkiv/math-arr.mkiv b/tex/context/base/mkiv/math-arr.mkiv new file mode 100644 index 000000000..9056bf5a4 --- /dev/null +++ b/tex/context/base/mkiv/math-arr.mkiv @@ -0,0 +1,446 @@ +%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 + \def\m_math_arrows_factor{1}% + \def\m_math_arrows_extra {0}% + \edef\p_math_spacing{#1}% + \csname\??matharrowsettings + \ifcsname\??matharrowsettings\p_math_spacing\endcsname\p_math_spacing\else\s!unknown\fi + \endcsname + \mathsurround\zeropoint + \muskip0=\muexpr\m_math_arrows_factor\muexpr\thirdoffourarguments #2\onemuskip\relax+\m_math_arrows_extra\onemuskip+\firstoffourarguments #2\onemuskip\relax + \muskip2=\muexpr\m_math_arrows_factor\muexpr\fourthoffourarguments#2\onemuskip\relax+\m_math_arrows_extra\onemuskip+\secondoffourarguments#2\onemuskip\relax + \setbox0\hbox{$\scriptstyle + \mkern\muskip0\relax + #5\relax + \mkern\muskip2\relax + $}% + \setbox2\hbox{$\scriptstyle + \mkern\muskip0\relax + #4\relax + \mkern\muskip2\relax + $}% + \setbox4\hbox{#3\displaystyle}% + \dimen0\wd0\relax + \ifdim\wd2>\dimen0 + \dimen0\wd2\relax + \fi + \ifdim\wd4>\dimen0 + \dimen0\wd4\relax + \fi + \ifdim\wd4=\dimen0\else + \setbox4\hbox to \dimen0{#3\displaystyle}% + \fi + \mathrel{\mathop{\hbox to \dimen0{\hss\copy4\hss}}\limits\normalsuperscript{\box0}\normalsubscript{\box2}}% + \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 + \setbox0\hbox{$\math_arrows_construct{#1}{#2}{#4}{\phantom{#6}}{#7}$}% + \setbox2\hbox{$\math_arrows_construct{#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 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% + {$\mathsurround\zeropoint + \thickmuskip\zeromuskip\medmuskip\thickmuskip\thinmuskip\thickmuskip + \relax#8#5% + \mkern-#1\onemuskip + \cleaders\hbox{$#8\mkern-#2\onemuskip#6\mkern-#3\onemuskip$}\hfill + \mkern-#4\onemuskip#7$} + +\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{##\crcr + #2#3\crcr + \noalign{\kern#1\nointerlineskip}% + $\mathsurround\zeropoint\hfil#3#4\hfil$\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{##\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 |