% \iffalse meta-comment % % Copyright (C) 2004-2011 by Morten Hoegholm % Copyright (C) 2012-2019 by Lars Madsen % Copyright (C) 2020- by Lars Madsen, The LaTeX3 team % % This work may be distributed and/or modified under the % conditions of the LaTeX Project Public License, either % version 1.3c of this license or (at your option) any later % version. The latest version of this license is in % http://www.latex-project.org/lppl.txt % and version 1.3c or later is part of all distributions of % LaTeX version 2008/05/05 or later. % % This work has the LPPL maintenance status "maintained". % % This Current Maintainer of this work is % Lars Madsen % % This work consists of the main source file mathtools.dtx % and the derived files % mathtools.sty, mathtools.pdf, mathtools.ins, mathtools.drv. % % Distribution: % CTAN:macros/latex/contrib/mh/mathtools.dtx % CTAN:macros/latex/contrib/mh/mathtools.pdf % % Unpacking: % (a) If mathtools.ins is present: % tex mathtools.ins % (b) Without mathtools.ins: % tex mathtools.dtx % (c) If you insist on using LaTeX % latex \let\install=y\input{mathtools.dtx} % (quote the arguments according to the demands of your shell) % % Documentation: % (a) If mathtools.drv is present: % latex mathtools.drv % (b) Without mathtools.drv: % latex mathtools.dtx; ... % The class ltxdoc loads the configuration file ltxdoc.cfg % if available. Here you can specify further options, e.g. % use A4 as paper format: % \PassOptionsToClass{a4paper}{article} % % Programm calls to get the documentation (example): % pdflatex mathtools.dtx % makeindex -s gind.ist mathtools.idx % pdflatex mathtools.dtx % makeindex -s gind.ist mathtools.idx % pdflatex mathtools.dtx % % Installation: % TDS:tex/latex/mh/mathtools.sty % TDS:doc/latex/mh/mathtools.pdf % TDS:source/latex/mh/mathtools.dtx % %<*ignore> \begingroup \def\x{LaTeX2e} \expandafter\endgroup \ifcase 0\ifx\install y1\fi\expandafter \ifx\csname processbatchFile\endcsname\relax\else1\fi \ifx\fmtname\x\else 1\fi\relax \else\csname fi\endcsname % %<*install> \input docstrip.tex \Msg{************************************************************************} \Msg{* Installation} \Msg{* Package: mathtools 2024/10/04 v1.31} \Msg{************************************************************************} \keepsilent \askforoverwritefalse \preamble This is a generated file. Copyright (C) 2002-2011 by Morten Hoegholm Copyright (C) 2012-2019 by Lars Madsen Copyright (C) 2020- by Lars Madsen, the LaTeX3 project This work may be distributed and/or modified under the conditions of the LaTeX Project Public License, either version 1.3c of this license or (at your option) any later version. The latest version of this license is in http://www.latex-project.org/lppl.txt and version 1.3c or later is part of all distributions of LaTeX version 2008/05/04 or later. This work has the LPPL maintenance status "maintained". This Current Maintainer of this work is Lars Madsen and the LaTeX3 project This work consists of the main source file mathtools.dtx and the derived files mathtools.sty, mathtools.pdf, mathtools.ins, mathtools.drv. \endpreamble \generate{% \file{mathtools.ins}{\from{mathtools.dtx}{install}}% \file{mathtools.drv}{\from{mathtools.dtx}{driver}}% \usedir{tex/latex/mh}% \file{mathtools.sty}{\from{mathtools.dtx}{package}}% } \obeyspaces \Msg{************************************************************************} \Msg{*} \Msg{* To finish the installation you have to move the following} \Msg{* file into a directory searched by TeX:} \Msg{*} \Msg{* mathtools.sty} \Msg{*} \Msg{* To produce the documentation run the file `mathtools.drv'} \Msg{* through LaTeX.} \Msg{*} \Msg{* Happy TeXing!} \Msg{*} \Msg{************************************************************************} \endbatchfile % %<*ignore> \fi % %<*driver> \NeedsTeXFormat{LaTeX2e} \ProvidesFile{mathtools.drv}% [2024/10/04 v1.31 mathematical typesetting tools] \documentclass{ltxdoc} \IfFileExists{fourier.sty}{\usepackage{fourier}}{} \addtolength\marginparwidth{-25pt} \usepackage{mathtools} \setcounter{IndexColumns}{2} \providecommand*\pkg[1]{\textsf{#1}} \providecommand*\env[1]{\texttt{#1}} \providecommand*\email[1]{\href{mailto:#1}{\texttt{#1}}} \providecommand*\mode[1]{\texttt{[#1]}} \providecommand*\file[1]{\texttt{#1}} \usepackage{xcolor,varioref,amssymb} \makeatletter \newcommand*\thinfbox[2][black]{\fboxsep0pt\textcolor{#1}{\rulebox{{\normalcolor#2}}}} \newcommand*\thinboxed[2][black]{\thinfbox[#1]{\ensuremath{\displaystyle#2}}} \newcommand*\rulebox[1]{% \sbox\z@{\ensuremath{\displaystyle#1}}% \@tempdima\dp\z@ \hbox{% \lower\@tempdima\hbox{% \vbox{\hrule height\fboxrule\box\z@\hrule height\fboxrule}% }% }% } \newenvironment{codesyntax} {\par\small\addvspace{4.5ex plus 1ex}% \vskip -\parskip \noindent \begin{tabular}{|l|}\hline\ignorespaces}% {\\\hline\end{tabular}\nobreak\par\nobreak \vspace{2.3ex}\vskip -\parskip\noindent\ignorespacesafterend} \makeatletter \newcommand*\FeatureRequest[2]{% \hskip1sp \marginpar{% \parbox[b]{\marginparwidth}{\small\sffamily\raggedright \strut Feature request by\\#1\\#2% } }% } \newcommand*\ProvidedBy[2]{% \hskip1sp \marginpar{% \parbox[b]{\marginparwidth}{\small\sffamily\raggedright \strut Feature provided by\\#1\\#2% } }% } \newcommand*\SuggestedBy[2]{% \hskip1sp \marginpar{% \parbox[b]{\marginparwidth}{\small\sffamily\raggedright \strut Suggested by\\#1\\#2% } }% } \newcommand*\cttPosting[2]{% \hskip1sp \marginpar{% \parbox[b]{\marginparwidth}{\small\sffamily\raggedright \strut Posted on \texttt{comp.text.tex} \\#1\\#2% }% }% } \newcommand*\tsxPosting[2]{% \hskip1sp \marginpar{% \parbox[b]{\marginparwidth}{\small\sffamily\raggedright \strut Posted on \texttt{\small tex.stackexchange.com} \\#1\\#2% }% }% } \newcommand*\tsxchatPosting[3][Requested on]{% \hskip1sp \marginpar{% \parbox[b]{\marginparwidth}{\small\sffamily\raggedright \strut #1 \texttt{\scriptsize tex.stackexchange.com chat} \\#2\\#3% }% }% } \newcommand*\CommentAdded[1]{% \hskip1sp \marginpar{% \parbox[b]{\marginparwidth}{\small\sffamily\raggedright \strut Comment added\\#1% }% }% } \expandafter\def\expandafter\MakePrivateLetters\expandafter{% \MakePrivateLetters \catcode`\_=11\relax } \providecommand*\SpecialOptIndex[1]{% \@bsphack \index{#1\actualchar{\protect\ttfamily #1} (option)\encapchar usage}% \index{options:\levelchar#1\actualchar{\protect\ttfamily #1}\encapchar usage}\@esphack} \providecommand*\opt[1]{\texttt{#1}} \providecommand*\SpecialKeyIndex[1]{% \@bsphack \index{#1\actualchar{\protect\ttfamily #1} (key)\encapchar usage}% \index{keys:\levelchar#1\actualchar{\protect\ttfamily #1}\encapchar usage}\@esphack} \providecommand*\key[1]{\textsf{#1}} \providecommand*\eTeX{$\m@th\varepsilon$-\TeX} \def\MTmeta#1{% \ensuremath\langle \ifmmode \expandafter \nfss@text \fi {% \meta@font@select \edef\meta@hyphen@restore {\hyphenchar\the\font\the\hyphenchar\font}% \hyphenchar\font\m@ne \language\l@nohyphenation #1\/% \meta@hyphen@restore }\ensuremath\rangle \endgroup } \makeatother \DeclareRobustCommand\meta{\begingroup\MakePrivateLetters\MTmeta}% \def\MToarg#1{{\ttfamily[}\meta{#1}{\ttfamily]}\endgroup} \DeclareRobustCommand\oarg{\begingroup\MakePrivateLetters\MToarg}% \def\MHmarg#1{{\ttfamily\char`\{}\meta{#1}{\ttfamily\char`\}}\endgroup} \DeclareRobustCommand\marg{\begingroup\MakePrivateLetters\MHmarg}% \def\MHarg#1{{\ttfamily\char`\{#1\ttfamily\char`\}}\endgroup} \DeclareRobustCommand\arg{\begingroup\MakePrivateLetters\MHarg}% \def\MHcs#1{\texttt{\char`\\#1}\endgroup} \DeclareRobustCommand\cs{\begingroup\MakePrivateLetters\MHcs} \def\endverbatim{\if@newlist \leavevmode\fi\endtrivlist\vspace{-\baselineskip}} \expandafter\let\csname endverbatim*\endcsname =\endverbatim \let\MTtheindex\theindex \def\theindex{\MTtheindex\MakePrivateLetters} \NewDocumentCommand\Framebox{ o O{c} m }{% \IfNoValueTF{#1}{% \framebox{\footnotesize\strut #3}% }{% \framebox[#1][#2]{\footnotesize\strut #3}% }% } %\usepackage[draft]{fixme} %\fxsetup{ % multiuser, %layout=marginnote, %} %\providecommand\fxnote[2][]{} \usepackage{xurl} \usepackage[final, hyperindex=false, colorlinks, ]{hyperref} \renewcommand*\usage[1]{\textit{\hyperpage{#1}}} \OnlyDescription \begin{document} \DocInput{mathtools.dtx} \end{document} % % \fi % % \changes{v1.19}{2017/03/31}{Updated to match some macro renaming in % \pkg{mhsetup}} % \changes{v1.0}{2004/07/26}{Initial release} % % \GetFileInfo{mathtools.drv} % % \CheckSum{3775} % % \title{The \pkg{mathtools} package\thanks{This file has version number % \fileversion, last revised \filedate.}} % % \author{Morten Høgholm, Lars Madsen and the \LaTeX3 project} % \date{\filedate} % % \maketitle % % \begin{abstract} % \noindent The \pkg{mathtools} package is an extension package to % \pkg{amsmath}. There are two things on \pkg{mathtools}' agenda: % (1)~correct various bugs/deficiencies in \pkg{amsmath} until % these are fixed by the \AmS{} and (2)~provide useful tools % for mathematical typesetting, be it a small macro for % typesetting a prescript or an underbracket, or entirely new % display math constructs such as a \env{multlined} environment. % \end{abstract} % % \tableofcontents % % \section{Introduction} % % Although \pkg{amsmath} provides many handy tools for mathematical % typesetting, it is nonetheless a static package. This is not a bad % thing, because what it does, it mostly does quite well and having % a stable math typesetting package is ``a good thing.'' However, % \pkg{amsmath} does not fulfill all the needs of the mathematical % part of the \LaTeX{} community, resulting in many authors writing % small snippets of code for tweaking the mathematical layout. Some % of these snippets have also been posted to newsgroups and mailing % lists over the years, although more often than not without being % released as stand-alone packages. % % The \pkg{mathtools} package is exactly what its name implies: tools % for mathematical typesetting. It is a collection of many of these % often needed small tweaks---with some big tweaks added as well. It % can only do so by having harvesting newsgroups for code and/or you % writing the maintainers with wishes for code to be included, so if % you have any good macros or just macros that help you when writing % mathematics, then don't hesitate to report them. % % As of 2020, \pkg{mathtools} (and \pkg{empheq}) is now hosted at the % \LaTeX3 team GitHub at % \begin{center} % \url{https://github.com/latex3/mathtools} % \end{center} % So if you have any issue, feel free to register an issue there. % % \medskip\noindent % Update 2013: We now make \cs{(}\cs{)} and \cs[\cs] % robust (can be disabled via \texttt{nonrobust} package option). % % \section{Package loading} % % % The \pkg{mathtools} package requires \pkg{amsmath} but is able to % pass options to it as well. Thus a line like % \begin{verbatim} % \usepackage[fleqn,tbtags]{mathtools} % \end{verbatim} % is equivalent to % \begin{verbatim} % \usepackage[fleqn,tbtags]{amsmath} % \usepackage{mathtools} % \end{verbatim} % % % \subsection{Special \pkg{mathtools} options} % % \begin{codesyntax} % \SpecialOptIndex{fixamsmath}\opt{fixamsmath}\texttt{~~~~} % \SpecialOptIndex{donotfixamsmathbugs}\opt{donotfixamsmathbugs} % \end{codesyntax} % The option \opt{fixamsmath} (default) fixes two bugs in % \pkg{amsmath}.\footnote{See the online \LaTeX{} bugs database % \url{http://www.latex-project.org/cgi-bin/ltxbugs2html} under % \AmS-\LaTeX{} problem reports 3591 and 3614.} Should you for some % reason not want to fix these bugs then just add the option % \opt{donotfixamsmathbugs} (if you can do it without typos). The % reason for this extremely long name is that I really don't see why % you wouldn't want these bugs to be fixed, so I've made it slightly % difficult not to fix them. % % \begin{codesyntax} % \SpecialOptIndex{allowspaces}\opt{allowspaces}\texttt{~~~~} % \SpecialOptIndex{disallowspaces}\opt{disallowspaces} % \end{codesyntax} % Sometimes \pkg{amsmath} gives you nasty surprises, as here where % things look seemingly innocent: % \begin{verbatim} % \[ % \begin{gathered} % [t] = 100 \\ % [v] = 200 % \end{gathered} % \] % \end{verbatim} % Without \pkg{mathtools} this will result in this output: % \[ % \begin{gathered}[c] % = 100 \\ % [v] = 200 % \end{gathered} % \] % Yes, the \texttt{[t]} has been gobbled without warning! Note, with % modern \pkg{amsmath} \verb|\begin{gathered}[x]| will eat \verb|[x]| % and \emph{issue a warning unless} \texttt{x} is \texttt{t}, % \texttt{b} or \texttt{c}.\footnote{Older \pkg{amsmath} will % silently gobble the argument.} This is hardly what you'd expect % as an end user, as the desired output was probably something like % this instead: % \[ % \begin{gathered}[c] % [t] = 100 \\ % [v] = 200 % \end{gathered} % \] % With the option \opt{disallowspaces} (default) \pkg{mathtools} % disallows spaces in front of optional arguments where it could % possibly cause problems just as \pkg{amsmath} does with |\\| % inside the display environments. This includes the environments % \env{gathered} (and also those shown in \S % \vref{subsec:gathered}), \env{aligned}, \env{multlined}, and the % extended \env{matrix}-environments (\S \vref{subsubsec:matrices}). % If you however want to preserve the more dangerous standard % optional spaces, simply choose the option \opt{allowspaces}. % % \begin{codesyntax} % \SpecialOptIndex{legacycolonsymbols}\opt{legacycolonsymbols} % \end{codesyntax} % As of Summer 2022, we've had to rename several \cs{...colon...} % symbol macros in order to have a consistent naming scheme across % different packages.\footnote{For example with \pkg{unicode-math}.} % If needed, this package option brings back the original % \cs{...colon...} definitions. See page~\pageref{colonsymbols} for % more information. % % \section{Tools for mathematical typesetting} % % \begin{codesyntax} % \SpecialUsageIndex{\mathtoolsset}\cs{mathtoolsset}\marg{key val list} % \end{codesyntax} % Many of the tools shown in this manual can be turned on and off by % setting a switch to either true or false. In all cases it is done % with the command \cs{mathtoolsset}. A typical use could be something like % \begin{verbatim} % \mathtoolsset{ % showonlyrefs, % mathic % or mathic = true % } % \end{verbatim} % More information on the keys later on. % % % \subsection{Fine-tuning mathematical layout} % % Sometimes you need to tweak the layout of formulas a little to get % the best result and this part of the manual describes the various % macros \pkg{mathtools} provides for this. % % \subsubsection{A complement to \texttt{\textbackslash smash}, % \texttt{\textbackslash llap}, and \texttt{\textbackslash rlap}} % % \begin{codesyntax} % \SpecialUsageIndex{\mathllap} % \cs{mathllap}\oarg{mathstyle}\marg{math}\texttt{~~} % \SpecialUsageIndex{\mathclap} % \cs{mathclap}\oarg{mathstyle}\marg{math}\\ % \SpecialUsageIndex{\mathrlap} % \cs{mathrlap}\oarg{mathstyle}\marg{math}\texttt{~~} % \SpecialUsageIndex{\clap} % \cs{clap}\marg{text}\\ % \SpecialUsageIndex{\mathmbox} % \cs{mathmbox}\marg{math}\phantom{\meta{mathstyle}}\texttt{~~~~} % \SpecialUsageIndex{\mathmakebox} % \cs{mathmakebox}\oarg{width}\oarg{pos}\marg{math} % \end{codesyntax} % In \cite{Perlis01}, Alexander R.~Perlis describes some simple yet % useful macros for use in math displays. For example the display % \begin{verbatim} % \[ % X = \sum_{1\le i\le j\le n} X_{ij} % \] % \end{verbatim} % \[ % X = \sum_{1\le i\le j\le n} X_{ij} % \] % contains a lot of excessive white space. The idea that comes to % mind is to fake the width of the subscript. The command % \cs{mathclap} puts its argument in a zero width box and centers % it, so it could possibly be of use here. % \begin{verbatim} % \[ % X = \sum_{\mathclap{1\le i\le j\le n}} X_{ij} % \] % \end{verbatim} % \[ % X = \sum_{\mathclap{1\le i\le j\le n}} X_{ij} % \] % For an in-depth discussion of % these macros I find it better to read the article; an online % version can be found at % \begin{quote} % \url{http://www.tug.org/TUGboat/Articles/tb22-4/tb72perlS.pdf} % \end{quote} % Note that the definitions shown in the article do not exactly % match the definitions in \pkg{mathtools}. Besides providing an % optional argument for specifying the desired math style, these % versions also work around a most unfortunate \TeX{} % ``feature.''\footnote{The faulty reboxing procedure.} The % \cs{smash} macro is fixed too. % % % \subsubsection{Forcing a cramped style} % % \begin{codesyntax} % \SpecialUsageIndex{\cramped} % \cs{cramped}\oarg{mathstyle}\marg{math} % \end{codesyntax} % \cttPosting{Michael Herschorn}{1992/07/21} % Let's look at another example where we have used \cs{mathclap}: % \begin{verbatim} % \begin{equation}\label{eq:mathclap} % \sum_{\mathclap{a^20$\\ % x^3 & else % \end{rcases*} \quad \Rightarrow \cdots % \] % \end{verbatim} % \[ % \begin{rcases*} % x^2 & for $x>0$\\ % x^3 & else % \end{rcases*} \quad \Rightarrow\cdots % \] % % % \subsubsection{Emulating indented lines in alignments} % \begin{codesyntax} % \SpecialEnvIndex{\MoveEqLeft}\cs{MoveEqLeft}\oarg{number} % \end{codesyntax} % \ProvidedBy{Lars Madsen}{2008/06/05} In \cite{Swanson}, Ellen % Swanson recommends that whenever one has a long displayed formula, % spanning several lines, and it is unfeasible to align against a % relation within the first line, then all lines in the display % should be aligned at the left most edge of the first line, and all % subsequent lines should be indented by 2\,em (or if needed by a % smaller amount). That is we are talking about displays that end up % looking like this\footnote{Maintainer (daleif)'s note: This is one % of my most used constructions whenever I edit manuscripts. I'd % rather use this than for example \env{multline} as I find it gives % the text a more consistent look.} % \begin{align*} % \MoveEqLeft \Framebox[10cm][c]{Long first line}\\ % & = \Framebox[6cm][c]{2nd line}\\ % & \leq \dots % \end{align*} % Traditionally one could do this by starting subsequent lines by % \verb+&\qquad ...+, but that is tedious. Instead the example above % was made using \cs{MoveEqLeft}: % \begin{verbatim} % \begin{align*} % \MoveEqLeft \Framebox[10cm][c]{Long first line}\\ % & = \Framebox[6cm][c]{2nd line}\\ % & \leq \dots % \end{align*} % \end{verbatim} % \cs{MoveEqLeft} is placed instead of the \verb+&+ on the first % line, and will effectively \emph{move} the entire first line % \oarg{number} of ems to the left (default is 2). If you choose to % align to the right of the relation, use \cs{MoveEqLeft}\verb+[3]+ % to accommodate the extra distance to the alignment point: % \begin{verbatim} % \begin{align*} % \MoveEqLeft[3] \Framebox[10cm][c]{Part 1}\\ % = {} & \Framebox[8cm][c]{2nd line}\\ % & + \Framebox[4cm][c]{last part} % \end{align*} % \end{verbatim} % \begin{align*} % \MoveEqLeft[3] \Framebox[10cm][c]{Long first line}\\ % = {} & \Framebox[6cm][c]{2nd line}\\ % & + \Framebox[4cm][c]{last part} % \end{align*} % % % \noindent\textbf{Caveat regarding \cs{MoveEqLeft}}: If the first % part of the equation starts with say \verb|[a]|, \cs{MoveEqLeft} may % attempt to eat it! You can prevent this by specifying the optional % argument (remember the default is the same as \cs{MoveEqLeft[2]}) or % by using \cs{MoveEqLeft\{\}}. % % \subsubsection{Boxing a single line in an alignment} % % The \texttt{amsmath} package provides the \cs{boxed} macro to box % material in math mode. But this of course will not work if the box % should cross an alignment point. We provide a macro that % can.\footnote{Note that internally \cs{Aboxed} does use % \cs{boxed}.} \hskip1sp \marginpar{% % \parbox[b]{\marginparwidth}{\small\sffamily\raggedright % \strut Evolved from a request by\\Merciadri Luca\\ % 2010/06/28\\on comp.text.tex% % }\strut % }% % \marginpar{\strut\\% % \parbox[b]{\marginparwidth}{\small\sffamily\raggedright % \strut Reimplemented by\\Florent Chervet (GL) \\ % 2011/06/11\\on comp.text.tex% % }\strut % }% % \begin{codesyntax} % \SpecialEnvIndex{\Aboxed}\cs{Aboxed}\marg{left hand side % \quad\texttt{\textnormal{\&}}\quad right hand side} % \end{codesyntax} % Example % \begin{verbatim} % \begin{align*} % \Aboxed{ f(x) & = \int h(x)\, dx} \\ % & = g(x) % \end{align*} % \end{verbatim} % Resulting in: % \begin{align*} % \Aboxed{ f(x) & = \int h(x)\, dx} \\ % & = g(x) % \end{align*} % One can have multiple boxes on each line, and the % ``\texttt{\textnormal{\&}}\quad right hand side'' can even be % missing. Here is an example of how the padding in the box can be changed. % \begin{verbatim} % \begin{align*} % \setlength\fboxsep{1em} % \Aboxed{ f(x) &= 0 } & \Aboxed{ g(x) &= b} \\ % \Aboxed{ h(x) } & \Aboxed{ i(x) } % \end{align*} % \end{verbatim} % \begin{align*} % \setlength\fboxsep{1em} % \Aboxed{ f(x) &= 0 } & \Aboxed{ g(x) &= b} \\ % \Aboxed{ h(x) } & \Aboxed{ i(x) } % \end{align*} % Note how the \cs{fboxsep} change only affects the box coming % immediately after it. % % \marginpar{\strut\\% % \parbox[b]{\marginparwidth}{\small\sffamily\raggedright % \strut Comment by Qrrbrbirlbel on \url{tex.stackexchange.com}, 2013/05/20. % }\strut % }% % As \cs{Aboxed} looks for the alignment \texttt{\&} it may be % necessary to \emph{hide} constructions like matrices that also make % use of \texttt{\&}. Just add a set of braces around the construction % you want to hide. % % \medskip\noindent\textbf{Tip:} At times users want a \cs{Aboxed} % with a different type of box. To help we provide a \cs{Aboxed} builder: % \begin{codesyntax} % \SpecialUsageIndex{\MakeAboxedCommand}\cs{MakeAboxedCommand}\cs{Aboxedname}\cs{boxmacro} % \end{codesyntax} % where \cs{boxname} should be a macro taking a single argument. The % normal \cs{Aboxed} is the same as % \verb|\MakeAboxedCommand\Aboxed\fbox|. Thus you can do % \newcommand\myboxA[1]{\fcolorbox{gray}{yellow}{#1}} % \newcommand\myboxB[1]{{\fboxsep=5pt\fboxrule=2pt\fbox{#1}}} % \MakeAboxedCommand\AboxedA\myboxA % \MakeAboxedCommand\AboxedB\myboxB % \begin{align*} % \AboxedA{ f(x) &= x^2 } & \AboxedB{ f(x) &= x^2 } % \end{align*} % via % \begin{verbatim} % \newcommand\myboxA[1]{\fcolorbox{gray}{yellow}{#1}} % \newcommand\myboxB[1]{{\fboxsep=5pt\fboxrule=2pt\fbox{#1}}} % \MakeAboxedCommand\AboxedA\myboxA % \MakeAboxedCommand\AboxedB\myboxB % \begin{align*} % \AboxedA{ f(x) &= x^2 } & \AboxedB{ f(x) &= x^2 } % \end{align*} % \end{verbatim} % % % \subsubsection{Adding arrows between lines in an alignment} % % This first macro is a bit misleading, it is only intended to be % used in combination with the \env{alignat(*)} environment. % \begin{codesyntax} % \SpecialEnvIndex{\ArrowBetweenLines}\cs{ArrowBetweenLines}\oarg{symbol}\\ % \SpecialEnvIndex{\ArrowBetweenLines*}\cs{ArrowBetweenLines*}\oarg{symbol} % \end{codesyntax} % \hskip1sp % \marginpar{% % \parbox[b]{\marginparwidth}{\small\sffamily\raggedright % \strut Evolved from a request by\\Christian % Bohr-Halling\\2004/03/31\\on dk.edb.tekst% % } % }% % To add, say $\Updownarrow$ between two lines in an alignment use % \cs{ArrowBetweenLines} and the \env{alignat} environment (note the % extra pair of \texttt{\&}'s in front): % \begin{verbatim} % \begin{alignat}{2} % && \framebox[1.5cm]{} &= \framebox[3cm]{}\\ % \ArrowBetweenLines % \Updownarrow is the default % && \framebox[1.5cm]{} &= \framebox[2cm]{} % \end{alignat} % \end{verbatim} % resulting in % \begin{alignat}{2} % && \framebox[1.5cm]{} &= \framebox[3cm]{}\\ % \ArrowBetweenLines % && \framebox[1.5cm]{} &= \framebox[2cm]{} % \end{alignat} % Note the use of \verb+&&+ starting each \emph{regular} line of % math. For adding the arrow on the right, use % \cs{ArrowBetweenLines*}\oarg{symbol}, and end each line of math % with \verb+&&+. % \begin{verbatim} % \begin{alignat*}{2} % \framebox[1.5cm]{} &= \framebox[3cm]{} &&\\ % \ArrowBetweenLines*[\Downarrow] % \framebox[1.5cm]{} &= \framebox[2cm]{} && % \end{alignat*} % \end{verbatim} % resulting in % \begin{alignat*}{2} % \framebox[1.5cm]{} &= \framebox[3cm]{} &&\\ % \ArrowBetweenLines*[\Downarrow] % \framebox[1.5cm]{} &= \framebox[2cm]{} && % \end{alignat*} % % % \subsubsection{Centered \texorpdfstring{\cs{vdots}}{\textbackslash vdots}} % % If one wants to mark a vertical continuation, there is % the \verb?\vdots? command, but combine this with an alignment and % we get something rather suboptimal % \FeatureRequest{Bruno Le Floch \\(and many others)}{2011/01/25} % \begin{align*} % \framebox[1.5cm]{} &= \framebox[3cm]{}\\ % & \vdots\\ % &= \framebox[3cm]{} % \end{align*} % It would be nice to have (1) a \verb?\vdots? centered within the % width of another symbol, and (2) a construction similar to % \verb?\ArrowBetweenLines? that does not take up so much space. % We provide both. % \begin{codesyntax} % \SpecialUsageIndex{\vdotswithin}\cs{vdotswithin}\marg{symbol}\\ % \SpecialUsageIndex{\shortvdotswithin}\cs{shortvdotswithin}\marg{symbol}\\ % \SpecialUsageIndex{\shortvdotswithin*}\cs{shortvdotswithin*}\marg{symbol}\\ % \SpecialUsageIndex{\MTFlushSpaceAbove}\cs{MTFlushSpaceAbove}\\ % \SpecialUsageIndex{\MTFlushSpaceBelow}\cs{MTFlushSpaceBelow}\\ % \SpecialKeyIndex{shortvdotsadjustabove}\makebox{$\key{shortvdotsadjustabove}=\meta{length}$}\\ % \SpecialKeyIndex{shortvdotsadjustbelow}\makebox{$\key{shortvdotsadjustbelow}=\meta{length}$} % \end{codesyntax} % Two examples in one % \begin{verbatim} % \begin{align*} % a &= b \\ % & \vdotswithin{=} \\ % & = c \\ % \shortvdotswithin{=} % & = d % \end{align*} % \end{verbatim} % yielding % \begin{align*} % a &= b \\ % & \vdotswithin{=} \\ % & = c \\ % \shortvdotswithin{=} % & = d % \end{align*} % Thus \verb?\vdotswithin{=}? creates a box corresponding to % \verb?{}={}? and typesets a ``$\vdots$'' centered inside it. When % doing this as a normal line in an alignment leaves us with excessive % space which \verb?\shortvdotswithin{=}? takes care with for us. % % The macro call \verb?\shortvdotswithin{=}? corresponds to % \begin{verbatim} % \MTFlushSpaceAbove % & \vdotswithin{=} % \MTFlushSpaceBelow % \end{verbatim} % whereas \verb?\shortvdotswithin*{=}? is the case with % \begin{verbatim} % \MTFlushSpaceAbove % \vdotswithin{=} & % \MTFlushSpaceBelow % \end{verbatim} % Note how \verb?\MTFlushSpaceBelow? implicitly adds a \verb?\\? at % the end of the line. Thus one cannot have more on the line when % using \verb?\shortvdotswithin? or the starred version. But, if % needed, one can de-construct the macro and arrive at % \begin{verbatim} % \begin{alignat*}{3} % A&+ B &&= C &&+ D \\ % \MTFlushSpaceAbove % &\vdotswithin{+} &&&& \vdotswithin{+} % \MTFlushSpaceBelow % C &+ D &&= Y &&+K % \end{alignat*} % \end{verbatim} % yielding % \begin{alignat*}{3} % A&+ B &&= C &&+ D \\ % \MTFlushSpaceAbove % &\vdotswithin{+} &&&& \vdotswithin{+} % \MTFlushSpaceBelow % C &+ D &&= Y &&+K % \end{alignat*} % If one has the need for such a construction. % % The de-spaced version does support the \env{spreadlines} % environment. The actual amount of space being \emph{flushed} above % and below can be controlled by the user using the two options % indicated. Their original values are \verb?2.15\origjot? and % \verb?\origjot? respectively (\verb?\origjot? is usually 3pt). % % \subsection{Intertext and short intertext} % % % \begin{codesyntax} % \SpecialUsageIndex{\shortintertext}\cs{shortintertext}\marg{text} % \end{codesyntax} % \cttPosting{Gabriel Zachmann and Donald Arseneau}{2000/05/12--13} % \pkg{amsmath} provides the command \cs{intertext} for interrupting % a multiline display while still maintaining the alignment points. % However the spacing often seems quite excessive as seen below. % \begin{verbatim} % \begin{align} % a&=b \intertext{Some text} % c&=d % \end{align} % \end{verbatim} % \begin{align} % a&=b \intertext{Some text} % c&=d % \end{align} % % Using the command \cs{shortintertext} alleviates this situation % somewhat: % \begin{verbatim} % \begin{align} % a&=b \shortintertext{Some text} % c&=d % \end{align} % \end{verbatim} % \begin{align} % a&=b \shortintertext{Some text} % c&=d % \end{align} % % \noindent % It turns out that both \cs{shortintertext} and the original % \cs{intertext} from \pkg{amsmath} has a slight problem. If we use % the \env{spreadlines} (see section~\ref{sec:spread}) to open up % the equations in a multiline calculation, then this opening up % value also applies to the spacing above and below the original % \cs{shortintertext} and \cs{intertext}. \tsxPosting{Tobias Weh % \\(referring to a suggestion by Chung-chieh Shan)}{2011/05/29} % It can be illustrated using the following example, an interested % reader can apply it with and without the original \cs{intertext} % and \cs{shortintertext}. % \begin{verbatim} % % the original \intertext and \shortintertext % \mathtoolsset{original-intertext,original-shortintertext} % \newcommand\myline{\par\noindent\rule{\textwidth}{1mm}} % \myline % \begin{spreadlines}{1em} % \begin{align*} % AA\\ BB\\ \intertext{\myline} % AA\\ BB\\ \shortintertext{\myline} % AA\\ BB % \end{align*} % \end{spreadlines} % \myline % \end{verbatim} % % We now fix this internally for both \cs{intertext} and % \cs{shortintertext}, plus we add the possibility to fine-tune % spacing around these constructions. The original versions can be % brought back using the \texttt{original-x} keys below. % \begin{codesyntax} % \SpecialUsageIndex{\intertext}\cs{intertext}\marg{text}\\ % \SpecialUsageIndex{\shortintertext}\cs{shortintertext}\marg{text}\\ % \SpecialKeyIndex{original-intertext}$\key{original-intertext}=\texttt{true}\vert\texttt{false}$ \quad(default: \texttt{false})\\ % \SpecialKeyIndex{original-shortintertext}$\key{original-shortintertext}=\texttt{true}\vert\texttt{false}$ % \quad(default: \texttt{false})\\ % \SpecialKeyIndex{above-intertext-sep}$\key{above-intertext-sep}=\meta{dimen}$ \quad(default: 0pt)\\ % \SpecialKeyIndex{below-intertext-sep}$\key{below-intertext-sep}=\meta{dimen}$ \quad(default: 0pt)\\ % \SpecialKeyIndex{above-shortintertext-sep}$\key{above-shortintertext-sep}=\meta{dimen}$ \quad(default: 3pt)\\ % \SpecialKeyIndex{below-shortintertext-sep}$\key{below-shortintertext-sep}=\meta{dimen}$ \quad(default: 3pt) % \end{codesyntax} % The updated \cs{shortintertext} will look like the original version % unless for areas with an enlarged \cs{jot} value (see for example % the \env{spreadlines}, section~\ref{sec:spread}). Whereas \cs{intertext} % will have a slightly smaller value above and below (corresponding % to about 3pt less space above and below), the spacing around % \cs{intertext} should now match the normal spacing going into and % out of an \env{align}. % % \textbf{Tip:} \cs{intertext} and \cs{shortintertext} also works % within \env{gather}. % % % \subsection{Paired delimiters} % % % \begin{codesyntax} % \SpecialUsageIndex{\DeclarePairedDelimiter} % \cs{DeclarePairedDelimiter}\marg{cmd}\marg{left_delim}\marg{right_delim} % \end{codesyntax} % \FeatureRequest{Lars Madsen}{2004/06/25} % In the \pkg{amsmath} documentation it is shown how to define a few % commands for typesetting the absolute value and norm. These % definitions are: % \begin{verbatim} % \newcommand*\abs[1]{\lvert#1\rvert} % \newcommand*\norm[1]{\lVert#1\rVert} % \end{verbatim} % \DeclarePairedDelimiter\abs\lvert\rvert % While they produce correct horizontal spacing you have to be % careful about the vertical spacing if the argument is just a % little taller than usual as in % \[ % \abs{\frac{a}{b}} % \] % Here it won't give a nice result, so you have to manually put in % either a \cs{left}--\cs{right} pair or a \cs{bigl}--\cs{bigr} pair. % Both methods mean that you have to delete your \cs{abs} command, % which may not sound like an ideal solution. % % With the command \cs{DeclarePairedDelimiter} you can combine all % these features in one easy to use command. Let's show an example: % \begin{verbatim} % \DeclarePairedDelimiter\abs{\lvert}{\rvert} % \end{verbatim} % This defines the command \cs{abs} just like in the % \pkg{amsmath} documentation but with a few additions: % \begin{itemize} % \item A starred variant: \cs{abs*} produces delimiters that are preceded % by \cs{left} and \cs{right} resp.: % \begin{verbatim} % \[ % \abs*{\frac{a}{b}} % \] % \end{verbatim} % \[ % \abs*{\frac{a}{b}} % \] % \item A variant with an optional argument: % \cs{abs}\oarg{size_cmd}, where % \meta{size_cmd} is either \cs{big}, \cs{Big}, \cs{bigg}, or % \cs{Bigg} (if you have any bigggger versions you can use them % too). % \begin{verbatim} % \[ % \abs[\Bigg]{\frac{a}{b}} % \] % \end{verbatim} % \[ % \abs[\Bigg]{\frac{a}{b}} % \] % \end{itemize} % % \paragraph{A note on the delimiters.} Whenever the manual scalings % are used we internally convert them into their \cs{...l} and % \cs{...r} variants. Therefore if you define your own manual % scalers, remember to also have -l and -r variants. % \\ % \emph{New from version 1.30.} You can now use »\verb|.|« (dot) % as an empty delimiter, for macros what only have a delimiter on one % side.\footnote{The syntax is borrowed from % \cs{left.}\cs{frac\{1\}\{2\}}\cs{right}\cs{rvert} where the dot marks an empty % delimiter. } % % \begin{codesyntax} % \SpecialUsageIndex{\DeclarePairedDelimiterX} % \cs{DeclarePairedDelimiterX}\marg{cmd}\oarg{num args}\marg{left_delim}\marg{right_delim}\marg{body}\\ % \cs{delimsize} % \end{codesyntax} % Sometimes one might want to have the capabilities of % \cs{DeclarePairedDelimiter}, but also want a macro which takes more % than one argument plus being able to specify the body of the % generated macro. % % \cs{DeclarePairedDelimiterX} extends the features of % \cs{DeclarePairedDelimiter} such that the user will get a macro % which is fenced off at either end, plus the capability to provide % the \meta{body} for whatever the macro should do within these % fences. % % Inside the \meta{body} part, the macro \cs{delimsize} refers to the % size of the outer fences. It can then be used inside \meta{body} to % scale any inner fences. % % Thus % \begin{quote} % \cs{DeclarePairedDelimiter}\marg{cmd}\marg{left_delim}\marg{right_delim} % \end{quote} % is the same thing as % \begin{quote} % \cs{DeclarePairedDelimiterX}\marg{cmd}\texttt{[1]}\marg{left_delim}\marg{right_delim}\rlap{\texttt{\{\#1\}}} % \end{quote} % % % Let us do some examples. First we want to prepare a macro for inner % products, with two arguments such that we can hide the character % separating the arguments (a~journal style might require a % semi-colon, so we will save a lot of hand editing). This can be % done via % \begin{verbatim} % \DeclarePairedDelimiterX\innerp[2]{\langle}{\rangle}{#1,#2} % \end{verbatim} % More interestingly we can refer to the size inside the % \meta{code}. Here we do a weird three argument `braket' % \begin{verbatim} % \DeclarePairedDelimiterX\braket[3]{\langle}{\rangle}% % {#1\,\delimsize\vert\,\mathopen{}#2\,\delimsize\vert\,\mathopen{}#3} % \end{verbatim} % \begin{itshape} % Note the use of `\verb|\mathopen{}|' in the \meta{body} of % \cs{braket}, this is very important when a scalable delimiter is % being used and it does not present itself as a left or right % delimiter. You will see why it is needed if you use % \verb|\braket{A}{-B}{C}| in a version without % \verb|\mathopen{}|.\footnote{Basically, the problem is that % \cs{vert} is a `symbol', thus $\vert-B$ is interpreted % \emph{subtraction}, not a symbol followed by negative $B$ (aka a % sign). When \cs{mathopen\{\}} is added, \TeX\ is told that an % opening delimiter just occurred, and it will adjust the minus % accordingly.} % \end{itshape} % % Then we get % \DeclarePairedDelimiterX\innerp[2]{\langle}{\rangle}{#1,#2} % \DeclarePairedDelimiterX\braket[3]{\langle}{\rangle}% % {#1\,\delimsize\vert\,\mathopen{}#2\,\delimsize\vert\,\mathopen{}#3} % \begin{verbatim} % \[ % \innerp*{A}{ \frac{1}{2} } \quad % \braket[\Big]{B}{\sum_{k} f_k}{C} % \] % \end{verbatim} % \[ % \innerp*{A}{ \frac{1}{2} } \quad % \braket[\Big]{B}{\sum_{k}}{C} % \] % % % \iffalse % \bigskip % % \noindent % \textbf{\textit{Side note:}} We have changed the internal code of % \cs{DeclarePairedDelimiter} and \cs{DeclarePairedDelimiterX} such % that the starred version does no longer give the odd spacings that % \cs{left}\dots\cs{right} sometimes give. Compare this % \begin{verbatim} % \[ % 2\innerp{A}{B} \quad 2\innerp*{A}{B} \quad 2\left\langle A,B \right\rangle % \] % \end{verbatim} % \[ % \sin\innerp{A}{B} \quad % \sin\innerp*{A}{B} \quad % \sin\left\langle A,B \right\rangle % \] % The spacing in the last one does not behave like other fences (this % is a feature of the \cs{left}\dots\cs{right} construction). % \fi % % With the inner scaling, we can provide macros whose syntax closely % follows the mathematical meaning. Fx for building sets, try % this\footnote{The reason for using a separate \cs{SetSymbol} macro % has to do with complicated set definitions, where the condition % spans several lines. In this case \cs{Set} cannot be used. Thus it % is nice to be able to refer to the specific set building symbol we % have decided to use in this document. Also remember to add % \cs{allowbreak} \emph{before} the proceeding inserted space. Then % that space will disappear when a line break occurs.} % \begin{verbatim} % % just to make sure it exists % \providecommand\given{} % % can be useful to refer to this outside \Set % \newcommand\SetSymbol[1][]{% % \nonscript\:#1\vert % \allowbreak % \nonscript\: % \mathopen{}} % \DeclarePairedDelimiterX\Set[1]\{\}{% % \renewcommand\given{\SetSymbol[\delimsize]} % #1 % } % \end{verbatim} % \providecommand\given{} % \newcommand\SetSymbol[1][]{\nonscript\:#1\vert\allowbreak\nonscript\:\mathopen{}} % \DeclarePairedDelimiterX\Set[1]\{\}{% % \renewcommand\given{\SetSymbol[\delimsize]} % #1 % } % \begin{verbatim} % \[ \Set*{ x \in X \given \frac{\sqrt{x}}{x^2+1} > 1 } \] % \end{verbatim} % \[ \Set*{ x \in X \given \frac{\sqrt{x}}{x^2+1} > 1 } \] % Thus we end up with a syntax much closer to how we read this % aloud. Also we hide the `given' symbol for easy % replacement.\footnote{The \cs{nonscript} construction removes the % \cs{:} in sub- and superscript, this might not always be % preferable. You can use % \cs{mathchoice\{}\cs{:\}\{}\cs{:\}\{}\cs{,\}\{}\cs{,\}} instead of \cs{nonscript}\cs{:}.} % % Combining with \pkg{etoolbox} it becomes easy to make a function % that automatically provides a marker for a blank argument: % \begin{verbatim} % \usepackage{etoolbox} % \DeclarePairedDelimiterX\norm[1]\lVert\rVert{ % \ifblank{#1}{\:\cdot\:}{#1} % } % \end{verbatim} % Then \verb|\norm{}| will give you $\lVert\:\cdot\:\rVert$ while % \verb|\norm{a}| gives the expected $\lVert a \rVert$. % % \begin{codesyntax} % \SpecialUsageIndex{\DeclarePairedDelimiterXPP} % \cs{DeclarePairedDelimiterXPP}\marg{cmd}\oarg{num args}\marg{pre % code}\marg{left_delim}\\% % \marg{right_delim}\marg{post code}\marg{body} % \end{codesyntax} % \FeatureRequest{Barbara Beeton (on TSE)}{2013/10/07} % \cs{DeclarePairedDelimiterX} has an annoying caveat: it is very hard % to make a macro \verb|\lnorm{a}| that should result in $\lVert % a\rVert_2$.\footnote{The added `\texttt{\_2}' is hard to get around % the argument parsing.} % % As a consequence we provide % \cs{DeclarePairedDelimiterXPP}.\footnote{Extended % DeclarePairedDelimiter with Pre and Post code.} With the addition of % the \marg{pre code} and \marg{post code} it is identical to % \cs{DeclarePairedDelimiterX}. It should be interpreted as % \begin{center} % \marg{pre code} \marg{left_delim} \marg{right_delim} % \marg{post code} \marg{body} % \end{center} % % % An $\mathcal{L}^2$ norm can now be defined as % \begin{verbatim} % \DeclarePairedDelimiterXPP\lnorm[1]{}\lVert\rVert{_2}{#1} % \end{verbatim} % A probability macro with build in support for conditionals % (\cs{given} initialized as above) % \begin{verbatim} % \DeclarePairedDelimiterXPP\Prob[1]{\mathbb{P}}(){}{ % \renewcommand\given{\nonscript\:\delimsize\vert\nonscript\:\mathopen{}} % #1} % \end{verbatim} % Thus giving support for \verb|\Prob{A \given B}|. % % \medskip\noindent\textbf{Note 1:} As the number of arguments increases % the \cs{DeclarePairedDelimiter...} macros become hard for users to % understand. A key-value interface would be better. This is planed % for a future release. In % \url{http://tex.stackexchange.com/a/136767/3929} there is a % suggested replacement for \cs{DeclarePairedDelimiter}, that greatly % reduces the number of macros and provides a key-val % interface. However, the code uses \pkg{xparse}, and if we want to use % \pkg{xparse} for some of our macros, we might just as well rewrite % the entire \pkg{mathtools} package in \pkg{expl3}. Also it is not % obvious how to get \pkg{xparse} to support \verb|[3]| for the number % of arguments. We will consider this for a future release. % % \medskip\noindent\textbf{Note 2:} If you want to define your own % manual scaler macros, it is important that you besides \cs{foo} also % define \cs{fool} and \cs{foor}. When a scaler is specified, in say % \cs{abs[\cs{big}]}\marg{arg}, we actually use \cs{bigl} and % \cs{bigr}. % % \medskip\noindent\textbf{Note 3:} In the unlikely event that you % choose to use, say, \verb+\section{Foo $\norm[\big]{bar}$}+ you will % get an error because \cs{big} is getting expanded too early. Sadly, % due to how \cs{DeclarePairedDelimiter} is implemented one cannot use % \verb|[\protect\big]|. At present (until \pkg{amsmath} makes % \cs{big} and friends robust), the best % solution\footnote{\protect\url{https://tex.stackexchange.com/a/639238/3929}} % is to load the \pkg{etoolbox} package and add \verb|\robustify\big| % and similar to your preamble. % % \subsubsection{Expert use} % % Within the starred version of \cs{DeclarePairedDelimiter} and % \cs{DeclarePairedDelimiterX} we make a few changes such that the % auto scaled \cs{left} and \cs{right} fences behave as opening and % closing fences, i.e.\ $\sin(x)$ vs. $\sin\left(x\right)$ (the later % made via \verb|$\sin\left(x\right)$|), notice the gap between % `$\sin$' and `('. In some special cases it may be useful to be % able to tinker with the behavior. % \begin{codesyntax} % \SpecialUsageIndex{\reDeclarePairedDelimiterInnerWrapper} % \cs{reDeclarePairedDelimiterInnerWrapper}\marg{macro name}\%\\ % \qquad \marg{\textnormal{\texttt{star}} or \textnormal{\texttt{nostarnonscaled}} or \textnormal{\texttt{nostarscaled}}}\marg{code} % \end{codesyntax} % Internally several macros are created, including three call backs % that take care of the formatting. There is one internal macro for % the starred version, labeled \texttt{star}, the other two are % labeled \texttt{nostarnonscaled} and \texttt{nostarscaled}. Within % \meta{code}, \texttt{\#1} will be replaced by the (scaled) left % fence, \texttt{\#3} the corresponding (scaled) right fence, and % \texttt{\#2} the stuff in between. For example, here is how one % might turn the content into \cs{mathinner}: % \begin{verbatim} % \DeclarePairedDelimiter\abs\lvert\rvert % \reDeclarePairedDelimiterInnerWrapper\abs{star}{#1#2#3} % \reDeclarePairedDelimiterInnerWrapper\abs{nostarnonscaled}{\mathinner{#1#2#3}} % \reDeclarePairedDelimiterInnerWrapper\abs{nostarscaled}{\mathinner{#1#2#3}} % \end{verbatim} % The default values for the call backs correspond to % \begin{verbatim} % star: \mathopen{}\mathclose\bgroup #1#2\aftergroup\egroup #3 % nostarnonscaled: \ifx.#1\else\mathopen#1\fi#2\ifx.#3\else\mathclose#3\fi % nostarscaled: \mathopen{#1}#2\mathclose{#3} % \end{verbatim} % The two \texttt{nostar...} versions look the same, but they are % not. In most (math) fonts, the first item in this list will be % different from the rest (the superscript sits % higher).\footnote{Interestingly it did not show up in the font of % this manual, which uses the \pkg{fourier} font set.} % \begin{verbatim} % \mathclose{\rvert}^2\mathclose\rvert^2\rvert^2 % \end{verbatim} % % % \bigskip\noindent \textbf{Breaking change:} Prior to May 2017, we % used two wrappers, the other named \texttt{nostar}. As of May 2017 % \texttt{nostar} has been split into \texttt{nostarnonscaled} and % \texttt{nostarscaled} and \texttt{nostar} alone is no longer % supported (will give an error). % % \bigskip\noindent \textbf{Note:} Since we are using macros to add % the \verb|\left...\right| constructions around some body, it % \emph{is} (in principle) possible to make such a construction % breakable across lines, even breakable within an \env{align} % construction. Currently, this can only be applied to macros made % using \cs{DeclarePairedDelimiter} and \emph{not} macros made using % \cs{DeclarePairedDelimiterX} or \cs{DeclarePairedDelimiterXPP} as % the contents are typeset inside a group (to limit \cs{delimsize}) % and thus hide any \verb|&| or \verb|\\| from \env{align} and % \env{align} breaks down. % % When \cs{DeclarePairedDelimiter} is used, Sebastien Gouezel has % provided the following example \ProvidedBy{Sebastien % Gouezel}{2014/05/14} % \begin{verbatim} % \newcommand\MTkillspecial[1]{% helper macro % \bgroup % \catcode`\&=9 % \let\\\relax% % \scantokens{#1}% % \egroup % } % \DeclarePairedDelimiter\abs\lvert\rvert % \reDeclarePairedDelimiterInnerWrapper\abs{star}{ % \mathopen{#1\vphantom{\MTkillspecial{#2}}\kern-\nulldelimiterspace\right.} % #2 % \mathclose{\left.\kern-\nulldelimiterspace\vphantom{\MTkillspecial{#2}}#3}} % \end{verbatim} % Then this example works just fine: % \begin{verbatim} % \begin{align*} % f(a) &= % \!\begin{aligned}[t] % \abs*{ & \frac{1}{2}+\cdots \\ % & \dots+\frac{1}{2} } % \end{aligned} % \end{align*} % \end{verbatim} % \newcommand\MTkillspecial[1]{% helper macro % \bgroup % \catcode`\&=9 % \let\\\relax% % \scantokens{#1}% % \egroup % } % \let\abs\relax % \MHInternalSyntaxOn % \MH_let:NwN\MT_delim_abs_nostar:\relax % \MHInternalSyntaxOff % \DeclarePairedDelimiter\abs\lvert\rvert % \reDeclarePairedDelimiterInnerWrapper\abs{star}{ % \mathopen{#1\vphantom{\MTkillspecial{#2}}\kern-\nulldelimiterspace\right.} % #2 % \mathclose{\left.\kern-\nulldelimiterspace\vphantom{\MTkillspecial{#2}}#3}} % \begin{align*} % f(a) &= % \!\begin{aligned}[t] % \abs*{&\frac{1}{2}+\cdots \\ % &\dots+\frac{1}{2}} % \end{aligned} % \end{align*} % % % \subsection{Special symbols} % % This part of the manual is about special symbols. So far only one % technique is covered, but more will come. % % \subsubsection{Left and right parentheses} % % \begin{codesyntax} % \SpecialUsageIndex{\lparen}\cs{lparen}\texttt{~~} % \SpecialUsageIndex{\rparen}\cs{rparen} % \end{codesyntax} % When you want a big parenthesis or bracket in a math display you % usually just type % \begin{quote} % |\left( ... \right)|\quad or\quad |\left[ ... \right]| % \end{quote} % \LaTeX{} also defines the macro names \cs{lbrack} and \cs{rbrack} % to be shorthands for the left and right square bracket resp., but % doesn't provide similar definitions for the parentheses. Some % packages need command names to work with\footnote{The \pkg{empheq} % package needs command names for delimiters in order to make % auto-scaling versions.} so \pkg{mathtools} defines the commands % \cs{lparen} and \cs{rparen} to represent the left and right % parenthesis resp. % % % \subsubsection{Vertically centered colon} % % \begin{codesyntax} % \SpecialKeyIndex{centercolon}$\key{centercolon}=\texttt{true}\vert\texttt{false}$\\ % \SpecialUsageIndex{\vcentcolon}\cs{vcentcolon}\texttt{~~} % \SpecialUsageIndex{\ordinarycolon}\cs{ordinarycolon} % \end{codesyntax} % \cttPosting{Donald Arseneau}{2000/12/07} % When trying to show assignment operations as in $ a := b $, one % quickly notices that the colon is not centered on the math axis as % the equal sign, leading to an odd-looking output. The command % \cs{vcentcolon} is a shorthand for such a vertically centered % colon, and can be used as in |$a \vcentcolon= b$| and results in % the desired output: $a \vcentcolon= b$. % See also the \pkg{colonequals} package. % % Typing \cs{vcentcolon} every time is quite tedious, so one can use % the key \key{centercolon} to make the colon active instead. % \begin{verbatim} % \mathtoolsset{centercolon} % \[ % a := b % \] % \mathtoolsset{centercolon=false} % \end{verbatim} % \[\mathtoolsset{centercolon} % a := b % \] % In this case the command \cs{ordinarycolon} typesets an~\ldots\ % ordinary colon (what a surprise). % % \medskip % \noindent\textbf{Warning:} \texttt{centercolon} \emph{does not} % work with languages that make use of an active colon, most notably % \emph{French}. Sadly the \texttt{babel} package does not distinguish % between text and math when it comes to active characters. Nor does % it provide any hooks to deal with math. So currently no general % solution exists for this problem. % % \subsubsection{Some extra symbols involving vertically centered colon} % % Inspired by the \pkg{txfonts} and \pkg{pxfonts} we provide some colon+symbol combinations such that they will be % available even when current font does not provide the combined symbol. % % \medskip\noindent \textbf{Breaking change Summer 2022:} As is listed in the manual for % \pkg{newtxmath}/\pkg{newpxmath}\footnote{These superceeds \pkg{txfonts} and \pkg{pxfonts}.}, the symbols % \cmd{\coloneq}/\cmd{\Coloneq} and \cmd{\eqcolon}/\cmd{\Eqcolon} in \pkg{txfonts}/\pkg{pxfonts} generated the wrong % symbols, or at least was not consistent with the naming converntion by other packages. This has now also been % fixed in \pkg{mathtools}, giving us the following colon symbol list: % % \begin{center} % \small\label{colonsymbols} % \newcommand\SSS[1]{\SpecialUsageIndex{#1}\texttt{\detokenize{#1}}&$#1$} % \fbox{\begin{tabular}{*{8}{l} } % \SSS{\dblcolon} \\ % \SSS{\coloneq} & \SSS{\Coloneq} & \SSS{\eqcolon} & \SSS{\Eqcolon} % \\ % \SSS{\colonapprox} & \SSS{\Colonapprox} & \SSS{\colonsim} & \SSS{\Colonsim} % \\ % \noalign{\smallskip} % \multicolumn{8}{l}{\itshape Legacy duplicate names:} \\ % \noalign{\smallskip} % \SSS{\coloneqq} & \SSS{\eqqcolon} & \SSS{\Coloneqq} & \SSS{\Eqqcolon} \\ % \noalign{\smallskip} % \multicolumn{8}{l}{\itshape Extra symbols added Summer 2022:} \\ % \noalign{\smallskip} % \SSS{\approxcolon} & \SSS{\Approxcolon} & \SSS{\simcolon} & \SSS{\Simcolon} \\ % \SSS{\colondash} & \SSS{\Colondash} & \SSS{\dashcolon} & \SSS{\Dashcolon} \\ % \end{tabular}} % \end{center} % % \medskip\noindent If for some reason you need to revert to original (pre summer 2022) colon symbol names, use the % \opt{legacycolonsymbols} package option. In which case the macro names maps to: % % \begin{center} % \small\label{colonsymbols-legacy} % \makeatletter % \newcommand\SSS[2]{\SpecialUsageIndex{#1}\texttt{\detokenize{#1}}&$\@nameuse{#2}$} % \makeatother % \fbox{\begin{tabular}{*{8}{l}} % \SSS{\coloneqq}{MATHT@coloneq} & \SSS{\Coloneqq}{MATHT@dblcoloneq} % & \SSS{\coloneq}{MATHT@colondash} & \SSS{Coloneq}{MATHT@dblcolondash} \\ % \SSS{\eqqcolon}{MATHT@eqcolon} & \SSS{\Eqqcolon}{MATHT@eqdblcolon} % & \SSS{\eqcolon}{MATHT@dashcolon} & \SSS{\Eqcolon}{MATHT@dashdblcolon} \\ % \SSS{\colonapprox}{MATHT@colonapprox} & \SSS{\Colonapprox}{MATHT@dblcolonapprox} % & \SSS{\colonsim}{MATHT@colonsim} & \SSS{\Colonsim}{MATHT@dblcolonsim} \\ % \SSS{\dblcolon}{MATHT@dblcolon}\\ % \noalign{\smallskip} % \multicolumn{8}{l}{\itshape Extra symbols added Summer 2022:} \\ % \noalign{\smallskip} % \SSS{\approxcolon}{MATHT@approxcolon} & \SSS{\Approxcolon}{MATHT@approxdblcolon} % & \SSS{\simcolon}{MATHT@simcolon} & \SSS{\Simcolon}{MATHT@simdblcolon} \\ % \SSS{\colondash}{MATHT@colondash} & \SSS{\Colondash}{MATHT@dblcolondash} % & \SSS{\dashcolon}{MATHT@dashcolon} & \SSS{\Dashcolon}{MATHT@dashdblcolon} % \end{tabular}}\par\smallskip % Colon symbol names with \opt{legacycolonsymbols} package option. % \end{center} % % \medskip\noindent Note that the symbol names are added at the start of the document via the \cs{provide...} mechanism, % thus if some font package provide a symbol of the same macro name, we do nothing. % % % % \subsubsection{A few additional symbols} % % Most provided math font sets are missing the symbols \cs{nuparrow} % and \cs{ndownarrow} (i.e.\ negated up- and downarrow) plus a `big' % version of \cs{times}. Therefore we will provide constructed % versions of these whenever they are not already available. % \begin{codesyntax} % \SpecialUsageIndex{\nuparrow}\cs{nuparrow}\\ % \SpecialUsageIndex{\ndownarrow}\cs{ndownarrow}\\ % \SpecialUsageIndex{\bigtimes}\cs{bigtimes} % \end{codesyntax} % % \noindent % \textbf{Note:} These symbols are constructed via % features from the \pkg{graphicx} package, and thus may not display % correctly in most DVI previewers. Also note that \cs{nuparrow} and % \cs{ndownarrow} are constructed via \cs{nrightarrow} and % \cs{nleftarrrow} respectively, so these need to be % present. Usually this is done via \pkg{amssymb}, but some packages % may be incompatible with \pkg{amssymb} so the user will have to % load \pkg{amssymb} or a similar package, that provides % \cs{nrightarrow} and \cs{nleftarrow}, themselves. % % With those requirements in place, we have % \begin{verbatim} % \[ % \lim_{a\ndownarrow 0} f(a) \neq \bigtimes_n X_n \qquad % \frac{ \bigtimes_{k=1}^7 B_k \nuparrow \Omega }{2} % \] % \end{verbatim} % \[ % \lim_{a\ndownarrow 0} f(a) \neq \bigtimes_n X_n \qquad % \frac{ \bigtimes_{k=1}^7 B_k \nuparrow \Omega }{2} % \] % % % % % \section{A tribute to Michael J.~Downes} % % Michael J.~Downes (1958--2003) was one of the major architects % behind \pkg{amsmath} and member of the \LaTeX{} Team. He made many % great contributions to the \TeX{} community; not only by the means % of widely spread macro packages such as \pkg{amsmath} but also in % the form of actively giving advice on newsgroups. Some of % Michael's macro solutions on the newsgroups never made it into % publicly available macro packages although they certainly deserved % it, so \pkg{mathtools} tries to rectify this matter. The macros % described in this section are either straight copies or heavily % inspired by his original postings. % % \subsection{Mathematics within italic text} % % \begin{codesyntax} % \SpecialKeyIndex{mathic}$\key{mathic}=\texttt{true}\vert\texttt{false}$ % \end{codesyntax} % \cttPosting{Michael J.~Downes}{1998/05/14} % \TeX{} usually takes care of italic corrections in text, but fails % when it comes to math. If you use the \LaTeX{} inline math % commands \cs{(} and \cs{)} you can however work around it by % setting the key \key{mathic} to true as shown below. % \begin{verbatim} % \begin{quote}\itshape % Compare these lines: \par % \mathtoolsset{mathic} % or \mathtoolsset{mathic=true} % Subset of \(V\) and subset of \(A\). \par % \mathtoolsset{mathic=false} % Subset of \(V\) and subset of \(A\). % \par % \end{quote} % \end{verbatim} % \begin{quote}\itshape % Compare these lines: \par % \mathtoolsset{mathic} % Subset of \(V\) and subset of \(A\). \par % \mathtoolsset{mathic=false} % Subset of \(V\) and subset of \(A\). % \par % \end{quote} % \noindent % As of 2013, \cs(\cs) are robust, as are the italic corrected versions. % % \medskip\noindent \textbf{Caveat:} Italic correction is a % treacherous area. For example any penalties will cancel the italic % correction inserted by % \verb|\(| (for an explanation see \cite{TBT}, section 4.3.3). We % have changed Michael's original to accommodate one specific penalty % construction: the \emph{tie}, i.e., % `\verb|text~\(|' will work as expected (as~of July, 2014). % % \subsection{Left sub/superscripts} % % \begin{codesyntax} % \SpecialUsageIndex{\prescript} % \cs{prescript}\marg{sup}\marg{sub}\marg{arg}\texttt{~~} % \SpecialKeyIndex{prescript-sup-format} % $\key{prescript-sup-format}=\meta{cmd}$\\ % \SpecialKeyIndex{prescript-sub-format} % $\key{prescript-sub-format}=\meta{cmd}$\hfill % \SpecialKeyIndex{prescript-arg-format} % \rlap{$\key{prescript-arg-format}=\meta{cmd}$}^^A % \phantom{$\key{prescript-sup-format}=\meta{cmd}$} % \end{codesyntax} % \cttPosting{Michael J.~Downes}{2000/12/20} % Sometimes one wants to put a sub- or superscript on the left of % the argument. The \cs{prescript} command does just that: % \begin{verbatim} % \[ % {}^{4}_{12}\mathbf{C}^{5+}_{2} \quad % \prescript{14}{2}{\mathbf{C}}^{5+}_{2} \quad % \prescript{4}{12}{\mathbf{C}}^{5+}_{2} \quad % \prescript{14}{}{\mathbf{C}}^{5+}_{2} \quad % \prescript{}{2}{\mathbf{C}}^{5+}_{2} % \] % \end{verbatim} % \[ % {}^{4}_{12}\mathbf{C}^{5+}_{2} \quad % \prescript{14}{2}{\mathbf{C}}^{5+}_{2} \quad % \prescript{4}{12}{\mathbf{C}}^{5+}_{2} \quad % \prescript{14}{}{\mathbf{C}}^{5+}_{2} \quad % \prescript{}{2}{\mathbf{C}}^{5+}_{2} % \] % % The formatting of the arguments is controlled by three keys. This % silly example shows you how to use them: % \begin{verbatim} % \newcommand*\myisotope[3]{% % \begingroup % to keep changes local. We cannot use a brace group % % as it affects spacing! % \mathtoolsset{ % prescript-sup-format=\mathit, % prescript-sub-format=\mathbf, % prescript-arg-format=\mathrm, % }% % \prescript{#1}{#2}{#3}% % \endgroup % } % \[ % \myisotope{A}{Z}{X}\to \myisotope{A-4}{Z-2}{Y}+ % \myisotope{4}{2}{\alpha} % \] % \end{verbatim} % \newcommand*\myisotope[3]{% % \begingroup % \mathtoolsset{ % prescript-sup-format=\mathit, % prescript-sub-format=\mathbf, % prescript-arg-format=\mathrm, % }% % \prescript{#1}{#2}{#3}% % \endgroup % } % \[ % \myisotope{A}{Z}{X}\to \myisotope{A-4}{Z-2}{Y}+ % \myisotope{4}{2}{\alpha} % \] % (Though a package like \pkg{mhchem} might be more suitable for this % type of material.) % % % \subsection{Declaring math sizes} % % \begin{codesyntax} % \SpecialUsageIndex{\DeclareMathSizes} % \cs{DeclareMathSizes}\marg{dimen}\marg{dimen}\marg{dimen}\marg{dimen} % \end{codesyntax} % \cttPosting{Michael J.~Downes}{2002/10/17} % If you don't know about \cs{DeclareMathSizes}, then skip the rest % of this text. If you do know, then all that is needed to say is % that with \pkg{mathtools} it is patched so that all regular % dimension suffixes are now valid in the last three arguments. Thus % a declaration such as % \begin{verbatim} % \DeclareMathSize{9.5dd}{9.5dd}{7.5dd}{6.5dd} % \end{verbatim} % will now work (it doesn't in standard \LaTeX). When this bug has % been fixed in \LaTeX, this fix will be removed from % \pkg{mathtools}. % % The \CommentAdded{2015/11/12} fix was added to the \LaTeX{} kernel % in 2015. We will continue to provide it on older kernels. % % \subsection{Spreading equations}\label{sec:spread} % % \begin{codesyntax} % \SpecialEnvIndex{spreadlines} % \cs{begin}\arg{spreadlines}\marg{dimen} \meta{contents} % \cs{end}\arg{spreadlines} % \end{codesyntax} % \cttPosting{Michael J.~Downes}{2002/10/17} % The spacing between lines in a multiline math environment such as % \env{gather} is governed by the dimension \cs{jot}. The % \env{spreadlines} environment takes one argument denoting the % value of \cs{jot} inside the environment: % \begin{verbatim} % \begin{spreadlines}{20pt} % Large spaces between the lines. % \begin{gather} % a=b\\ % c=d % \end{gather} % \end{spreadlines} % Back to normal spacing. % \begin{gather} % a=b\\ % c=d % \end{gather} % \end{verbatim} % \begin{spreadlines}{20pt} % Large spaces between the lines. % \begin{gather} % a=b\\ % c=d % \end{gather} % \end{spreadlines} % Back to normal spacing. % \begin{gather} % a=b\\ % c=d % \end{gather} % % % \subsection{Gathered environments}\label{subsec:gathered} % % \begin{codesyntax} % \SpecialEnvIndex{lgathered}\cs{begin}\arg{lgathered}\oarg{pos} % \meta{contents} \cs{end}\arg{lgathered} \\ % \SpecialEnvIndex{rgathered}\cs{begin}\arg{rgathered}\oarg{pos} % \meta{contents} \cs{end}\arg{rgathered} \\ % \SpecialUsageIndex{\newgathered}\cs{newgathered}\marg{name}\marg{pre_line}\marg{post_line}\marg{after}\\ % \SpecialUsageIndex{\renewgathered}\cs{renewgathered}\marg{name}\marg{pre_line}\marg{post_line}\marg{after} % \end{codesyntax} % \cttPosting{Michael J.~Downes}{2001/01/17} % In a document set in \opt{fleqn}, you might sometimes want an % inner \env{gathered} environment that doesn't center its lines but % puts them flush left. The \env{lgathered} environment works just % like the standard \env{gathered} except that it flushes its % contents left: % \begin{verbatim} % \begin{equation} % \begin{lgathered} % x=1,\quad x+1=2 \\ % y=2 % \end{lgathered} % \end{equation} % \end{verbatim} % \begin{equation} % \begin{lgathered} % x=1,\quad x+1=2 \\ % y=2 % \end{lgathered} % \end{equation} % Similarly the \env{rgathered} puts it contents flush right. % % More interesting is probably the command \cs{newgathered}. In this % example we define a gathered version that centers the lines and % also prints a star and a number at the left of each line. % \begin{verbatim} % \newcounter{steplinecnt} % \newcommand\stepline{\stepcounter{steplinecnt}\thesteplinecnt} % \newgathered{stargathered} % {\llap{\stepline}$*$\quad\hfil}% \hfil for centering % {\hfil}% \hfil for centering % {\setcounter{steplinecnt}{0}}% reset counter % \end{verbatim} % \newcounter{steplinecnt} % \newcommand\stepline{\stepcounter{steplinecnt}\thesteplinecnt} % \newgathered{stargathered}{\llap{\stepline}$*$\quad\hfil}{\hfil}{\setcounter{steplinecnt}{0}} % With these definitions we can get something like this: % \begin{verbatim} % \begin{gather} % \begin{stargathered} % x=1,\quad x+1=2 \\ % y=2 % \end{stargathered} % \end{gather} % \end{verbatim} % \begin{gather} % \begin{stargathered} % x=1,\quad x+1=2 \\ % y=2 % \end{stargathered} % \end{gather} % \cs{renewgathered} renews a gathered environment of course. % % In all fairness it should be stated that the original concept by % Michael has been extended quite a bit in \pkg{mathtools}. Only the % end product of \env{lgathered} is the same. % % \subsection{Split fractions} % % \begin{codesyntax} % \SpecialUsageIndex{\splitfrac}\cs{splitfrac}\marg{start line}\marg{continuation}\\ % \SpecialUsageIndex{\splitdfrac}\cs{splitdfrac}\marg{start line}\marg{continuation} % \end{codesyntax} % \cttPosting{Michael J.~Downes}{2001/12/06} % These commands provide split fractions, e.g., multiline fractions: % \begin{verbatim} % \[ % a=\frac{ % \splitfrac{xy + xy + xy + xy + xy} % {+ xy + xy + xy + xy} % } % {z} % =\frac{ % \splitdfrac{xy + xy + xy + xy + xy} % {+ xy + xy + xy + xy} % } % {z} % \] % \end{verbatim} % \[ % a=\frac{ % \splitfrac{xy + xy + xy + xy + xy} % {+ xy + xy + xy + xy} % } % {z} % =\frac{ % \splitdfrac{xy + xy + xy + xy + xy} % {+ xy + xy + xy + xy} % } % {z} % \] % The difference between \cs{splitfrac} and \cs{splitdfrac} is that % the former forces its arguments to be typeset in text-mode math, the % latter does not. % % \medskip\noindent \textbf{Note:} If you try to nest \cs{splitfrac} % inside each other you may need to add \cs{mathstrut} to the first % argument of the nested fraction to get the spacing look even. It is % not added by default as often a more cramped look is desired: % \begin{verbatim} % \[ % \frac{ % \splitfrac{xy + xy + xy + xy + xy} % { % \splitfrac{xy + xy + xy + xy + xy} % {+ xy + xy + xy + xy} % } % } % {z} % =\frac{ % \splitfrac{xy + xy + xy + xy + xy} % { % \splitfrac{\mathstrut xy + xy + xy + xy + xy} % {+ xy + xy + xy + xy} % } % } % {z} % \] % \end{verbatim} % \[ % \frac{ % \splitfrac{xy + xy + xy + xy + xy} % { % \splitfrac{xy + xy + xy + xy + xy} % {+ xy + xy + xy + xy} % } % } % {z} % =\frac{ % \splitfrac{xy + xy + xy + xy + xy} % { % \splitfrac{\mathstrut xy + xy + xy + xy + xy} % {+ xy + xy + xy + xy} % } % } % {z} % \] % Note how the line spaces aren't even on the left hand side. % % For even more control, one can use \env{aligned} or \env{gathered} % instead of \cs{splitfrac}. % % % \newpage % % \section{New additions} % % \subsection{Variable math strut} % \begin{codesyntax} % \SpecialUsageIndex{\xmathstrut}\cs{xmathstrut}\oarg{depth increase}\marg{increase} % \end{codesyntax} % \FeatureRequest{Frank Mittelbach}{2020} In typography we use % \emph{struts} to ensure specific line spacing. In text we have the % \cs{strut} and in math \cs{mathstrut}. Both have no width, but % equal the height and depth of an »(« from the current text/math % font and size. In math we often need to make minute adjustments in % macro definitions etc. The \emph{extended} math strut % \cs{xmathstrut} allows to \emph{increase} (decrease if negative) % the math strut in two ways. % % For an \meta{increase} (a decimal number), say~\verb|0.1|, % \begin{center} % \verb|\xmathstrut{0.1}| % \end{center} % will give you a new strut where 10\% of the \emph{total height of % the normal math strut} (\verb|\mathstrut=\xmathstrut{0}|) will be % added to both \emph{the height} and \emph{the depth} of the % original strut (thus 20\% gets added in total). On the other hand % \begin{center} % \verb|\xmathstrut[0.2]{0.1}| % \end{center} % will result in a strut where 20\% is added to the depth and 10\% is % added to the height, resulting in a strut that is 30\% larger than % normal. % % The following example is inspired (with permission) from an example % showcasing \cs{xmathstrut} in the upcoming third edition of % \emph{The LaTeX Companion}. The example is very relevant as the % entries of the \env{cases(*)} environment are typeset in \emph{text % style} math and thus may end up looking quite % squished.\footnote{Which is why Frank suggested the macro % (including its implementation) in the first place.} % \[ % \begin{cases*} % \frac{\frac{ x-1 }{ x-\sin x} }{ \sqrt{ 1 -x }} & $x >0$ \\ % 0 & otherwise % \end{cases*} % \qquad\text{vs.}\qquad % \begin{cases*} % \frac{\frac{ \xmathstrut{0.1} x-1 }{ \xmathstrut{0.25} x-\sin x} }{\xmathstrut{0.4} \sqrt{ 1 -x }} & $x >0$ \\ % 0 & otherwise % \end{cases*} % \] % \begin{verbatim} % \[ \begin{cases*} % \frac{ \frac{ x-1 }{ x-\sin x } }{ \sqrt{ 1-x } } & $x>0$ \\ % 0 & otherwise % \end{cases*} % \qquad\text{vs.}\qquad % \begin{cases*} % \frac{ \frac{ \xmathstrut{0.1} x-1 } % { \xmathstrut{0.25} x-\sin x } } % {\xmathstrut{0.4} \sqrt{ 1-x } } & $x>0$ \\ % 0 & otherwise % \end{cases*} \] % \end{verbatim} % % To showcase the optional argument, it is % probably easiest to make the strut visible. Here you'll see that % \verb|\mathstrut| and \verb|\xmathstrut{0}| is the same: % \newcommand\vfb[1]{\begingroup\fboxsep=0pt\boxed{\,#1\,}\endgroup} % \[ % \llap{\rlap{\rule{18mm}{0.1pt}}\quad}a \vfb{\mathstrut} \ \vfb{\xmathstrut{0}}\ % \vfb{\xmathstrut{0.5} } \ \vfb{\xmathstrut{-0.1} }\ \vfb{\xmathstrut[0.5]{0}} a % \] % \newpage % \begin{verbatim} % \newcommand\vfb[1]{\begingroup\fboxsep=0pt\boxed{\,#1\,}\endgroup} % \[ % a % \vfb{ \mathstrut } \ % normal strut % \vfb{ \xmathstrut{0} } \ % just 0 => normal strut % \vfb{ \xmathstrut{0.5} } \ % twice as large 50% + 50% % \vfb{ \xmathstrut{-0.1} } \ % negative gives something smaller % \vfb{ \xmathstrut[0.5]{0} } % change only the depth % a % \] % \end{verbatim} % -- the last box showcases a strut where we have only changed the % depth of the strut. One can see \verb|\xmathstrut[0.5]{0}| kind of the % opposite of \verb|\smash[b]{...}|, the former makes the depth larger % and the latter ignores the depth. % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % \begin{thebibliography}{9} % \bibitem{Perlis01} Alexander R. Perlis, \emph{A complement to % \cs{smash}, \cs{llap}, and \cs{rlap}}, TUGboat 22(4) % (2001). Available at % \url{https://www.tug.org/TUGboat/tb22-4/tb72perlS.pdf}. % \bibitem{Ams99} American Mathematical Society and Michael Downes, % \emph{Technical notes on the \pkg{amsmath} package}. Version 2.0, % 1999/10/29. Available via % \url{http://mirrors.ctan.org/macros/latex/required/amsmath/technote.pdf}. % \bibitem{Ams00} Frank Mittelbach, Rainer Sch\"opf, Michael Downes, % David M.~Jones and David Carlisle, \emph{The \pkg{amsmath} % package}. Version 2.17e, 2020/01/20. Maintained by the \LaTeX3 % project. Available as file % \url{http://mirrors.ctan.org/macros/latex/required/amsmath/amsmath.dtx}. % \bibitem{A-W:MG04} % Frank Mittelbach and Michel Goossens. % \emph{The {\LaTeX} Companion}. % Tools and Techniques for Computer Typesetting. Addison-Wesley, % Boston, Massachusetts, 2 edition, 2004. % With Johannes Braams, David Carlisle, and Chris Rowley. % % \bibitem{Carl99} David Carlisle, \emph{The \pkg{keyval} Package}. % Version 1.15, 2014/10/28. Available via % \url{https://ctan.org/pkg/keyval}. % % \bibitem{Voss:2004} Herbert Vo\ss, \emph{Math mode}. Version 2.47, % 2014/01/30. Available as % \url{http://mirrors.ctan.org/obsolete/info/math/voss/mathmode/Mathmode.pdf}. Please % note that the author has marked the document as \emph{obsolete}. % % \bibitem{Swanson} % Ellen Swanson, % \emph{Mathematics into type}. % American Mathematical Society, updated edition, 1999. % Updated by Arlene O'Sean and Antoinette Schleyer. Available from % the AMS at \url{https://www.ams.org/arc/styleguide/mit-2.pdf}. % % \bibitem{TBT} Victor Eijkhout, \emph{\TeX\ by Topic, A Texnician's % Reference}, 2007. The book is available at % \url{https://ctan.org/pkg/texbytopic}. % \end{thebibliography} % % % \StopEventually{} % % % \section{Options and package loading} % % % Lets start the package. % \begin{macrocode} %<*package> \ProvidesPackage{mathtools}% [2024/10/04 v1.31 mathematical typesetting tools] % \end{macrocode} % \changes{v1.10}{2011/02/12}{Might as well make sure that we need the % latest version of \texttt{mhsetup}} % \begin{macrocode} \RequirePackage{keyval,calc} \RequirePackage{mhsetup}[2021/03/18] \MHInternalSyntaxOn % \end{macrocode} % \changes{v1.13}{2013/02/11}{Robustifying \cs{(}\cs{)}\cs{[}\cs{]}} % We'd like to make \cs{(}\cs{)} and \cs{[}\cs{]} robust. This can % easily be done via the \pkg{fixltx2e} package, but auto loading that % package may cause problems for some. We make copies instead. % Update 2021: We have removed robustifying \cs{(}\cs{)}\cs{[}\cs{]} % as this is now in the \LaTeX\ kernel. We still use % \verb|\EQ_MakeRobust| elsewhere though. % \begin{macro}{\EQ_MakeRobust} % \begin{macro}{\forced_EQ_MakeRobust} % \begin{macrocode} % borrowed from fixltx2e \def\EQ_MakeRobust#1{% \@ifundefined{\expandafter\@gobble\string#1}{% \@latex@error{The~control~sequence~`\string#1'~is~undefined!% \MessageBreak There~is~nothing~here~to~make~robust}% \@eha }% {% \@ifundefined{\expandafter\@gobble\string#1\space}% {% \expandafter\let\csname \expandafter\@gobble\string#1\space\endcsname=#1% \edef\reserved@a{\string#1}% \def\reserved@b{#1}% \edef\reserved@b{\expandafter\strip@prefix\meaning\reserved@b}% \edef#1{% \ifx\reserved@a\reserved@b \noexpand\x@protect\noexpand#1% \fi \noexpand\protect\expandafter\noexpand \csname\expandafter\@gobble\string#1\space\endcsname}% }% {\@latex@info{The~control~sequence~`\string#1'~is~already~robust}}% }% } % \end{macrocode} % We also provide a handy alternativ version, that will robustify no % matter what. Useful for the \texttt{mathic} option. % \begin{macrocode} \def\forced_EQ_MakeRobust#1{% \@ifundefined{\expandafter\@gobble\string#1}{% \@latex@error{The~control~sequence~`\string#1'~is~undefined!% \MessageBreak There~is~nothing~here~to~make~robust}% \@eha }% {% % \@ifundefined{\expandafter\@gobble\string#1\space}% % {% \expandafter\let\csname \expandafter\@gobble\string#1\space\endcsname=#1% \edef\reserved@a{\string#1}% \def\reserved@b{#1}% \edef\reserved@b{\expandafter\strip@prefix\meaning\reserved@b}% \edef#1{% \ifx\reserved@a\reserved@b \noexpand\x@protect\noexpand#1% \fi \noexpand\protect\expandafter\noexpand \csname\expandafter\@gobble\string#1\space\endcsname}% % }% % {\@latex@info{The control sequence `\string#1' is already robust}}% }% } % \end{macrocode} % \end{macro} % \end{macro} % % \begin{macro}{\MT_options_name:} % \begin{macro}{\mathtoolsset} % The name for the options and a user interface for setting keys. % \begin{macrocode} \def\MT_options_name:{mathtools} \newcommand*\mathtoolsset[1]{\setkeys{\MT_options_name:}{#1}} % \end{macrocode} % \end{macro} % \end{macro} % % Fix \pkg{amsmath} bugs (strongly recommended!). It requires a % great deal of typing to avoid fixing the bugs. He he. % \begin{macrocode} \MH_new_boolean:n {fixamsmath} \DeclareOption{fixamsmath}{ \MH_set_boolean_T:n {fixamsmath} } \DeclareOption{donotfixamsmathbugs}{ \MH_set_boolean_F:n {fixamsmath} } % \end{macrocode} % Disallow spaces before optional arguments in certain \pkg{amsmath} % building blocks. % \begin{macrocode} \DeclareOption{allowspaces}{ \MH_let:NwN \MaybeMHPrecedingSpacesOff \relax \MH_let:NwN \MH_maybe_nospace_ifnextchar:Nnn \kernel@ifnextchar } \DeclareOption{disallowspaces}{ \MH_let:NwN \MaybeMHPrecedingSpacesOff \MHPrecedingSpacesOff \MH_let:NwN \MH_maybe_nospace_ifnextchar:Nnn \MH_nospace_ifnextchar:Nnn } % \end{macrocode} % \changes{v1.13}{2013/02/11}{Option to disable robustifying % \cs{(}\cs{)} and \cs{[}\cs{]}} % Option to disallow robustifying \cs{(}\cs{)} and \cs{[}\cs{]}. % \begin{macrocode} \MH_new_boolean:n {robustify} \MH_set_boolean_T:n {robustify} \DeclareOption{nonrobust}{ \MH_set_boolean_F:n {robustify} } % \end{macrocode} % \changes{v1.29}{2022/06/24}{Added package option to bring back old % colon symbols} % As of juni/july 2022 we've had to rename several of the provided % \cs{...colon...} macros. If needed this package option brings them back. % \begin{macrocode} \MH_new_boolean:n {legacycolonsymbols} \MH_set_boolean_F:n {legacycolonsymbols} \DeclareOption{legacycolonsymbols}{ \MH_set_boolean_T:n {legacycolonsymbols} } % \end{macrocode} % Pass all other options directly to \pkg{amsmath}. % \begin{macrocode} \DeclareOption*{ \PassOptionsToPackage{\CurrentOption}{amsmath} } % \end{macrocode} % Executing options % \begin{macrocode} \ExecuteOptions{fixamsmath,disallowspaces} \ProcessOptions\relax % \end{macrocode} % We have to turn off the new syntax when \pkg{amstext} is loaded. % \begin{macrocode} \MHInternalSyntaxOff \RequirePackage{amsmath}[2016/11/05] % \end{macrocode} % \changes{v1.29}{2022/06/27}{Added \pkg{unicode-math} warning} % \begin{macrocode} \@ifpackageloaded{unicode-math}{ \PackageWarning{mathtools}{For best results, please load mathtools *before* \MessageBreak unicode-math} }{} % \end{macrocode} % \begin{macrocode} \MHInternalSyntaxOn \AtEndOfPackage{\MHInternalSyntaxOff} % \end{macrocode} % \begin{macro}{\MT_true_false_error:} % Make sure the user selects either `true' or `false' when asked too. % \begin{macrocode} \def\MT_true_false_error:{ \PackageError{mathtools} {You~ have~ to~ select~ either~ `true'~ or~ `false'} {I'll~ assume~ you~ chose~ `false'~ for~ now.} } % \end{macrocode} % \end{macro} % ^^A \changes{v1.13}{2013/02/11}{Make \cs{(}\cs{)} and \cs{[}\cs{]} % ^^A robust} % ^^A We start of with making \cs{(}\cs{)} and \cs{[}\cs{]} robust, % ^^A unless the user explicitly asked us not to. % ^^A \changes{v1.28}{2021/12/31}{Removed robustifying \cs{(}\cs{)} and % ^^A \cs{[}\cs{]} as this is now in the \LaTeX{} kernel.} % ^^A % \begin{macrocode} % ^^A \MH_if_boolean:nT {robustify}{ % ^^A \EQ_MakeRobust\( % ^^A \EQ_MakeRobust\) % ^^A \EQ_MakeRobust\[ % ^^A \EQ_MakeRobust\] % ^^A } % ^^A % \end{macrocode} % % % \section{Macros I got ideas for myself} % % % % \subsection{Tag forms} % This is quite simple, but why isn't it then a part of some widely % distributed package? Beats me. % % \begin{macro}{\MT_define_tagform:nwnn} % We start out by defining a command that will allow us to define % commands similar to \cs{tagform@} only this will give us tag form % \emph{types}. The actual code is very similar to the one in % \pkg{amsmath}. % \changes{v1.30}{2024/01/19}{Add group so \#2 (the inner format) does not leak} % \begin{macrocode} \def\MT_define_tagform:nwnn #1[#2]#3#4{ \@namedef{MT_tagform_#1:n}##1 {\maketag@@@{#3\ignorespaces{#2{##1}}\unskip\@@italiccorr#4}} } % \end{macrocode} % \end{macro} % % \begin{macro}{\newtagform} % Similar to \cs{newcommand}. Check if defined and scan for presence % of optional argument. Then call generic command. % \begin{macrocode} \providecommand*\newtagform[1]{% \@ifundefined{MT_tagform_#1:n} {\@ifnextchar[% {\MT_define_tagform:nwnn #1}% {\MT_define_tagform:nwnn #1[]}% }{\PackageError{mathtools} {The~ tag~ form~ `#1'~ is~ already~ defined\MessageBreak You~ probably~ want~ to~ look~ up~ \@backslashchar renewtagform~ instead} {I~ will~ just~ ignore~ your~ wish~ for~ now.}} } % \end{macrocode} % Provide a default tag form which---surprise, surprise---is % identical to the standard definition. % \begin{macrocode} \newtagform{default}{(}{)} % \end{macrocode} % \end{macro} % \begin{macro}{\renewtagform} % Similar to \cs{renewcommand}. % \begin{macrocode} \providecommand*\renewtagform[1]{% \@ifundefined{MT_tagform_#1:n} {\PackageError{mathtools} {The~ tag~ form~ `#1'~ is~ not~ defined\MessageBreak You~ probably~ want~ to~ look~ up~ \@backslashchar newtagform~ instead} {I~ will~ just~ ignore~ your~ wish~ for~ now.}} {\@ifnextchar[% {\MT_define_tagform:nwnn #1}% {\MT_define_tagform:nwnn #1[]}% } } % \end{macrocode} % \end{macro} % \begin{macro}{\usetagform} % Then the activator. Test if the tag form is defined and then % activate it by redefining \cs{tagform@}. % \begin{macrocode} \providecommand*\usetagform[1]{% \@ifundefined{MT_tagform_#1:n} { \PackageError{mathtools}{% You~ have~ chosen~ the~ tag~ form~ `#1'\MessageBreak but~ it~ appears~ to~ be~ undefined} {I~ will~ use~ the~ default~ tag~ form~ instead.}% \@namedef{tagform@}{\@nameuse{MT_tagform_default:n}} } { \@namedef{tagform@}{\@nameuse{MT_tagform_#1:n}} } % \end{macrocode} % Here we patch if we're using the special ``show only referenced % equations'' feature. % \begin{macrocode} \MH_if_boolean:nT {show_only_refs}{ \MH_let:NwN \MT_prev_tagform:n \tagform@ \def\tagform@##1{\MT_extended_tagform:n {##1}} } } % \end{macrocode} % \end{macro} % % \subsubsection{Showing only referenced tags} % A little more interesting is the way to print only the equation % numbers that are actually referenced. % % A few booleans to help determine which situations we're in. % \begin{macrocode} \MH_new_boolean:n {manual_tag} \MH_new_boolean:n {raw_maketag} % \end{macrocode} % \begin{macro}{\MT_AmS_tag_in_align:} % \begin{macro}{\tag@in@align} % \begin{macro}{\tag@in@display} % We'll need to know when the user has put in a manual tag, and since % \cs{tag} is \cs{let} to all sorts of things inside the \pkg{amsmath} % code it is safer to provide a small hack to the functions it is copied % from. Note that we can't use \cs{iftag@}. % \begin{macrocode} \MH_let:NwN \MT_AmS_tag_in_align: \tag@in@align \def\tag@in@align{ \global\MH_set_boolean_T:n {manual_tag} \MT_AmS_tag_in_align: } \def\tag@in@display#1#{ \relax \global\MH_set_boolean_T:n {manual_tag} \tag@in@display@a{#1} } % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % % \begin{macro}{\MT_extended_tagform:n} % \changes{v1.01}{2004/08/03}{Simplified quite a bit} % The extended version of \cs{tagform@}. % \begin{macrocode} \def\MT_extended_tagform:n #1{ \MH_set_boolean_F:n {raw_maketag} % \end{macrocode} % We test if the equation was labelled. We already know if it was % tagged manually. Have to watch out for \TeX\ inserting a blank line % so do not let the tag have width zero. Rememeber % \cs{@safe@activestrue/false} in order to handle active chars in labels. % \changes{v1.12}{2012/04/24}{Added \cs{@safe@activestrue/false}} % \changes{v1.19}{2017/03/31}{Added MH\_ prefix} % \begin{macrocode} \MH_if_meaning:NN \df@label\@empty \MH_if_boolean:nTF {manual_tag}% this was \MH_if_boolean:nT before { \MH_if_boolean:nTF {show_manual_tags} { \MT_prev_tagform:n {#1} } { \stepcounter{equation} } }{\kern1sp}% this last {\kern1sp} is new. \MH_else: \MH_if_boolean:nTF {manual_tag} { \MH_if_boolean:nTF {show_manual_tags} { \MT_prev_tagform:n {#1} } { \@safe@activestrue \@ifundefined{MT_r_\df@label} % \end{macrocode} % Next we need to remember to deactivate the manual tags switch. This % is usually done using \verb|\MT_extended_maketag:n|, but this is not % the case if the show manual tags is false and the manual tag is not % referred to. % \changes{v1.12}{2011/06/08}{Added the falsification of manual tag % when show manual tags is off and maual tag is not referred to} % \changes{v1.19}{2017/03/31}{Added MH\_ prefix} % \changes{v1.23}{2020/01/17}{Added \cs{kern1sp} in a few places to % make sure the tag has a non zero width.} % \begin{macrocode} { \global\MH_set_boolean_F:n {manual_tag} \kern1sp } % kern added 2020 { \MT_prev_tagform:n {#1} } \@safe@activesfalse } } { \@safe@activestrue \@ifundefined{MT_r_\df@label} { \kern1sp }% kern added 2020 { \refstepcounter{equation}\MT_prev_tagform:n {#1} } \@safe@activesfalse } \MH_fi: \global\MH_set_boolean_T:n {raw_maketag} } % \end{macrocode} % \end{macro} % \begin{macro}{\MT_extended_maketag:n} % The extended version of \cs{maketag@@@}. % \changes{v1.12}{2012/04/24}{Added \cs{@safe@activestrue/false}} % \changes{v1.19}{2017/03/31}{Added MH\_ prefix} % \begin{macrocode} \def\MT_extended_maketag:n #1{ \ifx\df@label\@empty \MT_maketag:n {#1} \MH_else: \MH_if_boolean:nTF {raw_maketag} { \MH_if_boolean:nTF {show_manual_tags} { \MT_maketag:n {#1} } { \@safe@activestrue \@ifundefined{MT_r_\df@label} { } { \MT_maketag:n {#1} } \@safe@activesfalse } } { \MT_maketag:n {#1} } \MH_fi: % \end{macrocode} % As this function is always called we let it set the marker for a manual % tag false when exiting (well actually not true, see above). % \begin{macrocode} \global\MH_set_boolean_F:n {manual_tag} } % \end{macrocode} % \end{macro} % \begin{macro}{\MT_extended_eqref:n} % \changes{v1.01}{2004/08/03}{Make it robust} % We let \cs{eqref} write the label to the \file{aux} file, which is % read at the beginning of the next run. Then we print the equation % number as usual. % \changes{v1.14}{2013/03/07}{It was not really robust} % \begin{macrocode} \def\MT_extended_eqref:n #1{ \protected@write\@auxout{} {\string\MT@newlabel{#1}} % \end{macrocode} % \changes{v1.16}{2015/05/11}{Fix bug in \cs{eqref} in \cs{text} vs. \textsf{showonlyrefs}} % The manner in which \key{showonlyrefs} is implemented causes % problems when \cs{eqref} is used within \cs{text}. The problem is % that \cs{MT_prev_tagform:n} is used both in \cs{eqref} and within, % say, \env{align}. Thus a test within \cs{MT_prev_tagform:n} fails % for \cs{eqref}. We fix this by making sure we end up in the proper % branch of the test, when \cs{MT_prev_tagform:n} is used to typeset \cs{eqref}. % \begin{macrocode} \textup{\let\df@label\@empty\MT_prev_tagform:n {\ref{#1}}} } \EQ_MakeRobust\MT_extended_eqref:n % \end{macrocode} % \end{macro} % % \begin{macro}{\refeq} % \begin{macro}{\MT_extended_refeq:n} % Similar to \cs{eqref} and \cs{MT_extended_eqref:n}. % \begin{macrocode} \newcommand*\refeq[1]{ \textup{\ref{#1}} } \def\MT_extended_refeq:n #1{ \protected@write\@auxout{} {\string\MT@newlabel{#1}} \textup{\ref{#1}} } % \end{macrocode} % \end{macro} % \end{macro} % % \begin{macro}{\MT@newlabel} % We can't use |:| or |_| in the command name (yet). We define the % special labels for the equations that have been referenced in the % previous run. % \begin{macrocode} \newcommand*\MT@newlabel[1]{ \global\@namedef{MT_r_#1}{} } % \end{macrocode} % \end{macro} % \changes{v1.19}{2017/03/31}{Added MH\_ prefix} % \begin{macrocode} \MH_new_boolean:n {show_only_refs} \MH_new_boolean:n {show_manual_tags} \define@key{\MT_options_name:}{showmanualtags}[true]{ \@ifundefined{MH_boolean_show_manual_tags_#1:} { \MT_true_false_error: \@nameuse{MH_boolean_show_manual_tags_false:} } { \@nameuse{MH_boolean_show_manual_tags_#1:} } } % \end{macrocode} % \begin{macro}{\MT_showonlyrefs_true:} % The implementation is based on the idea that \cs{tagform@} can be % called in two circumstances: when the tag is being printed in the % equation and when it is being printed during a reference. % \begin{macrocode} \newcommand*\MT_showonlyrefs_true:{ \MH_if_boolean:nF {show_only_refs}{ \MH_set_boolean_T:n {show_only_refs} % \end{macrocode} % Save the definitions of the original commands. % \begin{macrocode} \MH_let:NwN \MT_incr_eqnum: \incr@eqnum \MH_let:NwN \incr@eqnum \@empty \MH_let:NwN \MT_array_parbox_restore: \@arrayparboxrestore \@xp\def\@xp\@arrayparboxrestore\@xp{\@arrayparboxrestore \MH_let:NwN \incr@eqnum \@empty } \MH_let:NwN \MT_prev_tagform:n \tagform@ \MH_let:NwN \MT_eqref:n \eqref \MH_let:NwN \MT_refeq:n \refeq \MH_let:NwN \MT_maketag:n \maketag@@@ \MH_let:NwN \maketag@@@ \MT_extended_maketag:n % \end{macrocode} % We redefine \cs{tagform@}. % \begin{macrocode} \def\tagform@##1{\MT_extended_tagform:n {##1}} % \end{macrocode} % Then \cs{eqref}: % \begin{macrocode} \MH_let:NwN \eqref \MT_extended_eqref:n \MH_let:NwN \refeq \MT_extended_refeq:n } } % \end{macrocode} % \end{macro} % \begin{macro}{\MT_showonlyrefs_false:} % This macro reverts the settings. % \begin{macrocode} \def\MT_showonlyrefs_false: { \MH_if_boolean:nT {show_only_refs}{ \MH_set_boolean_F:n {show_only_refs} \MH_let:NwN \tagform@ \MT_prev_tagform:n \MH_let:NwN \eqref \MT_eqref:n \MH_let:NwN \refeq \MT_refeq:n \MH_let:NwN \maketag@@@ \MT_maketag:n \MH_let:NwN \incr@eqnum \MT_incr_eqnum: \MH_let:NwN \@arrayparboxrestore \MT_array_parbox_restore: } } \define@key{\MT_options_name:}{showonlyrefs}[true]{ \@nameuse{MT_showonlyrefs_#1:} } % \end{macrocode} % \end{macro} % % % \begin{macro}{\nonumber} % \changes{v1.01}{2004/08/03}{Fixed using \cs{notag} or \cs{nonumber} % with the \key{showonlyrefs} feature} % We have to redefine \cs{nonumber} else it will subtract one from the % equation number where we don't want it. This is probably not needed % since \cs{nonumber} is unnecessary when \key{showonlyrefs} is in % effect, but now you can use it with old documents as well. % \changes{v1.19}{2017/03/31}{Added MH\_ prefix} % \begin{macrocode} \renewcommand\nonumber{ \if@eqnsw \MH_if_meaning:NN \incr@eqnum\@empty % \end{macrocode} % Only subtract the number if |show_only_refs| is false. % \changes{v1.19}{2017/03/31}{Added MH\_ prefix} % \begin{macrocode} \MH_if_boolean:nF {show_only_refs} {\addtocounter{equation}\m@ne} \MH_fi: \MH_fi: \MH_let:NwN \print@eqnum\@empty \MH_let:NwN \incr@eqnum\@empty \global\@eqnswfalse } % \end{macrocode} % \end{macro} % % \begin{macro}{\noeqref} % \changes{v1.04}{2008/03/26}{Added \cs{noeqref} (daleif)} % \changes{v1.12}{2012/04/20}{Labels containing active chars (babel) % are now allowed} % \changes{v1.12}{2012/04/24}{\cs{noeqref} will now make a reference % warning if users use undefined labels in \cs{noeqref}, requested % by Tue Christensen} % Macro for adding numbers to non-referred equations. Syntax similar % to \cs{nocite}. % \begin{macrocode} \MHInternalSyntaxOff \newcommand\noeqref[1]{\@bsphack% \@for\@tempa:=#1\do{% \@safe@activestrue% \edef\@tempa{\expandafter\@firstofone\@tempa}% \@ifundefined{r@\@tempa}{% \protect\G@refundefinedtrue% \@latex@warning{Reference `\@tempa' on page \thepage \space undefined (\string\noeqref)}% }{}% \if@filesw\protected@write\@auxout{}% {\string\MT@newlabel{\@tempa}}\fi% \@safe@activesfalse}% \@esphack} % \end{macrocode} % \end{macro} % % \begin{macro}{\@safe@activestrue} % \begin{macro}{\@safe@activesfalse} % These macros are provided by babel. We \emph{provide} them here, % just to make sure they exist. % \begin{macrocode} \providecommand\@safe@activestrue{}% \providecommand\@safe@activesfalse{}% \MHInternalSyntaxOn % \end{macrocode} % % \end{macro} % \end{macro} % % \subsection{Extensible arrows etc.} % % \begin{macro}{\xleftrightarrow} % \begin{macro}{\MT_leftrightarrow_fill:} % \begin{macro}{\xLeftarrow} % \begin{macro}{\xRightarrow} % \begin{macro}{\xLeftrightarrow} % % These are straight adaptions from \pkg{amsmath}. % \changes{v1.24}{2020/03/13}{Added spaces to move the argument away % from the arrow head in \cs{xLeftarrow}, \cs{xRightarrow} and % \cs{xLeftrightarrow}. Suggested by FM} % \changes{1.28}{2022/01/01}{Added \cs{xlongrightarrow} and % \cs{xlongleftarrow} as suggested in Issue \#12} % \begin{macrocode} \providecommand*\xleftrightarrow[2][]{% \ext@arrow 3095\MT_leftrightarrow_fill:{#1}{#2}} \def\MT_leftrightarrow_fill:{% \arrowfill@\leftarrow\relbar\rightarrow} \providecommand*\xLeftarrow[2][]{% \ext@arrow 0055{\Leftarrowfill@}{\ #1}{\ #2}} \providecommand*\xRightarrow[2][]{% \ext@arrow 0055{\Rightarrowfill@}{#1\ }{#2\ }} \providecommand*\xLeftrightarrow[2][]{% \ext@arrow 0055{\Leftrightarrowfill@}{\ #1\ }{\ #2\ }} % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \begin{macro}{\MT_rightharpoondown_fill:} % \begin{macro}{\MT_rightharpoonup_fill:} % \begin{macro}{\MT_leftharpoondown_fill:} % \begin{macro}{\MT_leftharpoonup_fill:} % \begin{macro}{\xrightharpoondown} % \begin{macro}{\xrightharpoonup} % \begin{macro}{\xleftharpoondown} % \begin{macro}{\xleftharpoonup} % \begin{macro}{\xleftrightharpoons} % \begin{macro}{\xrightleftharpoons} % The harpoons. % \begin{macrocode} \def\MT_rightharpoondown_fill:{% \arrowfill@\relbar\relbar\rightharpoondown} \def\MT_rightharpoonup_fill:{% \arrowfill@\relbar\relbar\rightharpoonup} \def\MT_leftharpoondown_fill:{% \arrowfill@\leftharpoondown\relbar\relbar} \def\MT_leftharpoonup_fill:{% \arrowfill@\leftharpoonup\relbar\relbar} % \end{macrocode} % 2022: added \verb+_fill:+ macros based upon \cs{longrightarrow} and \cs{longleftarrow} % \begin{macrocode} \def\MT_longrightarrow_fill:{% \arrowfill@\relbar\relbar\longrightarrow} \def\MT_longleftarrow_fill:{% \arrowfill@\longleftarrow\relbar\relbar} \providecommand*\xrightharpoondown[2][]{% \ext@arrow 0359\MT_rightharpoondown_fill:{#1}{#2}} \providecommand*\xrightharpoonup[2][]{% \ext@arrow 0359\MT_rightharpoonup_fill:{#1}{#2}} \providecommand*\xleftharpoondown[2][]{% \ext@arrow 3095\MT_leftharpoondown_fill:{#1}{#2}} \providecommand*\xleftharpoonup[2][]{% \ext@arrow 3095\MT_leftharpoonup_fill:{#1}{#2}} \providecommand*\xleftrightharpoons[2][]{\mathrel{% \raise.22ex\hbox{% $\ext@arrow 3095\MT_leftharpoonup_fill:{\phantom{#1}}{#2}$}% \setbox0=\hbox{% $\ext@arrow 0359\MT_rightharpoondown_fill:{#1}{\phantom{#2}}$}% \kern-\wd0 \lower.22ex\box0}} \providecommand*\xrightleftharpoons[2][]{\mathrel{% \raise.22ex\hbox{% $\ext@arrow 0359\MT_rightharpoonup_fill:{\phantom{#1}}{#2}$}% \setbox0=\hbox{% $\ext@arrow 3095\MT_leftharpoondown_fill:{#1}{\phantom{#2}}$}% \kern-\wd0 \lower.22ex\box0}} % \end{macrocode} % 2022: added \verb+\xlong...+ macros based upon \cs{longrightarrow} % and \cs{longleftarrow} % \begin{macrocode} \providecommand*\xlongrightarrow[2][]{% \ext@arrow 0359\MT_longrightarrow_fill:{#1}{#2}} \providecommand*\xlongleftarrow[2][]{% \ext@arrow 3095\MT_longleftarrow_fill:{#1}{#2}} % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \begin{macro}{\xhookleftarrow} % \begin{macro}{\xhookrightarrow} % \begin{macro}{\MT_hookright_fill:} % The hooks. % \begin{macrocode} \providecommand*\xhookleftarrow[2][]{% \ext@arrow 3095\MT_hookleft_fill:{#1}{#2}} \def\MT_hookleft_fill:{% \arrowfill@\leftarrow\relbar{\relbar\joinrel\rhook}} \providecommand*\xhookrightarrow[2][]{% \ext@arrow 3095\MT_hookright_fill:{#1}{#2}} \def\MT_hookright_fill:{% \arrowfill@{\lhook\joinrel\relbar}\relbar\rightarrow} % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \begin{macro}{\xmapsto} % \begin{macro}{\MT_mapsto_fill:} % The maps-to arrow. % \begin{macrocode} \providecommand*\xmapsto[2][]{% \ext@arrow 0395\MT_mapsto_fill:{#1}{#2}} \def\MT_mapsto_fill:{% \arrowfill@{\mapstochar\relbar}\relbar\rightarrow} % \end{macrocode} % \end{macro} % \end{macro} % 2024 (v1.30): Added \verb+\xLongrightarrow+ and \verb+\xLongleftarrow+. Code by muzimuchi on GitHub. I added extra spaces like for |\xRightarrow| above. % \begin{macro}{\MT_Longrightarrow_fill:} % \begin{macro}{\MT_Longleftarrow_fill:} % \begin{macro}{\xLongrightarrow} % \begin{macro}{\xLongleftarrow} % \begin{macrocode} \def\MT_Longrightarrow_fill:{% \arrowfill@\Relbar\Relbar\Longrightarrow} \def\MT_Longleftarrow_fill:{% \arrowfill@\Longleftarrow\Relbar\Relbar} \providecommand*\xLongrightarrow[2][]{% \ext@arrow 0359\MT_Longrightarrow_fill:{#1\ }{#2\ }} \providecommand*\xLongleftarrow[2][]{% \ext@arrow 3095\MT_Longleftarrow_fill:{\ #1}{\ #2}} % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % % \subsection{Underbrackets etc.} % % \begin{macro}{\underbracket} % \begin{macro}{\MT_underbracket_I:w} % \begin{macro}{\MT_underbracket_II:w} % \begin{macro}{\upbracketfill} % \begin{macro}{\upbracketend} % The \cs{underbracket} macro. Scan for two optional arguments. When % \pkg{xparse} becomes the standard this will be so much easier. % \begin{macrocode} \providecommand*\underbracket{ \@ifnextchar[ {\MT_underbracket_I:w} {\MT_underbracket_I:w[\l_MT_bracketheight_fdim]}} \def\MT_underbracket_I:w[#1]{ \@ifnextchar[ {\MT_underbracket_II:w[#1]} {\MT_underbracket_II:w[#1][.7\fontdimen5\textfont2]}} \def\MT_underbracket_II:w[#1][#2]#3{% \mathop{\vtop{\m@th\ialign{## \crcr $\hfil\displaystyle{#3}\hfil$% \crcr \noalign{\kern .2\fontdimen5\textfont2 \nointerlineskip}% \upbracketfill {#1}{#2}% \crcr}}} \limits} \def\upbracketfill#1#2{% \sbox\z@{$\braceld$} \edef\l_MT_bracketheight_fdim{\the\ht\z@}% \upbracketend{#1}{#2} \leaders \vrule \@height \z@ \@depth #1 \hfill \upbracketend{#1}{#2}% } \def\upbracketend#1#2{\vrule \@height #2 \@width #1\relax} % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \begin{macro}{\overbracket} % \begin{macro}{\MT_overbracket_I:w} % \begin{macro}{\MT_overbracket_II:w} % \begin{macro}{\downbracketfill} % \begin{macro}{\downbracketend} % The overbracket is quite similar. % \begin{macrocode} \providecommand*\overbracket{ \@ifnextchar[ {\MT_overbracket_I:w} {\MT_overbracket_I:w[\l_MT_bracketheight_fdim]}} \def\MT_overbracket_I:w[#1]{ \@ifnextchar[ {\MT_overbracket_II:w[#1]} {\MT_overbracket_II:w[#1][.7\fontdimen5\textfont2]}} \def\MT_overbracket_II:w[#1][#2]#3{% \mathop{\vbox{\m@th\ialign{## \crcr \downbracketfill{#1}{#2}% \crcr \noalign{\kern .2\fontdimen5\textfont2 \nointerlineskip}% $\hfil\displaystyle{#3}\hfil$ \crcr}}}% \limits} \def\downbracketfill#1#2{% \sbox\z@{$\braceld$}\edef\l_MT_bracketheight_fdim{\the\ht\z@} \downbracketend{#1}{#2} \leaders \vrule \@height #1 \@depth \z@ \hfill \downbracketend{#1}{#2}% } \def\downbracketend#1#2{\vrule \@width #1\@depth #2\relax} % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \begin{macro}{\LaTeXunderbrace} % \begin{macro}{\underbrace} % Redefinition of \cs{underbrace} and \cs{overbrace}. % \begin{macrocode} \MH_let:NwN \LaTeXunderbrace \underbrace \def\underbrace#1{\mathop{\vtop{\m@th\ialign{##\crcr $\hfil\displaystyle{#1}\hfil$\crcr \noalign{\kern.7\fontdimen5\textfont2\nointerlineskip}% % \end{macrocode} % |.5\fontdimen5\textfont2| is the height of the tip of the brace. % the remaining |.2\fontdimen5\textfont2| is for space between % \begin{macrocode} \upbracefill\crcr\noalign{\kern.5\fontdimen5\textfont2}}}}\limits} % \end{macrocode} % \end{macro} % \end{macro} % \begin{macro}{\LaTeXoverbrace} % \begin{macro}{\overbrace} % Same technique for \cs{overbrace}. % \begin{macrocode} \MH_let:NwN \LaTeXoverbrace \overbrace \def\overbrace#1{\mathop{\vbox{\m@th\ialign{##\crcr \noalign{\kern.5\fontdimen5\textfont2}% % \end{macrocode} % Adjust for tip height % \begin{macrocode} \downbracefill\crcr \noalign{\kern.7\fontdimen5\textfont2\nointerlineskip}% % \end{macrocode} % |.5\fontdimen5\textfont2| is the height of the tip of the brace. % The remaining |.2\fontdimen5\textfont2| is for space between % \begin{macrocode} $\hfil\displaystyle{#1}\hfil$\crcr}}}\limits} % \end{macrocode} % \end{macro} % \end{macro} % % % % % % \subsection{Special symbols} % % \subsubsection{Command names for parentheses} % \begin{macro}{\lparen} % \begin{macro}{\rparen} % Just an addition to the \LaTeXe\ kernel. % \begin{macrocode} \providecommand*\lparen{(} \providecommand*\rparen{)} % \end{macrocode} % \end{macro} % \end{macro} % \subsubsection{Vertically centered colon} % % \begin{macro}{\vcentcolon} % \begin{macro}{\ordinarycolon} % \begin{macro}{\MT_active_colon_true:} % \begin{macro}{\MT_active_colon_false:} % This is from the hands of Donald Arseneau. Somehow it is not % distributed, so I include it here. Here's the original text by % Donald: % \begin{verbatim} % centercolon.sty Dec 7, 2000 % Donald Arseneau asnd@triumf.ca % Public domain. % Vertically center colon characters (:) in math mode. % Particularly useful for $ a:=b$, and still correct for % $f : x\to y$. May be used in any TeX. % \end{verbatim} % % Slight change: the colon meaning is given only if \verb|centercolon| % is explicitly requested (before it was always assigned even if : remained % catcode 12). This allows better interaction with packages like babel % that also make colon active. % \begin{macrocode} \def\vcentcolon{\mathrel{\mathop\ordinarycolon}} \providecommand\ordinarycolon{:} \begingroup \catcode`\:=\active \lowercase{\endgroup \def\MT_activate_colon{% \ifnum\mathcode`\:=32768\relax \let\ordinarycolon= :% \else \mathchardef\ordinarycolon\mathcode`\: % \fi \let :\vcentcolon } } % \end{macrocode} % Option processing. % The `false' branch can only be requested if the option has previously been set `true'. % (By default neither are set.) % \begin{macrocode} \MH_new_boolean:n {center_colon} \define@key{\MT_options_name:}{centercolon}[true]{ \@ifundefined{MT_active_colon_#1:} { \MT_true_false_error:n \@nameuse{MT_active_colon_false:} } { \@nameuse{MT_active_colon_#1:} } } \def\MT_active_colon_true: { \MT_activate_colon \MH_if_boolean:nF {center_colon}{ \MH_set_boolean_T:n {center_colon} \edef\MT_active_colon_false: {\mathcode`\noexpand\:=\the\mathcode`\:\relax} \mathcode`\:=32768 } } % \end{macrocode} % % \changes{v1.30}{2022/11/15}{Forgot to define a default % \cs{MT\_active\_colon_false:}, who would run centercolon=false % before it being true?} % \begin{macrocode} \def\MT_active_colon_false:{} % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \begin{macro}{\MATHT@dblcolon} % \begin{macro}{\MATHT@coloneq} % \begin{macro}{\MATHT@dblcoloneq} % \begin{macro}{\MATHT@colondash} % \begin{macro}{\MATHT@dblcolondash} % \begin{macro}{\MATHT@eqcolon} % \begin{macro}{\MATHT@eqdblcolon} % \begin{macro}{\MATHT@dashcolon} % \begin{macro}{\MATHT@dashdblcolon} % \begin{macro}{\MATHT@colonapprox} % \begin{macro}{\MATHT@dblcolonapprox} % \begin{macro}{\MATHT@approxcolon} % \begin{macro}{\MATHT@approxdblcolon} % \begin{macro}{\MATHT@colonsim} % \begin{macro}{\MATHT@dblcolonsim} % \begin{macro}{\MATHT@simcolon} % \begin{macro}{\MATHT@simdblcolon} % We can now use \cs{vcentcolon} to define some colon related % symbols. Orinally the names of these macro names came from % \pkg{txfonts} and \pkg{pxfonts}. Though it turned out that some of % them we named inconsistently. Instead we now first name the macros % using an internal name and then later map these onto names similar % to those coming from \pkg{newtxmath} and \pkg{newpxmath}. % \changes{v1.08c}{2010/11/17}{Enclosed all in \cs{mathrel}} % \changes{v1.18}{2015/11/12}{Moved the enclosing \cs{mathrel} to % \cs{mkern}. This is a result of % \url{http://chat.stackexchange.com/transcript/message/23630342#23630342} and \url{http://chat.stackexchange.com/transcript/message/25348032#25348032}} % \changes{v1.29}{2022/06/27}{Moved symbol defs into separate MATHT named % macros} % \begin{macrocode} \newcommand*\MATHT@dblcolon{\vcentcolon\mathrel{\mkern-.9mu}\vcentcolon} \newcommand*\MATHT@coloneq{\vcentcolon\mathrel{\mkern-1.2mu}=} \newcommand*\MATHT@dblcoloneq{\dblcolon\mathrel{\mkern-1.2mu}=} \newcommand*\MATHT@colondash{\vcentcolon\mathrel{\mkern-1.2mu}\mathrel{-}} \newcommand*\MATHT@dblcolondash{\dblcolon\mathrel{\mkern-1.2mu}\mathrel{-}} \newcommand*\MATHT@eqcolon{=\mathrel{\mkern-1.2mu}\vcentcolon} \newcommand*\MATHT@eqdblcolon{=\mathrel{\mkern-1.2mu}\dblcolon} \newcommand*\MATHT@dashcolon{\mathrel{-}\mathrel{\mkern-1.2mu}\vcentcolon} \newcommand*\MATHT@dashdblcolon{\mathrel{-}\mathrel{\mkern-1.2mu}\dblcolon} \newcommand*\MATHT@colonapprox{\vcentcolon\mathrel{\mkern-1.2mu}\approx} \newcommand*\MATHT@dblcolonapprox{\dblcolon\mathrel{\mkern-1.2mu}\approx} \newcommand*\MATHT@approxcolon{\approx\mathrel{\mkern-1.2mu}\vcentcolon} \newcommand*\MATHT@approxdblcolon{\approx\mathrel{\mkern-1.2mu}\dblcolon} \newcommand*\MATHT@colonsim{\vcentcolon\mathrel{\mkern-1.2mu}\sim} \newcommand*\MATHT@dblcolonsim{\dblcolon\mathrel{\mkern-1.2mu}\sim} \newcommand*\MATHT@simcolon{\sim\mathrel{\mkern-1.2mu}\vcentcolon} \newcommand*\MATHT@simdblcolon{\sim\mathrel{\mkern-1.2mu}\dblcolon} % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \begin{macro}{\dblcolon} % \begin{macro}{\coloneqq} % \begin{macro}{\Coloneqq} % \begin{macro}{\coloneq} % \begin{macro}{\Coloneq} % \begin{macro}{\eqqcolon} % \begin{macro}{\Eqqcolon} % \begin{macro}{\eqcolon} % \begin{macro}{\Eqcolon} % \begin{macro}{\colonapprox} % \begin{macro}{\Colonapprox} % \begin{macro}{\colonsim} % \begin{macro}{\Colonsim} % This is just to simulate all the \cs{..colon..} symbols from % % \pkg{txfonts} and \pkg{pxfonts}. % \noindent % \textbf{2022/06/24:} Actually these were inconsistenly named in \pkg{txfonts} % and \pkg{pxfonts}. Some was properly renamed in \pkg{newtxmath} and % \pkg{newpxmath}, but not all. % \begin{macrocode} \MH_if_boolean:nTF {legacycolonsymbols}{ \AtBeginDocument{ \providecommand*\dblcolon{\MATHT@dblcolon} \providecommand*\coloneqq{\MATHT@coloneq} \providecommand*\Coloneqq{\MATHT@dblcoloneq} \providecommand*\coloneq{\MATHT@colondash} \providecommand*\Coloneq{\MATHT@dblcolondash} \providecommand*\eqqcolon{\MATHT@eqcolon} \providecommand*\Eqqcolon{\MATHT@eqdblcolon} \providecommand*\eqcolon{\MATHT@dashcolon} \providecommand*\Eqcolon{\MATHT@dashdblcolon} \providecommand*\colonapprox{\MATHT@colonapprox} \providecommand*\Colonapprox{\MATHT@dblcolonapprox} \providecommand*\colonsim{\MATHT@colonsim} \providecommand*\Colonsim{\MATHT@dblcolonsim} % new \providecommand*\approxcolon{\MATHT@approxcolon} \providecommand*\Approxcolon{\MATHT@approxdblcolon} \providecommand*\simcolon{\MATHT@simcolon} \providecommand*\Simcolon{\MATHT@simdblcolon} \providecommand*\colondash{\MATHT@colondash} \providecommand*\Colondash{\MATHT@dblcolondash} \providecommand*\dashcolon{\MATHT@dashcolon} \providecommand*\Dashcolon{\MATHT@dashdblcolon} } }{ \AtBeginDocument{ \providecommand*\dblcolon{\MATHT@dblcolon} \providecommand*\coloneqq{\MATHT@coloneq} % duplet \providecommand*\Coloneqq{\MATHT@dblcoloneq}% duplet \providecommand*\coloneq{\MATHT@coloneq} % changed \providecommand*\Coloneq{\MATHT@dblcoloneq} % changed \providecommand*\eqqcolon{\MATHT@eqcolon} % duplet \providecommand*\Eqqcolon{\MATHT@eqdblcolon}% duplet \providecommand*\eqcolon{\MATHT@eqcolon} % changed \providecommand*\Eqcolon{\MATHT@eqdblcolon} % changed \providecommand*\colonapprox{\MATHT@colonapprox} \providecommand*\Colonapprox{\MATHT@dblcolonapprox} \providecommand*\colonsim{\MATHT@colonsim} \providecommand*\Colonsim{\MATHT@dblcolonsim} % new \providecommand*\approxcolon{\MATHT@approxcolon} \providecommand*\Approxcolon{\MATHT@approxdblcolon} \providecommand*\simcolon{\MATHT@simcolon} \providecommand*\Simcolon{\MATHT@simdblcolon} \providecommand*\colondash{\MATHT@colondash} \providecommand*\Colondash{\MATHT@dblcolondash} \providecommand*\dashcolon{\MATHT@dashcolon} \providecommand*\Dashcolon{\MATHT@dashdblcolon} } } % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % % % \subsection{Multlined} % % \begin{macro}{\g_MT_multlinerow_int} % \begin{macro}{\l_MT_multwidth_dim} % Helpers. % \begin{macrocode} \let \AMS@math@cr@@ \math@cr@@ \MH_new_boolean:n {mult_firstline} \MH_new_boolean:n {outer_mult} \newcount\g_MT_multlinerow_int \newdimen\l_MT_multwidth_dim % \end{macrocode} % \end{macro} % \end{macro} % \begin{macro}{\MT_test_for_tcb_other:nnnnn} % This tests if the token(s) is/are equal to either t, c, or~b, or % something entirely different. % \changes{v1.19}{2017/03/31}{Added MH\_ prefix} % \begin{macrocode} \newcommand*\MT_test_for_tcb_other:nnnnn [1]{ \MH_if:w t#1\relax \expandafter\MH_use_choice_i:nnnn \MH_else: \MH_if:w c#1\relax \expandafter\expandafter\expandafter\MH_use_choice_ii:nnnn \MH_else: \MH_if:w b#1\relax \expandafter\expandafter\expandafter \expandafter\expandafter\expandafter\expandafter \MH_use_choice_iii:nnnn \MH_else: \expandafter\expandafter\expandafter \expandafter\expandafter\expandafter\expandafter \MH_use_choice_iv:nnnn \MH_fi: \MH_fi: \MH_fi: } % \end{macrocode} % \end{macro} % \begin{macro}{\MT_mult_invisible_line:} % An invisible line. % \textbf{BUG:} \cs{baselineskip} is zero inside an array or matrix, % thus in those cases the line is \emph{not} invisible. % \changes{v1.14}{2014/05/21}{Added -\cs{jot}} % \changes{v1.19}{2017/05/24}{Removed -\cs{jot} again, do not % remember why we added it in the first place} % \begin{macrocode} \def\MT_mult_invisible_line: { \crcr \global\MH_set_boolean_F:n {mult_firstline} \hbox to \l_MT_multwidth_dim{}\crcr \noalign{\vskip-\baselineskip \vskip-\normallineskip} } % \end{macrocode} % \end{macro} % \begin{macro}{\MT_mult_mathcr_atat:w} % The normal \cs{math@cr@@} with our hooks. % \changes{v1.19}{2017/03/31}{Added MH\_ prefix} % \begin{macrocode} \def\MT_mult_mathcr_atat:w [#1]{% \MH_if_num:w 0=`{\MH_fi: \iffalse}\MH_fi: \MH_if_boolean:nT {mult_firstline}{ \kern\l_MT_mult_left_fdim \MT_mult_invisible_line: } \crcr \noalign{\vskip#1\relax} \global\advance\g_MT_multlinerow_int\@ne \MH_if_num:w \g_MT_multlinerow_int=\l_MT_multline_lastline_fint \MH_let:NwN \math@cr@@\MT_mult_last_mathcr:w \MH_fi: } % \end{macrocode} % \end{macro} % \begin{macro}{\MT_mult_firstandlast_mathcr:w} % The special case where there is a two-line \env{multlined}. We % insert the first kern, then the invisible line of the desired % width, the optional vertical space and then the last kern. % \changes{v1.19}{2017/03/31}{Added MH\_ prefix} % \begin{macrocode} \def\MT_mult_firstandlast_mathcr:w [#1]{% \MH_if_num:w 0=`{\MH_fi: \iffalse}\MH_fi: \kern\l_MT_mult_left_fdim \MT_mult_invisible_line: \noalign{\vskip#1\relax} \kern\l_MT_mult_right_fdim } % \end{macrocode} % \end{macro} % \begin{macro}{\MT_mult_last_mathcr:w} % The normal last \cs{math@cr@@} which inserts the last kern. % \changes{v1.19}{2017/03/31}{Added MH\_ prefix} % \begin{macrocode} \def\MT_mult_last_mathcr:w [#1]{ \MH_if_num:w 0=`{\MH_fi: \iffalse}\MH_fi:\math@cr@@@ \noalign{\vskip#1\relax} \kern\l_MT_mult_right_fdim} % \end{macrocode} % \end{macro} % \begin{macro}{\MT_start_mult:N} % Setup for \env{multlined}. Finds the position. % \begin{macrocode} \newcommand\MT_start_mult:N [1]{ \MT_test_for_tcb_other:nnnnn {#1} { \MH_let:NwN \MT_next:\vtop } { \MH_let:NwN \MT_next:\vcenter } { \MH_let:NwN \MT_next:\vbox } { \PackageError{mathtools} {Invalid~ position~ specifier.~ I'll~ try~ to~ recover~ with~ `c'}\@ehc } \collect@body\MT_mult_internal:n } % \end{macrocode} % \end{macro} % \begin{macro}{\MT_shoveright:wn} % \begin{macro}{\MT_shoveleft:wn} % Extended versions of \cs{shoveleft} and \cs{shoveright}. % \begin{macrocode} \newcommand*\MT_shoveright:wn [2][0pt]{% #2\hfilneg \setlength\@tempdima{#1} \kern\@tempdima } \newcommand*\MT_shoveleft:wn [2][0pt]{% \hfilneg \setlength\@tempdima{#1} \kern\@tempdima #2 } % \end{macrocode} % \end{macro} % \end{macro} % \begin{macro}{\MT_mult_internal:n} % \changes{v1.01a}{2004/10/10}{Added Ord atom to beginning of each line} % The real internal \env{multlined}. % \changes{v1.19}{2017/05/22}{Added \cs{alignedspace@left} instead of % \cs{null}\cs{,}} % \begin{macrocode} \newcommand*\MT_mult_internal:n [1]{ \MH_if_boolean:nF {outer_mult}{\alignedspace@left} %<-- requires amsmath 2016/11/05 \MT_next: \bgroup % \end{macrocode} % Restore the meaning of \cmd{\\} inside \env{multlined}, else it % wouldn't work in the \env{equation} environment. Set the fake row % counter to zero. % \begin{macrocode} \Let@ \def\l_MT_multline_lastline_fint{0 } \chardef\dspbrk@context\@ne \restore@math@cr % \end{macrocode} % Use private versions. % \begin{macrocode} \MH_let:NwN \math@cr@@\MT_mult_mathcr_atat:w \MH_let:NwN \shoveleft\MT_shoveleft:wn \MH_let:NwN \shoveright\MT_shoveright:wn \spread@equation \MH_set_boolean_F:n {mult_firstline} % \end{macrocode} % Do some measuring. % \begin{macrocode} \MT_measure_mult:n {#1} % \end{macrocode} % Make sure the box is wide enough. % \changes{v1.19}{2017/03/31}{Added MH\_ prefix} % \begin{macrocode} \MH_if_dim:w \l_MT_multwidth_dim<\l_MT_multline_measure_fdim \MH_setlength:dn \l_MT_multwidth_dim{\l_MT_multline_measure_fdim} \fi \MH_set_boolean_T:n {mult_firstline} % \end{macrocode} % Tricky bit: If we only encountered one \cmd{\\} then use a very % special \cs{math@cr@@} that inserts everything needed. % \changes{v1.19}{2017/03/31}{Added MH\_ prefix} % \begin{macrocode} \MH_if_num:w \l_MT_multline_lastline_fint=\@ne \MH_let:NwN \math@cr@@ \MT_mult_firstandlast_mathcr:w \MH_fi: % \end{macrocode} % Do the typesetting. % \begin{macrocode} \ialign\bgroup \hfil\strut@$\m@th\displaystyle{}##$\hfil \crcr \hfilneg #1 } % \end{macrocode} % \end{macro} % \begin{macro}{\MT_measure_mult:n} % \changes{v1.01a}{2004/10/10}{Added Ord atom to beginning of each line} % Measuring. Disable all labelling and check the number of lines. % \changes{v1.18}{2015/11/12}{Added \cs{measuring@true} inside the % \env{multlined}} % \begin{macrocode} \newcommand\MT_measure_mult:n [1]{ \begingroup \measuring@true \g_MT_multlinerow_int\@ne \MH_let:NwN \label\MT_gobblelabel:w \MH_let:NwN \tag\gobble@tag \setbox\z@\vbox{ \ialign{\strut@$\m@th\displaystyle{}##$ \crcr #1 \crcr } } \xdef\l_MT_multline_measure_fdim{\the\wdz@} \advance\g_MT_multlinerow_int\m@ne \xdef\l_MT_multline_lastline_fint{\number\g_MT_multlinerow_int} \endgroup \g_MT_multlinerow_int\@ne } % \end{macrocode} % \end{macro} % \begin{macro}{\MT_multlined_second_arg:w} % Scan for a second optional argument. % \changes{v1.19}{2017/03/31}{Added MH\_ prefix} % \begin{macrocode} \MaybeMHPrecedingSpacesOff \newcommand*\MT_multlined_second_arg:w [1][\@empty]{ \MT_test_for_tcb_other:nnnnn {#1} {\def\MT_mult_default_pos:{#1}} {\def\MT_mult_default_pos:{#1}} {\def\MT_mult_default_pos:{#1}} { \MH_if_meaning:NN \@empty#1\@empty \MH_else: \setlength \l_MT_multwidth_dim{#1} \MH_fi: } \MT_start_mult:N \MT_mult_default_pos: } % \end{macrocode} % \end{macro} % % \begin{macro}{\MultlinedHook} % \changes{v1.18}{2015/11/12}{Added this hook} % Due to the methods used by \env{multlined}, some constructions may % fail. We already know that \env{multlined} does not work well inside % arrays or matrices. Be things used inside \cs{multlined} may also % fail. Thus we provide a hook that can be added to in order to make % redefinitions of these constructions when used inside % \env{multlined}. The default value include a fix to \env{subarray} % and thus \cs{substack}. The fix to this environment was suggested by % Ulrike Fisher, \url{http://chat.stackexchange.com/transcript/message/25105970#25105970} % \changes{v1.22}{2019/07/22}{Also added crampedsubarray} % \changes{v1.22}{2019/07/22}{Also added fixes for smallmatrix and the % MT versions of these} % \changes{v1.26}{2021/03/27}{We need a lualatex branch of this as % well. We need to find a better way to manage this. Patching?} % \begin{macrocode} \ifx\directlua\@undefined % THIS IS NORMAL \newcommand\MultlinedHook{ \renewenvironment{subarray}[1]{% \vcenter\bgroup \Let@ \restore@math@cr \default@tag \let\math@cr@@\AMS@math@cr@@ % <--- the fix \baselineskip\fontdimen10 \scriptfont\tw@ \advance\baselineskip\fontdimen12 \scriptfont\tw@ \lineskip\thr@@\fontdimen8 \scriptfont\thr@@ \lineskiplimit\lineskip \ialign\bgroup\ifx c##1\hfil\fi $\m@th\scriptstyle####$\hfil\crcr }{% \crcr\egroup\egroup } \renewenvironment{crampedsubarray}[1]{% \vcenter\bgroup \Let@ \restore@math@cr \default@tag \let\math@cr@@\AMS@math@cr@@ % <--- the fix \baselineskip\fontdimen10 \scriptfont\tw@ \advance\baselineskip\fontdimen12 \scriptfont\tw@ \lineskip\thr@@\fontdimen8 \scriptfont\thr@@ \lineskiplimit\lineskip \ialign\bgroup\ifx c##1\hfil\fi % \end{macrocode} % \changes{v1.25}{2021/03/18}{use \cs{MT_cramped_internal:Nn} instead, % see issue \#17} % Here we should use the proper cramped internal macro % \begin{macrocode} \span\MT_cramped_internal:Nn \scriptstyle {####}% \hfil\crcr }{% \crcr\egroup\egroup } % from mathtools \def\MT_smallmatrix_begin:N ##1{% \Let@\restore@math@cr\default@tag \let\math@cr@@\AMS@math@cr@@ % <--- the fix \baselineskip6\ex@ \lineskip1.5\ex@ \lineskiplimit\lineskip \csname MT_smallmatrix_##1_begin:\endcsname } % from amsmath \renewenvironment{smallmatrix}{\null\,\vcenter\bgroup \Let@\restore@math@cr\default@tag \let\math@cr@@\AMS@math@cr@@ % <--- the fix \baselineskip6\ex@ \lineskip1.5\ex@ \lineskiplimit\lineskip \ialign\bgroup\hfil$\m@th\scriptstyle####$\hfil&&\thickspace\hfil $\m@th\scriptstyle####$\hfil\crcr }{% \crcr\egroup\egroup\,% } } \else % \end{macrocode} % The LuaLaTeX version, only difference is the definition of crampedsubarray % \begin{macrocode} % THIS IS LUALATEX \newcommand\MultlinedHook{ % from amsmath % \end{macrocode} % \changes{1.27}{2021/04/12}{need to be \cs{renewenvironment}} % \begin{macrocode} \renewenvironment{subarray}[1]{% \vcenter\bgroup \Let@ \restore@math@cr \default@tag \let\math@cr@@\AMS@math@cr@@ % <--- the fix \baselineskip \Umathstacknumup \scriptstyle \advance\baselineskip \Umathstackdenomdown \scriptstyle \lineskip \Umathstackvgap \scriptstyle \lineskiplimit \lineskip \ialign\bgroup\ifx c##1\hfil\fi \Ustartmath \m@th\scriptstyle#### \Ustopmath \hfil\crcr }{% \crcr\egroup\egroup } % from mathtools % \end{macrocode} % \changes{1.27}{2021/04/12}{need to be \cs{renewenvironment}} % \begin{macrocode} \renewenvironment{crampedsubarray}[1]{% \vcenter\bgroup \Let@ \restore@math@cr \default@tag \let\math@cr@@\AMS@math@cr@@ % <--- the fix \baselineskip \Umathstacknumup \scriptstyle \advance\baselineskip \Umathstackdenomdown \scriptstyle \lineskip \Umathstackvgap \scriptstyle \lineskiplimit \lineskip \ialign\bgroup\ifx c##1\hfil\fi \Ustartmath \crampedscriptstyle{####} \Ustopmath \hfil\crcr }{% \crcr\egroup\egroup } % from mathtools \def\MT_smallmatrix_begin:N ##1{% \Let@\restore@math@cr\default@tag \let\math@cr@@\AMS@math@cr@@ % <--- the fix \baselineskip6\ex@ \lineskip1.5\ex@ \lineskiplimit\lineskip \csname MT_smallmatrix_##1_begin:\endcsname } % from amsmath \renewenvironment{smallmatrix}{\null\,\vcenter\bgroup \Let@\restore@math@cr\default@tag \let\math@cr@@\AMS@math@cr@@ % <--- the fix \baselineskip6\ex@ \lineskip1.5\ex@ \lineskiplimit\lineskip \ialign\bgroup\hfil$\m@th\scriptstyle####$\hfil&&\thickspace\hfil $\m@th\scriptstyle####$\hfil\crcr }{% \crcr\egroup\egroup\,% } } \fi % \end{macrocode} % \end{macro} % % \begin{environment}{multlined} % The user environment. Scan for an optional argument. % \changes{v1.18}{2015/11/12}{Added \cs{MultlinedHook}} % \changes{v1.19}{2017/03/31}{Added MH\_ prefix} % \begin{macrocode} \newenvironment{multlined}[1][] {\MH_group_align_safe_begin: \MultlinedHook \MT_test_for_tcb_other:nnnnn {#1} {\def\MT_mult_default_pos:{#1}} {\def\MT_mult_default_pos:{#1}} {\def\MT_mult_default_pos:{#1}} { \MH_if_meaning:NN \@empty#1\@empty \MH_else: \setlength \l_MT_multwidth_dim{#1} \MH_fi: } \MT_multlined_second_arg:w } { \hfilneg \endaligned \MH_group_align_safe_end: } \MHPrecedingSpacesOn % \end{macrocode} % \end{environment} % The keys needed. % \begin{macrocode} \define@key{\MT_options_name:} {firstline-afterskip}{\def\l_MT_mult_left_fdim{#1}} \define@key{\MT_options_name:} {lastline-preskip}{\def\l_MT_mult_right_fdim{#1}} \define@key{\MT_options_name:} {multlined-width}{\setlength \l_MT_multwidth_dim{#1}} \define@key{\MT_options_name:} {multlined-pos}{\def\MT_mult_default_pos:{#1}} \setkeys{\MT_options_name:}{ firstline-afterskip=\multlinegap, lastline-preskip=\multlinegap, multlined-width=0pt, multlined-pos=c, } % \end{macrocode} % \begin{macro}{\MT_gobblelabel:w} % Better than to assume that \cs{label} has exactly one mandatory % argument, hence the \texttt{w} specifier. % \begin{macrocode} \def\MT_gobblelabel:w #1{} % \end{macrocode} % \end{macro} % % % % % \section{Macros suggested/requested by Lars Madsen} % % The macros in this section are all requests made by Lars Madsen. % % \subsection{Paired delimiters} % % \changes{v1.13}{2012/05/10}{Extended \cs{DeclarePairedDelimiter(X)}} % \begin{macro}{\MT_delim_default_inner_wrappers:n} % In some cases users may want to control the internals a bit more. We % therefore create two call back macros each time the % \cs{DeclarePaired...} macro is issued. The default value of these % call backs are provided by |\MT_delim_default_inner_wrappers:n| % \begin{macrocode} \newcommand\MT_delim_default_inner_wrappers:n [1]{ \@namedef{MT_delim_\MH_cs_to_str:N #1 _star_wrapper:nnn}##1##2##3{ \mathopen{}\mathclose\bgroup ##1 ##2 \aftergroup\egroup ##3 } % \end{macrocode} % Turns out that there is a difference between \verb|\mathclose{)}| % and \verb|\mathclose)| (placement of for example superscript), so instead of two wrappers, we need three. % \changes{v1.19}{2017/05/22}{added \cs{...nostarnonscaled..} wrapper} % \changes{v1.19}{2017/05/22}{renamed \cs{...nostar..} to \cs{...nostarscaled..} } % \begin{macrocode} \@namedef{MT_delim_\MH_cs_to_str:N #1 _nostarscaled_wrapper:nnn}##1##2##3{ \mathopen{##1}##2\mathclose{##3} } % \end{macrocode} % \changes{v1.30}{2024/01/18}{Changed the nostarnonscaled to support the empty scaler (dot).} % If we want to support the empty scaler (dot) we need a test in the non-scaled case, otherwise a dot would be left in the output. % Test sugggested by David Carlisle. % \begin{macrocode} \@namedef{MT_delim_\MH_cs_to_str:N #1 _nostarnonscaled_wrapper:nnn}##1##2##3{ \ifx.##1\else\mathopen##1\fi##2\ifx.##3\else\mathclose##3\fi } } % \end{macrocode} % \end{macro} % % \begin{macro}{\reDeclarePairedDelimiterInnerWrapper} % Macro enabling the user to alter an existing call back. First % argument is the name of the macro we are altering (as defined via % \cs{DeclarePaired...}), the second is \texttt{star}, % \texttt{nostarnonscaled} or \texttt{nostarscaled}. In the last % argument \texttt{\#1} and \texttt{\#3} respectively refer to the % scaled fences and \texttt{\#2} refer to whatever come between. % \changes{v1.19}{2017/05/23}{Added a test and error} % \begin{macrocode} \newcommand\reDeclarePairedDelimiterInnerWrapper[3]{ \@ifundefined{MT_delim_\MH_cs_to_str:N #1 _ #2 _wrapper:nnn}{ \PackageError{mathtools}{ Wrapper~not~found~for~\string#1~and~option~'#2'.\MessageBreak Either~\string#1~is~ not~ defined,~or~ you~ are~using~ the~ \MessageBreak 'nostar'~ option,~which~ is~ no~ longer~ supported.~ \MessageBreak Please~ use~ 'nostarnonscaled'~ or~ 'nostarscaled~ \MessageBreak instead.~ }{See the manual} }{ \@namedef{MT_delim_\MH_cs_to_str:N #1 _ #2 _wrapper:nnn}##1##2##3{ #3 } } } % \end{macrocode} % % \begin{macro}{\MT_etb_ifdefempty_x:nnn} % \begin{macro}{\MT_etb_ifblank:nnn} % \changes{v1.19}{2017/05/23}{Added so we can test for empty args} % This is a copy of \cs{etb@ifdefempty} (it is \emph{not} the same % as \cs{ifdefempty}) and \cs{ifblank} from \pkg{etoolbox}, % currently we do not want to make \pkg{etoolbox} a requirement, % that may change in the future. We need a reliable method to check % whether a macro is blank or not (including spaces). % \begin{macrocode} \def\MT_etb_ifdefempty_x:nnn #1{ \expandafter\expandafter\expandafter \MT_etb_ifblank:nnn \expandafter\expandafter\expandafter{% \expandafter\strip@prefix\meaning#1} } \def\MT_etb_ifblank:nnn #1{ \expandafter\ifx\expandafter\relax\detokenize\expandafter{\@gobble#1?}\relax \expandafter\@firstoftwo \else \expandafter\@secondoftwo \fi } % \end{macrocode} % \end{macro} % \end{macro} % % % % \end{macro} % \begin{macro}{\DeclarePairedDelimiter} % \changes{v1.06}{2008/08/01}{Made user command robust} % This macro defines |#1| to be a control sequence that takes either % a star or an optional argument and one mandatory argument. % \begin{macrocode} \newcommand*\DeclarePairedDelimiter[3]{% \@ifdefinable{#1}{ % \end{macrocode} % Define the starred command to just put \cs{left} and \cs{right} % before the delimiters, wrapped in a callback function. % \changes{1.08e}{2010/09/02}{`Fixed' \cs{left}\dots\cs{right} bad spacing} % \changes{1.08e}{2010/09/14}{redid the \cs{left}\dots\cs{right} fix, % see \cs{DeclarePairedDelimiterXPP} for details.} % \changes{v1.13}{2012/05/10}{Using call back instead} % \begin{macrocode} \MT_delim_default_inner_wrappers:n{#1} % define the wrappers \@namedef{MT_delim_\MH_cs_to_str:N #1 _star:}##1 { \@nameuse{MT_delim_\MH_cs_to_str:N #1 _star_wrapper:nnn}% {\left#2}{##1}{\right#3} }% % \end{macrocode} % The command with optional argument. It should be \cs{bigg} or % alike. % \begin{macrocode} \@xp\@xp\@xp \newcommand \@xp\csname MT_delim_\MH_cs_to_str:N #1 _nostar:\endcsname [2][\\@gobble] { % \end{macrocode} % With the default optional argument we wind up with \cs{relax}, % else we get \cs{biggr} and \cs{biggl} etc. % \changes{v1.13}{2012/05/10}{Using call back instead} % \changes{v1.19}{2017/05/23}{Split the wrappers in two, so know % \cs{}\cs{@gobble} is now only used to check if the optional % argument is empty.} % \begin{macrocode} \def\@tempa{\\@gobble} \def\@tempb{##1} \ifx\@tempa\@tempb % \end{macrocode} % As of May 2017, we now run explicit wrapper in the nonscaled % version, so we can remove the feature to to add l and r version of % the scaler (as there is none). % \begin{macrocode} \@nameuse{MT_delim_\MH_cs_to_str:N #1 _nostarnonscaled_wrapper:nnn}% {#2} {##2} {#3} \else % \end{macrocode} % Next we need to check whether \texttt{\#\#1} is blank as that % should not be scaled % \begin{macrocode} \MT_etb_ifblank:nnn {##1}{ \@nameuse{MT_delim_\MH_cs_to_str:N #1 _nostarnonscaled_wrapper:nnn}% {#2} {##2} {#3} }{ \@nameuse{MT_delim_\MH_cs_to_str:N #1 _nostarscaled_wrapper:nnn}% {\@nameuse {\MH_cs_to_str:N ##1 l} #2} {##2} {\@nameuse {\MH_cs_to_str:N ##1 r} #3} } \fi } % \end{macrocode} % The user command comes here. Just check for the star and choose % the right internal command. % \begin{macrocode} \DeclareRobustCommand{#1}{ \@ifstar {\@nameuse{MT_delim_\MH_cs_to_str:N #1 _star:}} {\@nameuse{MT_delim_\MH_cs_to_str:N #1 _nostar:}} } } } % \end{macrocode} % \end{macro} % % \begin{macro}{\MT_paired_delimx_arg_test:n} % This tests the \oarg{num args} part of % \cs{DeclarePairedDelimiterX} and \cs{DeclarePairedDelimiterXPP} % (code reuse), and complains if it is not 1,\dots,9. % \changes{v1.14}{2014/05/20}{Added} % \begin{macrocode} \def\MT_paired_delimx_arg_test:n #1{ \ifnum#1>9\relax \PackageError{mathtools}{No~ more~ than~ 9~ arguments}{} \else \ifnum#1<1\relax \PackageError{mathtools}{Macro~ need~ 1~ or~ more~ arguments.\MessageBreak Please~ change~ [#1]~ to~ [1]~ ... [9]}{} \fi \fi } % \end{macrocode} % \end{macro} % \begin{macro}{\MT_delim_inner_generator:n..n} % \changes{v1.19}{2017/05/14}{Macro added, changes notes in the % implementation are taken from when this code was not factored out} % This generates the internal macro from % \cs{DeclarePairedDelimiterX} and \cs{DeclarePairedDelimiterXPP} % that handles the non-starred part of the generated macro. The % macro takes 7 arguments mimicing the arguments of % \cs{DeclarePairedDelimiterXPP}: % \begin{enumerate}\setlength\itemsep{0pt} % \item external macro name % \item number of arguments, 1-9, already checked at this stage % \item predata % \item left scaler % \item right scaler % \item postdata % \item body % \end{enumerate} % % \begin{macrocode} \def\@MHempty{} \newcommand\MT_delim_inner_generator:nnnnnnn [7]{ % \end{macrocode} % In order for the starred and non-starred version of % \cs{DeclarePairedDelimiterX(PP)} to have the same arguments, we need % to introduce an extra macro to catch the optional argument (this % means that the non-starred version can actually support ten % arguments!). Here we do things a little differently than with % \cs{DeclarePairedDelimiter}. The optional argument have % \cs{@MHempty} as the default. This was earlier locally redefined to % eat l/r additions to the scaler when there were no scaler. In this % implementation, we just look for that macro to see if no scaler has % been given at all. % \begin{macrocode} \@xp\@xp\@xp \newcommand \@xp\csname MT_delim_\MH_cs_to_str:N #1 _nostar_inner:\endcsname [#2] { % \end{macrocode} % Add the (possibly empty) precode: % \begin{macrocode} #3 % \end{macrocode} % Next we provide the inner workhorse. We need a bit of expansion % magic to get \cs{delimsize} to work. % \changes{v1.13}{2012/05/10}{Using call backs for \cs{mathopen} and % \cs{mathclose} additions} % \changes{v1.19}{2017/04/27}{Added resetting code for \cs{@MHempty}, % cannot rely on groups here. 2017/05/23 removed because of reimplementation} % % May 2017: Due to \verb+\mathclose{|}^2+ generally not being equal to % \verb+\mathclose|^2+ we needed to split the wrapper macro into % separate nonscaled and scaled versions. This also have the benefit % of completely eliminating the need to gobble any chars. There is now % the nonscaled version, which we do not add any scalers to and the % manually scaled version where we \emph{know} there is a scaler. The % complication is now that we need to be able to check for blank % input, thus the including of a few macros from \pkg{etoolbox}. % \changes{v1.19}{2017/05/23}{Split into two wrappers and some tests} % First we need to look at \cs{delimsize} to see if it is equal to % \cs{@MHempty}. If it is run the nonscaled version. % \begin{macrocode} \def\@tempa{\@MHempty} \@xp\def\@xp\@tempb\@xp{\delimsize} \ifx\@tempa\@tempb \@nameuse{MT_delim_\MH_cs_to_str:N #1 _nostarnonscaled_wrapper:nnn} {#4}{#7}{#5} \else % \end{macrocode} % Next we use a copy of a macro from \pkg{etoolbox} to determine % whether \cs{delimsize} is empty or not. This is to be sure that % \verb|\abs[]| and similar still end up in the unscaled branch. % \begin{macrocode} \MT_etb_ifdefempty_x:nnn {\delimsize}{ \@nameuse{MT_delim_\MH_cs_to_str:N #1 _nostarnonscaled_wrapper:nnn} {#4}{#7}{#5} }{ % \end{macrocode} % In the scaled version we add features to convert til scaler to its % l/r versions. % \begin{macrocode} \@nameuse{MT_delim_\MH_cs_to_str:N #1 _nostarscaled_wrapper:nnn} { \@xp\@xp\@xp\csname\@xp\MH_cs_to_str:N \delimsize l\endcsname #4 } {#7} { \@xp\@xp\@xp\csname\@xp\MH_cs_to_str:N \delimsize r\endcsname #5 } } \fi % \end{macrocode} % Add the (possibly empty) post code % \begin{macrocode} #6 \endgroup } } % \end{macrocode} % % \end{macro} % \begin{macro}{\DeclarePairedDelimiterXPP} % \changes{v1.19}{2017/05/24}{Rewritten as we might as well % implement ...X via ...XPP} It turns out it is useful to have a % more general version of \cs{DeclarePairedDelimiter} where we can % access the body and perhaps even add stuff on the outside of the % fences. Historically, we added \cs{DeclarePairedDelimiterX} first, % giving access to the body and the most general % \cs{DeclarePairedDelimiterXPP} was requested after that, thus % ending up with two macros so not to break existing document. As of % May 2017, since \cs{DeclarePairedDelimiterX} is just % \cs{DeclarePairedDelimiterXPP} with no pre- or postcode, we will % use this update to just define \cs{DeclarePairedDelimiterXPP} and % define \cs{DeclarePairedDelimiterX} from that. % % The arguments for \cs{DeclarePairedDelimiterXPP} are interpreted % as % \begin{center} % \marg{macroname}\oarg{num~args}\allowbreak\marg{pre~code}\allowbreak\marg{left % delim}\goodbreak \marg{right delim}\marg{post code}\marg{body} % \end{center} % Inside \marg{body} \cs{delimsize} % refers to the current size of the scaler (\cs{middle} in the starred version). % \begin{macrocode} \def\DeclarePairedDelimiterXPP#1[#2]#3#4#5#6#7{% \@ifdefinable{#1}{ % \end{macrocode} % The constructor takes five arguments, the name of the macro, the % number of arguments (1-9), the left and right delimiter, the inner % code for the two macros. First we verify that the number of arguments fit. % \changes{v1.14}{2014/05/20}{Factored out in separate macro % (\cs{MT_paired_delimx_arg_test:n}) for reuse. Comment refers back to % old \cs{DeclarePairedDelimiterX} implementation.} % \begin{macrocode} \MT_paired_delimx_arg_test:n{#2} % \end{macrocode} % \changes{v1.13}{2012/05/10}{Using call back instead} % Define the default call backs. % \begin{macrocode} \MT_delim_default_inner_wrappers:n{#1} % \end{macrocode} % We make sure to store the delimiter size in the local variable % \cs{delimsize}. Then users can refer to the size in the \marg{body} % argument. In the starred version it will refer to \cs{middle} and in % the normal version it will hold the provided optional argument. % \begin{macrocode} \@xp\@xp\@xp \newcommand \@xp\csname MT_delim_\MH_cs_to_str:N #1 _star:\endcsname [#2] { \begingroup \def\delimsize{\middle} % \end{macrocode} % Adding the \marg{precode} (possibly empty) % \begin{macrocode} #3 % \end{macrocode} % This is slightly controversial, \cs{left}\dots\cs{right} are known % to produce an inner atom, thus may cause different spacing than % normal delimiters. We `fix' this by introducing \cs{mathopen} and % \cs{mathclose}. This change is now factored out into call backs. % \changes{v1.08e}{2010/09/14}{redid the left/right fix, inspired by % ctt thread named `spacing after \cs{right}) and before \cs{left})' % started 2010-08-12.} % \changes{v1.13}{2012/05/10}{Using call back instead} % \begin{macrocode} \@nameuse{MT_delim_\MH_cs_to_str:N #1 _star_wrapper:nnn} {\left#4}{#7}{\right#5} #6 \endgroup } % \end{macrocode} % In order for the starred and non-starred version to have the same % arguments, we need to introduce an extra macro to catch the optional % argument (this means that the non-starred version can actually % support ten arguments!). % \begin{macrocode} \@xp\@xp\@xp \newcommand \@xp\csname MT_delim_\MH_cs_to_str:N #1 _nostar:\endcsname [1][\@MHempty] { % \end{macrocode} % We need to introduce a local group in order to support nesting. It % is ended inside \verb|\MT_delim_\MH_cs_to_str:N #1 _nostar_inner:|, % here we also stores the scaler in \cs{delimsize}. % \begin{macrocode} \begingroup \def\delimsize{##1} \@nameuse{MT_delim_\MH_cs_to_str:N #1 _nostar_inner:} } % \end{macrocode} % To make the code easier to work with we factored the next macro % out. Since \cs{DeclarePairedDelimiterX} is now implemented via % \cs{DeclarePairedDelimiterXPP} we did not need to. But it makes the % code a bit simpler. \cs{MT_delim_inner_generator:nnnnnnn} just % takes care of generating the appropriate \cs{..._nostar_inner:} macro. % \begin{macrocode} \MT_delim_inner_generator:nnnnnnn {#1}{#2}{#3}{#4}{#5}{#6}{#7} % \end{macrocode} % At the end, generate the actual user command. % \begin{macrocode} \DeclareRobustCommand{#1}{ \@ifstar {\@nameuse{MT_delim_\MH_cs_to_str:N #1 _star:}} {\@nameuse{MT_delim_\MH_cs_to_str:N #1 _nostar:}} } } } % \end{macrocode} % \end{macro} % \begin{macro}{\DeclarePairedDelimiterX} % \changes{v1.08}{2010/06/10}{Added % \cs{DeclarePairedDelimiterX}. 2017/05/24: old comment, kept for % historic reasons.} % \changes{v1.08e}{2010/09/02}{Provided better implementation of % \cs{DeclarePairedDelimiterX}. 2017/05/24: old comment, kept for % historic reasons.} % As of May 2017, this is now just a call to \cs{DeclarePairedDelimiterXPP}. % \begin{macrocode} \def\DeclarePairedDelimiterX#1[#2]#3#4#5{ \DeclarePairedDelimiterXPP{#1}[#2]{}{#3}{#4}{}{#5} } % \end{macrocode} % \end{macro} % % % \subsection{A \texttt{\textbackslash displaystyle} \env{cases} environment} % % \begin{macro}{\MT_start_cases:nnn} % We define a single command that does all the hard work. % \changes{v1.08}{2010/06/10}{made \cs{MT_start_cases:nnnn} more general} % \begin{macrocode} \def\MT_start_cases:nnnn #1#2#3#4{ % #1=sep,#2=lpreamble,#3=rpreamble,#4=delim \RIfM@\else \nonmatherr@{\begin{\@currenvir}} \fi \MH_group_align_safe_begin: \left#4 \vcenter \bgroup \Let@ \chardef\dspbrk@context\@ne \restore@math@cr \let \math@cr@@\AMS@math@cr@@ \spread@equation \ialign\bgroup % \end{macrocode} % Set the first column flush left in \cs{displaystyle} math and the % second as specified by the second argument. The first argument is % the separation between the columns. It could be a \cs{quad} or % something entirely different. % \begin{macrocode} \strut@#2 \strut@ #3 \crcr } % \end{macrocode} % \end{macro} % \begin{macro}{\MH_end_cases:} % \begin{macrocode} \def\MH_end_cases:{\crcr\egroup \restorecolumn@ \egroup \MH_group_align_safe_end: } % \end{macrocode} % \end{macro} % \begin{macro}{\newcases} % \begin{macro}{\renewcases} % Easy creation of new \env{cases}-like environments. % \changes{v1.08}{2010/06/10}{changed to match the change in \cs{MT_start_cases:nnnn}} % \begin{macrocode} \newcommand*\newcases[6]{% #1=name, #2=sep, #3=preamble, #4=left, #5=right \newenvironment{#1} {\MT_start_cases:nnnn {#2}{#3}{#4}{#5}} {\MH_end_cases:\right#6} } \newcommand*\renewcases[6]{ \renewenvironment{#1} {\MT_start_cases:nnnn {#2}{#3}{#4}{#5}} {\MH_end_cases:\right#6} } % \end{macrocode} % \begin{environment}{dcases} % \begin{environment}{dcases*} % \begin{environment}{rcases} % \begin{environment}{rcases*} % \begin{environment}{drcases} % \begin{environment}{drcases*} % \begin{environment}{cases*} % \env{dcases} is a traditional cases with display style math in % both columns, while \env{dcases*} has text in the second column. % \changes{v1.08}{2010/06/10}{changed to match the change in % \cs{newcases} plus added rcases and drcases} % \changes{v1.25}{2021/01/14}{Replaced \texttt{\{\#\#\}} by % \texttt{\#\#}, otherwise one cannot counteract the \cs{hfil} in the % definition with a \cs{hfil(l)} in a cell. Related to issue \#20 and https://tex.stackexchange.com/a/252412/3929} % \begin{macrocode} \newcases{dcases}{\quad}{% $\m@th\displaystyle##$\hfil}{$\m@th\displaystyle##$\hfil}{\lbrace}{.} \newcases{dcases*}{\quad}{% $\m@th\displaystyle##$\hfil}{##\hfil}{\lbrace}{.} \newcases{rcases}{\quad}{% $\m@th##$\hfil}{$\m@th##$\hfil}{.}{\rbrace} \newcases{rcases*}{\quad}{% $\m@th##$\hfil}{##\hfil}{.}{\rbrace} \newcases{drcases}{\quad}{% $\m@th\displaystyle##$\hfil}{$\m@th\displaystyle##$\hfil}{.}{\rbrace} \newcases{drcases*}{\quad}{% $\m@th\displaystyle##$\hfil}{##\hfil}{.}{\rbrace} \newcases{cases*}{\quad}{% $\m@th##$\hfil}{##\hfil}{\lbrace}{.} % \end{macrocode} % \end{environment} % \end{environment} % \end{environment} % \end{environment} % \end{environment} % \end{environment} % \end{environment} % \end{macro} % \end{macro} % % \subsection{New matrix environments} % \begin{macro}{\MT_matrix_begin:N} % \begin{macro}{\MT_matrix_end:} % Here are a few helpers for the matrices. \cs{MT_matrix_begin:N} % takes one argument specifying the column type for the array inside % the matrix. and \cs{MT_matrix_end:} inserts the correct ending. % \begin{macrocode} \def\MT_matrix_begin:N #1{% \hskip -\arraycolsep \MH_let:NwN \@ifnextchar \MH_nospace_ifnextchar:Nnn \array{*\c@MaxMatrixCols #1}} \def\MT_matrix_end:{\endarray \hskip -\arraycolsep} % \end{macrocode} % \end{macro} % \end{macro} % Before we define the environments we better make sure that spaces % before the optional argument is disallowed. Else a user who types % \begin{verbatim} % \[ % \begin{pmatrix*} % [c] & a \\ % b & d % \end{pmatrix*} % \] % \end{verbatim} % will lose the \texttt{[c]}! % \begin{macrocode} \MaybeMHPrecedingSpacesOff % \end{macrocode} % \begin{environment}{matrix*} % This environment is just like \env{matrix} only it takes an % optional argument specifying the column type. % \begin{macrocode} \newenvironment{matrix*}[1][c] {\MT_matrix_begin:N #1} {\MT_matrix_end:} % \end{macrocode} % \end{environment} % \begin{environment}{pmatrix*} % \begin{environment}{bmatrix*} % \begin{environment}{Bmatrix*} % \begin{environment}{vmatrix*} % \begin{environment}{Vmatrix*} % Then starred versions of the other \AmS{} matrices. % \begin{macrocode} \newenvironment{pmatrix*}[1][c] {\left(\MT_matrix_begin:N #1} {\MT_matrix_end:\right)} \newenvironment{bmatrix*}[1][c] {\left[\MT_matrix_begin:N #1} {\MT_matrix_end:\right]} \newenvironment{Bmatrix*}[1][c] {\left\lbrace\MT_matrix_begin:N #1} {\MT_matrix_end:\right\rbrace} \newenvironment{vmatrix*}[1][c] {\left\lvert\MT_matrix_begin:N #1} {\MT_matrix_end:\right\rvert} \newenvironment{Vmatrix*}[1][c] {\left\lVert\MT_matrix_begin:N #1} {\MT_matrix_end:\right\lVert} % \end{macrocode} % \end{environment} % \end{environment} % \end{environment} % \end{environment} % \end{environment} % % \changes{v1.10}{2011/02/12}{Added the code below, courtesy of Rasmus Villemoes} % Now we are at it why not provide fenced versions of the % \env{smallmatrix} construction as well. We will only provide a % version that can be adjusted as \env{matrix*} above, thus we keep % the * in the name. The implementation is courtesy of Rasmus % Villemoes. Rasmus also suggested making the default alignment in % these environments globally adjustable, so we did % (\texttt{smallmatrix-align=c} by default). It \emph{is} possible to % do something similar with the large matrix environments, but that % might cause problems with the \texttt{array} package, thus for now % we lease that feature alone. % % The base code is a variation over the original \env{smallmatrix} % environmetn fround in \texttt{amsmath}, thus we will not comment it further. % % TODO: make the code check that the optional argument is either % \texttt{c}, \texttt{l} or \texttt{r}. % \begin{macrocode} \def\MT_smallmatrix_begin:N #1{% \Let@\restore@math@cr\default@tag \baselineskip6\ex@ \lineskip1.5\ex@ \lineskiplimit\lineskip \csname MT_smallmatrix_#1_begin:\endcsname } \def\MT_smallmatrix_end:{\crcr\egroup\egroup\MT_smallmatrix_inner_space:} \def\MT_smallmatrix_l_begin:{\null\MT_smallmatrix_inner_space:\vcenter\bgroup \ialign\bgroup$\m@th\scriptstyle##$\hfil&&\thickspace $\m@th\scriptstyle##$\hfil\crcr } \def\MT_smallmatrix_c_begin:{\null\MT_smallmatrix_inner_space:\vcenter\bgroup \ialign\bgroup\hfil$\m@th\scriptstyle##$\hfil&&\thickspace\hfil $\m@th\scriptstyle##$\hfil\crcr } \def\MT_smallmatrix_r_begin:{\null\MT_smallmatrix_inner_space:\vcenter\bgroup \ialign\bgroup\hfil$\m@th\scriptstyle##$&&\thickspace\hfil $\m@th\scriptstyle##$\crcr } \newenvironment{smallmatrix*}[1][\MT_smallmatrix_default_align:] {\MT_smallmatrix_begin:N #1} {\MT_smallmatrix_end:} % \end{macrocode} % We would like to keep to the tradition of the \verb?Xmatrix? and % \verb?Xmatrix*? macros we added earlier, since most code is similar % we define them using a constructor macro. We also apply the trick % used within \verb?\DeclarePairedDelimiter(X)? such that \verb?\left? % \verb?\right? constructions produce spacings corresponding to % \verb?\mathopen? and \verb?\mathclose?. % \begin{macrocode} \def\MT_fenced_sm_generator:nnn #1#2#3{% \@ifundefined{#1}{% \newenvironment{#1} {\@nameuse{#1hook}\mathopen{}\mathclose\bgroup\left#2\MT_smallmatrix_begin:N c}% {\MT_smallmatrix_end:\aftergroup\egroup\right#3}% }{}% \@ifundefined{#1*}{% \newenvironment{#1*}[1][\MT_smallmatrix_default_align:]% {\@nameuse{#1hook}\mathopen{}\mathclose\bgroup\left#2\MT_smallmatrix_begin:N ##1}% {\MT_smallmatrix_end:\aftergroup\egroup\right#3}% }{}% } \MT_fenced_sm_generator:nnn{psmallmatrix}() \MT_fenced_sm_generator:nnn{bsmallmatrix}[] \MT_fenced_sm_generator:nnn{Bsmallmatrix}\lbrace\rbrace \MT_fenced_sm_generator:nnn{vsmallmatrix}\lvert\rvert \MT_fenced_sm_generator:nnn{Vsmallmatrix}\lVert\rVert % \end{macrocode} % % The options associated with this. % \begin{macrocode} \define@key{\MT_options_name:} {smallmatrix-align}{\def\MT_smallmatrix_default_align:{#1}} \define@key{\MT_options_name:} {smallmatrix-inner-space}{\def\MT_smallmatrix_inner_space:{#1}} \setkeys{\MT_options_name:}{ smallmatrix-align=c, smallmatrix-inner-space=\, } % \end{macrocode} % Restore the usual spacing behavior. % \begin{macrocode} \MHPrecedingSpacesOn % \end{macrocode} % % % % \subsection{Smashing an operator with limits} % % \begin{macro}{\smashoperator} % The user command. Define \cs{MT_smop_use:NNNNN} to be one of the % specialized commands \cs{MT_smop_smash_l:NNNNN}, % \cs{MT_smop_smash_r:NNNNN}, or the default % \cs{MT_smop_smash_lr:NNNNN}. % \changes{v1.25}{2021/03/04}{Verify that opt arg corresponds to % something predefined} % \begin{macrocode} \newcommand*\smashoperator[2][lr]{ \@ifundefined{MT_smop_smash_#1:NNNNN}{ \PackageError{mathtools}{Opt~ arg~ '#1'~ for~ \@backslashchar smashoperator~ is~ not~ supported.\MessageBreak Use~ l,~r~or~lr~ (default)}{} }{ \def\MT_smop_use:NNNNN {\@nameuse{MT_smop_smash_#1:NNNNN}} \toks@{#2} \expandafter\MT_smop_get_args:wwwNnNn \the\toks@\@nil\@nil\@nil\@nil\@nil\@nil\@@nil } } % \end{macrocode} % \end{macro} % \begin{macro}{\MT_smop_remove_nil_vi:N} % \begin{macro}{\MT_smop_mathop:n} % \begin{macro}{\MT_smop_limits:} % Some helper functions. % \begin{macrocode} \def\MT_smop_remove_nil_vi:N #1\@nil\@nil\@nil\@nil\@nil\@nil{#1} \def\MT_smop_mathop:n {\mathop} \def\MT_smop_limits: {\limits} % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % Some conditionals. % \begin{macrocode} \MH_new_boolean:n {smop_one} \MH_new_boolean:n {smop_two} % \end{macrocode} % \begin{macro}{\MT_smop_get_args:wwwNnNn} % The argument stripping. There are three different valid types of % input: % \begin{enumerate} % \item An operator with neither subscript nor superscript. % \item An operator with one subscript or superscript. % \item An operator with both subscript and superscript. % \end{enumerate} % Additionally an operator can be either a single macro as in % \cs{sum} or in \cs{mathop}\arg{A} and people might be tempted to % put a \cs{limits} after the operator, even though it's not % necessary. Thus the input with most tokens would be something like % \begin{verbatim} % \mathop{TTT}\limits_{sub}^{sup} % \end{verbatim} % Therefore we have to scan for seven arguments, but there might % only be one actually. So let's list the possible situations: % \begin{enumerate} % \item \verb|\mathop{TTT}\limits_{subsub}^{supsup}| % \item \verb|\mathop{TTT}_{subsub}^{supsup}| % \item \verb|\sum\limits_{subsub}^{supsup}| % \item \verb|\sum_{subsub}^{supsup}| % \end{enumerate} % Furthermore the |_{subsub}^{supsup}| part can also just be % |_{subsub}| or empty. % \begin{macrocode} \def\MT_smop_get_args:wwwNnNn #1#2#3#4#5#6#7\@@nil{% \begingroup \def\MT_smop_arg_A: {#1} \def\MT_smop_arg_B: {#2} \def\MT_smop_arg_C: {#3} \def\MT_smop_arg_D: {#4} \def\MT_smop_arg_E: {#5} \def\MT_smop_arg_F: {#6} \def\MT_smop_arg_G: {#7} % \end{macrocode} % Check if A is \cs{mathop}. If it is, we know that B is the argument % of the \cs{mathop}. % \changes{v1.19}{2017/03/31}{Added MH\_ prefix} % \begin{macrocode} \MH_if_meaning:NN \MT_smop_arg_A: \MT_smop_mathop:n % \end{macrocode} % If A was \cs{mathop} we check if C is \cs{limits} % \changes{v1.19}{2017/03/31}{Added MH\_ prefix} % \begin{macrocode} \MH_if_meaning:NN \MT_smop_arg_C:\MT_smop_limits: \def\MT_smop_final_arg_A:{#1{#2}}% % \end{macrocode} % Now we have something like \verb|\mathop{TTT}\limits|. Then check % if D is \cs{@nil}. % \changes{v1.19}{2017/03/31}{Added MH\_ prefix} % \begin{macrocode} \MH_if_meaning:NN \MT_smop_arg_D: \@nnil \MH_else: \MH_set_boolean_T:n {smop_one} \MH_let:NwN \MT_smop_final_arg_B: \MT_smop_arg_D: \MH_let:NwN \MT_smop_final_arg_C: \MT_smop_arg_E: \MH_if_meaning:NN \MT_smop_arg_F: \@nnil \MH_else: \MH_set_boolean_T:n {smop_two} \MH_let:NwN \MT_smop_final_arg_D: \MT_smop_arg_F: \edef\MT_smop_final_arg_E: {\expandafter\MT_smop_remove_nil_vi:N \MT_smop_arg_G: } \MH_fi: \MH_fi: \MH_else: % \end{macrocode} % Here we have something like \verb|\mathop{TTT}|. Still check % if D is \cs{@nil}. % \changes{v1.19}{2017/03/31}{Added MH\_ prefix} % \begin{macrocode} \def\MT_smop_final_arg_A:{#1{#2}}% \MH_if_meaning:NN \MT_smop_arg_D: \@nnil \MH_else: \MH_set_boolean_T:n {smop_one} \MH_let:NwN \MT_smop_final_arg_B: \MT_smop_arg_C: \MH_let:NwN \MT_smop_final_arg_C: \MT_smop_arg_D: \MH_if_meaning:NN \MT_smop_arg_F: \@nnil \MH_else: \MH_set_boolean_T:n {smop_two} \MH_let:NwN \MT_smop_final_arg_D: \MT_smop_arg_E: \MH_let:NwN \MT_smop_final_arg_E: \MT_smop_arg_F: \MH_fi: \MH_fi: \MH_fi: % \end{macrocode} % If A was not \cs{mathop}, it is an operator in itself, so we check % if B is \cs{limits} % \changes{v1.19}{2017/03/31}{Added MH\_ prefix} % \begin{macrocode} \MH_else: \MH_if_meaning:NN \MT_smop_arg_B:\MT_smop_limits: \def\MT_smop_final_arg_A:{#1}% \MH_if_meaning:NN \MT_smop_arg_D: \@nnil \MH_else: \MH_set_boolean_T:n {smop_one} \MH_let:NwN \MT_smop_final_arg_B: \MT_smop_arg_C: \MH_let:NwN \MT_smop_final_arg_C: \MT_smop_arg_D: \MH_if_meaning:NN \MT_smop_arg_F: \@nnil \MH_else: \MH_set_boolean_T:n {smop_two} \MH_let:NwN \MT_smop_final_arg_D: \MT_smop_arg_E: \MH_let:NwN \MT_smop_final_arg_E: \MT_smop_arg_F: \MH_fi: \MH_fi: \MH_else: % \end{macrocode} % No \cs{limits} was found, so we already have the right input. Just % forget about the last two arguments. % \changes{v1.19}{2017/03/31}{Added MH\_ prefix} % \begin{macrocode} \def\MT_smop_final_arg_A:{#1}% \MH_if_meaning:NN \MT_smop_arg_C: \@nnil \MH_else: \MH_set_boolean_T:n {smop_one} \MH_let:NwN \MT_smop_final_arg_B: \MT_smop_arg_B: \MH_let:NwN \MT_smop_final_arg_C: \MT_smop_arg_C: \MH_if_meaning:NN \MT_smop_arg_D: \@nnil \MH_else: \MH_set_boolean_T:n {smop_two} \MH_let:NwN \MT_smop_final_arg_D: \MT_smop_arg_D: \MH_let:NwN \MT_smop_final_arg_E: \MT_smop_arg_E: \MH_fi: \MH_fi: \MH_fi: \MH_fi: % \end{macrocode} % No reason to measure if there's no sub or sup. % \begin{macrocode} \MH_if_boolean:nT {smop_one}{ \MT_smop_measure:NNNNN \MT_smop_final_arg_A: \MT_smop_final_arg_B: \MT_smop_final_arg_C: \MT_smop_final_arg_D: \MT_smop_final_arg_E: } \MT_smop_use:NNNNN \MT_smop_final_arg_A: \MT_smop_final_arg_B: \MT_smop_final_arg_C: \MT_smop_final_arg_D: \MT_smop_final_arg_E: \endgroup } % \end{macrocode} % \end{macro} % Typeset what is necessary and ignore width of sub and sup: % \begin{macrocode} \def\MT_smop_needed_args:NNNNN #1#2#3#4#5{% \displaystyle #1 \MH_if_boolean:nT {smop_one}{ % \end{macrocode} % Let's use the internal versions of \cs{crampedclap} now that we now % it is set in \cs{scriptstyle}. % \begin{macrocode} \limits#2{\MT_cramped_clap_internal:Nn \scriptstyle{#3}} \MH_if_boolean:nT {smop_two}{ #4{\MT_cramped_clap_internal:Nn \scriptstyle{#5}} } } } % \end{macrocode} % Measure the natural width. \cs{@tempdima} holds the dimen we need to % adjust it all with. % \begin{macrocode} \def\MT_smop_measure:NNNNN #1#2#3#4#5{% \MH_let:NwN \MT_saved_mathclap:Nn \MT_cramped_clap_internal:Nn \MH_let:NwN \MT_cramped_clap_internal:Nn \@secondoftwo \sbox\z@{$\m@th\MT_smop_needed_args:NNNNN #1#2#3#4#5$} \MH_let:NwN \MT_cramped_clap_internal:Nn \MT_saved_mathclap:Nn \sbox\tw@{$\m@th\displaystyle#1$} \@tempdima=.5\wd0 \advance\@tempdima-.5\wd2 } % \end{macrocode} % The `l' variant % \begin{macrocode} \def\MT_smop_smash_l:NNNNN #1#2#3#4#5{ \MT_smop_needed_args:NNNNN #1#2#3#4#5\kern\@tempdima } % \end{macrocode} % The `r' variant % \begin{macrocode} \def\MT_smop_smash_r:NNNNN #1#2#3#4#5{ \kern\@tempdima\MT_smop_needed_args:NNNNN #1#2#3#4#5 } % \end{macrocode} % The `lr' variant % \changes{v1.25}{2021/03/04}{add `rl' as an alias for `lr'} % \begin{macrocode} \def\MT_smop_smash_lr:NNNNN #1#2#3#4#5{ \MT_smop_needed_args:NNNNN #1#2#3#4#5 } % \end{macrocode} % Add `rl' as an alias for `lr' % \begin{macrocode} \MH_let:NwN \MT_smop_smash_rl:NNNNN \MT_smop_smash_lr:NNNNN % \end{macrocode} % % % \subsection{Adjusting limits} % % % \begin{macro}{\MT_vphantom:Nn} % \begin{macro}{\MT_hphantom:Nn} % \begin{macro}{\MT_phantom:Nn} % \begin{macro}{\MT_internal_phantom:N} % The main advantage of \cs{phantom} et al., is the ability to % choose the right size automatically, but it requires the input to % be typeset four times. Since we will need to have a \cs{cramped} % inside a \cs{vphantom} it is much, much faster to choose the style % ourselves (we already know it). These macros make it possible. % \begin{macrocode} \def\MT_vphantom:Nn {\v@true\h@false\MT_internal_phantom:N} \def\MT_hphantom:Nn {\v@false\h@true\MT_internal_phantom:N} \def\MT_phantom:Nn {\v@true\h@true\MT_internal_phantom:N} \def\MT_internal_phantom:N #1{ \ifmmode \expandafter\mathph@nt\expandafter#1 \else \expandafter\makeph@nt \fi } % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % % \begin{macro}{\adjustlimits} % This is for making sure limits line up on two consecutive % operators. % \begin{macrocode} \newcommand*\adjustlimits[6]{ % \end{macrocode} % We measure the two operators and save the difference of their % depths. % \begin{macrocode} \sbox\z@{$\m@th \displaystyle #1$} \sbox\tw@{$\m@th \displaystyle #4$} \@tempdima=\dp\z@ \advance\@tempdima-\dp\tw@ % \end{macrocode} % We force \cs{displaystyle} for the operator and \cs{scripstyle} % for the limit. If we make use of the regular \cs{smash}, % \cs{vphantom}, and \cs{cramped} macros, and let \TeX{} choose the % right style for each one of them, we get a lot of redundant code % as we have no need for the combination % $(\cs{displaystyle},\cs{textstyle})$ etc. Only % $(\cs{scriptstyle},\cs{scriptstyle})$ is useful. % \changes{v1.19}{2017/03/31}{Added MH\_ prefix} % \begin{macrocode} \MH_if_dim:w \@tempdima>\z@ \mathop{#1}\limits#2{#3} \MH_else: \mathop{#1\MT_vphantom:Nn \displaystyle{#4}}\limits #2{ \def\finsm@sh{\ht\z@\z@ \box\z@} \mathsm@sh\scriptstyle{\MT_cramped_internal:Nn \scriptstyle{#3}} \MT_vphantom:Nn \scriptstyle {\MT_cramped_internal:Nn \scriptstyle{#6}} } \MH_fi: \MH_if_dim:w \@tempdima>\z@ \mathop{#4\MT_vphantom:Nn \displaystyle{#1}}\limits #5 { \MT_vphantom:Nn \scriptstyle {\MT_cramped_internal:Nn \scriptstyle{#3}} \def\finsm@sh{\ht\z@\z@ \box\z@} \mathsm@sh\scriptstyle{\MT_cramped_internal:Nn \scriptstyle{#6}} } \MH_else: \mathop{#4}\limits#5{#6} \MH_fi: } % \end{macrocode} % \end{macro} % % \subsection{Swapping above display skip} % % \begin{macro}{\SwapAboveDisplaySkip} % This macro is intended to be used at the start of \AmS\ % environments, in order to force it to use % \cs{abovedisplayshortskip} instead of \cs{abovedisplayskip} above % the displayed math. Because of the use of \cs{noalign} it will not % work inside \env{equation} or \env{multline}. % \begin{macrocode} \newcommand\SwapAboveDisplaySkip{% \noalign{\vskip-\abovedisplayskip\vskip\abovedisplayshortskip} } % \end{macrocode} % % \end{macro} % % \subsection{An aid to alignment} % % \begin{macro}{\MoveEqLeft} % \changes{v1.05}{2008/06/05}{Added \cs{MoveEqLeft} (daleif)} % \changes{v1.05b}{2008/06/18}{We don't need \cs{setlength} here % (daleif), after discussion about \cs{global} and \cs{setlength} % on ctt} % \changes{v1.12}{2011/06/12}{We don't even need lengths. GL % suggested on ctt to just apply them directly.} % This is a very simple macro, we `move' a line in an % alignment backwards in order to simulate that all subsequent lines % have been indented. Note that simply using \verb+\kern-2m+ after % the \verb+&+ is not enough, then the alignemnt environment never % detects that there is anything (though simulated) in the cell % before the \verb+&+. % \begin{macrocode} \newcommand\MoveEqLeft[1][2]{\kern #1em & \kern -#1em} % \end{macrocode} % \end{macro} % % \begin{macro}{\Aboxed} % \changes{v1.08}{2010/06/29}{Added \cs{Aboxed}} % The idea from \cs{MoveEqLeft} can be used for other things. Here we % create a macro that will allow a user to box an equation inside an % alignment. % \changes{v1.12}{2011/08/17}{\cs{Aboxed} reimplemented, cudos to GL} % \begin{macrocode} \newcommand\Aboxed[1]{\let\bgroup{\romannumeral-`}\@Aboxed#1&&\ENDDNE} % \end{macrocode} % \sloppy % The macro has been reimplemented courtesy of Florent Chervet out of % a posting on ctt, \url{https://groups.google.com/group/comp.text.tex/browse_thread/thread/5d66395f2a1b5134/93fd9661484bd8d8?#93fd9661484bd8d8} % \begin{macrocode} \def\@Aboxed#1\ENDDNE{% \ifnum0=`{}\fi \setbox \z@ \hbox{$\displaystyle#1{}\m@th$\kern\fboxsep \kern\fboxrule }% \edef\@tempa {\kern \wd\z@ &\kern -\the\wd\z@ % \end{macrocode} % The \verb|\fboxsep\the\fboxsep...| line ensures that you can use % \verb|\fboxsep=10pt\Aboxed{...}| in a pinch. % \begin{macrocode} \fboxsep\the\fboxsep \fboxrule \the\fboxrule }\@tempa \boxed {#1#2}% } % \end{macrocode} % \end{macro} % % \begin{macro}{\MakeAboxedCommand} % \changes{1.28}{2022/01/01}{Added} % At times users want macros equivalent to \cs{Aboxed} but with a % different box as the base. So we provide one % \begin{macrocode} \newcommand\MakeAboxedCommand[2]{ % #1: command to create % #2: box command to use \newcommand#1[1]{\let\bgroup{\romannumeral-`}% \@nameuse{@@\MH_cs_to_str:N #1}##1&&\ENDDNE} \@namedef{@@\MH_cs_to_str:N #1}##1&##2&##3\ENDDNE{% % \end{macrocode} % Instead of hardcoding the kerning of box rule and box sep, we record % the width of an empty box and kern half of it. % \begin{macrocode} \settowidth\@tempdimc{#2{}}% \ifnum0=`{}\fi \setbox \z@ \hbox{$\displaystyle##1{}\m@th$\kern0.5\@tempdimc}% % \end{macrocode} % The \verb|\fboxsep\the\fboxsep...| line enables % \verb|\fboxsep=10\Command{...&...}|. Of course only works for boxed % that uses \cs{fboxsep} and \cs{fboxrule}. % \begin{macrocode} \edef\@tempa{\kern\wd\z@&\kern-\the\wd\z@% \fboxsep\the\fboxsep \fboxrule \the\fboxrule}% \@tempa% % \end{macrocode} % Instead of using \cs{boxed} directly, we mimick the definition of % \cs{boxed} and should thus be able to use any box. % \begin{macrocode} #2{\m@th$\displaystyle ##1##2$}% } } % \end{macrocode} % % \end{macro} % % % \begin{macro}{\ArrowBetweenLines} % \changes{v1.05}{2008/06/05}{Added \cs{ArrowBetweenLines} as it % belongs here and not just in my \LaTeX book (daleif)} % ????Implementation notes are needed???? % \begin{macrocode} \MHInternalSyntaxOff \def\ArrowBetweenLines{\relax \iffalse{\fi\ifnum0=`}\fi \@ifstar{\ArrowBetweenLines@auxI{00}}{\ArrowBetweenLines@auxI{01}}} \def\ArrowBetweenLines@auxI#1{% \@ifnextchar[% {\ArrowBetweenLines@auxII{#1}}% {\ArrowBetweenLines@auxII{#1}[\Updownarrow]}} \def\ArrowBetweenLines@auxII#1[#2]{% \ifnum0=`{\fi \iffalse}\fi % \end{macrocode} % It turns out that for some reason the \cs{crcr} (next) removes the % automatic equation number replacement. The replacement hack seems to % the trick, though I have no idea why \cs{crcr} broke things (/daleif). % \changes{v1.08}{2010/06/15}{fixed eq num replacement bug} % \begin{macrocode} % \crcr \expandafter\in@\expandafter{\@currenvir}% {alignedat,aligned,gathered}% \ifin@ \else \notag \fi% \\ \noalign{\nobreak\vskip-\baselineskip\vskip-\lineskip}% \noalign{\expandafter\in@\expandafter{\@currenvir}% {alignedat,aligned,gathered}% \ifin@ \else\notag\fi% }% \if#1 &&\quad #2\else #2\quad\fi \\\noalign{\nobreak\vskip-\lineskip}} \MHInternalSyntaxOn % \end{macrocode} % \end{macro} % % % \subsection{Centered vertical dots} % % Doing a \verb?\vdots? centered within a different sized box, is % rather easy with the tools available. Note that it does \emph{not} % check for the style we are running in, thus do not expect this to % work well within \verb?\scriptstyle? and smaller. Basically we % create a box of a width corresponding to \verb?{}#1{}? and center % the \verb?\vdots? within it. % \begin{macrocode} \newcommand\vdotswithin[1]{% {\mathmakebox[\widthof{\ensuremath{{}#1{}}}][c]{{\vdots}}}} % \end{macrocode} % Next we are inspired by \verb?\ArrowBetweenLines? and provide a % costruction to be used within alignments with much less vertical % space above and below. % % First in order to support \env{spreadlines} we need to store the % original value of \verb?\jot? (and hope the user does not mess with it). % \begin{macrocode} \newlength\origjot \setlength\origjot{\jot} % \end{macrocode} % Next define how much we spacing we flush out, and make this user adjustable. % \begin{macrocode} \newdimen\l_MT_shortvdotswithinadjustabove_dim \newdimen\l_MT_shortvdotswithinadjustbelow_dim \define@key{\MT_options_name:} {shortvdotsadjustabove}{\setlength\l_MT_shortvdotswithinadjustabove_dim{#1}} \define@key{\MT_options_name:} {shortvdotsadjustbelow}{\setlength\l_MT_shortvdotswithinadjustbelow_dim{#1}} % \end{macrocode} % The actual defaults we found by trail and error. % \begin{macrocode} \setkeys{\MT_options_name:}{ shortvdotsadjustabove=2.15\origjot, shortvdotsadjustbelow=\origjot } % \end{macrocode} % The user macro comes in two versions, starred version corresponding % to alignment \emph{before} and \verb?&? and a non-starred version % with alignment \emph{after} \verb?&?. % \begin{macrocode} \def\shortvdotswithin{\relax \@ifstar{\MT_svwi_aux:nn{00}}{\MT_svwi_aux:nn{01}}} \def\MT_svwi_aux:nn #1#2{ \MTFlushSpaceAbove \if#1 \vdotswithin{#2}& \else &\vdotswithin{#2} \fi \MTFlushSpaceBelow } % \end{macrocode} % We will need a way to remove any tags (eq. numbers) on the % \verb?\vdots? line. We cannot use the method used by % \verb?\ArrowBetweenLines? so we use inspiration from % \texttt{etoolbox}. % \begin{macrocode} \def\MT_remove_tag_unless_inner:n #1{% \begingroup \def\etb@tempa##1|#1|##2\MT@END{\endgroup \ifx\@empty##2\@empty\notag\fi}% \expandafter\etb@tempa\expandafter|alignedat|aligned|split|#1|\MT@END} %| emacs % \end{macrocode} % These macros take care of removing the space above or below. Since % these may be useful for the user in very special cases, we provide % them as separate macros. % \begin{macrocode} \newcommand\MTFlushSpaceAbove{ \expandafter\MT_remove_tag_unless_inner:n\expandafter{\@currenvir} \\ \noalign{% \nobreak\vskip-\baselineskip\vskip-\lineskip% \vskip-\l_MT_shortvdotswithinadjustabove_dim \vskip-\origjot \vskip\jot }% \noalign{ \expandafter\MT_remove_tag_unless_inner:n\expandafter{\@currenvir} } } \newcommand\MTFlushSpaceBelow{ \\\noalign{% \nobreak\vskip-\lineskip \vskip-\l_MT_shortvdotswithinadjustbelow_dim \vskip-\origjot \vskip\jot } } % \end{macrocode} % % % \section{A few extra symbols} % % Most math font sets are missing three symbols: \cs{nuparrow}, % \cs{ndownarrow} and \cs{bigtimes}. We provide \emph{simulated} % versions of these symbols in case they are missing. % % \subsection{Negated up- and down arrows} % % Note that the \cs{nuparrow} and the \cs{ndownarrow} are made from % \cs{nrightarrow} and \cs{nleftarrow}, so these have to be % present. If they are not, we throw an error at use. The % implementation details are due to Enrico Gregorio % (\url{http://groups.google.com/group/comp.text.tex/msg/689cc8bd604fdb51}), % the basic idea is to reflect and rotate existing negated % arrows. Note that the reflection and rotation will not show up i % most DVI previewers. % \begin{macro}{\MH_nrotarrow:NN} % \changes{v1.07}{2008/08/11}{Added support for \cs{nuparrow} and \cs{ndownaddow}} % First a common construction macro. % \begin{macrocode} \def\MH_nrotarrow:NN #1#2{% \setbox0=\hbox{$\m@th#1\uparrow$}\dimen0=\dp0 \setbox0=\hbox{% \reflectbox{\rotatebox[origin=c]{90}{$\m@th#1\mkern2.22mu #2$}}}% \dp0=\dimen0 \box0 \mkern2.3965mu } % \end{macrocode} % \end{macro} % The negated arrows are then made using this macro on respectively % \cs{nrightarrow} and \cs{nleftarrow} % \begin{macro}{\MH_nuparrow:} % \begin{macro}{\MH_ndownarrow:} % \begin{macrocode} \def\MH_nuparrow: {% \mathrel{\mathpalette\MH_nrotarrow:NN\nrightarrow} } \def\MH_ndownarrow: {% \mathrel{\mathpalette\MH_nrotarrow:NN\nleftarrow} } % \end{macrocode} % \end{macro} % \end{macro} % \begin{macro}{\nuparrow} % \begin{macro}{\ndownarrow} % Next we provide \cs{nuparrow} and \cs{ndownarrow} at begin % document. Since they depend on \cs{nrightarrow} and % \cs{nleftarrow} we test for these and let the macros throw an % error if they are missing. % \changes{v1.08b}{2010/07/21}{Moved graphicx loading down here such % that we do not get into option clash problems} % \begin{macrocode} \AtBeginDocument{% \RequirePackage{graphicx}% \@ifundefined{nrightarrow}{% \providecommand\nuparrow{% \PackageError{mathtools}{\string\nuparrow\space~ is~ constructed~ from~ \string\nrightarrow,~ which~ is~ not~ provided.~ Please~ load~ the~ amssymb~ package~ or~ similar}{} }}{ \providecommand\nuparrow{\MH_nuparrow:}} \@ifundefined{nleftarrow}{% \providecommand\ndownarrow{% \PackageError{mathtools}{\string\ndownarrow\space~ is~ constructed~ from~ \string\nleftarrow,~ which~ is~ not~ provided.~ Please~ load~ the~ amssymb~ package~ or~ similar}{} }}{ \providecommand\ndownarrow{\MH_ndownarrow:}} } % \end{macrocode} % \end{macro} % \end{macro} % % % \subsection{Providing bigtimes} % % The idea is to use the original \cs{times} and then scale it % accordingly. Again the implementation details have been improved by % Enrico Gregorio % (\url{http://groups.google.com/group/comp.text.tex/msg/9685c9405df2ff94}). % % \begin{macro}{\MH_bigtimes_scaler:N} % \begin{macro}{\MH_bigtimes_inner:} % \begin{macro}{\MH_csym_bigtimes:} % \changes{v1.07}{2008/08/11}{Added support for \cs{bigtimes}} % \begin{macrocode} \def\MH_bigtimes_scaler:N #1{% \vcenter{\hbox{#1$\m@th\mkern-2mu\times\mkern-2mu$}}} % \end{macrocode} % This is then combined with \cs{mathchoice} to form the inner parts % of the macro % \begin{macrocode} \def\MH_bigtimes_inner: { \mathchoice{\MH_bigtimes_scaler:N \huge} % display style {\MH_bigtimes_scaler:N \LARGE} % text style {\MH_bigtimes_scaler:N {}} % script style {\MH_bigtimes_scaler:N \footnotesize} % script script style } % \end{macrocode} % And thus the internal prepresentaion of the \cs{bigtimes} macro. % \begin{macrocode} \def\MH_csym_bigtimes: {\mathop{\MH_bigtimes_inner:}\displaylimits} % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \begin{macro}{\bigtimes} % In the end we provide \cs{bigtimes} if otherwise not defined. % \begin{macrocode} \AtBeginDocument{ \providecommand\bigtimes{\MH_csym_bigtimes:} } % \end{macrocode} % \end{macro} % % \section{Macros by other people} % % \subsection{Intertext and short intertext} % % It turns out that \cs{intertext} use a bit too much % space. Especially noticable if combined with the \env{spreadlines} % environment, the extra space is also applied above and below % \cs{intertext}, which ends up looking unproffesional. Chung-chieh % Shan % (\url{http://conway.rutgers.edu/~ccshan/wiki/blog/posts/Beyond_amsmath/}) % via Tobias Weh suggested a fix. We apply it here, but also keep the % original \cs{intertext} in case a user would rather want it. % \begin{macro}{\MT_orig_intertext:} % \begin{macro}{\MT_intertext:} % \changes{v1.13}{2012/08/19}{\cs{l_MT_X_intertext_dim} renamed to % \cs{l_MT_X_intertext_sep}} % \begin{macro}{\l_MT_above_intertext_sep} % \begin{macro}{\l_MT_below_intertext_sep} % First store the originam Ams version. % \begin{macrocode} \MH_let:NwN \MT_orig_intertext: \intertext@ % \end{macrocode} % And then for some reconfiguration. First a few lengths % \changes{v1.13}{2012/08/19}{Fixed typos and changed the names} % \begin{macrocode} \newdimen\l_MT_above_intertext_sep \newdimen\l_MT_below_intertext_sep \define@key{\MT_options_name:} {aboveintertextdim}{\setlength\l_MT_above_intertext_sep{#1}} \define@key{\MT_options_name:} {belowintertextdim}{\setlength\l_MT_below_intertext_sep{#1}} \define@key{\MT_options_name:} {above-intertext-dim}{\setlength\l_MT_above_intertext_sep{#1}} \define@key{\MT_options_name:} {below-intertext-dim}{\setlength\l_MT_below_intertext_sep{#1}} \define@key{\MT_options_name:} {above-intertext-sep}{\setlength\l_MT_above_intertext_sep{#1}} \define@key{\MT_options_name:} {below-intertext-sep}{\setlength\l_MT_below_intertext_sep{#1}} % \end{macrocode} % Their default values are zero. Now for our extended version of % CCShan's solution. % \begin{macrocode} \def\MT_intertext: {% \def\intertext##1{% \ifvmode\else\\\@empty\fi \noalign{% \penalty\postdisplaypenalty\vskip\belowdisplayskip \vskip-\lineskiplimit % CCS \vskip\normallineskiplimit % CCS \vskip\l_MT_above_intertext_sep \vbox{\normalbaselines % \end{macrocode} % \changes{v1.17}{2015/06/17}{Added extra `in list' check} % Johannes Böttcher has reported a problem in \cs{intertext} in % relation to usage within lists or constructs that locally changes % the margin (often implemented as a list). Markus Kohm suggested to % test not only \cs{linewidth} against \cs{columnwidth} but also if % \cs{@totalleftmargin} is not zero. The implementation used is due to % David Carlisle. % \changes{v1.19}{2016/05/26}{Added \cs{ignorespaces} after % \cs{noindent}, bug inherited from \pkg{amsmath}} % \begin{macrocode} \ifdim \ifdim\@totalleftmargin=\z@ \linewidth \else -\maxdimen \fi =\columnwidth \else \parshape\@ne \@totalleftmargin \linewidth \fi \noindent\ignorespaces##1\par}% \penalty\predisplaypenalty\vskip\abovedisplayskip% \vskip-\lineskiplimit % CCS \vskip\normallineskiplimit % CCS % \end{macrocode} % \changes{v1.21}{2018/01/08}{Typo, it should use \texttt{\_below\_} % not \texttt{\_above\_}} % \begin{macrocode} \vskip\l_MT_below_intertext_sep }% }% % \end{macrocode} % We might as well hook on to this and only activate % \cs{shortintertext} whenever \cs{intertext} is active. This allows % us to get the same error messages as \cs{intertext}. % \changes{v1.19}{2017/03/31}{Added} % \begin{macrocode} % also activate \shortintertext, such that is is only available when % \intertext is \MH_let:NwN \shortintertext \shortintertext@ } % \end{macrocode} % And provide a key to switch % \changes{v1.19}{2017/03/31}{Changed \cs{MT_orig_intertext_true:}} % Changed \cs{MT_orig_intertext_true:} to also activate % \cs{shortintertext}, because when this is active, our change to % \cs{intertext@} is not active. % \begin{macrocode} \def\MT_orig_intertext_true: { \MH_let:NwN \intertext@ \MT_orig_intertext: \MH_let:NwN \shortintertext \shortintertext@ } \def\MT_orig_intertext_false: { \MH_let:NwN \intertext@ \MT_intertext: } \define@key{\MT_options_name:}{original-intertext}[true]{ \@nameuse{MT_orig_intertext_#1:} } % \end{macrocode} % And use the new version as default. % \begin{macrocode} \setkeys{\MT_options_name:}{ original-intertext=false } % \end{macrocode} % % \end{macro} % \end{macro} % \end{macro} % \end{macro} % % Gabriel Zachmann, Donald Arseneau on comp.text.tex 2000/05/12-13 % \begin{macro}{\shortintertext} % \begin{macro}{\MT_orig_shortintertext} % \begin{macro}{\MT_shortintertext} % \begin{macro}{\l_above_shortintertext_sep} % \begin{macro}{\l_below_shortintertext_sep} % This is like \cs{intertext} but uses shorter skips between the % math. Again this turned out to have the same problem as % \cs{intertext}, so we provide two versions. % \begin{macrocode} \def\MT_orig_shortintertext:n #1{% \ifvmode\else\\\@empty\fi \noalign{% \penalty\postdisplaypenalty\vskip\abovedisplayshortskip \vbox{\normalbaselines % \end{macrocode} % \changes{v1.17}{2015/06/17}{Added extra `in list' check} % Same comment as for \cs{intertext} above. % \changes{v1.19}{2016/05/26}{Added \cs{ignorespaces} after % \cs{noindent}, bug inherited from \pkg{amsmath}} % \changes{v1.19}{2017/03/31}{Added MH\_ prefix} % \begin{macrocode} \MH_if_dim:w \MH_if_dim:w \@totalleftmargin=\z@ \linewidth \MH_else: -\maxdimen \MH_fi: =\columnwidth \MH_else: \parshape\@ne \@totalleftmargin \linewidth \MH_fi: \noindent\ignorespaces#1\par}% \penalty\predisplaypenalty\vskip\abovedisplayshortskip% }% } % \end{macrocode} % Lengths like above % \changes{v1.13}{2012/08/19}{The option was named differently in the % manual. Also renamed to use the postfix \emph{sep} instead. Though % the old names remain for compatibility.} % \changes{v1.14}{2014/01/20}{Apparently did not check it good enough, % the option should have shortintertext not short-intertext} % \begin{macrocode} \newdimen\l_MT_above_shortintertext_sep \newdimen\l_MT_below_shortintertext_sep \define@key{\MT_options_name:} {aboveshortintertextdim}{\setlength \l_MT_above_shortintertext_sep{#1}} \define@key{\MT_options_name:} {belowshortintertextdim}{\setlength \l_MT_below_shortintertext_sep{#1}} \define@key{\MT_options_name:} {above-short-intertext-dim}{\setlength \l_MT_above_shortintertext_sep{#1}} % old typo in manual \define@key{\MT_options_name:} {below-short-intertext-dim}{\setlength \l_MT_below_shortintertext_sep{#1}} \define@key{\MT_options_name:} {above-short-intertext-sep}{\setlength \l_MT_above_shortintertext_sep{#1}} % old typo in manual \define@key{\MT_options_name:} {below-short-intertext-sep}{\setlength \l_MT_below_shortintertext_sep{#1}} \define@key{\MT_options_name:} {above-shortintertext-sep}{\setlength \l_MT_above_shortintertext_sep{#1}} \define@key{\MT_options_name:} {below-shortintertext-sep}{\setlength \l_MT_below_shortintertext_sep{#1}} % \end{macrocode} % Looks best with the `old' values of the original \cs{jot} % setting. So we set them to 3pt each. % \begin{macrocode} \setkeys{\MT_options_name:}{ aboveshortintertextdim=3pt, belowshortintertextdim=3pt } % \end{macrocode} % Next, just add the same as we did for \cs{intertext} % \begin{macrocode} \def\MT_shortintertext:n #1{% \ifvmode\else\\\@empty\fi \noalign{% \penalty\postdisplaypenalty\vskip\abovedisplayshortskip \vskip-\lineskiplimit \vskip\normallineskiplimit \vskip\l_MT_above_shortintertext_sep \vbox{\normalbaselines % \end{macrocode} % \changes{v1.17}{2015/06/17}{Added extra `in list' check} % Same comment as for \cs{intertext} above. % \changes{v1.19}{2016/05/26}{Added \cs{ignorespaces} after % \cs{noindent}, bug inherited from \pkg{amsmath}} % \changes{v1.19}{2017/03/31}{Added MH\_ prefix} % \begin{macrocode} \MH_if_dim:w \MH_if_dim:w \@totalleftmargin=\z@ \linewidth \MH_else: -\maxdimen \MH_fi: =\columnwidth \MH_else: \parshape\@ne \@totalleftmargin \linewidth \MH_fi: \noindent\ignorespaces#1\par}% \penalty\predisplaypenalty\vskip\abovedisplayshortskip% \vskip-\lineskiplimit \vskip\normallineskiplimit \vskip\l_MT_below_shortintertext_sep }% } % \end{macrocode} % Next we need to be able to switch. % \changes{v1.19}{2017/03/31}{Changed \cs{shortintertext} to be % internal here.} % \begin{macrocode} \def\MT_orig_shortintertext_true: { \MH_let:NwN \shortintertext@ \MT_orig_shortintertext:n } \def\MT_orig_shortintertext_false: { \MH_let:NwN \shortintertext@ \MT_shortintertext:n } % \end{macrocode} % Next make \cs{shortintertext} a no-go everywhere. Thus \cs{shortintertext} is only % available when \cs{intertext} is, or when % \verb+original-intertext=true+ is used. % \changes{v1.19}{2017/03/31}{Added} % \begin{macrocode} \newcommand{\shortintertext}{\@amsmath@err{\Invalid@@\shortintertext}\@eha} % \end{macrocode} % \begin{macrocode} \define@key{\MT_options_name:}{original-shortintertext}[true]{ \@nameuse{MT_orig_shortintertext_#1:} } % \end{macrocode} % With the updated one as the default. % \begin{macrocode} \setkeys{\MT_options_name:}{ original-shortintertext=false } % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % % \subsection{Fine-tuning mathematical layout} % % \subsubsection{A complement to \texttt{\textbackslash smash}, % \texttt{\textbackslash llap}, and \texttt{\textbackslash rlap}} % \begin{macro}{\clap} % \begin{macro}{\mathllap} % \begin{macro}{\mathrlap} % \begin{macro}{\mathclap} % \begin{macro}{\MT_mathllap:Nn} % \begin{macro}{\MT_mathrlap:Nn} % \begin{macro}{\MT_mathclap:Nn} % First we'll \cs{provide} those macros (they are so simple that I % think other packages might define them as well). % \changes{v1.15}{2021/03/04}{Add \cs{relax} before the \cs{ifx}'s to % prevent corner case premature expansions} % \begin{macrocode} \providecommand*\clap[1]{\hb@xt@\z@{\hss#1\hss}} \providecommand*\mathllap[1][\@empty]{ \relax\ifx\@empty#1\@empty \expandafter \mathpalette \expandafter \MT_mathllap:Nn \else \expandafter \MT_mathllap:Nn \expandafter #1 \fi } \providecommand*\mathrlap[1][\@empty]{ \relax\ifx\@empty#1\@empty \expandafter \mathpalette \expandafter \MT_mathrlap:Nn \else \expandafter \MT_mathrlap:Nn \expandafter #1 \fi } \providecommand*\mathclap[1][\@empty]{ \relax\ifx\@empty#1\@empty \expandafter \mathpalette \expandafter \MT_mathclap:Nn \else \expandafter \MT_mathclap:Nn \expandafter #1 \fi } % \end{macrocode} % We have to insert |{}| because we otherwise risk triggering a % ``feature'' in \TeX. % \begin{macrocode} \def\MT_mathllap:Nn #1#2{{}\llap{$\m@th#1{#2}$}} \def\MT_mathrlap:Nn #1#2{{}\rlap{$\m@th#1{#2}$}} \def\MT_mathclap:Nn #1#2{{}\clap{$\m@th#1{#2}$}} % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \begin{macro}{\mathmbox} % \begin{macro}{\MT_mathmbox:nn} % \begin{macro}{\mathmakebox} % \begin{macro}{\MT_mathmakebox_I:w} % \begin{macro}{\MT_mathmakebox_II:w} % \begin{macro}{\MT_mathmakebox_III:w} % Then the \cs{mathmbox}\marg{arg} and % \cs{mathmakebox}\oarg{width}\oarg{pos}\marg{arg} macros which are % very similar to \cs{mbox} and \cs{makebox}. The differences are: % \begin{itemize} % \item \meta{arg} is set in math mode of course. % \item No need for \cs{leavevmode} as we're in math mode. % \item No need to make them \cs{long} (we're still in math mode). % \item No need to support a picture version. % \end{itemize} % The first is easy. % \begin{macrocode} \providecommand*\mathmbox{\mathpalette\MT_mathmbox:nn} \def\MT_mathmbox:nn #1#2{\mbox{$\m@th#1#2$}} % \end{macrocode} % We scan for the optional arguments first. % \begin{macrocode} \providecommand*\mathmakebox{ \@ifnextchar[ \MT_mathmakebox_I:w \mathmbox} \def\MT_mathmakebox_I:w[#1]{% \@ifnextchar[ {\MT_mathmakebox_II:w[#1]} {\MT_mathmakebox_II:w[#1][c]}} % \end{macrocode} % We had to get the optional arguments out of the way before calling % upon the powers of \cs{mathpalette}. % \begin{macrocode} \def\MT_mathmakebox_II:w[#1][#2]{ \mathpalette{\MT_mathmakebox_III:w[#1][#2]}} \def\MT_mathmakebox_III:w[#1][#2]#3#4{% \@begin@tempboxa\hbox{$\m@th#3#4$}% \setlength\@tempdima{#1}% \hbox{\hb@xt@\@tempdima{\csname bm@#2\endcsname}}% \@end@tempboxa} % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \begin{macro}{\mathsm@sh} % Fix \cs{smash}. % \begin{macrocode} \def\mathsm@sh#1#2{% \setbox\z@\hbox{$\m@th#1{#2}$}{}\finsm@sh} % \end{macrocode} % \end{macro} % % % \subsubsection{A cramped style} % % comp.text.tex on 1992/07/21 by Michael Herschorn. % With speed-ups by the Grand Wizard himself as shown on % \begin{quote}\rightskip-\leftmargini % \url{http://mirrors.ctan.org/info/digests/tex-implementors/042} % \end{quote} % The (better) user interface by the author. % % \begin{macro}{\cramped} % Make sure the expansion is timed correctly. % \changes{v1.15}{2021/03/04}{Add \cs{relax} before the \cs{ifx}'s to % prevent corner case premature expansions} % \begin{macrocode} \providecommand*\cramped[1][\@empty]{ \relax\ifx\@empty#1\@empty \expandafter \mathpalette \expandafter \MT_cramped_internal:Nn \else \expandafter \MT_cramped_internal:Nn \expandafter #1 \fi } % \end{macrocode} % \end{macro} % \begin{macro}{\MT_cramped_internal:Nn} % The internal command. % \begin{macrocode} \def\MT_cramped_internal:Nn #1#2{ % \end{macrocode} % Create a box containing the math and force a cramped style by % issuing a non-existing radical. % \changes{v1.25}{2020/12/16}{Don't set \cs{nulldelimiterspace} to % zero, back kern intead, solves issue \#18} % \changes{v1.25}{2021/03/18}{placed \cs{sbox}\cs{z@} by % \cs{setbox}\cs{z@}\cs{hbox} to better handle expansion in % \env{crampedsubarray}, see issue \#17} % \begin{macrocode} %% \sbox\z@{$\m@th#1\kern-\nulldelimiterspace\radical\z@{#2}$} \setbox\z@\hbox{$\m@th#1\kern-\nulldelimiterspace\radical\z@{#2}$} % \end{macrocode} % Then make sure the height is correct. % \begin{macrocode} \ifx#1\displaystyle \dimen@=\fontdimen8\textfont3 \advance\dimen@ .25\fontdimen5\textfont2 \else \dimen@=1.25\fontdimen8 \ifx#1\textstyle\textfont \else \ifx#1\scriptstyle \scriptfont \else \scriptscriptfont \fi \fi 3 \fi \advance\dimen@-\ht\z@ \ht\z@=-\dimen@ % \end{macrocode} % Leave vertical mode before typesetting the box and add a % \texttt{\{\}} in front to gard against unnecessary reboxing % \changes{v1.25}{2021/03/04}{Added vmode protection and reboxing % gard, see issue \#19} % \begin{macrocode} \ifvmode\leavevmode\fi {}\box\z@ } % \end{macrocode} % For LuaLaTeX we can use much less code as they have % their own direct \cs{cramped...} macros. Directly listed % from \verb|lualatex-math.sty| v1.9 2020/09/25 by Philipp Stephani. Quote: ``Here the % additional set of braces is absolutely necessary, otherwise the changed % mathematical style would be applied to the material after the % \cs{mathchoice} construct. As the original (mathtools) command works in both text and % math mode, we use \cs{ensuremath} here.'' % \begin{macrocode} \ifx\directlua\@undefined\else \def\MT_cramped_internal:Nn #1#2{ { \ensuremath { \use:c { cramped \cs_to_str:N #1 } #2 } } } \fi % \end{macrocode} % \end{macro} % % \subsubsection{Cramped versions of \texttt{\textbackslash % mathllap}, \texttt{\textbackslash mathclap}, and % \texttt{\textbackslash mathrlap}} % \begin{macro}{\crampedllap} % \begin{macro}{\MT_cramped_llap_internal:Nn} % \begin{macro}{\crampedclap} % \begin{macro}{\MT_cramped_clap_internal:Nn} % \begin{macro}{\crampedrlap} % \begin{macro}{\MT_cramped_rlap_internal:Nn} % Cramped versions of \cs{mathXlap} (for speed). Made by the author. % \changes{v1.15}{2021/03/04}{Add \cs{relax} before the \cs{ifx}'s to % prevent corner case premature expansions} % \begin{macrocode} \providecommand*\crampedllap[1][\@empty]{ \relax\ifx\@empty#1\@empty \expandafter \mathpalette \expandafter \MT_cramped_llap_internal:Nn \else \expandafter \MT_cramped_llap_internal:Nn \expandafter #1 \fi } \def\MT_cramped_llap_internal:Nn #1#2{ {}\llap{\MT_cramped_internal:Nn #1{#2}} } \providecommand*\crampedclap[1][\@empty]{ \relax\ifx\@empty#1\@empty \expandafter \mathpalette \expandafter \MT_cramped_clap_internal:Nn \else \expandafter \MT_cramped_clap_internal:Nn \expandafter #1 \fi } \def\MT_cramped_clap_internal:Nn #1#2{ {}\clap{\MT_cramped_internal:Nn #1{#2}} } \providecommand*\crampedrlap[1][\@empty]{ \relax\ifx\@empty#1\@empty \expandafter \mathpalette \expandafter \MT_cramped_rlap_internal:Nn \else \expandafter \MT_cramped_rlap_internal:Nn \expandafter #1 \fi } \def\MT_cramped_rlap_internal:Nn #1#2{ {}\rlap{\MT_cramped_internal:Nn #1{#2}} } % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % % % % \subsubsection{Cramped versions of subarray and \cs{substack}} % % % \changes{v1.22}{2019/07/22}{Added cramped versions of subarray and % \cs{substack}} This was suggested by Henri Menke in % \url{https://github.com/latex3/latex2e/issues/149} and % \url{https://chat.stackexchange.com/transcript/message/50943985#50943985}. % As we are slowly moving away from the expl3 like syntax, we'll % implement this % with an adjusted copy of \env{subarray} from \pkg{amsmath}. % \changes{v1.26}{2021/03/27}{Fresh copy of subarray from \pkg{amsmath} % including the lualatex branch} % \begin{environment}{crampedsubarray} % \begin{macrocode} \ifx\directlua\@undefined \newenvironment{crampedsubarray}[1]{% \vcenter\bgroup \Let@ \restore@math@cr \default@tag \baselineskip\fontdimen10 \scriptfont\tw@ \advance\baselineskip\fontdimen12 \scriptfont\tw@ \lineskip\thr@@\fontdimen8 \scriptfont\thr@@ \lineskiplimit\lineskip \ialign\bgroup\ifx c#1\hfil\fi % \end{macrocode} % Though here we ought to use the proper cramped internal macro, as % otherwise there will be a slight difference in vertical spacing % \changes{v1.25}{2021/03/18}{Added \cs{MT_cramped_internal:Nn}, see % issue \#17} % \begin{macrocode} %%$\m@th\scriptstyle\kern-\nulldelimiterspace\radical\z@{##}$% <-- changed line \span\MT_cramped_internal:Nn \scriptstyle {##}% \hfil\crcr }{% \crcr\egroup\egroup } \else \newenvironment{crampedsubarray}[1]{% \vcenter\bgroup \Let@ \restore@math@cr \default@tag \baselineskip \Umathstacknumup \scriptstyle \advance\baselineskip \Umathstackdenomdown \scriptstyle \lineskip \Umathstackvgap \scriptstyle \lineskiplimit \lineskip \ialign\bgroup\ifx c#1\hfil\fi \Ustartmath % \end{macrocode} % Here we simply use the build in cramped command from LuaLaTeX % \begin{macrocode} \crampedscriptstyle{##} \Ustopmath \hfil\crcr }{% \crcr\egroup\egroup } \fi % \end{macrocode} % \end{environment} % \begin{macro}{\crampedsubstack} % And the identical implementation for \cs{crampedsubstack}: % \begin{macrocode} \newcommand{\crampedsubstack}[1]{\crampedsubarray{c}#1\endcrampedsubarray} % \end{macrocode} % \end{macro} % % % % \section{Macros by Michael J.~Downes} % % The macros in this section are all by Michael J.~Downes. Either % they are straight copies of his original macros or inspired and % extended here. % % % \subsection{Prescript} % \begin{macro}{\prescript} % This command is taken from a posting to comp.text.tex on % December~20th 2000 by Michael J.~Downes. The comments are his. I % have added some formatting options to the arguments so that a user % can emulate the \pkg{isotope} package. % % \changes{v.1.12}{2012/04/19}{Extended \cs{prescript} to change style % if used in say S context. Requestd by Oliver Buerschaper.} % Update 2012: One drawback from MJD's original implementation, is % that the math style is hardwired, such that if used in say % \cs{scriptstyle} context, then the style/size of the prescript % remain the same size. A slightly expensive fix, is to use the % \cs{mathchoice} construction. First exdent MJD's code a little % (keeping his comments) % \begin{macro}{\MT_prescript_inner:} % We make the style an extra forth argument % \begin{macrocode} \newcommand{\MT_prescript_inner:}[4]{ % \end{macrocode} % Put the sup in box 0 and the sub in box 2. % \changes{v1.19}{2017/03/31}{Added MH\_ prefix} % \begin{macrocode} \@mathmeasure\z@#4{\MT_prescript_sup:{#1}} \@mathmeasure\tw@#4{\MT_prescript_sub:{#2}} \MH_if_dim:w \wd\tw@>\wd\z@ \setbox\z@\hbox to\wd\tw@{\hfil\unhbox\z@} \MH_else: \setbox\tw@\hbox to\wd\z@{\hfil\unhbox\tw@} \MH_fi: % \end{macrocode} % Do not let a preceding mathord symbol approach without any % intervening space. % \begin{macrocode} \mathop{} % \end{macrocode} % Use \cs{mathopen} to suppress space between the prescripts and the % base object even when the latter is not of type ord. % \begin{macrocode} \mathopen{\vphantom{\MT_prescript_arg:{#3}}}^{\box\z@}\sb{\box\tw@} \MT_prescript_arg:{#3} } % \end{macrocode} % \end{macro} % Next create \cs{prescript} using \cs{mathchoice} % \begin{macrocode} \DeclareRobustCommand{\prescript}[3]{ \mathchoice % \end{macrocode} % In D and T style, we use MJD's default: % \begin{macrocode} {\MT_prescript_inner:{#1}{#2}{#3}{\scriptstyle}} {\MT_prescript_inner:{#1}{#2}{#3}{\scriptstyle}} % \end{macrocode} % In the others we step one style down. Of couse in SS style, using % \cs{scriptscript} may seem wrong, but there is no lower style. % \begin{macrocode} {\MT_prescript_inner:{#1}{#2}{#3}{\scriptscriptstyle}} {\MT_prescript_inner:{#1}{#2}{#3}{\scriptscriptstyle}} } % \end{macrocode} % \end{macro} % Then the named arguments. Can you see I'm preparing for templates? % \begin{macrocode} \define@key{\MT_options_name:} {prescript-sup-format}{\def\MT_prescript_sup:{#1}} \define@key{\MT_options_name:} {prescript-sub-format}{\def\MT_prescript_sub:{#1}} \define@key{\MT_options_name:} {prescript-arg-format}{\def\MT_prescript_arg:{#1}} \setkeys{\MT_options_name:}{ prescript-sup-format={}, prescript-sub-format={}, prescript-arg-format={}, } % \end{macrocode} % % \subsection{Math sizes} % \begin{macro}{\@DeclareMathSizes} % This command is taken from a posting to comp.text.tex on % October~17th 2002 by Michael J.~Downes. The purpose is to be able % to put dimensions on the last three arguments of % \cs{DeclareMathSizes}. % % As of 2015, this fix has made it into the \LaTeX{} kernel. Thus we % only provide the fix for older kernels. % \changes{v1.18}{2015/11/12}{This was now moved into the kernel, thus % we only provide it for older kernels} % \changes{v1.19}{2017/03/31}{Added MH\_ prefix} % \begin{macrocode} \ifx\e@alloc\@undefined% kernel thus older than 2015 \def\@DeclareMathSizes #1#2#3#4#5{% \@defaultunits\dimen@ #2pt\relax\@nnil \MH_if:w $#3$% \MH_let:cN {S@\strip@pt\dimen@}\math@fontsfalse \MH_else: \@defaultunits\dimen@ii #3pt\relax\@nnil \@defaultunits\@tempdima #4pt\relax\@nnil \@defaultunits\@tempdimb #5pt\relax\@nnil \toks@{#1}% \expandafter\xdef\csname S@\strip@pt\dimen@\endcsname{% \gdef\noexpand\tf@size{\strip@pt\dimen@ii}% \gdef\noexpand\sf@size{\strip@pt\@tempdima}% \gdef\noexpand\ssf@size{\strip@pt\@tempdimb}% \the\toks@ }% \MH_fi: } \fi % \end{macrocode} % \end{macro} % % \subsection{Mathematics within italic text} % mathic: Michael J.~Downes on comp.text.tex, 1998/05/14. % \begin{macro}{\MT_mathic_true:} % \begin{macro}{\MT_mathic_false:} % Renew \cs{(} so that it detects the slant of the font and inserts % an italic correction. In January 2013 Andrew Swann suggested that % this should be made robust. It is a little tricky, but seems to % work. % \changes{v1.13}{2013/02/11}{Added robustness code} % \begin{macrocode} \def\MT_mathic_true: { \MH_if_boolean:nF {math_italic_corr}{ \MH_set_boolean_T:n {math_italic_corr} % \end{macrocode} % Save the original meaning if you need to go back (note that this % does not save the robust part of the macro, we fix this later on by % rerobustifying). % \changes{v1.19}{2017/03/31}{Added MH\_ prefix} % \begin{macrocode} \MH_if_boolean:nTF {robustify}{ \MH_let:NwN \MT_mathic_redeffer: \DeclareRobustCommand }{ \MH_let:NwN \MT_mathic_redeffer: \renewcommand } \MH_let:NwN \MT_begin_inlinemath: \( %\renewcommand*\({ \MT_mathic_redeffer:*\({ \relax\ifmmode\@badmath\else \ifhmode \MH_if_dim:w \fontdimen\@ne\font>\z@ % \end{macrocode} % We have a small problem here, if the user use >>\verb|text~\(|<< then % the italic correction is lost due to the penalty (see \cite{TBT}, % section 4.3.3). However, we \emph{know} what \verb|~| does, a % (positive) penalty and a skip. % \changes{v1.19}{2017/03/31}{Added MH\_ prefix} % \begin{macrocode} \MH_if_dim:w \lastskip>\z@ \skip@\lastskip\unskip % \end{macrocode} % \changes{v1.15}{2014/07/16}{Added penalty workaround} % Here is the fix. % \changes{v1.19}{2017/03/31}{Added MH\_ prefix} % The code we inserted here in 2014, had a bug in it. The intent was % to move the penalty on to the other side of the italic correction. % But when we reinsert the penalty we only test if the scratch % counter is non-zero, so it may insert random penalties depending % on the non-zero value of \cs{count@}. Simple fix: initialise \cs{count@}. % \changes{v1.31}{2024/10/03}{Added missing counter initialisation, fixing issue \#62} % In chat David C. mentioned that \verb|\ifnum\lastnodetype=13| is a better % test than \verb|\ifnum\lastpenalty>\z@|. Just leaving this here for when we do the % Expl3 conversion. % \begin{macrocode} \MH_if_num:w \lastpenalty>\z@ \count@\lastpenalty\unpenalty \MH_else: \count@\z@ \MH_fi: \@@italiccorr % \end{macrocode} % \changes{v1.15}{2014/07/16}{Added penalty workaround} % And here it is inserted again. % \changes{v1.19}{2017/03/31}{Added MH\_ prefix} % \begin{macrocode} \MH_if_num:w \count@>\z@ \penalty\count@ \MH_fi: \hskip\skip@ \MH_else: \@@italiccorr \MH_fi: \MH_fi: % \end{macrocode} % % \changes{v1.31}{2024/10/03}{Also fixed typo here, the last two \cs{fi} comes from non-MH syntax} % \begin{macrocode} \fi $\fi } } } %$ for emacs coloring ;-) % \end{macrocode} % Just for restoring the old behavior. % \begin{macrocode} \def\MT_mathic_false: { \MH_if_boolean:nT {math_italic_corr}{ \MH_set_boolean_F:n {math_italic_corr} % \end{macrocode} % When \cs{(} is robust, we cannot simply relet it to the old value, % as all the robust macro is not saved. Instead we redefined partly % and force robustness. % \begin{macrocode} \MH_if_boolean:nTF {robustify}{ \edef\({\MT_begin_inlinemath:}% \forced_EQ_MakeRobust\(% }{ \MH_let:NwN \( \MT_begin_inlinemath: } } } \MH_new_boolean:n {math_italic_corr} \define@key{\MT_options_name:}{mathic}[true]{ \@ifundefined{MT_mathic_#1:} { \MT_true_false_error: \@nameuse{MT_mathic_false:} } { \@nameuse{MT_mathic_#1:} } } % \end{macrocode} % \end{macro} % \end{macro} % % \subsection{Spreading equations} % % Michael J.~Downes on comp.text.tex 1999/08/25 % \begin{environment}{spreadlines} % This is meant to be used outside math, just like % \env{subequations}. % \begin{macrocode} \newenvironment{spreadlines}[1]{ \setlength{\jot}{#1} \ignorespaces }{ \ignorespacesafterend } % \end{macrocode} % \end{environment} % % \subsection{Gathered} % % Inspired by Michael J.~Downes on comp.text.tex 2002/01/17. % \begin{environment}{MT_gathered_env} % Just like the normal \env{gathered}, only here we're allowed to % specify actions before and after each line. % \changes{2017/10/30}{v1.20}{added \cs{alignedspace@left} instead of % \cs{null}\cs{,} as in the other amsmath adjustments} % \begin{macrocode} \MaybeMHPrecedingSpacesOff \newenvironment{MT_gathered_env}[1][c]{% \RIfM@\else \nonmatherr@{\begin{\@currenvir}}% \fi %\null\,% \alignedspace@left% \if #1t\vtop \else \if#1b\vbox \else \vcenter \fi\fi \bgroup \Let@ \chardef\dspbrk@context\@ne \restore@math@cr \spread@equation \ialign\bgroup \MT_gathered_pre: \strut@$\m@th\displaystyle##$ \MT_gathered_post: \crcr }{% \endaligned \MT_gathered_env_end: } \MHPrecedingSpacesOn % \end{macrocode} % \end{environment} % \begin{macro}{\newgathered} % \begin{macro}{\renewgathered} % \begin{environment}{lgathered} % \begin{environment}{rgathered} % \begin{environment}{gathered} % An easier interface. % \begin{macrocode} \newcommand*\newgathered[4]{ \newenvironment{#1} { \def\MT_gathered_pre:{#2} \def\MT_gathered_post:{#3} \def\MT_gathered_env_end:{#4} \MT_gathered_env }{\endMT_gathered_env} } \newcommand*\renewgathered[4]{ \renewenvironment{#1} { \def\MT_gathered_pre:{#2} \def\MT_gathered_post:{#3} \def\MT_gathered_env_end:{#4} \MT_gathered_env }{\endMT_gathered_env} } \newgathered{lgathered}{}{\hfil}{} \newgathered{rgathered}{\hfil}{}{} \renewgathered{gathered}{\hfil}{\hfil}{} % \end{macrocode} % \end{environment} % \end{environment} % \end{environment} % \end{macro} % \end{macro} % % \subsection{Split fractions} % % Michael J.~Downes on comp.text.tex 2001/12/06. % \begin{macro}{\splitfrac} % \begin{macro}{\splitdfrac} % These commands use \cs{genfrac} to typeset a split fraction. The % thickness of the fraction rule is simply set to zero. % \begin{macrocode} \newcommand*\splitfrac[2]{% \genfrac{}{}{0pt}{1}% {\textstyle#1\quad\hfill}% {\textstyle\hfill\quad\mathstrut#2}% } \newcommand*\splitdfrac[2]{% \genfrac{}{}{0pt}{0}{#1\quad\hfill}{\hfill\quad\mathstrut #2}% } % \end{macrocode} % \end{macro} % \end{macro} % % % \section{Bug fixes for \pkg{amsmath}} % The following fixes some bugs in \pkg{amsmath}, but only if the % switch is true. % \begin{macrocode} \MH_if_boolean:nT {fixamsmath}{ % \end{macrocode} % \begin{macro}{\place@tag} % This corrects a bug in \pkg{amsmath} affecting tag placement in % \env{flalign}.\footnote{See % \url{http://www.latex-project.org/cgi-bin/ltxbugs2html?pr=amslatex/3591}} % \begin{macrocode} \def\place@tag{% \iftagsleft@ \kern-\tagshift@ % \end{macrocode} % The addition. If we're in \env{flalign} (meaning % $\cs{xatlevel@}=\cs{tw@}$) we skip back by an amount of % \cs{@mathmargin}. This test is also true for the \env{xxalignat} % environment, but it doesn't matter because a)~it's not % supported/described in the documentation anymore so new users % won't know about it and b)~it forbids the use of \cs{tag} % anyway. % \changes{v1.19}{2017/03/31}{Added MH\_ prefix} % \begin{macrocode} \if@fleqn \MH_if_num:w \xatlevel@=\tw@ \kern-\@mathmargin \MH_fi: \MH_fi: % \end{macrocode} % End of additions. % \changes{v1.19}{2017/03/31}{Added MH\_ prefix} % \begin{macrocode} \MH_if:w 1\shift@tag\row@\relax \rlap{\vbox{% \normalbaselines \boxz@ \vbox to\lineht@{}% \raise@tag }}% \MH_else: \rlap{\boxz@}% \MH_fi: \kern\displaywidth@ \MH_else: \kern-\tagshift@ \MH_if:w 1\shift@tag\row@\relax \llap{\vtop{% \raise@tag \normalbaselines \setbox\@ne\null \dp\@ne\lineht@ \box\@ne \boxz@ }}% \MH_else: \llap{\boxz@}% \MH_fi: \MH_fi: } % \end{macrocode} % \end{macro} % % \begin{macro}{\x@calc@shift@lf} % This corrects a bug\footnote{See % \url{http://www.latex-project.org/cgi-bin/ltxbugs2html?pr=amslatex/3614}} % in \pkg{amsmath} that could cause a non-positive value of the dimension % \cs{@mathmargin} to cause an % \begin{verbatim} % ! Arithmetic overflow. % \@tempcntb % \end{verbatim} % when in \mode{fleqn,leqno} mode. Not very comprehensible for the user. % \changes{v1.19}{2017/03/31}{Added MH\_ prefix} % \begin{macrocode} \def\x@calc@shift@lf{% \MH_if_dim:w \eqnshift@=\z@ \global\eqnshift@\@mathmargin\relax \alignsep@\displaywidth \advance\alignsep@-\totwidth@ % \end{macrocode} % The addition: If \cs{@tempcntb} is zero we avoid division. % \changes{v1.19}{2017/03/31}{Added MH\_ prefix} % \begin{macrocode} \MH_if_num:w \@tempcntb=0 \MH_else: \global\divide\alignsep@\@tempcntb % original line \MH_fi: % \end{macrocode} % Addition end. % \changes{v1.19}{2017/03/31}{Added MH\_ prefix} % \begin{macrocode} \MH_if_dim:w \alignsep@<\minalignsep\relax \global\alignsep@\minalignsep\relax \MH_fi: \MH_fi: \MH_if_dim:w \tag@width\row@>\@tempdima \saveshift@1% \MH_else: \saveshift@0% \MH_fi:}% % \end{macrocode} % \end{macro} % \begin{macrocode} } % \end{macrocode} % End of bug fixing. % % \subsection{Making environments safer} % % \begin{macro}{\aligned@a} % Here we make the \pkg{amsmath} inner environments disallow spaces % before their optional positioning specifier. % \begin{macrocode} \MaybeMHPrecedingSpacesOff \renewcommand\aligned@a[1][c]{\start@aligned{#1}\m@ne} \MHPrecedingSpacesOn % \end{macrocode} % \end{macro} % % \section{Additional features 2020–} % % The selection below is meant for additions addeed 2020 onwards that % are not integrated into existing macros. % % \subsection{\cs{xmathstrut}} % % \begin{macro}{\xmathstrut@box} % \begin{macro}{\xmathstrut@dim} % \begin{macro}{\xmathstrut} % \begin{macro}{\xmathstrut@} % \begin{macro}{\xmathstrut@do} % Suggested and implemented by Frank Mittelbach. The basic idea is to % add (or subtract) a fraction of the total height of the normal math % strut to both the height and depth of the new strut. The input from % the user is suppose to be a decimal number. The value zero results % in no change compared to the normal math strut. % \changes{v1.24}{2020/03/06}{Added \cs{xmathstrut}} % \begin{macrocode} \newbox\xmathstrut@box \newdimen\xmathstrut@dim \def\xmathstrut{\@dblarg\xmathstrut@} \def\xmathstrut@[#1]#2{% \def\xmathstrut@dp{#1}% \vphantom{\mathpalette\xmathstrut@do{#2}}% } % \end{macrocode} % The algorithm is simple. Start by recording the size (a box) of \verb|$($| % in the current style (via \verb|\mathpalette|) % \begin{macrocode} \def\xmathstrut@do#1#2{% \setbox\xmathstrut@box\hbox{$#1($}%)%emacs \xmathstrut@dim\dimexpr\ht\xmathstrut@box+\dp\xmathstrut@box\relax % \end{macrocode} % Then manipulate the size of the box by adding the user input times % the total height of the original box to the height and depth % respectfully. % \begin{macrocode} \ht\xmathstrut@box\dimexpr\ht\xmathstrut@box +#2\xmathstrut@dim \relax \dp\xmathstrut@box\dimexpr\dp\xmathstrut@box +\xmathstrut@dp\xmathstrut@dim \relax % \end{macrocode} % In the end ship the modified box (it is typeset inside a \verb|\vphantom|). % \begin{macrocode} \box\xmathstrut@box} % \end{macrocode} % Do note that this means that for \verb|\xmathstrut{0.1}| 10\% is % added twice. But it make explaining \verb|\xmathstrut[0.2]{0.1}| a % lot easier as it is just 10\% added to the height and 20\% added to % the depth. % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % % This is the end of the \pkg{mathtools} package. % \begin{macrocode} % % \end{macrocode} % % \Finale \endinput