math-arr.mkiv /size: 19 Kb    last modification: 2020-07-01 14:35
 1%D \module 2%D [ file=math-arr, 3%D version=2007.07.19, 4%D title=\CONTEXT\ Math Macros, 5%D subtitle=Arrows, 6%D author={Hans Hagen \& Taco Hoekwater \& Aditya Mahajan}, 7%D date=\currentdate, 8%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] 9%C 10%C This module is part of the \CONTEXT\ macro||package and is 11%C therefore copyrighted by \PRAGMA. See mreadme.pdf for 12%C details. 13 14%D We keep this file around as reference of his things were done in the 15%D past. You can still load this module but it has been replaced by more 16%D modern code. 17 18\writestatus{loading}{ConTeXt Math Macros / Arrows} 19 20\unprotect 21 22%D These will be generalized! Is it still needed in \MKIV? Also, we need to 23%D to it using regular opentype math! 24 25% Plain code: 26% 27% \def\rightarrowfill 28% {$% 29% \mathsurround\zeropoint 30% \smash-% 31% \mkern-7mu% 32% \cleaders\hbox{$\mkern-2mu\smash-\mkern-2mu$}\hfill 33% \mkern-7mu% 34% \mathord\rightarrow 35%$} 36% 37% \def\leftarrowfill % brrr no longer in luatex 38% {$% 39% \mathsurround\zeropoint 40% \mathord\leftarrow 41% \mkern-7mu% 42% \cleaders\hbox{$\mkern-2mu\smash-\mkern-2mu$}\hfill 43% \mkern-7mu 44% \smash-% 45%$} 46 47%D Extensible arrows are arrows that change their length according to the width of 48%D the text to be placed above and below the arrow. 49%D 50%D Since we need to define a lot of arrows, we first define some helper macros. The 51%D basic idea is to measure the width of the box to be placed above and below the 52%D arrow, and make the \quote {body} of the arrow as long as the bigger of the two 53%D widths. 54 55\installcorenamespace{matharrowsettings} 56 57\def\m_math_arrows_factor{1} 58\def\m_math_arrows_extra {0} 59 60\setvalue{\??matharrowsettings\v!none }{\def\m_math_arrows_factor{0}} 61\setvalue{\??matharrowsettings\v!small }{\def\m_math_arrows_extra{10}} 62\setvalue{\??matharrowsettings\v!medium }{\def\m_math_arrows_extra{15}} 63\setvalue{\??matharrowsettings\v!big }{\def\m_math_arrows_extra{20}} 64\setvalue{\??matharrowsettings\v!normal }{} 65\setvalue{\??matharrowsettings }{} 66\setvalue{\??matharrowsettings\s!unknown}{\doifelsenumber\p_math_spacing{\let\m_math_arrows_extra\p_math_spacing}\donothing} 67 68\def\math_arrows_construct#1#2#3#4#5% hm, looks like we do a double mathrel (a bit cleaned up .. needs checking) 69 {\begingroup 70 \let\m_math_arrows_factor\!!plusone 71 \let\m_math_arrows_extra \!!zerocount 72 \edef\p_math_spacing{#1}% 73 \csname\??matharrowsettings 74 \ifcsname\??matharrowsettings\p_math_spacing\endcsname\p_math_spacing\else\s!unknown\fi 75 \endcsname 76 \mathsurround\zeropoint 77 \scratchmuskipone\muexpr\m_math_arrows_factor\muexpr\thirdoffourarguments #2\onemuskip\relax+\m_math_arrows_extra\onemuskip+\firstoffourarguments #2\onemuskip\relax 78 \scratchmuskiptwo\muexpr\m_math_arrows_factor\muexpr\fourthoffourarguments#2\onemuskip\relax+\m_math_arrows_extra\onemuskip+\secondoffourarguments#2\onemuskip\relax 79 \setbox\scratchboxone\hbox 80 {\normalstartimath 81 \scriptstyle 82 \mkern\scratchmuskipone\relax 83 #5\relax 84 \mkern\scratchmuskiptwo\relax 85 \normalstopimath}% 86 \setbox\scratchboxtwo\hbox 87 {\normalstartimath 88 \scriptstyle 89 \mkern\scratchmuskipone\relax 90 #4\relax 91 \mkern\scratchmuskiptwo\relax 92 \normalstopimath}% 93 \setbox\scratchboxthree\hbox{#3\displaystyle}% 94 \scratchdimenone\wd\scratchboxone\relax 95 \ifdim\wd\scratchboxtwo>\scratchdimenone 96 \scratchdimenone\wd\scratchboxtwo\relax 97 \fi 98 \ifdim\wd\scratchboxthree>\scratchdimenone 99 \scratchdimenone\wd\scratchboxthree\relax 100 \fi 101 \ifdim\wd\scratchboxthree=\scratchdimenone\else 102 \setbox\scratchboxthree\hbox to \scratchdimenone{#3\displaystyle}% 103 \fi 104 \mathrel 105 {\mathop 106 {\hpack to \scratchdimenone{\hss\box\scratchboxthree\hss}}% pack ? copy ? 107 \limits 108 \normalsuperscript{\box\scratchboxone}% 109 \normalsubscript {\box\scratchboxtwo}}% 110 \endgroup} 111 112\let\math_arrows_construct_single\math_arrows_construct 113 114%D There are some arrows which are created by stacking two arrows. The next 115%D macro helps in defining such \quotation{double arrows}. 116 117% weird, we get a shift with the double ... but will become core luatex anyway 118% 119% \startchemicalformula 120% \chemical{S} 121% \chemical{+} 122% \chemical{O_2} 123% \chemical{EQUILIBRIUM}{boven}{onder} 124% \chemical{SO_2} 125% \stopchemicalformula 126 127\def\math_arrows_construct_double#1#2#3#4#5#6#7% opt l r sp rs top bot 128 {\mathrel 129 {\scratchdimen.32\exheight\relax % was .22, todo: make configurable 130 \setbox\scratchboxone\hbox{\normalstartimath\math_arrows_construct{#1}{#2}{#4}{\phantom{#6}}{#7}\normalstopimath}% 131 \setbox\scratchboxtwo\hbox{\normalstartimath\math_arrows_construct{#1}{#3}{#5}{#6}{\phantom{#7}}\normalstopimath}% 132 \raise\scratchdimen\box\scratchboxone 133 \kern-\wd\scratchboxtwo 134 \lower\scratchdimen\box\scratchboxtwo}} 135 136%D \macros{definematharrow} 137%D 138%D Macro for defining new arrows. We can define two types of arrows|<|single arrows 139%D and double arrows. Single arrows are defined as 140%D 141%D \starttyping 142%D \definematharrow [xrightarrow] [0359] [\rightarrowfill] 143%D \stoptyping 144%D 145%D The first argument is the name of the arrow (\tex {xrightarrow} in this case.) The 146%D second argument consists of a set of 4 numbers and specify the spacing correction 147%D in math units~\type {mu}. These numbers define: 148%D 149%D \startlines 150%D 1st number: arrow||tip correction 151%D 2nd number: arrow||tip correction 152%D 3rd number: space (multiplied by \tex{matharrfactor} and advanced by \tex{matharrextra}) 153%D 4th number: space (multiplied by \tex{matharrfactor} and advanced by \tex{matharrextra}) 154%D \stoplines 155%D 156%D The third argument is the name of the extensible fill. The third argument is optional 157%D when the arrow is redefined later (this is useful for font specific tweaking of the 158%D skips.) For example, 159%D 160%D \startbuffer 161%D \math{\xrightarrow{above}} 162%D \definematharrow[xrightarrow][0000] 163%D \math{\xrightarrow{above}} 164%D \definematharrow[xrightarrow][55{50}{50}] 165%D \math{\xrightarrow{above}} 166%D \stopbuffer 167%D \typebuffer gives {\getbuffer} 168%D 169%D The double arrows are defined as follows 170%D 171%D \starttyping 172%D \definematharrow [xrightleftharpoons] [3095,0359] 173%D [\rightharpoonupfill,\leftharpoondownfill] 174%D \stoptyping 175%D 176%D The second and the third set of arguments consist of comma separated values. The 177%D first element of the second argument (\type {3095}) corresponds to the spacing 178%D correction of top arrow fill (\tex{rightarrowupfill}). Similarly, \type {0359} 179%D corresponds to bottom arrow fill \tex {leftharpoondownfill}). Stacking them on 180%D top of each other we get $\xrightleftharpoons [big] {above} {below}$. The 181%D following math arrows are defined 182%D 183%D \placetable[none]{}{\starttable[|l|m|] 184%D \NC \tex{xrightarrow} \NC \xrightarrow [big] \NC \NR 185%D \NC \tex{xleftarrow} \NC \xleftarrow [big] \NC \NR 186%D \NC \tex{xequal} \NC \xequal [big] \NC \NR 187%D \NC \tex{xRightarrow} \NC \xRightarrow [big] \NC \NR 188%D \NC \tex{xLeftarrow} \NC \xLeftarrow [big] \NC \NR 189%D \NC \tex{xLeftrightarrow} \NC \xLeftrightarrow [big] \NC \NR 190%D \NC \tex{xleftrightarrow} \NC \xleftrightarrow [big] \NC \NR 191%D \NC \tex{xmapsto} \NC \xmapsto [big] \NC \NR 192%D \NC \tex{xtwoheadrightarrow} \NC \xtwoheadrightarrow [big] \NC \NR 193%D \NC \tex{xtwoheadleftarrow} \NC \xtwoheadleftarrow [big] \NC \NR 194%D \NC \tex{xrightharpoondown} \NC \xrightharpoondown [big] \NC \NR 195%D \NC \tex{xrightharpoonup} \NC \xrightharpoonup [big] \NC \NR 196%D \NC \tex{xleftharpoondown} \NC \xleftharpoondown [big] \NC \NR 197%D \NC \tex{xleftharpoonup} \NC \xleftharpoonup [big] \NC \NR 198%D \NC \tex{xhookleftarrow} \NC \xhookleftarrow [big] \NC \NR 199%D \NC \tex{xhookrightarrow} \NC \xhookrightarrow [big] \NC \NR 200%D \NC \tex{xleftrightharpoons} \NC \xleftrightharpoons [big] \NC \NR 201%D \NC \tex{xrightleftharpoons} \NC \xrightleftharpoons [big] \NC \NR 202%D \stoptable} 203 204%D If needed this can be optimized (i.e. we can preexpand using \type 205%D {\docheckedpair}). 206 207\unexpanded\def\definematharrow 208 {\doquadrupleargument\math_arrows_define} 209 210\def\math_arrows_define[#1][#2][#3][#4]% name type[none|both] template command 211 {\iffourthargument 212 \executeifdefined{math_arrows_define_#2}\gobblethreearguments{#1}{#3}{#4}% 213 \else\ifthirdargument 214 \math_arrows_define_both{#1}{#2}{#3}% 215 \else\ifsecondargument 216 \math_arrows_define_both_again{#1}{#2}{#3}% 217 \fi\fi\fi} 218 219\def\math_arrows_define_both_again#1#2#3% real dirty, this overload! 220 {\ifcsname#1\endcsname 221 \pushmacro\math_arrows_do 222 \def\math_arrows_do[##1][##2]{\setuvalue{#1}{\math_arrows_do[#2][##2]}}% 223 \csname#1\endcsname 224 \popmacro\math_arrows_do 225 \fi} 226 227\def\math_arrows_define_both#1#2#3% 228 {\setuvalue{#1}{\math_arrows_do[#2][#3]}} 229 230\unexpanded\def\math_arrows_do 231 {\doquadrupleempty\math_arrows_handle} 232 233\def\math_arrows_handle[#1][#2][#3][#4]% #3 == optional arg .. \empty can be just 'empty' [#4] gobbles spaces 234 {\def\math_arrows_handle_indeed{\math_arrows_handle_finalize[#1,\empty,\empty][#2,\empty,\empty][#3]}% {##1}{##2} 235 \dodoublegroupempty\math_arrows_handle_indeed} 236 237\def\math_arrows_handle_finalize[#1,#2,#3][#4,#5,#6][#7]#8#9% [#7] is the optional arg 238 {\edef\!!stringa{#2}% 239 \ifx\!!stringa\empty 240 \ifsecondargument 241 \mathrel{\math_arrows_construct_single{#7}{#1}{#4}{#8}{#9}}% 242 \else 243 \mathrel{\math_arrows_construct_single{#7}{#1}{#4}{}{#8}}% 244 \fi 245 \else 246 \ifsecondargument 247 \mathrel{\math_arrows_construct_double{#7}{#1}{#2}{#4}{#5}{#8}{#9}}% 248 \else 249 \mathrel{\math_arrows_construct_double{#7}{#1}{#2}{#4}{#5}{}{#8}}% 250 \fi 251 \fi} 252 253% Adapted from amsmath. 254 255%D \macros{mtharrowfill,defaultmtharrowfill} 256%D 257%D To extend the arrows we need to define a \quotation {math arrow fill}. This 258%D command takes 8 arguments: the first four correspond the second argument of 259%D \tex {definematharrow} explained above. The other three specify the tail, 260%D body and head of the arrow. The last argument specifies the math-mode in which 261%D the arrow is drawn. \tex {defaultmtharrowfill} has values tweaked to match 262%D Latin Modern fonts. For fonts that are significantly different (e.g. cows) a 263%D different set of values need to be determined. 264 265\def\mtharrowfill#1#2#3#4#5#6#7#8% 266 {\normalstartimath 267 \mathsurround\zeropoint 268 \thickmuskip\zeromuskip\medmuskip\thickmuskip\thinmuskip\thickmuskip 269 \relax#8#5% 270 \mkern-#1\onemuskip 271 \cleaders\hbox{\normalstartimath#8\mkern-#2\onemuskip#6\mkern-#3\onemuskip\normalstopimath}\hfill 272 \mkern-#4\onemuskip#7% 273 \normalstopimath} 274 275\def\defaultmtharrowfill{\mtharrowfill 7227} 276 277%D We now define some arrow fills that will be used for defining the arrows. Plain 278%D \TEX\ already defines \tex {leftarrowfill} and \tex {rightarrowfill}. The \tex 279%D {defaultmtharrowfill} command defines an arrowfill that takes an argument (so 280%D that it can also be used with over and under arrows). However the Plain \TEX\ 281%D definitions of \tex {leftarrowfill} and \tex {rightarrowfill} do not take this 282%D extra argument. To be backward compatible with Plain \TEX, we define two 283%D arrowfills: \tex {specrightarrowfill} which takes an extra argument, and \tex 284%D {rightarrowfill} which does not. 285 286\unexpanded\def\specrightarrowfill {\defaultmtharrowfill \relbar \relbar \rightarrow} 287\unexpanded\def\specleftarrowfill {\defaultmtharrowfill \leftarrow \relbar \relbar} 288 289\unexpanded\def\rightarrowfill {\specrightarrowfill\textstyle} 290\unexpanded\def\leftarrowfill {\specleftarrowfill \textstyle} 291 292\unexpanded\def\equalfill {\defaultmtharrowfill \Relbar \Relbar \Relbar} 293\unexpanded\def\Rightarrowfill {\defaultmtharrowfill \Relbar \Relbar \Rightarrow} 294\unexpanded\def\Leftarrowfill {\defaultmtharrowfill \Leftarrow \Relbar \Relbar} 295\unexpanded\def\Leftrightarrowfill {\defaultmtharrowfill \Leftarrow \Relbar \Rightarrow} 296\unexpanded\def\leftrightarrowfill {\defaultmtharrowfill \leftarrow \relbar \rightarrow} 297\unexpanded\def\mapstofill {\defaultmtharrowfill{\mapstochar\relbar} \relbar \rightarrow} 298\unexpanded\def\twoheadrightarrowfill{\defaultmtharrowfill \relbar \relbar \twoheadrightarrow} 299\unexpanded\def\twoheadleftarrowfill {\defaultmtharrowfill \twoheadleftarrow \relbar \relbar} 300\unexpanded\def\rightharpoondownfill {\defaultmtharrowfill \relbar \relbar \rightharpoondown} 301\unexpanded\def\rightharpoonupfill {\defaultmtharrowfill \relbar \relbar \rightharpoonup} 302\unexpanded\def\leftharpoondownfill {\defaultmtharrowfill \leftharpoondown \relbar \relbar} 303\unexpanded\def\leftharpoonupfill {\defaultmtharrowfill \leftharpoonup \relbar \relbar} 304\unexpanded\def\hookleftfill {\defaultmtharrowfill \leftarrow \relbar{\relbar\joinrel\rhook}} 305\unexpanded\def\hookrightfill {\defaultmtharrowfill{\lhook\joinrel\relbar}\relbar \rightarrow} 306\unexpanded\def\relfill {\defaultmtharrowfill \relbar \relbar \relbar} 307 308\unexpanded\def\triplerelbar {\mathrel\equiv} 309\unexpanded\def\triplerelfill{\defaultmtharrowfill\triplerelbar\triplerelbar\triplerelbar} 310 311\unexpanded\def\singlebond{{\xrel}} % or \def\singlebond{{\xrel[2]}} 312\unexpanded\def\doublebond{{\xequal}} 313\unexpanded\def\triplebond{{\xtriplerel}} 314 315%D A bit or arrow juggling: 316%D 317%D \startbuffer 318%D \hbox to \hsize{\rightoverleftarrowfill} 319%D \stopbuffer 320%D 321%D \typebuffer \blank \getbuffer \blank 322 323\unexpanded\def\rightoverleftarrowfill 324 {\specrightoverleftarrowfill} 325 326\unexpanded\def\specrightoverleftarrowfill 327 {\defaultmtharrowfill 328 \ctxdoublearrowfillleftend 329 \ctxdoublearrowfillmiddlepart 330 \ctxdoublearrowfillrightend 331 \textstyle} 332 333%D Now we define most commonly used arrows. These include arrows defined in \filename 334%D {amsmath.sty}, \filename {extarrows.sty}, \filename {extpfel.sty} and \filename 335%D {mathtools.sty} packages for \LATEX\ (plus a few more). 336 337\definematharrow [xrightarrow] [0359] [\specrightarrowfill] 338\definematharrow [xleftarrow] [3095] [\specleftarrowfill] 339\definematharrow [xequal] [0099] [\equalfill] 340\definematharrow [xRightarrow] [0359] [\Rightarrowfill] 341\definematharrow [xLeftarrow] [3095] [\Leftarrowfill] 342\definematharrow [xLeftrightarrow] [0099] [\Leftrightarrowfill] 343\definematharrow [xleftrightarrow] [0099] [\leftrightarrowfill] 344\definematharrow [xmapsto] [3599] [\mapstofill] 345\definematharrow [xtwoheadrightarrow] [5009] [\twoheadrightarrowfill] 346\definematharrow [xtwoheadleftarrow] [0590] [\twoheadleftarrowfill] 347\definematharrow [xrightharpoondown] [0359] [\rightharpoondownfill] 348\definematharrow [xrightharpoonup] [0359] [\rightharpoonupfill] 349\definematharrow [xleftharpoondown] [3095] [\leftharpoondownfill] 350\definematharrow [xleftharpoonup] [3095] [\leftharpoonupfill] 351\definematharrow [xhookleftarrow] [3095] [\hookleftfill] 352\definematharrow [xhookrightarrow] [0395] [\hookrightfill] 353\definematharrow [xrel] [0099] [\relfill] 354\definematharrow [xtriplerel] [0099] [\triplerelfill] 355\definematharrow [xrightoverleftarrow] [0359,3095] [\specrightarrowfill,\specleftarrowfill] 356\definematharrow [xleftrightharpoons] [3399,3399] [\leftharpoonupfill,\rightharpoondownfill] 357\definematharrow [xrightleftharpoons] [3399,3399] [\rightharpoonupfill,\leftharpoondownfill] 358 359%D These arrows can be used as follows: 360%D 361%D \startbuffer 362%D \startformula \xrightarrow{stuff on top}\stopformula 363%D \startformula \xrightarrow{}{stuff on top}\stopformula 364%D \startformula \xrightarrow{stuff below}{}\stopformula 365%D \startformula \xrightarrow{stuff below}{stuff on top}\stopformula 366%D 367%D \startformula \xleftarrow [none]{stuff below}{stuff on top}\stopformula 368%D \startformula \xleftarrow [small]{stuff below}{stuff on top}\stopformula 369%D \startformula \xleftarrow [medium]{stuff below}{stuff on top}\stopformula 370%D \startformula \xleftarrow [big]{stuff below}{stuff on top}\stopformula 371%D \stopbuffer 372%D 373%D \typebuffer which gives \getbuffer 374 375%D \macros{definemathoverarrow,defineunderarrow} 376%D 377%D These macros for define math-overarrows are adapted from \filename {amsmath.sty} 378 379\unexpanded\def\definemathoverarrow 380 {\dotripleargument\math_arrows_define_over} 381 382\def\math_arrows_define_over[#1][#2][#3]% 383 {\ifthirdargument 384 \setuvalue{#1}{\math_arrows_over_handle[#2][#3]}% 385 \else 386 \setuvalue{#1}{\math_arrows_over_handle[\zeropoint][#2]}% 387 \fi} 388 389\def\math_arrows_over_handle[#1][#2]% 390 {\mathpalette{\math_arrows_over_handle_indeed{#1}{#2}}} 391 392%D Note: \filename {math-pln.tex} has \type {\kern-\onepoint} and \filename 393%D {amsmath.sty} does not. We keep the kern amount configurable. This is useful 394%D for harpoons. 395 396\def\math_arrows_over_handle_indeed#1#2#3#4% 397 {\vbox{\ialign{% 398 \alignmark\alignmark 399 \crcr 400 #2#3% 401 \crcr 402 \noalign{\kern#1\nointerlineskip}% 403 \normalstartimath 404 \mathsurround\zeropoint\hfil#3#4\hfil 405 \normalstopimath 406 \crcr 407 }}} 408 409%D Now the under arrows 410 411\unexpanded\def\definemathunderarrow 412 {\dotripleargument\math_arrows_define_under} 413 414%D For underarrows the default kern is 0.3ex 415 416\def\math_arrows_define_under[#1][#2][#3]% 417 {\ifthirdargument 418 \setuvalue{#1}{\math_arrows_under_handle[#2][#3]}% 419 \else 420 \setuvalue{#1}{\math_arrows_under_handle[0.3ex][#2]}% 421 \fi} 422 423\def\math_arrows_under_handle[#1][#2]% 424 {\mathpalette{\math_arrows_under_handle_indeed{#1}{#2}}} 425 426\def\math_arrows_under_handle_indeed#1#2#3#4% 427 {\vtop{\ialign{% 428 \alignmark\alignmark 429 \crcr 430 \normalstartimath\mathsurround\zeropoint\hfil#3#4\hfil\normalstopimath 431 \crcr 432 \noalign{\nointerlineskip\kern#1}% 433 #2#3% 434 \crcr 435 }}} 436 437%D Now we define the arrows 438 439\definemathoverarrow [overleftarrow] [\specleftarrowfill] 440\definemathoverarrow [overrightarrow] [\specrightarrowfill] 441\definemathoverarrow [overleftrightarrow] [\leftrightarrowfill] 442\definemathoverarrow [overtwoheadrightarrow] [\twoheadrightarrowfill] 443\definemathoverarrow [overtwoheadleftarrow] [\twoheadleftarrowfill] 444\definemathoverarrow [overrightharpoondown] [1pt] [\rightharpoondownfill] 445\definemathoverarrow [overrightharpoonup] [\rightharpoonupfill] 446\definemathoverarrow [overleftharpoondown] [1pt] [\leftharpoondownfill] 447\definemathoverarrow [overleftharpoonup] [\leftharpoonupfill] 448 449\definemathunderarrow [underleftarrow] [\specleftarrowfill] 450\definemathunderarrow [underrightarrow] [\specrightarrowfill] 451\definemathunderarrow [underleftrightarrow] [\leftrightarrowfill] 452\definemathunderarrow [undertwoheadrightarrow][\twoheadrightarrowfill] 453\definemathunderarrow [undertwoheadleftarrow] [\twoheadleftarrowfill] 454\definemathunderarrow [underrightharpoondown] [\rightharpoondownfill] 455\definemathunderarrow [underrightharpoonup] [\rightharpoonupfill] 456\definemathunderarrow [underleftharpoondown] [\leftharpoondownfill] 457\definemathunderarrow [underleftharpoonup] [\leftharpoonupfill] 458 459%D These can be used as follows: 460%D 461%D \startbuffer 462%D $\overleftarrow{A}$ $\overleftarrow{ABC}$ 463%D $a_{\overleftarrow{A}}$ $b_{\overleftarrow{ABC}}$ 464%D \stopbuffer 465%D \typebuffer which gives \getbuffer 466 467%D TODO: Possibly have a single arrow command define all the arrows. 468 469\protect \endinput 470