diff options
author | Karl Berry <karl@freefriends.org> | 2024-01-17 16:30:43 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2024-01-17 16:30:43 +0000 |
commit | 31fe966e09508db1864ad11ca0a7069a29e513af (patch) | |
tree | beedc670f5d8798b3f9e4f54049d552d8cf27825 /Master/texmf-dist/tex | |
parent | b4d149ff60112869b17ba1f395cd9bc649bcc5d4 (diff) |
medmath (15jan24)
git-svn-id: svn://tug.org/texlive/trunk@69466 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex')
-rw-r--r-- | Master/texmf-dist/tex/latex/medmath/medmath.sty | 469 |
1 files changed, 469 insertions, 0 deletions
diff --git a/Master/texmf-dist/tex/latex/medmath/medmath.sty b/Master/texmf-dist/tex/latex/medmath/medmath.sty new file mode 100644 index 00000000000..7232e01531f --- /dev/null +++ b/Master/texmf-dist/tex/latex/medmath/medmath.sty @@ -0,0 +1,469 @@ +% -*- coding: utf-8 -*- +% ---------------------------------------------------------------------------- +% Author: Jianrui Lyu <tolvjr@163.com> +% License: The LaTeX Project Public License 1.3c +% ---------------------------------------------------------------------------- +% This package started as a fork of mediummath code of nccmath package, +% aiming to provide more stable and flexible medium-size math commands. + +\NeedsTeXFormat{LaTeX2e} +\ProvidesPackage{medmath}[2024-01-15 v2024D Better medium-size math commands] + +\RequirePackage{array} +\RequirePackage{etoolbox} + +\newbool{mdm@bare} \boolfalse{mdm@bare} % don't define any public commands +\newbool{mdm@base} \boolfalse{mdm@base} % define only basic public commands +\newbool{mdm@amsfonts} \booltrue{mdm@amsfonts} % use ams symbol fonts + +\DeclareKeys{ + bare .if = mdm@bare, + base .if = mdm@base, + all .ifnot = mdm@base, + mdm@amsfonts .if = mdm@amsfonts +} + +\ProcessKeyOptions + +\RequirePackage{amsmath} + +%%% -------------------------------------------------------- +%%> \section{Define medium-size math commands with base option} +%%% -------------------------------------------------------- + +%% The |\mdm@select@msize| command prepares dimensions for medium-size math: +%% \begin{itemize} +%% \item In |\mdm@fracrulewidth| --- a rule width in fractions; +%% \item In |@tempdima| --- a raising value; and +%% \item In |@tempdimb| --- a font size to be used in medium fractions +%% and matrices. +%% \end{itemize} + +\newdimen\mdm@fracrulewidth +\def\mdm@select@msize{\relax +% |\@tempdima| contains the current font size + \@tempdima \f@size\p@ +% Calculate in |\@tempdimb| a text font size in medium fraction + \ifdim\@tempdima>11.5\p@ + \@tempdimb .83\@tempdima + \else + \@tempdimb .8\@tempdima + \ifdim\@tempdimb<5\p@ \@tempdimb 5\p@\fi + \fi +% Calculate in |\mdm@fracrulewidth| the rule width and in +% |\@tempdima| --- the raising value + \mdm@fracrulewidth .04\@tempdima + \@tempdima 1.25\mdm@fracrulewidth + \ifdim\mdm@fracrulewidth>.45\p@ \else + \ifdim\mdm@fracrulewidth>.34\p@ \mdm@fracrulewidth .4\p@ + \else \mdm@fracrulewidth .3\p@ + \fi + \fi +} + +%% The |\mdm@innerfrac|\marg{style} prepares a fraction with a +%% special width in the given style: + +\def\mdm@innerfrac#1{\genfrac{}{}\mdm@fracrulewidth{#1}} + +%% Select a font by rounding its pt-size to the nearest integer +%% and redefine fractions to have the given rule width. The |\binom| +%% command is redefined also to its original value because it can be +%% changed when the |mediummath| option is applied. + +\def\mdm@prepare@msize{% + \@tempdima 1.2\@tempdimb + \advance\@tempdimb .5\p@ + \edef\@tempa{\strip@pt\@tempdimb}% + \expandafter\mdm@floor\expandafter\@tempa\@tempa.\@nil + \fontsize\@tempa\@tempdima\selectfont + \def\frac{\protect\mdm@innerfrac{}}% + \def\dfrac{\mdm@innerfrac\z@}% + \def\tfrac{\mdm@innerfrac\@ne}% + \def\binom{\protect\genfrac()\z@{}}% +} +\def\mdm@floor#1#2.#3\@nil{\def#1{#2}} + +%% Fix fractions and subfractions in superscripts/subscripts +%% Always use current style size to typeset the fractions + +\newcommand{\mdm@larger@frac}[2]{% + \mathchoice{\genfrac{}{}{}{0}{#1}{#2}}{\genfrac{}{}{}{0}{#1}{#2}}% + {\genfrac{}{}{}{1}{#1}{#2}}{\genfrac{}{}{}{2}{#1}{#2}}% +} +\def\mdm@prepare@msize{% + \@tempdima 1.2\@tempdimb + \advance\@tempdimb .5\p@ + \edef\@tempa{\strip@pt\@tempdimb}% + \expandafter\mdm@floor\expandafter\@tempa\@tempa.\@nil + \fontsize\@tempa\@tempdima\selectfont + \let\frac=\mdm@larger@frac + \def\dfrac{\mdm@innerfrac\z@}% + \def\tfrac{\mdm@innerfrac\@ne}% + \def\binom{\protect\genfrac()\z@{}}% +} + +%% |\mdm@op@prepare|\marg{integral} +%% command prepares an integral. It looks forward, extracts indices +%% and limits-change commands, and puts the integral with required kerning +%% of indices. The |\mdm@op@print| driver is a command to print the integral. +%% Its default value is |\mdm@op@printm|. The driver uses the following hooks: +%% |\mdm@op| contains an integral command, |\mdm@op@lim| contains +%% the selected limits-style, |\mdm@op@sb| contains a subscript, +%% |\mdm@op@sp| contains a superscript, |mdm@op@kern| contains the +%% kerning value for medium-size integrals. If subscript or superscript +%% is omitted, the corresponding hook is equal to |\relax|. + +\DeclareRobustCommand*\mdm@op@prepare[1]{% + \def\mdm@op{#1}% + \let\mdm@op@print\mdm@op@printm + \mdm@op@prepare@ +} +\def\mdm@op@prepare@{% + \let\mdm@op@lim\ilimits@ + \let\mdm@op@sp\relax + \let\mdm@op@sb\relax + \mdm@op@next +} +\def\mdm@op@next{\futurelet\@let@token\mdm@op@getnext} +% Test the next token and get it if necessary: +\def\mdm@op@getnext{% + \let\@tempa\mdm@op@skip + \ifx\@let@token\limits + \let\mdm@op@lim\limits \else + \ifx\@let@token\nolimits + \let\mdm@op@lim\nolimits \else + \ifx\@let@token\displaylimits + \let\mdm@op@lim\displaylimits \else + \ifx\@let@token\sp + \mdm@op@test\mdm@op@sp + \def\@tempa{\mdm@op@get\mdm@op@sp}\else + \ifx\@let@token\sb + \mdm@op@test\mdm@op@sb + \def\@tempa{\mdm@op@get\mdm@op@sb}\else + \ifx\@let@token\@sptoken + \let\@tempa\mdm@op@skipsp \else + \let\@tempa\mdm@op@print + \fi + \fi + \fi + \fi + \fi + \fi + \@tempa +} +% Skip |\limits|-like token: +\def\mdm@op@skip#1{\mdm@op@next} +% Skip a space token. A space token is skipped within |\@ifnextchar| +% before comparing it with the first parameter. So, it does not important +% what char to test for: +\def\mdm@op@skipsp{% + \@ifnextchar0{\mdm@op@next}{\mdm@op@next}% +} +% Test subscript or superscript to be already defined: +\def\mdm@op@test#1{% + \ifx#1\relax \else + \PackageError{nccmath}{Double index in math operator}{} + \fi +} +% Get a subscript or superscript: +\def\mdm@op@get#1#2#3{\def#1{#3}\mdm@op@next} + +%% Driver for printing the medium-size integral with indices: + +\def\mdm@op@printm{% + \ifx\mdm@op@lim\nolimits \mdm@op@printm@\@ne \else + \ifx\mdm@op@lim\limits \mdm@op@printm@\z@ \else + \mathchoice{\displaystyle\mdm@op@printm@\z@}% + {\textstyle\mdm@op@printm@\@ne}% + {\scriptstyle\mdm@op@printm@\@ne}% + {\scriptscriptstyle\mdm@op@printm@\@ne}% + \fi + \fi +} +\def\mdm@op@printm@{\mdm@op@print@\mdm@op\mdm@op@kern} + +%% Fix sizes of integral operators in superscripts/subscripts + +\newlength{\@mdm@em} +\setlength{\@mdm@em}{1em} +\ifmdm@amsfonts + \def\mdm@op@kern{0.5\@mdm@em}% +\else + \def\mdm@op@kern{0.3\@mdm@em}% +\fi +\newcommand{\mdm@style@unit}[1]{% + \mathchoice{\setlength{\@mdm@em}{1em}#1}{\setlength{\@mdm@em}{1em}#1} + {\setlength{\@mdm@em}{0.5em}#1}{\setlength{\@mdm@em}{0.3em}#1}% +} +\let\mdm@saved@op@printm=\mdm@op@printm +\def\mdm@op@printm{\mdm@style@unit{\mdm@saved@op@printm}} + +%% |\mdm@op@print@|\marg{integral}\marg{kern}\marg{level} command +%% prints an \meta{integral} using the specified \meta{kern} in indices. +%% If \meta{level} = 0 use |\limits| else use |\nolimits|. + +\def\mdm@op@print@#1#2#3{\mathop{#1}% + \setlength\@tempdima{#2}% + \@tempswatrue + \ifx\mdm@op@sb\relax \else \ifnum#3>\z@ \@tempswafalse \fi \fi + \ifx\mdm@op@sp\relax \else \ifnum#3>\z@ \@tempswafalse \fi \fi + \edef\@tempa{% + \ifnum#3=\z@ \noexpand\limits \else \noexpand\nolimits \fi + \ifx\mdm@op@sb\relax \else + \noexpand\sb{% + \ifnum#3=\z@ \kern -\@tempdima\else \kern -.8\@tempdima \fi + \noexpand\mdm@op@sb}% + \fi + \ifx\mdm@op@sp\relax \else + \noexpand\sp{\ifnum#3=\z@ \kern \@tempdima\fi + \noexpand\mdm@op@sp}% + \fi + \if@tempswa \kern -.2\@tempdima \fi + }% + \@tempa +} + +%% The |\medmath|\marg{formula} prepares a medium-size formula +%% in display style: + +\NewDocumentCommand\mdm@base@medmath{m}{\mdm@select@msize + \mathord{\raise\@tempdima\hbox{\mdm@prepare@msize + $\displaystyle#1$}}% +} + +%% Fix sizes of non integral operators in superscripts/subscripts +%% We use the method in scalerel package for saving math styles +% big operator in normal text is 80% of the size of \displaystyle +% big operator in script is 80% of the size of \textstyle +% big operator in script script is 80% of the size of \scriptstyle + +\def\@mdm@style@D{\displaystyle} +\def\@mdm@style@T{\displaystyle} +\def\@mdm@style@S{\textstyle} +\def\@mdm@style@s{\scriptstyle} +\def\mdm@style@saved{\csname @mdm@style@\@mdm@style@switch\endcsname} +\newcommand{\mdm@style@this}[1]{% + \mathchoice{\def\@mdm@style@switch{D}#1}{\def\@mdm@style@switch{T}#1} + {\def\@mdm@style@switch{S}#1}{\def\@mdm@style@switch{s}#1}% +} +\DeclareDocumentCommand\mdm@base@medmath{m}{\mdm@select@msize + \mathord{\mdm@style@this{\raise\@tempdima\hbox{\mdm@prepare@msize$\mdm@style@saved #1$}}}% +} + +%% The |\medop|\marg{operator} prepares an operator in the medium size: + +\NewExpandableDocumentCommand\mdm@base@medop{m}{\DOTSB\mathop{\medmath{#1}}\slimits@} + +%% The |\medintcorr|\marg{length} specifies an italic correction +%% for a medium integral: + +\NewExpandableDocumentCommand\mdm@base@medintcorr{m}{\def\mdm@op@kern{#1}} +\mdm@base@medintcorr{0.5\@mdm@em} + +%% The |\medint|\marg{integral} command prepares a medium integral: + +\NewExpandableDocumentCommand\mdm@base@medint{m}{\DOTSI\mdm@op@prepare{\medmath{#1}}} + +%% The |\mfrac|\marg{numerator}\marg{denominator} prepares +%% a medium-size fraction: + +\NewDocumentCommand\mdm@base@mfrac{mm}{\medmath{\frac{#1}{#2}}} + +%% The |\mbinom|\marg{numerator}\marg{denominator} prepares +%% a medium-size binomial expression: + +\NewDocumentCommand\mdm@base@mbinom{mm}{% + \Bigl(\medmath{\genfrac{}{}{\z@}{}{#1}{#2}}\Bigr)% +} + +%% The |medsize| environment is useful for preparing medium-size arrays: + +\NewDocumentEnvironment{mdm@base@medsize}{}{\mdm@select@msize + \mathord\bgroup + \raise\@tempdima\hbox\bgroup\mdm@prepare@msize + \arraycolsep .8\arraycolsep $}{$\egroup\egroup} + +%% The |mmatrix| environment prepares a medium-size matrix: + +\NewDocumentEnvironment{mdm@base@mmatrix}{}{\medsize\begin{matrix}}{\end{matrix}\endmedsize} + +%% Improve the |\MultiIntegral| kerning method on the base of +%% |\mdm@op@prepare@| hook. The original method from |amsmath| works +%% bad if a multi-integral is an argument of the |\medint| command. + +\NewDocumentCommand\mdm@base@MultiIntegral{m}{% + \edef\mdm@op{\noexpand\intop + \ifnum#1=\z@\noexpand\intdots@\else\noexpand\intkern@\fi + \ifnum#1>\tw@\noexpand\intop\noexpand\intkern@\fi + \ifnum#1>\thr@@\noexpand\intop\noexpand\intkern@\fi + \noexpand\intop + }% + \let\mdm@op@print\mdm@op@printd + \mdm@op@prepare@ +} +\def\mdm@op@printd{% + \setlength\@tempdima{\mdm@op@kern}% + \ifx\mdm@op@lim\nolimits \@tempcnta\@ne \else + \ifx\mdm@op@lim\limits \@tempcnta\z@ \else + \@tempcnta\m@ne + \fi + \fi + \mathchoice{\mdm@op@printd@{\displaystyle}{1.2\@tempdima}}% + {\mdm@op@printd@{\textstyle}{.8\@tempdima}}% + {\mdm@op@printd@{\scriptstyle}{.8\@tempdima}}% + {\mdm@op@printd@{\scriptscriptstyle}{.8\@tempdima}}% +} +\def\mdm@op@printd@#1#2{#1% + \ifnum\@tempcnta>\m@ne + \mdm@op@print@{\hbox{$#1\mdm@op$}}{#2}\@tempcnta + \else + \ifx#1\displaystyle + \mdm@op@print@{\hbox{$#1\mdm@op$}}{#2}\z@ + \else + \mdm@op@print@{\hbox{$#1\mdm@op$}}{#2}\@ne + \fi + \fi +} + +%%% -------------------------------------------------------- +%%> \section{Redefine existing math commands with all option} +%%% -------------------------------------------------------- + +%% Redifine fractions and binoms. + +\NewDocumentCommand\mdm@all@frac{}{\mdm@op@select\mfrac{\genfrac{}{}{}{}}} +\NewDocumentCommand\mdm@all@binom{}{\mdm@op@select\mbinom{\genfrac()\z@{}}} +\def\mdm@op@select#1#2#3#4{% + \mathchoice{#1{#3}{#4}}{#1{#3}{#4}}% + {\scriptstyle#2{#3}{#4}}{\scriptscriptstyle#2{#3}{#4}}% +} + +%% Fix fractions and subfractions in superscripts/subscripts +%% Always use current style size to typeset the fractions + +\DeclareDocumentCommand\mdm@all@frac{mm}{% + \mathchoice{\mfrac{#1}{#2}}{\mfrac{#1}{#2}}% + {\mdm@larger@frac{#1}{#2}}{\mdm@larger@frac{#1}{#2}}% +} + +%% Redefine all math operators except integrals: + +\NewDocumentCommand\mdm@redef@operators{mmm}{% + \ifx#2\@undefined \let#2#1\fi + \def#3{\DOTSB\medop{#2}}% +} +\mdm@redef@operators \coprod \coprod@ \mdm@all@coprod +\mdm@redef@operators \bigvee \bigvee@ \mdm@all@bigvee +\mdm@redef@operators \bigwedge \bigwedge@ \mdm@all@bigwedge +\mdm@redef@operators \biguplus \biguplus@ \mdm@all@biguplus +\mdm@redef@operators \bigcap \bigcap@ \mdm@all@bigcap +\mdm@redef@operators \bigcup \bigcup@ \mdm@all@bigcup +\mdm@redef@operators \prod \prod@ \mdm@all@prod +\mdm@redef@operators \sum \sum@ \mdm@all@sum +\mdm@redef@operators \bigotimes \bigotimes@ \mdm@all@bigotimes +\mdm@redef@operators \bigoplus \bigoplus@ \mdm@all@bigoplus +\mdm@redef@operators \bigodot \bigodot@ \mdm@all@bigodot +\mdm@redef@operators \bigsqcup \bigsqcup@ \mdm@all@bigsqcup + +%% Redefine integrals: + +\@ifundefined{NCC@op}{\let\mdm@op@int=\intop}{\let\mdm@op@int=\NCC@op@int} +\NewDocumentCommand\mdm@all@intop{}{\mathop{\medmath{\mdm@op@int}}} +\newcommand*\mdm@all@int{\DOTSI\mdm@op@prepare{\mdm@all@intop}} + +\@ifundefined{NCC@op}{\let\mdm@op@oint=\ointop}{\let\mdm@op@oint=\NCC@op@oint} +\NewDocumentCommand\mdm@all@ointop{}{\mathop{\medmath{\mdm@op@oint}}} +\newcommand*\mdm@all@oint{\DOTSI\mdm@op@prepare{\mdm@all@ointop}} + +%% Adjust \oiint operator. + +\ifdef{\oiint}{% + \let\mdm@op@oiint=\oiint + \NewDocumentCommand\mdm@all@oiintop{}{\mathop{\medmath{\mdm@op@oiint}}}% + \newcommand*\mdm@all@oiint{\DOTSI\mdm@op@prepare{\mdm@all@oiintop}}% +}{}% + +%% Redefine multiple integrals: + +\NewDocumentCommand\mdm@all@MultiIntegral{m}{% + \edef\mdm@op{\noexpand\intop + \ifnum#1=\z@\noexpand\intdots@\else\noexpand\intkern@\fi + \ifnum#1>\tw@\noexpand\intop\noexpand\intkern@\fi + \ifnum#1>\thr@@\noexpand\intop\noexpand\intkern@\fi + \noexpand\intop + }% + \let\mdm@op@print\mdm@op@printm + \mdm@op@prepare@ +} +\NewDocumentCommand\mdm@all@intkern@{}{\kern-\mdm@op@kern} +\NewDocumentCommand\mdm@all@intdots@{}{\setlength\@tempdima{\mdm@op@kern}% + \kern-.4\@tempdima{\cdotp}\mkern1.5mu{\cdotp}% + \mkern1.5mu{\cdotp}\kern-.4\@tempdima} + +%% The definite integrals in cases environment may cause infinite loops +%% Our redefinition moves \quad to the beginning of the second columns +%% Therefore removing extra spaces when there is only one column in it + +\NewDocumentEnvironment{mdm@all@cases}{}{% + \left\{\linespread{1.0}\selectfont\def\arraystretch{1.2}% + \begin{array}{@{}l@{}>{\quad}l@{}}% +}{% + \end{array}\right.% +} + +%%% -------------------------------------------------------- +%%> \section{Activate definitions at the beginning of the document} +%%% -------------------------------------------------------- + +\NewDocumentCommand\mdm@activate@base{}{ + \let \medmath = \mdm@base@medmath + \let \medop = \mdm@base@medop + \let \medintcorr = \mdm@base@medintcorr + \let \medint = \mdm@base@medint + \let \mfrac = \mdm@base@mfrac + \let \mbinom = \mdm@base@mbinom + \let \medsize = \mdm@base@medsize + \let \endmedsize = \endmdm@base@medsize + \let \mmatrix = \mdm@base@mmatrix + \let \endmmatrix = \endmdm@base@mmatrix + \let \MultiIntegral = \mdm@base@MultiIntegral +} + +\NewDocumentCommand\mdm@activate@all{}{% + \mdm@activate@base + \let \frac = \mdm@all@frac + \let \binom = \mdm@all@binom + \let \coprod = \mdm@all@coprod + \let \bigvee = \mdm@all@bigvee + \let \bigwedge = \mdm@all@bigwedge + \let \biguplus = \mdm@all@biguplus + \let \bigcap = \mdm@all@bigcap + \let \bigcup = \mdm@all@bigcup + \let \prod = \mdm@all@prod + \let \sum = \mdm@all@sum + \let \bigotimes = \mdm@all@bigotimes + \let \bigoplus = \mdm@all@bigoplus + \let \bigodot = \mdm@all@bigodot + \let \bigsqcup = \mdm@all@bigsqcup + \let \intop = \mdm@all@intop + \let \int = \mdm@all@int + \let \ointop = \mdm@all@ointop + \let \oint = \mdm@all@oint + \ifdef{\oiint}{% + \let \oiintop = \mdm@all@oiintop + \let \oiint = \mdm@all@oiint + }{}% + \let \MultiIntegral = \mdm@all@MultiIntegral + \let \intkern@ = \mdm@all@intkern@ + \let \intdots@ = \mdm@all@intdots@ + \let \cases = \mdm@all@cases + \let \endcases = \endmdm@all@cases +} + +\AtBeginDocument{% + \ifbool{mdm@bare}{}{% + \ifbool{mdm@base}{\mdm@activate@base}{\mdm@activate@all}% + }% +} + |