% \iffalse meta-comment % File `mathtools.dtx'. % Copyright 2004 Morten H\o gholm. % moho01ab@student.cbs.dk % % It may be distributed and/or modified under the % conditions of the LaTeX Project Public License, either version 1.3 % 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.3 or later is part of all distributions of LaTeX % version 2003/12/01 or later. % % This work has the LPPL maintenance status "maintained". % % The Current Maintainer of this work is Morten H\o gholm. % % This work consists of the files mathtools.dtx and mathtools.ins % and the derived file mathtools.sty. % %\NeedsTeXFormat{LaTeX2e} %\ProvidesPackage{mathtools} %<*dtx> \ProvidesFile{mathtools.dtx} % [2004/10/10 v1.01a mathematical typesetting tools (MH)] %<*driver> \documentclass[a4paper]{ltxdoc} \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{color,varioref} \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*\cttPosting[2]{% \hskip1sp \marginpar{% \parbox[b]{\marginparwidth}{\small\sffamily\raggedright \strut Posted on \texttt{comp.text.tex} \\#1\\#2% }% }% } \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} \usepackage[final,hyperindex=false,linkbordercolor=false]{hyperref} \renewcommand*\usage[1]{\textit{\hyperpage{#1}}} \OnlyDescription \begin{document} \DocInput{mathtools.dtx} \end{document} % % \fi % % \changes{v1.0}{2004/07/26}{Initial release} % % \GetFileInfo{mathtools.dtx} % % \CheckSum{2004} % % \title{The \pkg{mathtools} package\thanks{This file has version number % \fileversion, last revised \filedate.}} % % \author{Morten H\o gholm} % \date{\filedate} % % \maketitle % % \begin{abstract} % The \pkg{mathtools} package is an extension package to % \pkg{amsmath}. There are two things on \pkg{mathtools}' agenda: % 1)~correct various bugs/defeciencies 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 underbraket, 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 has 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 me harvesting newsgroups for % code and/or you writing me 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 to me. I % can be reached at % \begin{quote}\email{moho01ab@student.cbs.dk}\end{quote} % This is of course also the address to use in case of bug reports. % % \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} % [p] = 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[p] has been gobbled without any warning % whatsoever.\footnote{\pkg{amsmath} thought the \texttt[p] was an % optional argument, checked if it was \texttt{t} or \texttt{b} and % when both tests failed, assumed it was a \texttt{c}.} This is % hardly what you'd expect as an end user, as the desired output was % probably something like this instead: % \[ % \begin{gathered}[c] % [p] = 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}. % % % \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 be % 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^2 % \end{macrocode} % \begin{macrocode} \RequirePackage{keyval,calc} \RequirePackage{mhsetup}[2004/10/10] \MHInternalSyntaxOn % \end{macrocode} % % \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} % Pass all other options directly to \pkg{amsmath}. % \begin{macrocode} \DeclareOption*{ \PassOptionsToPackage{\CurrentOption}{amsmath} } \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}[2000/07/18] \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} % % \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}. % \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. % \begin{macrocode} \if_meaning:NN \df@label\@empty \MH_if_boolean:nT {manual_tag} { \MH_if_boolean:nTF {show_manual_tags} { \MT_prev_tagform:n {#1} } { \stepcounter{equation} } } \else: \MH_if_boolean:nTF {manual_tag} { \MH_if_boolean:nTF {show_manual_tags} { \MT_prev_tagform:n {#1} } { \@ifundefined{MT_r_\df@label} { } { \MT_prev_tagform:n {#1} } } } { \@ifundefined{MT_r_\df@label} { } { \refstepcounter{equation}\MT_prev_tagform:n {#1} } } \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@@@}. % \begin{macrocode} \def\MT_extended_maketag:n #1{ \ifx\df@label\@empty \MT_maketag:n {#1} \else: \MH_if_boolean:nTF {raw_maketag} { \MH_if_boolean:nTF {show_manual_tags} { \MT_maketag:n {#1} } { \@ifundefined{MT_r_\df@label} { } { \MT_maketag:n {#1} } } } { \MT_maketag:n {#1} } \fi: % \end{macrocode} % As this function is always called we let it set the marker for a manual % tag false when exiting. % \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. % \begin{macrocode} \def\MT_extended_eqref:n #1{ \protected@write\@auxout{} {\string\MT@newlabel{#1}} \textup{\MT_prev_tagform:n {\ref{#1}}} } % \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} % \begin{macrocode} \MH_new_boolean:n {show_only_refs} \MH_new_boolean:n {show_manual_tags} \define@key{\MT_options_name:}{showmanualtags}[true]{ \@ifundefined{boolean_show_manual_tags_#1:} { \MT_true_false_error: \@nameuse{boolean_show_manual_tags_false:} } { \@nameuse{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. % \begin{macrocode} \renewcommand\nonumber{ \if@eqnsw \if_meaning:NN \incr@eqnum\@empty % \end{macrocode} % Only subtract the number if |show_only_refs| is false. % \begin{macrocode} \MH_if_boolean:nF {show_only_refs} {\addtocounter{equation}\m@ne} \fi: \fi: \MH_let:NwN \print@eqnum\@empty \MH_let:NwN \incr@eqnum\@empty \global\@eqnswfalse } % \end{macrocode} % \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}. % \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} \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 3095\MT_rightharpoonup_fill:{\phantom{#1}}{#2}$}% \setbox0=\hbox{% $\ext@arrow 0359\MT_leftharpoondown_fill:{#1}{\phantom{#2}}$}% \kern-\wd0 \lower.22ex\box0}} % \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} % \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} % \begin{macrocode} \def\vcentcolon{\mathrel{\mathop\ordinarycolon}} \begingroup \catcode`\:=\active \lowercase{\endgroup \ifnum\mathcode`\:=32768\relax \let\ordinarycolon= :% \else \mathchardef\ordinarycolon\mathcode`\: % \fi \let :\vcentcolon } \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: { \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} % \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}. % \begin{macrocode} \AtBeginDocument{ \providecommand*\dblcolon{\vcentcolon\mkern-.9mu\vcentcolon} \providecommand*\coloneqq{\vcentcolon\mkern-1.2mu=} \providecommand*\Coloneqq{\dblcolon\mkern-1.2mu=} \providecommand*\coloneq{\vcentcolon\mkern-1.2mu\mathrel{-}} \providecommand*\Coloneq{\dblcolon\mkern-1.2mu\mathrel{-}} \providecommand*\eqqcolon{=\mkern-1.2mu\vcentcolon} \providecommand*\Eqqcolon{=\mkern-1.2mu\dblcolon} \providecommand*\eqcolon{\mathrel{-}\mkern-1.2mu\vcentcolon} \providecommand*\Eqcolon{\mathrel{-}\mkern-1.2mu\dblcolon} \providecommand*\colonapprox{\vcentcolon\mkern-1.2mu\approx} \providecommand*\Colonapprox{\dblcolon\mkern-1.2mu\approx} \providecommand*\colonsim{\vcentcolon\mkern-1.2mu\sim} \providecommand*\Colonsim{\dblcolon\mkern-1.2mu\sim} } % \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} \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. % \begin{macrocode} \newcommand*\MT_test_for_tcb_other:nnnnn [1]{ \if:w t#1\relax \expandafter\MH_use_choice_i:nnnn \else: \if:w c#1\relax \expandafter\expandafter\expandafter\MH_use_choice_ii:nnnn \else: \if:w b#1\relax \expandafter\expandafter\expandafter \expandafter\expandafter\expandafter\expandafter \MH_use_choice_iii:nnnn \else: \expandafter\expandafter\expandafter \expandafter\expandafter\expandafter\expandafter \MH_use_choice_iv:nnnn \fi: \fi: \fi: } % \end{macrocode} % \end{macro} % \begin{macro}{\MT_mult_invisible_line:} % An invisible line. % \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. % \begin{macrocode} \def\MT_mult_mathcr_atat:w [#1]{% \if_num:w 0=`{\fi: \iffalse}\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 \if_num:w \g_MT_multlinerow_int=\l_MT_multline_lastline_fint \MH_let:NwN \math@cr@@\MT_mult_last_mathcr:w \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. % \begin{macrocode} \def\MT_mult_firstandlast_mathcr:w [#1]{% \if_num:w 0=`{\fi: \iffalse}\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. % \begin{macrocode} \def\MT_mult_last_mathcr:w [#1]{ \if_num:w 0=`{\fi: \iffalse}\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}. % \begin{macrocode} \newcommand*\MT_mult_internal:n [1]{ \MH_if_boolean:nF {outer_mult}{\null\,} \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. % \begin{macrocode} \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. % \begin{macrocode} \if_num:w \l_MT_multline_lastline_fint=\@ne \MH_let:NwN \math@cr@@ \MT_mult_firstandlast_mathcr:w \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. % \begin{macrocode} \newcommand\MT_measure_mult:n [1]{ \begingroup \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. % \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}} { \if_meaning:NN \@empty#1\@empty \else: \setlength \l_MT_multwidth_dim{#1} \fi: } \MT_start_mult:N \MT_mult_default_pos: } % \end{macrocode} % \end{macro} % \begin{environment}{multlined} % The user environment. Scan for an optional argument. % \begin{macrocode} \newenvironment{multlined}[1][] { \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}} { \if_meaning:NN \@empty#1\@empty \else: \setlength \l_MT_multwidth_dim{#1} \fi: } \MT_multlined_second_arg:w } { \hfilneg \endaligned } \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} % % \begin{macro}{\DeclarePairedDelimiter} % This macro defines |#1| to be a control sequence that takes either % a star or an optional argument. % \begin{macrocode} \newcommand*\DeclarePairedDelimiter[3]{% \@ifdefinable{#1}{ \edef\MT_next: {\MH_cs_to_str:N #1} % \end{macrocode} % Define the starred command to just put \cs{left} and \cs{right} % before the delimiters. % \begin{macrocode} \@namedef{MT_delim_\MT_next: _star:}##1 {\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_\MT_next: _nostar:\endcsname[2][\\@gobble] { \edef\MT_next: {\MH_cs_to_str:N ##1} % \end{macrocode} % With the default optional argument we wind up with \cs{relax}, % else we get \cs{biggr} and \cs{biggl} etc. % \begin{macrocode} \@nameuse {\MT_next: l} #2 ##2 \@nameuse {\MT_next: r} #3} % \end{macrocode} % The user command comes here. Just check for the star and choose % the right internal command. % \begin{macrocode} \newcommand{#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} % % \subsection{A \texttt{\textbackslash displaystyle} \env{cases} environment} % % \begin{macro}{\MT_start_cases:nn} % We define a single command that does all the hard work. % \begin{macrocode} \def\MT_start_cases:nn #1#2{ \RIfM@\else \nonmatherr@{\begin{\@currenvir}}% \fi % \end{macrocode} % Put in the brace and center the contents (nothing else makes % sense). % \begin{macrocode} \left\lbrace \vcenter \bgroup \Let@ \chardef\dspbrk@context\@ne \restore@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@$\m@th\displaystyle{##}$\hfil\strut@ % \end{macrocode} % Insert the specification of the second column. % \begin{macrocode} #2 \crcr } % \end{macrocode} % \end{macro} % \begin{macro}{\newcases} % \begin{macro}{\renewcases} % Easy creation of new \env{cases}-like environments. % \begin{macrocode} \newcommand*\newcases[3]{ \newenvironment{#1} {\MT_start_cases:nn {#2}{#3}} {\endaligned\right.} } \newcommand*\renewcases[3]{ \renewenvironment{#1} {\MT_start_cases:nn {#2}{#3}} {\endaligned\right.} } % \end{macrocode} % \begin{environment}{dcases} % \begin{environment}{dcases*} % \env{dcases} is a traditional cases with display style math in % both columns, while \env{dcases*} has text in the second column. % \begin{macrocode} \newcases{dcases}{\quad}{$\m@th\displaystyle{##}$\hfil} \newcases{dcases*}{\quad}{{##}\hfil} % \end{macrocode} % \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} % Restore the usual behavior. % \begin{macrocode} \MHPrecedingSpacesOn % \end{macrocode} % \end{environment} % \end{environment} % \end{environment} % \end{environment} % \end{environment} % % % \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}. % \begin{macrocode} \newcommand*\smashoperator[2][lr]{ \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}. % \begin{macrocode} \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} % \begin{macrocode} \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}. % \begin{macrocode} \if_meaning:NN \MT_smop_arg_D: \@nnil \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: \if_meaning:NN \MT_smop_arg_F: \@nnil \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: } \fi: \fi: \else: % \end{macrocode} % Here we have something like \verb|\mathop{TTT}|. Still check % if D is \cs{@nil}. % \begin{macrocode} \def\MT_smop_final_arg_A:{#1{#2}}% \if_meaning:NN \MT_smop_arg_D: \@nnil \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: \if_meaning:NN \MT_smop_arg_F: \@nnil \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: \fi: \fi: \fi: % \end{macrocode} % If A was not \cs{mathop}, it is an operator in itself, so we check % if B is \cs{limits} % \begin{macrocode} \else: \if_meaning:NN \MT_smop_arg_B:\MT_smop_limits: \def\MT_smop_final_arg_A:{#1}% \if_meaning:NN \MT_smop_arg_D: \@nnil \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: \if_meaning:NN \MT_smop_arg_F: \@nnil \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: \fi: \fi: \else: % \end{macrocode} % No \cs{limits} was found, so we already have the right input. Just % forget about the last two arguments. % \begin{macrocode} \def\MT_smop_final_arg_A:{#1}% \if_meaning:NN \MT_smop_arg_C: \@nnil \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: \if_meaning:NN \MT_smop_arg_D: \@nnil \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: \fi: \fi: \fi: \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 % \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} % % % \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. % \begin{macrocode} \if_dim:w \@tempdima>\z@ \mathop{#1}\limits#2{#3} \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}} } \fi: \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}} } \else: \mathop{#4}\limits#5{#6} \fi: } % \end{macrocode} % \end{macro} % % \section{Macros by other people} % % \subsection{Short intertext} % % Gabriel Zachmann, Donald Arseneau on comp.text.tex 2000/05/12-13 % \begin{macro}{\shortintertext} % This is like \cs{intertext} but uses shorter skips betweeb the math. % \begin{macrocode} \def\shortintertext#1{% \ifvmode\else\\\@empty\fi \noalign{% \penalty\postdisplaypenalty\vskip\abovedisplayshortskip \vbox{\normalbaselines \if_dim:w \linewidth=\columnwidth \else: \parshape\@ne \@totalleftmargin \linewidth \fi: \noindent#1\par}% \penalty\predisplaypenalty\vskip\abovedisplayshortskip% }% } % \end{macrocode} % \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). % \begin{macrocode} \providecommand*\clap[1]{\hb@xt@\z@{\hss#1\hss}} \providecommand*\mathllap[1][\@empty]{ \ifx\@empty#1\@empty \expandafter \mathpalette \expandafter \MT_mathllap:Nn \else \expandafter \MT_mathllap:Nn \expandafter #1 \fi } \providecommand*\mathrlap[1][\@empty]{ \ifx\@empty#1\@empty \expandafter \mathpalette \expandafter \MT_mathrlap:Nn \else \expandafter \MT_mathrlap:Nn \expandafter #1 \fi } \providecommand*\mathclap[1][\@empty]{ \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://www.tug.org/tex-archive/digests/tex-implementors/042} % \end{quote} % The (better) user interface by the author. % % \begin{macro}{\cramped} % Make sure the expansion is timed correctly. % \begin{macrocode} \providecommand*\cramped[1][\@empty]{ \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. % \begin{macrocode} \sbox\z@{$\m@th#1\nulldelimiterspace=\z@\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@ \box\z@ } % \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. % \begin{macrocode} \providecommand*\crampedllap[1][\@empty]{ \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]{ \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]{ \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} % % % \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. % \begin{macrocode} \DeclareRobustCommand{\prescript}[3]{ % \end{macrocode} % Put the sup in box 0 and the sub in box 2. % \begin{macrocode} \@mathmeasure\z@\scriptstyle{\MT_prescript_sup:{#1}} \@mathmeasure\tw@\scriptstyle{\MT_prescript_sub:{#2}} \if_dim:w \wd\tw@>\wd\z@ \setbox\z@\hbox to\wd\tw@{\hfil\unhbox\z@} \else: \setbox\tw@\hbox to\wd\z@{\hfil\unhbox\tw@} \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} % 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}. % \begin{macrocode} \def\@DeclareMathSizes #1#2#3#4#5{% \@defaultunits\dimen@ #2pt\relax\@nnil \if:w $#3$% \MH_let:cN {S@\strip@pt\dimen@}\math@fontsfalse \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@ }% \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. % \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. % \begin{macrocode} \MH_let:NwN \MT_begin_inlinemath: \( \renewcommand*\({\relax\ifmmode\@badmath\else \ifhmode \if_dim:w \fontdimen\@ne\font>\z@ \if_dim:w \lastskip>\z@ \skip@\lastskip\unskip \@@italiccorr \hskip\skip@ \else: \@@italiccorr \fi: \fi: \fi: $\fi: } } } % \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} \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. % \begin{macrocode} \MaybeMHPrecedingSpacesOff \newenvironment{MT_gathered_env}[1][c]{% \RIfM@\else \nonmatherr@{\begin{\@currenvir}}% \fi \null\,% \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. % \begin{macrocode} \if@fleqn \if_num:w \xatlevel@=\tw@ \kern-\@mathmargin \fi: \fi: % \end{macrocode} % End of additions. % \begin{macrocode} \if:w 1\shift@tag\row@\relax \rlap{\vbox{% \normalbaselines \boxz@ \vbox to\lineht@{}% \raise@tag }}% \else: \rlap{\boxz@}% \fi: \kern\displaywidth@ \else: \kern-\tagshift@ \if:w 1\shift@tag\row@\relax \llap{\vtop{% \raise@tag \normalbaselines \setbox\@ne\null \dp\@ne\lineht@ \box\@ne \boxz@ }}% \else: \llap{\boxz@}% \fi: \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. % \begin{macrocode} \def\x@calc@shift@lf{% \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. % \begin{macrocode} \if_num:w \@tempcntb=0 \else: \global\divide\alignsep@\@tempcntb % original line \fi: % \end{macrocode} % Addition end. % \begin{macrocode} \if_dim:w \alignsep@<\minalignsep\relax \global\alignsep@\minalignsep\relax \fi: \fi: \if_dim:w \tag@width\row@>\@tempdima \saveshift@1% \else: \saveshift@0% \fi:}% % \end{macrocode} % \end{macro} % \begin{macrocode} } % \end{macrocode} % End of bug fixing. % % \subsection{Making environments safer} % % \begin{macro} % Here we make the \pkg{amsmath} inner environments disallow spaces % before their optional positioning specifier. % \begin{macrocode}{\aligned@a} \MaybeMHPrecedingSpacesOff \renewcommand\aligned@a[1][c]{\start@aligned{#1}\m@ne} \MHPrecedingSpacesOn % \end{macrocode} % \end{macro} % % This is the end of the \pkg{mathtools} package. % \begin{macrocode} % % \end{macrocode} % % \Finale \endinput