summaryrefslogtreecommitdiff
path: root/macros/optex/pkg/math.opm
diff options
context:
space:
mode:
Diffstat (limited to 'macros/optex/pkg/math.opm')
-rw-r--r--macros/optex/pkg/math.opm639
1 files changed, 639 insertions, 0 deletions
diff --git a/macros/optex/pkg/math.opm b/macros/optex/pkg/math.opm
new file mode 100644
index 0000000000..5b0f29dd2f
--- /dev/null
+++ b/macros/optex/pkg/math.opm
@@ -0,0 +1,639 @@
+% This is macro package used by OpTeX, see http://petr.olsak.net/optex
+% math.opm, Petr Olšák <petr@olsak.net>, 2022
+% This file can serve as an template for other package files
+% See end of the file for more information
+
+\_def\_math_version {0.02, 2022-11-26}
+\_codedecl \replacemissingchars {Doing math more comfortable <\_math_version>}
+\_namespace{math}
+
+ \_doc
+ \`\bigp`, \`\Bigp`, \`\biggp`, \`\Biggp`, \`\autop`, \`\normalp` are inspired from
+ \tricklink[bigp]{0094}
+ \_cod
+
+\_def\.bigp #1{\.fparam{#1}\_bigl\_bigr}
+\_def\.Bigp #1{\.fparam{#1}\_Bigl\_Bigr}
+\_def\.biggp#1{\.fparam{#1}\_biggl\_biggr}
+\_def\.Biggp#1{\.fparam{#1}\_Biggl\_Biggr}
+\_def\.autop#1{\.fparam{#1}\_left\_right}
+\_def\.normalp#1{\.fparam{#1}\_relax\_relax}
+\_def\.fparam#1#2#3{%
+ \_isequal .{#1}\_iffalse #1\_fi
+ \_let\.bigleft=#2\_let\.bigright=#3\_nospacefuturelet\.next\.fparamA}
+\_def\.fparamA{%
+ \_ifx\.next(\.afterrelax{\.fparamB()}\_fi
+ \_ifx\.next[\.afterrelax{\.fparamB[]}\_fi
+ \_ifx\.next\{\.afterrelax{\.fparamB\{\}}\_fi
+ \_ifx\.next\_bgroup \_def\.lparen{\{}\_def\.rparen{\}}\.afterrelax{\.fparamC}\_fi
+ \_relax
+}
+\_def\.fparamB#1#2{%
+ \_def\.lparen{#1}\_def\.rparen{#2}%
+ \_def\.next#1##1#2{\_trick_ensurebalanced#1#2\.fparamC{##1}}%
+ \.next
+}
+\_def\.fparamC#1{%
+ \_ifx\.bigleft\_left \_mathopen{}\_fi
+ \.bigleft\.lparen{#1}\.bigright\.rparen
+ \_ifx\.bigright\_right \_mathclose{}\_fi
+}
+\_def\.afterrelax#1#2\_relax{\_fi#1}
+
+\_nspublic \bigp \Bigp \biggp \Biggp \autop \normalp ;
+
+ \_doc
+ We need macro \`\.ensurebalanced` for balancing nested parentheses from
+ \tricklink[balancing]{0043}. We use `trick` namespace for these macros.
+ \_cod
+
+\_resetnamespace{trick}
+ \_def\.ensurebalanced#1#2#3{\_immediateassigned{%
+ \_def\.balopen{#1}\_def\.balclose{#2}\_let\.balaction=#3%
+ \_def\.readnextbal##1##2#2{\.ensurebalancedA{##1#2##2}}}%
+ \.ensurebalancedA}
+ \_def\.ensurebalancedA#1{\.isbalanced#1%
+ \_iftrue\_afterfi{\.balaction{#1}}\_else\_afterfi{\.readnextbal{#1}}\_fi}
+ \_def\.isbalanced#1\_iftrue{\_immediateassignment\_tmpnum=0 \.isbalancedA#1{\.isbalanced}}
+ \_def\.isbalancedA#1#{\.countbalanced#1\.isbalanced \.isbalancedB}
+ \_def\.isbalancedB#1{%
+ \_ifx\.isbalanced#1\_afterfi{\_cs{ifnum}\_tmpnum=0 }\_else\_ea\.isbalancedA\_fi}
+ \_def\.countbalanced#1{\_ea\_ifx\.balopen #1\_immediateassignment\_incr\_tmpnum\_fi
+ \_ea\_ifx\.balclose#1\_immediateassignment\_decr\_tmpnum\_fi
+ \_ifx\.isbalanced#1\_else\_ea\.countbalanced\_fi}
+\_resetnamespace{math}
+
+ \_doc
+ \`\smartdots` re-sets `\dots` to `\.dots`.
+ The `\.dots` lets `\.next` using `\futurelet` and checks the `\.next`:
+ It it is declared by `\_chardef` then `\.mchar` is the real Unicode character
+ with `\chardef`ed code.
+ If `\.next` is a real Unicode character then `\.mchar` includes it. This
+ is done by the expandable \o`\cstochar` macro provided by \OpTeX/.
+ If `\.next` is something else (i.e.\ `\.mchar` is empty) then print
+ \o`\ldots` else print \o`\cdots` for Op, Bin, Rel, Open, Close math
+ classes of the `\.next` math object or prints \o`\ldots` in other cases.
+ \_cod
+
+\_def\.smartdots {\_let\dots=\.dots}
+\_def\.dots{\_relax \_ifmmode \_ea\.specdots \_else \_dots \_fi}
+\_def\.specdots{\_futurelet\.next\.specdotsA}
+\_def\.specdotsA{%
+ \.ischardef\.next\_iftrue \_edef\.mchar{\_Uchar\.next}%
+ \_else \_edef\.mchar{\_cstochar\.next}%
+ \_fi
+ \_ifx\.mchar\_empty \_ldots
+ \_else \_Umathcharnumdef\.next=\_Umathcode\_ea`\.mchar \_relax
+ \_ifcase \.readclass\.next
+ \_ldots\_or \_cdots\_or \_cdots\_or \_cdots\_or \_cdots\_or \_cdots \_else \_ldots \_fi
+ \_fi
+}
+\_def\.ischardef #1\_iftrue {\_ea\.ischardefA\_meaning#1\_fin}
+\_def\.ischardefA #1#2#3#4#5#6\_fin {\_def\.tmpa{#1#2#3#4#5}\_ifx\.tmpa\.stringchar}
+\_edef\.stringchar{\_string\char}
+\_def\.readclass#1{\_ea\.readclassA\_meaning#1\_fin}
+\_def\.readclassA#1"#2"#3\_fin{#2}
+
+\_nspublic \smartdots ;
+
+ \_doc
+ \`\smartvert` sets `|` as math-active charcter and declares it
+ equal to `\.autovert` macro. This macro checks two variants: there
+ is single `|` or there is double `||`. It runs \`\.autovertA` or
+ \`\.autoVertA`. These macros find the closing `|` or `||` and use
+ `|` or `‖` in context of `\left`, `\right`. The \`\singlevert`
+ is declared here if a user want to use a single vertical bar.
+ \_cod
+
+\_newpublic \_mathchardef \_singlevert=\_mathcode`|
+\_def\.autovert {\_isnextchar|{\.autoVertA}{\.autovertA}}
+\_def\.autovertA #1|{\_mathopen{}\_mathclose{\_left|#1\_right|}}
+\_def\.autoVertA|#1||{\_mathopen{}\_mathclose{\_left‖#1\_right‖}}
+\_bgroup \_lccode`\~=`\| \_lowercase{\_egroup
+ \_def\.smartvert{\_let~=\.autovert \_mathcode`|="8000 }}
+
+\_nspublic \smartvert ;
+
+ \_doc
+ The control sequences \`\N`, \`\Z`, \`\Q`, \`\R`, \`\C`
+ \`\sgn`, \`\argmin`, \`\argmax`, \`\grad`, \`\rank`, \`\tr`, \`\diag`, \`\Span`,
+ \`\Rng`, \`\Null`, \`\Ker`, \`\Res`, \`\tg`, \`\arctg`,
+ \`\frac`, \`\dfrac`, \`\tfrac`, \`\.`
+ are defined directly in the user space by \o`\_newpublic`.
+ \_cod
+
+\_newpublic\_def \N {{\_bbchar N}}
+\_newpublic\_def \Z {{\_bbchar Z}}
+\_newpublic\_def \Q {{\_bbchar Q}}
+\_newpublic\_def \R {{\_bbchar R}}
+\_newpublic\_def \C {{\_bbchar C}}
+
+\_newpublic\_def \sgn {\_mathop{\_rm sgn}\_nolimits}
+\_newpublic\_def \argmin {\_mathop{\_rm argmin}}
+\_newpublic\_def \argmax {\_mathop{\_rm argmax}}
+\_newpublic\_def \grad {\_mathop{\_rm grad}\_nolimits}
+\_newpublic\_def \rank {\_mathop{\_rm rank}\_nolimits}
+\_newpublic\_def \tr {\_mathop{\_rm tr}\_nolimits}
+\_newpublic\_def \diag {\_mathop{\_rm diag}\_nolimits}
+\_newpublic\_def \Span {\_mathop{\_rm Span}\_nolimits}
+\_newpublic\_def \Rng {\_mathop{\_rm Rng}\_nolimits}
+\_newpublic\_def \Null {\_mathop{\_rm Null}\_nolimits}
+\_newpublic\_def \Ker {\_mathop{\_rm Ker}\_nolimits}
+\_newpublic\_def \Res {\_mathop{\_rm Res}\_nolimits}
+\_newpublic\_def \tg {\_mathop{\_rm tg}\_nolimits}
+\_newpublic\_def \arctg {\_mathop{\_rm arctg}\_nolimits}
+
+\_newpublic\_def \frac #1#2{{{#1}\_over#2}}
+\_newpublic\_def \dfrac #1#2{{\_displaystyle{{#1}\_over#2}}}
+\_newpublic\_def \tfrac #1#2{{\_textstyle{{#1}\_over#2}}}
+
+\_newpublic\_def \.#1{{\_bf#1}}
+
+ \_doc
+ The \`\toright` and \`\toleft` macros are based on the
+ \o`\setpos` and \o`\posx` macros. The printing point is shifted by `\posx`
+ to the left (i.e.\ to the left boundary of the sheet) and then it is shifted
+ to the desired space by `\kern\hoffset+\hsize`.
+ This idea is moved from \tricklink[torighteq]{0028}.
+ \_cod
+
+\_newcount \.tomarginno
+\_def\.toright #1{\_incr\.tomarginno {\_setpos[_math_tr:\_the\.tomarginno]%
+ \_rlap{\_kern-\_posx[_math_tr:\_the\.tomarginno]\_kern\_hoffset\_kern\_hsize\_llap{#1}}}}
+\_def\.toleft #1{\_incr\.tomarginno {\_setpos[_math_tr:\_the\.tomarginno]%
+ \_rlap{\_kern-\_posx[_math_tr:\_the\.tomarginno]\_kern\_hoffset\_rlap{#1}}}}
+
+\_nspublic \toright \toleft ;
+
+ \_doc
+ The \`\subeqmark` works because the internal \O`\_thednum`
+ is re-defined. The \`\.dnumpost` is added here. If you want to use another format
+ for \O`\_thednum` then you have to add the \`\.dnumpost` to it too.
+ \_cod
+
+\_def \_thednum {(\_the\_dnum \.dnumpost)}
+\_def\.dnumpost{}
+\_def\.subeqmark #1{\_def\.dnumpost{#1}\_lowercase{\_ifx a#1}\_else \_decr\_dnum\_fi \_eqmark}
+
+\_nspublic \subeqmark ;
+
+ \_doc
+ \`\textvariables`, \`\textdigits`, \`\textmoremath` initialize
+ new two families 5, 6 using `\.textmathini` and sets `\mathcode`s
+ of given characters to these families.
+ Moreover, `\textvariables` adds `\fam` register setting to `\rm` and `\it`
+ selectors and re-set Greek variables to use only math font (because we
+ are not sure if Greek letters are in the current text fonts).
+ \_cod
+
+\_def\.textmathini{%
+ \_fontdef\.mathrm{\_rm}\_fontdef\.mathit{\_it}%
+ \_fontdef\.mathbf{\_bf}\_fontdef\.mathbi{\_bi}%
+ \_addto\_normalmath{%
+ \_setmathfamily 5 \.mathrm
+ \_setmathfamily 6 \.mathit
+ }%
+ \_addto\_boldmath{%
+ \_setmathfamily 5 \.mathbf
+ \_setmathfamily 6 \.mathbi
+ }%
+ \_normalmath
+ \_let\.textmathini=\_relax
+}
+\_def\.textvariables {\.textmathini \_mathcodes 6 {7{\_Urange a-z \_Urange A-Z}}%
+ \_addto\_marm {\_fam5 }\_addto\_mait{\_fam6 }%
+ \_protected\_def\_itgreek {\_umathrangegreek01\_greekita}%
+ \_protected\_def\_rmgreek {\_umathrangegreek01\_greekrma}%
+ \_protected\_def\_itGreek {\_umathrangeGREEK01\_greekitA \_setnablait}
+ \_protected\_def\_rmGreek {\_umathrangeGREEK01\_greekrmA \_setnablarm}
+ \_itgreek \_rmGreek
+}
+\_def\.textdigits {\.textmathini \_mathcodes 5 {7{\_Urange 0-9}}}
+\_def\.textmoremath {\.textmathini
+ \_mathcodes 5 {5{!?} 2{*+-} 3{=<>} 6{,:;} 0{./|} 4{([\{} 5{\})]}}%
+ \_Umathcode `- = 2 5 "2212 % hyphen behaves like minus in math mode
+}
+\_nspublic \textvariables \textdigits \textmoremath ;
+
+ \_doc
+ \`\replacemissingchars``<family>` defines `\UnicodeMathSymbol` and reads
+ `unimath-table.opm`, i.e.\ it does for each math character following
+ if the character is missing in main math font and if it is present in
+ added font and if it is not already replaced character then apply new math
+ code or `\Umathaccent` definition. Its name is added to `\.alist` or
+ `\.clist`. The new codes are declared by `\matchars<family>{<expanded>\clist}`.
+ The `\.rlist` is the list of characters already replaced. They are not
+ replaced again if a new `\replacemissingchars` is used.
+ \_cod
+
+\_def\.rlist{}
+\_def\.replacemissingchars#1{%
+ \_def\.alist{}\_def\.clist{}
+ \_def\UnicodeMathSymbol##1##2##3##4{%
+ \_iffontchar\_textfont1##1 \_else % not in main math font
+ \_iffontchar\_textfont#1 ##1 % is presnet in added font
+ \_isinlist\.rlist{##2}\_iffalse % not already replaced
+ \_ifx##3\_mathaccent
+ \_protected\_def##2{\_Umathaccent fixed 7 #1 ##1 }%
+ \_addto\.alist{##2}%
+ \_else
+ \_addto\.clist{##2}%
+ \_fi\_fi\_fi\_fi
+ }
+ \_input unimath-table.opm
+ \_wlog{^^J\_string\replacemissingchars: From \_string\fam=\_string#1 is printed now:^^J%
+ CHARACTERS: \.clist^^JACCENTS: \.alist^^J}%
+ \_ea\_mathchars \_expanded{\_noexpand#1{\.clist}}%
+ \_edef\.rlist{\.rlist\.clist\.alist}%
+ \_def\.alist{}\_def\.clist{}\_let\UnicodeMathSymbol=\_undefined
+}
+\_nspublic \replacemissingchars ;
+
+ \_doc
+ \`\scriptspaces``{<s-rel>}{<s-bin>}{<ss-rel>}{<ss-bin>}`
+ sets internal \LuaTeX/ registers represented by
+ appropriate primitives, see section 7.5 in the \LuaTeX/ manual.
+ \_cod
+
+\_def\.scriptspaces #1#2#3#4{%
+ \_Umathordrelspacing\_scriptstyle=\.orzeromu{#1}\_relax
+ \_Umathrelordspacing\_scriptstyle=\.orzeromu{#1}\_relax
+ \_Umathordrelspacing\_crampedscriptstyle=\.orzeromu{#1}\_relax
+ \_Umathrelordspacing\_crampedscriptstyle=\.orzeromu{#1}\_relax
+ \_Umathordbinspacing\_scriptstyle=\.orzeromu{#2}\_relax
+ \_Umathbinordspacing\_scriptstyle=\.orzeromu{#2}\_relax
+ \_Umathordbinspacing\_crampedscriptstyle=\.orzeromu{#2}\_relax
+ \_Umathbinordspacing\_crampedscriptstyle=\.orzeromu{#2}\_relax
+ \_Umathordrelspacing\_scriptscriptstyle=\.orzeromu{#3}\_relax
+ \_Umathrelordspacing\_scriptscriptstyle=\.orzeromu{#3}\_relax
+ \_Umathordrelspacing\_crampedscriptscriptstyle=\.orzeromu{#3}\_relax
+ \_Umathrelordspacing\_crampedscriptscriptstyle=\.orzeromu{#3}\_relax
+ \_Umathordbinspacing\_scriptscriptstyle=\.orzeromu{#4}\_relax
+ \_Umathbinordspacing\_scriptscriptstyle=\.orzeromu{#4}\_relax
+ \_Umathordbinspacing\_crampedscriptscriptstyle=\.orzeromu{#4}\_relax
+ \_Umathbinordspacing\_crampedscriptscriptstyle=\.orzeromu{#4}\_relax
+}
+\_def\.orzeromu#1{\_ifx^#1^0mu\_else#1\_fi}
+
+\_nspublic \scriptspaces ;
+
+\_endnamespace
+\_endcode
+
+\sec Summary
+
+This package provides various extensions usable for math typesetting. Mostly
+of them are inspired from
+\ulink[http://petr.olsak.net/optex/optex-tricks.html]{\OpTeX/ tricks} www page.
+
+The following macros are defined in this package:
+\begitems
+* \~`\bigp`, \~`\Bigp`, \~`\biggp`, \~`\Biggp`, \~`\autop`, \~`\normalp`
+ gives better controlling of sizes of parentheses.
+* \~`\smartdots` declares `\dots` macro more intelligent.
+ \~`\smartvert` declares \"`|`" for better spacing.
+* There are many common math macros for sets or for operators, for example
+ \~`\R` or \~`\sgn`.
+* \~`\toright`, \~`\toleft` puts the \o`\eqmark` to desired position,
+ \~`\subeqmark` prints the given suffix as a part of the equation mark.
+* \~`\scriptspaces` sets more spaces around rel, bin in script and scripscript styles.
+* \~`\textvariables`, \~`\textdigits`, \~`\textmoremath`
+ enables characters from used text font in math mode
+ (variables, digits, more characters).
+* \~`\replacemissingchars` allows to re-declare all characters missing in math font
+ for printing them from additional math font.
+\enditems
+
+This package is not definitive. I plan to add more features in new versions
+if needed. Moreover, this package gives an example for package writers how
+to write their own packages, see section~\ref[pkgtemplate].
+
+\sec Controlled sizes of parentheses
+
+If you write `$f(x(y+z))$` then the outer parentheses should be bigger.
+Classical Plain \TeX/ provides macros \O`\bigl`, \O`\bigr`, etc., they can
+be used in this manner: `$f\bigl(x(y+z)\bigr)$`. But the source file looks
+bad with such markup. Better is to say that parentheses have to be bigger
+using a single prefix before functional symbol, i.e. `$\bigp f(x(y+z))$`.
+This should be print the same as previous example with \O`\bigl`, \O`\bigr`.
+
+The prefixes \^`\bigp` (big pair), \^`\Bigp` (Big pair),
+\^`\biggp` (bigg pair) and \^`\Biggp` (Bigg pair) are provided,
+they can be used before a functional symbol. The scaled parentheses
+surrounding the functional parameter can be (...) or [...] or `\{`...`\}` or
+\{...\}. I.e.\ `\Bigp\Gamma [x]` is the same as `\Gamma \Bigl[x\bigr]`.
+Moreover, the functional parameter gets its own \TeX/ group, so
+`\Bigp G(a\over2)` results to `G\Bigl({a\over2}\bigr)`.
+There are two more prefixes \^`\autop` and \^`\normalp`. First one applies
+`\left`, `\right` to the parentheses of the parameter, second one keeps
+the parentheses unscaled. If you want to scale the parentheses without
+preceding functional symbol then use dot instead this symbol, for example
+`\Bigp.(a)` is equal to `\Bigl(a\Bigr)`.
+
+Examples:
+\begtt
+$$
+ \displaylines{
+ \Biggp F (1+\biggp g (1+\Bigp f(1+\bigp f(1+f(x))))) \cr
+ f(x(y+z)),\quad \bigp f(x(y+z)),\quad \autop f (a\over b)\cr
+ \Bigp f(a\over b+c),\quad \Bigp f(x^2\over2),\quad \Bigp.(a\over b)
+ }
+$$
+\endtt
+gives:
+$$
+ \displaylines{
+ \Biggp F (1+\biggp g (1+\Bigp f(1+\bigp f(1+f(x))))) \cr
+ f(x(y+z)),\quad \bigp f(x(y+z)),\quad \autop f (a\over b)\cr
+ \Bigp f(a\over b+c),\quad \Bigp f(x^2\over2),\quad \Bigp.(a\over b)
+ }
+$$
+
+\sec Intelligent `\dots` like in AMS\TeX
+
+AMS\TeX/ provides \o`\dots` macro which works depending on the context. If it is surrounded
+by symbols like $+$, $-$, $=$ then it works like \o`\cdots`, if it is surrounded by
+comma or similar symbols then it works like \o`\ldots`.
+This package keeps \o`\dots` unchanged but it is changed (and behaves as
+mentioned above) after the \^`\smartdots` declaration.
+
+\smartdots
+You can try this after the \^`\smartdots` declaration:
+\medskip
+
+`$a_1, a_2, \dots, a_n$ ` prints $a_1, a_2, \dots, a_n$,
+
+`$a_1 + a_2 + \dots + a_n$ ` prints $a_1 + a_2 + \dots + a_n$,
+
+
+\sec Using vertical bars with better spacing
+
+The character \"`|`" is declared with Ord class by default in Plain \TeX/,
+but we are using it typically in the context `$|x|$`. It means there should
+be Open and Close classes. This example gives correct result but try to use
+`$|-1|$` which gives bad spacing: $|-1|$.
+And `$||x||$` gives bad result too.
+
+When you declare \^`\smartvert`, these problems are solved. Moreover, the
+\"`|`" or \"`||`" are expected to be always in pairs and they are scaled by
+`\left` and `\right` primitives automatically. If you don't want to use it
+in a pair, use \^`\singlevert` or `\big|`, or `\Big|` etc. Compare
+the result of `$|\sum a_n|+||x||$`:
+$$
+ \eqalign{
+ |\sum a_n|+||x|| &\quad \hbox{if \scantextokens{`\smartvert`} isn't initialized,}\cr
+ \smartvert
+ |\sum a_n|+||x|| &\quad \hbox{if \scantextokens{`\smartvert`} is initialized.}
+ }
+$$
+
+\sec Basic and typical macros for sets, functions etc.
+
+These typical macros are defined in `math.opm`:
+\^`\N` for $\N$, \^`\Z` for $\Z$, \^`\Q` for $\Q$, \^`\R` for $\R$, \^`\C` for $\C$,
+\^`\sgn`, \^`\argmin`, \^`\argmax`, \^`\grad`, \^`\rank`, \^`\tr`, \^`\diag`, \^`\Span`, \^`\Rng`,
+\^`\Null`, \^`\Ker`, \^`\Res`, \^`\tg`, \^`\arctg`.
+
+I hate the \^`\frac`, \^`\dfrac` and \^`\tfrac` macros defined in \LaTeX/
+but someone may want to use them. This package defines them.
+But I note: usage of `$1\over2$` for $1\over2$
+is much more understandable than \LaTeX's `$\frac12$`.
+
+The vectors and matrices are ususally printed by `{\bf A}{\bf x}`.
+The package provides a shortcut `\.<letter>` to do the same, so user can write
+`\.A\.x` for multiplication of a matrix $\.A$ by a vector $\.x$.
+We strictly don't recommend usage of `\.`, `\v`, `\=`, etc.\ for accents, so
+`math.opm` can define `\.` differently than the classical meaning \"dotaccent".
+
+\sec Equation marks in atypical cases
+
+We want to put equation marks `\eqmark` in more lines in display mode when we
+are using macros not designed for such case. For example in the lines of
+the `\cases` macro:
+
+\begtt
+$$ f(x) = \cases{0 & for $x<0$\toright\eqmark \cr
+ 1 & otherwise\toright\eqmark } $$
+\endtt
+This puts the equation marks to the right margin in each line generated by
+the `\cases` macro.
+$$ f(x) = \cases{0 & for $x\string<0$\toright\eqmark \cr
+ 1 & otherwise\toright\eqmark }
+$$
+The \^`\toright`\o`\eqmark` is used here. Analogically,
+\^`\toleft`\o`\eqmark` puts the equation mark to the left margin.
+The position of these marks are correct after second or more \TeX/ run
+because \TeX/ needs to read data from its previous run in this case.
+
+Sometime we want to declare a bunch of equations with the same numeric
+equation marks but with different suffixes, for example (1.1a), (1.1b). We
+provide the macro \^`\subeqmark``<suffix>` here.
+If `<suffix>` is `a` or `A` then \^`\subeqmark` starts a new bunch of
+equations with the next number. Following `\subeqmark b`, `\subeqmark c`,
+etc.\ use the same equation number, they differ only by given suffixes:
+You can put `[<label>]` after `<suffix>` for referencing purposes.
+Example:
+
+\begtt
+$$\adef~{\kern.5em }
+ \eqalignno{
+ x + 2y + 3z &= 600 & \subeqmark a \cr
+ 12x + ~y - 3z &= -7 & \subeqmark b[label] \cr
+ 4x - ~y + 5z &= ~5 & \subeqmark c \cr
+ }
+$$
+The equation~\ref[label] has negative right side. Moreover, it applies
+$$
+ a^2 + b^2 = c^2. \eqmark
+$$
+\endtt
+prints
+$$\adef~{\kern.5em }
+ \eqalignno{
+ x + 2y + 3z &= 600 & \subeqmark a \cr
+ 12x + ~y - 3z &= -7 & \subeqmark b[label] \cr
+ 4x - ~y + 5z &= ~5 & \subeqmark c \cr
+ }
+$$
+The equation~\ref[label] has negative right side. Moreover, it applies
+$$
+ a^2 + b^2 = c^2. \eqmark
+$$
+
+\sec Setting more spaces in script styles
+
+Classical \TeX/ puts \n`\thickmuskip` around relations and \n`\medmuskip` around
+binary operators only in \n`\textstyle` and \n`\displaystyle`. These spaces are
+missing in \n`\scripstyle` and \n`\scriptscriptstyle`. It means that we get, for
+example
+$$
+ \sum_{i=j+1}^\infty a_i
+$$
+The formula $i=k+1$ has no spaces here, so it looks unattractive. \LuaTeX/
+provides better control of all such spaces, so `math.opm` declares the macro
+\^`\scriptspaces``{<s-rel>}{<s-bin>}{<ss-rel>}{<ss-bin>}` for setting
+these spaces. <s-rel> is \"muskip" value used around relations in \n`\scriptstyle`,
+<s-bin> is \"muskip" used around binary operators in \n`\scriptstyle` and the
+last two parameters gives these spacing in \n`\scriptscriptstyle`.
+If a parameter is empty, it means that it has zero value.
+For example after `\scriptspaces {2mu}{1.3mu}{}{}`
+the formula mentioned above looks like
+$$
+ \scriptspaces {2mu}{1.3mu}{}{}
+ \sum_{i=j+1}^\infty a_i
+$$
+It looks better, doesn't it?
+
+\sec Variables and digits from currently used text font
+
+When Unicode math font is loaded then all variables and digits are printed
+from it in math mode. If you are using text fonts with another visual
+concept then you can see a differences when you use digits in text mode and in
+math mode. You can specify \^`\textdigits` if you want to use digits from
+current text `\rm` font in math and \^`\textvariables` if you want to use
+variables from current text `\it` font in math.
+You can set printing of
++−*/=<>\{([])\} from text `\rm` font in math by \^`\textmoremath`.
+You can inspire from the \^`\textmoremath` macro and set more similar
+characters from text font.
+
+You have to load a text font family (using \o`\fontfam` for example) first and
+use \^`\textdigits`, \^`\textvariables`, \^`\textmoremath` after it. This is
+due to these macros reads {\em current} text \o`\rm` and \o`\it` fonts and set
+them to math printing.
+
+Note that we cannot avoid a visual incompatibility of parentheses when they
+are use in the context \n`\left`, \n`\right`. These parentheses must be printed
+from math font always because text font is unable to create bigger versions of
+them.
+
+\sec Replacing all missing math characters from another font
+
+If we load an additional math font by \o`\addUmathfont`, for example:
+\begtt
+\addUmathfont \xits {[XITSMath-Regular]}{} {[XITSMath-Bold]}{} {}
+\endtt
+then we can re-declare the code of arbitrary math character in such a way
+that it is printed from this additional font. It can be done by \o`\mathchars`
+provided by \OpTeX/, for example:
+\begtt
+\mathchars \xits {\leftdasharrow \updasharrow \rightdasharrow \downdasharrow}
+\endtt
+But this method enables to re-declare only selected characters. Maybe, you
+want to re-declare {\em all} Unicode math characters which are missing in the main font.
+This can be done by \^`\replacemissingchars`\,`<family>` provided by the
+`math.opm`. For example
+\begtt
+\replacemissingchars \xits
+\endtt
+replaces all characters missing in the main font by characters from the
+`\xits` declared by previous \o`\addUmathfont`.
+The names of all replaced characters are printed in log file.
+If the additional math font doesn't provide all Unicode math characters
+then you can load a next additional math font using another \o`\addUmathfont` and do
+\^`\replacemissingchars`\,`<family>` again. Only those characters not replaced
+by previous steps are replaced.
+
+
+\sec[pkgtemplate] General recommendation for writing packages
+
+This section has nothing common with the subject of this package but this package
+can serve as inspiration for another package writers. It should be a template
+for another `<pkg>.opm` files. We emphasize several principles here.
+The basic information can be found in
+\ulink[https://petr.olsak.net/ftp/olsak/optex/optex-doc.pdf\#ref:prefixed]
+{section 2.2} of the \OpTeX/ manual.
+Try to run\fnote{Run it three times because Table of contents and Index are created.}
+\begtt
+optex -jobname math-doc '\docgen math'
+\endtt
+for creating this documentation. You can see (from the log file) that the
+`math.opm` is read four times during this process. First one is due to
+\o`\docgen`~`math`. It skips the part before \o`\_endcode` and searches the
+following {`\_doc...\_cod`} pair in the file and processes it (see the end
+of the file `math.opm`). The macros and main instruction about generating
+toc, index, etc.\ are here. First instruction is \o`\load``[doc,math]` which
+initializes `doc` mode of \OpTeX/ and loads `math.opm` secondly because we
+want to show some effects provided by this package. Then there is
+\o`\printdoctail`~`math.opm` which loads the `math.opm` again and prints the
+documentation starting from \o`\_endcode`. Finally, there is
+\o`\printdoc`~`math.opm` which prints the codes mixed by the documentation
+text inside pairs {`\_doc...\_cod`}. This causes the fourth loading of the
+`math.opm` file.
+
+The first part of the `math.opm` file looks like:
+\begtt \catcode`\<=13 \adef!{\string}
+% Optional comments
+
+\_def\_<pkg>_version {<version-number>, <version-date>}
+\_codedecl \pkgsequence {Doing the life more comfortable !<\_<pkg>_version>}
+\_namespace{<pkg>}
+\endtt
+The `\_<pkg>_version` macro should be declared here. The macro should expand
+to version number followed by version date. User can check
+the package version simply by expanding this macro after the package is
+loaded. And we want to have this data only at single place of the file.
+You may check the log file if the text given by `\_codedecl` isn't too long
+and isn't broken to more lines. Keeping single line is better because users can
+`grep @:` on log file in order to get information of all loaded packages
+and their version numbers.
+
+The \o`\_namespace``{<pkg>}` opens the name space used by your package where all
+`\.foo` are internally transformed to `\_<pkg>_foo`. Next part of the file
+includes the code itself documented in {`\_doc...\_cod`} pairs. It is
+finished by \o`\_endnamespace` which finalizes the scope where `\.foo` are
+transformed to `\_<pkg>_foo` and by \o`\_endcode` which does \n`\endinput` when
+the macros are load. Final part of the file after \o`\_endcode` can include
+more detailed documentation.
+
+If you have any idea of creating a macro package, you probably start with
+experimental macros in user name space. It means that there are
+`\def\mymacro` etc. Once such a code is working, you can include it to the
+macro package introduced by \o`\_namespace``{<pkg>}`. You have to go through
+your code carefully sequence per sequence and insert `_` or `.` in front of
+their name. The \"`_`" have to be used if the sequence is a primitive or
+\OpTeX/ macro and the \"`.`" if it is your macro. So, the code fragment
+`\def\mymacro` have to be rewritten to `\_def\.mymacro`. If the macro
+`\mymacro` is intended for usage in the user space, then append
+`\_nspublic \mymacro ;` too.
+
+Sometimes you may want to define a macro only for user space. Then
+use prefix \O`\_newpublic` before your declaration, see declaration of
+ \^`\sgn` in this package as an exampe. The reason is: if
+a user has defined such a macro already then the warning is printed.
+The user can read this warning and declare the macro after
+`\load[<pkg>]` in this case.
+
+ \_doc
+ \load [doc,math]
+ \def\opurl{http://petr.olsak.net/ftp/olsak/optex/optex-doc.pdf}
+ \def\tnurl{http://petr.olsak.net/ftp/olsak/optex/tex-nutshell.pdf}
+ \def\trurl{http://petr.olsak.net/optex/optex-tricks.html}
+ \def\tricklink[#1]#2{\ea\ulink \ea[\trurl\##1]{\OpTeX/ trick #2}}
+ \def\exlink#1#2{\ea\ulink\expanded{[#2\csstring#1]{\hbox{\tt\string#1\,}}}}
+ \def\o`#1`{\exlink#1{\opurl\#cs:^}}
+ \def\O`#1`{\exlink#1{\opurl\#cs:}}
+ \def\n`#1`{\exlink#1{\tnurl\#cs:}}
+ \outlines 0
+
+ \tit Macros for doing math more comfortable
+ \hfill Version: \_math_version \par
+ \centerline{\it Petr Olšák\/\fnotemark1, 2022}
+ \fnotetext{\url{https://petr.olsak.net}}
+
+ \notoc\nonum\sec Table of contents
+ \maketoc
+ \printdoctail math.opm % prints the documantation written after \_endcode
+ \sec Implementation
+ \printdoc math.opm % prints \_doc...\_cod parts + code before \_endcode
+ \nonum\sec Index
+ \begmulti 3
+ \tt \makeindex % prints index in three columns
+ \endmulti
+ \bye
+ \_cod
+
+\endinput
+
+0.02, 2022-11-26: \smartvert introduced
+0.01, 2022-11-25: released