summaryrefslogtreecommitdiff
path: root/tex/context/base/mkiv/math-arr.mkiv
diff options
context:
space:
mode:
Diffstat (limited to 'tex/context/base/mkiv/math-arr.mkiv')
-rw-r--r--tex/context/base/mkiv/math-arr.mkiv446
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