diff options
author | Karl Berry <karl@freefriends.org> | 2006-01-11 23:55:08 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2006-01-11 23:55:08 +0000 |
commit | 018eddbb412852f79bbfcee05c61b8a959601a6d (patch) | |
tree | 7cf67ac127efeae65589f319ee31a5ae0584be8d /Master/texmf-dist/source/latex/mh/empheq.dtx | |
parent | d9aa4a0d0dc45506f1b4d1b4454769c50eefc2a9 (diff) |
trunk/Master/texmf-dist/source/latex/mh
git-svn-id: svn://tug.org/texlive/trunk@387 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/source/latex/mh/empheq.dtx')
-rw-r--r-- | Master/texmf-dist/source/latex/mh/empheq.dtx | 4050 |
1 files changed, 4050 insertions, 0 deletions
diff --git a/Master/texmf-dist/source/latex/mh/empheq.dtx b/Master/texmf-dist/source/latex/mh/empheq.dtx new file mode 100644 index 00000000000..32f5fadbbd4 --- /dev/null +++ b/Master/texmf-dist/source/latex/mh/empheq.dtx @@ -0,0 +1,4050 @@ +% \iffalse meta-comment +% File `empheq.dtx'. +% Copyright 2002-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 empheq.dtx and empheq.ins and the +% derived files empheq.sty and ntheorem.fix. +% \fi +% \iffalse +%<empheq>\NeedsTeXFormat{LaTeX2e} +%<empheq>\ProvidesPackage{empheq} +%<ntheorem>\ProvidesFile{ntheorem.fix} +%<*dtx> + \ProvidesFile{empheq.dtx} +%</dtx> + [2004/10/10 v2.11a +%<empheq> Emphasizing equations (MH) +%<ntheorem> empheq support and fixes for ntheorem (MH) + ] +%<*driver> +\documentclass[a4paper]{ltxdoc} +\usepackage[overload]{empheq} +\usepackage{color,varioref,booktabs,fancybox} + +\pagestyle{headings} +\hyphenation{emph-eq} +\makeatletter +\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}} +\addtolength\marginparwidth{-30pt} + + +\newcommand*\AddDescribe[3]{% + \@namedef{Describe#1}{\leavevmode\@bsphack\begingroup\MakePrivateLetters + \@nameuse{Describe@#1}} + \@namedef{Describe@#1}##1{\endgroup + \marginpar{\raggedleft\@nameuse{PrintDescribe#1}{##1}}% + \@nameuse{Special#1Index}{##1}\@esphack\ignorespaces} + \@namedef{Special#1Index}##1{\@bsphack + \index{##1\actualchar{\protect\ttfamily ##1} + (#2)\encapchar usage}% + \index{#3:\levelchar##1\actualchar{\protect\ttfamily ##1}\encapchar + usage}\@esphack} + \@namedef{PrintDescribe#1}##1{\strut \MacroFont ##1\ }% + \@namedef{Print#1Name}##1{\strut \MacroFont ##1\ }% +} +\AddDescribe{Color}{color}{colors} +\AddDescribe{KeyFamily}{key family}{key families} +\newcommand*\DescribeDelimiter[1]{% + \cs{#1}&\SpecialMkhIndex{empheq#1}\cs{empheq}\texttt{#1} & + \SpecialMkhIndex{empheqbig#1}\cs{empheqbig}\texttt{#1} & + $\@nameuse{#1}$\tabularnewline} +\newcommand*\SpecialMkhIndex[1]{% + \@bsphack + \index{#1\actualchar{\protect\ttfamily \protect\bslash\space#1} + (` $\bslash#1$ ')\encapchar usage}% + \@esphack +} +\newcommand\TabDescribeOption[3][(default)]{% + \SpecialOptIndex{#2}\opt{#2} & #3 \tabularnewline +} +\newcommand*\TabDescribeAmsKey[2][]{% + \SpecialKeyIndex{#2}\env{#2} & + \texttt{\{#2#1\}} & + \SpecialKeyIndex{#2*}\env{#2*} & + \texttt{\{#2*#1\}} \tabularnewline +} +\newcommand*\TabDescribeOptKey[3][]{% + \SpecialKeyIndex{#2}\key{#2} & + \texttt{#2=}\meta{#3} & #1 \tabularnewline +} + +\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*\keyfam[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\MHbool#1{{\ttfamily #1}\endgroup} +\DeclareRobustCommand\bool{\begingroup\MakePrivateLetters\MHbool}% + +\def\endverbatim{\if@newlist +\leavevmode\fi\endtrivlist\vspace{-\baselineskip}} +\expandafter\let\csname endverbatim*\endcsname =\endverbatim + +\let\MTtheindex\theindex +\def\theindex{\MTtheindex\MakePrivateLetters} + +\newcommand*\widefbox[1]{\fbox{\hspace{1em}#1\hspace{1em}}} +\definecolor{myblue}{rgb}{.8, .8, 1} +\newcommand*\mybluebox[1]{% + \colorbox{myblue}{\hspace{1em}#1\hspace{1em}}} +\newenvironment{important}[2][]{% + \setkeys{EmphEqEnv}{#2}% + \setkeys{EmphEqOpt}{box=\mybluebox,#1}% + \EmphEqMainEnv}% + {\endEmphEqMainEnv} +\definecolor{shadecolor}{cmyk}{0,0,0.41,0} +\definecolor{light-blue}{cmyk}{0.25,0,0,0} +\newsavebox{\mysaveboxM} % M for math +\newsavebox{\mysaveboxT} % T for text +\newcommand*\Garybox[2][Example]{% + \sbox{\mysaveboxM}{#2}% + \sbox{\mysaveboxT}{\fcolorbox{black}{light-blue}{#1}}% + \sbox{\mysaveboxM}{% + \parbox[b][\ht\mysaveboxM+.5\ht\mysaveboxT+.5\dp\mysaveboxT][b]{% + \wd\mysaveboxM}{#2}% + }% + \sbox{\mysaveboxM}{% + \fcolorbox{black}{shadecolor}{% + \makebox[\linewidth-10em]{\usebox{\mysaveboxM}}% + }% + }% + \usebox{\mysaveboxM}% + \makebox[0pt][r]{% + \makebox[\wd\mysaveboxM][c]{% + \raisebox{\ht\mysaveboxM-0.5\ht\mysaveboxT + +0.5\dp\mysaveboxT-0.5\fboxrule}{\usebox{\mysaveboxT}}% + }% + }% +} + +\newcommand\EmphEqpart{% + \def\partname{\EmphEqpartname}% + \part} + +\def\EmphEqpartname{Part} +\makeatother + +\usepackage{graphicx} +\usepackage[final,breaklinks=true,hyperindex=false,linkbordercolor=false]{hyperref} +\renewcommand*\usage[1]{\textit{\hyperpage{#1}}} + +\OnlyDescription +\begin{document} +\DocInput{empheq.dtx} +\end{document} +%</driver> +% \fi +% +% \changes{v2.11}{2004/08/03}{Removed interface to the obsolete empheq +% package \pkg{empheq07}} +% +% \changes{v2.10}{2004/07/26}{Rewrote most of the documentation} +% +% \changes{v2.10}{2004/07/26}{Moved options \texttt{fixamsmath} and +% \texttt{donotfixamsmathbugs} to \pkg{mathtools}} +% +% \changes{v2.10}{2004/07/26}{Added support for \pkg{showkeys}} +% +% \changes{v2.00}{2004/04/14}{Added options \opt{overload}, +% \opt{overload2}, \texttt{fixamsmath}, and +% \texttt{donotfixamsmathbugs} plus descriptions of their use} +% +% \changes{v1.06}{2004/03/13}{Upgraded license to LPPL version 1.3} +% +% \changes{v1.00}{2004/02/15}{Complete rewrite of the package hence +% no description of the changes made} +% +% \changes{v0.7a}{2004/02/15}{Made the old package obsolete and +% changed its name to \pkg{empheq-obsolete}} +% +% \changes{v0.7}{2003/05/11}{Added further examples and changed +% existing ones} +% \changes{v0.6b}{2003/03/04}{Added example for changing margins +% inside the boxtype} +% \changes{v0.6a}{2003/01/28}{Minor updates to documentation} +% +% \changes{v0.5}{2002/12/30}{First experimental and very limited +% release} +% +% \GetFileInfo{empheq.dtx} +% \CheckSum{2495} +% +% \title{The \pkg{empheq} package\thanks{This file has version number +% \fileversion, last revised \filedate.}\\ +% Emphasizing equations in \LaTeXe} +% \author{Morten H\o gholm} +% \date{\filedate} +% +% \maketitle +% +% \begin{abstract} +% The \pkg{empheq} package can best be described as a visual markup +% extension to \pkg{amsmath}. In short it offers a)~a multi line +% equivalent of \cs{boxed} from \pkg{amsmath} and b)~a way to +% produce arbitrary delimiters that span entire math displays. +% \end{abstract} +% +% \tableofcontents +% +% \clearpage +% \EmphEqpart{Basic user's guide} +% +% There can be little doubt that the de facto standard for +% mathematical typesetting in \LaTeX{} is the \pkg{amsmath} package. +% For the creation of \pkg{empheq}, a visual markup package for use +% in math, it made perfect sense to have \pkg{amsmath} as the +% backbone. +% +% The main idea of \pkg{empheq} is to maintain the familiar syntax +% of the \pkg{amsmath} environments while still providing an easy +% way of specifying markup instructions. This manual is plastered +% with examples showing just how. +% +% +% \section{Basic use of the package} +% +% So what is it \pkg{empheq} does? Well, it allows you to produce +% displays like this: +% \begin{subequations} +% \begin{empheq}[ +% box=\mybluebox, +% right={\;\makebox[.9em]{$\raisebox{-.5\totalheight+\fontdimen22\textfont2} +% {\resizebox{!}{\EmphEqdisplayheight+\EmphEqdisplaydepth}{!}}$}}, +% left={X=Y\Rightarrow\empheqlbrace} +% ]{alignat=3} +% A_1&=b_1 & \qquad c_1&=d_1 & \qquad e_1&= f_1 +% \tag*{\_A\raisebox{1ex}{silly}\raisebox{-1ex}{tag}\_}\\ +% A_2&=b_2 & \qquad c_2&=d_2 & \qquad e_2&= f_2 \\ +% A_3&=b_3 & \qquad c_3&=d_3 & \qquad e_3&= f_3 +% \end{empheq} +% \end{subequations} +% In short \pkg{empheq} enables the user to put things on every side +% of the display without said user having to worry about what +% happens to the equation numbers. For example you can now have a +% display containing multiple lines and still get the effect of the +% \cs{boxed} command from \pkg{amsmath}. +% +% +% \subsection{Using the \env{empheq} environment} +% +% The package defines a single environment +% \SpecialEnvIndex{empheq}\env{empheq} and the usage is kind of straight +% forward: +% \begin{codesyntax} +% |\begin{empheq}|\oarg{markup instructions}\marg{\AmS{} env_name}\\ +% \mbox{}\quad\meta{contents of \AmS{} environment}\\ +% |\end{empheq}| +% \end{codesyntax} +% A first minimal example file would then be something like +% \begin{verbatim} +% \documentclass{minimal} +% \usepackage{empheq} +% \begin{document} +% \begin{empheq}{align*} +% a&=b \tag{*}\\ +% E&=mc^2 + \int_a^a x\, dx +% \end{empheq} +% \end{document} +% \end{verbatim} +% This gives the following display: +% \begin{empheq}{align*} +% a&=b \tag{*}\\ +% E&=mc^2 + \int_a^a x\, dx +% \end{empheq} +% Maybe not the most impressive example, but as you can see the +% contents of the environment is exactly the same as for the regular +% \env{align*} evironment from \pkg{amsmath}. The rest of the \AmS{} +% environments are chosen the same way by typing the name as the +% mandatory argument of \env{empheq} with the exception of the +% \env{alignat} environment. For this you have to specify the number +% of columns as shown below. +% \begin{verbatim} +% \begin{empheq}{alignat=2} +% a &= b &\quad c &= d \\ +% \text{this} &= \text{that} &\quad \mathit{fish}&\neq fish +% \end{empheq} +% \end{verbatim} +% \begin{empheq}{alignat=2} +% a &= b &\quad c &= d \\ +% \text{this} &= \text{that} &\quad \mathit{fish}&\neq fish +% \end{empheq} +% To choose the starred version of \env{alignat}, simply type +% \arg{alignat*=2} instead in the above example. +% +% The supported \AmS{} environments are listed in Table +% \vref{tab:environments}. Not supported is the standard \LaTeX{} +% \env{eqnarray} environment as it is fundamentally +% deficient.\footnote{See for instance +% \url{http://www.tex.ac.uk/cgi-bin/texfaq2html?label=eqnarray}} +% +% \begin{table} +% \centering +% \begin{tabular}{llll}\toprule +% Environment & Usage & Environment & Usage \\ \midrule +% \TabDescribeAmsKey{equation} +% \TabDescribeAmsKey{align} +% \TabDescribeAmsKey{gather} +% \TabDescribeAmsKey{flalign} +% \TabDescribeAmsKey[=\textrm{\meta{cols}}]{alignat} +% \TabDescribeAmsKey{multline} \bottomrule +% \end{tabular} +% \caption{The supported \pkg{amsmath} +% environments}\label{tab:environments} +% \end{table} +% +% +% \subsection{Markup instructions} +% +% The optional argument of the \env{empheq} environment will take +% markup instructions consisting of a $\meta{key}=\meta{value}$ list +% of assignments. There are currently five such keys (a sixth is +% added for naming consistency). They're shown in Table +% \vref{tab:keys}. +% +% \begin{table} +% \centering +% \begin{tabular}{llp{13em}}\toprule +% Key & Usage & Additional Info \tabularnewline \midrule +% \TabDescribeOptKey{box}{box command} +% \TabDescribeOptKey{innerbox}{box command} +% \TabDescribeOptKey[Use \cs{text}\arg{...} if you need text +% material.]{left}{math material} +% \TabDescribeOptKey[Use \cs{text}\arg{...} if you need text +% material.]{right}{math material} +% \TabDescribeOptKey[Alias for \key{box}.]{outerbox}{box command} +% \TabDescribeOptKey[Contents must be horizontally centered; +% can only be used in \mode{fleqn} mode.] +% {marginbox}{box command} +% \bottomrule +% \end{tabular} +% \caption{The six keys for the optional argument of the +% \env{empheq} environment}\label{tab:keys} +% \end{table} +% +% \begin{codesyntax} +% \SpecialKeyIndex{left}\key{left} +% \end{codesyntax} +% The key \key{left} is for material put on the left side of the +% display. The material is typeset in math mode and centered +% vertically. +% \begin{verbatim} +% \begin{empheq}[left=L\Rightarrow]{align} +% a&=b\\ +% E&=mc^2 + \int_a^a x\, dx +% \end{empheq} +% \end{verbatim} +% \begin{empheq}[left=L\Rightarrow]{align} +% a&=b\\ +% E&=mc^2 + \int_a^a x\, dx +% \end{empheq} +% +% +% \begin{codesyntax} +% \SpecialKeyIndex{right}\key{right} +% \end{codesyntax} +% As there is a \key{left} key it hopefully comes as no surprise +% that there is a companion \key{right} key for typesetting material +% on the right side of the display. +% \begin{verbatim} +% \begin{empheq}[right=\Leftarrow R]{align} +% a&=b\\ +% E&=mc^2 + \int_a^a x\, dx +% \end{empheq} +% \end{verbatim} +% \begin{empheq}[right=\Leftarrow R]{align} +% a&=b\\ +% E&=mc^2 + \int_a^a x\, dx +% \end{empheq} +% +% \begin{codesyntax} +% \SpecialKeyIndex{box}\key{box}\\ +% \SpecialKeyIndex{outerbox}\key{outerbox} +% \end{codesyntax} +% The key \key{box} specifies the kind of box you would like to put +% around the display. It can be any kind of box, as long as the +% contents of the box is situated on the baseline like in a +% \fbox{\cs{fbox}}. +% \begin{verbatim} +% \begin{empheq}[box=\fbox]{align} +% a&=b\\ +% E&=mc^2 + \int_a^a x\, dx +% \end{empheq} +% \end{verbatim} +% \begin{empheq}[box=\fbox]{align} +% a&=b\\ +% E&=mc^2 + \int_a^a x\, dx +% \end{empheq} +% The key \key{outerbox} is an alias for \key{box} and is added for +% naming consistency with the key described below. +% +% \begin{codesyntax} +% \SpecialKeyIndex{innerbox}\key{innerbox} +% \end{codesyntax} +% There is also an \key{innerbox} key. It is not very interesting +% unless you use one of the other keys. +% \begin{verbatim} +% \begin{empheq}[innerbox=\fbox, +% left=L\Rightarrow]{align} +% a&=b\\ +% E&=mc^2 + \int_a^a x\, dx +% \end{empheq} +% \end{verbatim} +% \begin{empheq}[innerbox=\fbox, +% left=L\Rightarrow]{align} +% a&=b\\ +% E&=mc^2 + \int_a^a x\, dx +% \end{empheq} +% +% \begin{codesyntax} +% \SpecialKeyIndex{marginbox}\key{marginbox} +% \end{codesyntax} +% \FeatureRequest{Uwe Siart}{2003/12/08} +% The last key is the \key{marginbox} key. If you typeset your math +% in \mode{fleqn} mode\footnote{Sorry, but I can't show you because +% this manual features centered math displays.} you may want the +% math display and not the outer box to align at the left margin (or +% rather: the indentation). If you make sure the contents of the +% outer box is centered horizontally inside the box, \key{marginbox} +% will align it properly. You shouldn't set both \key{box} and +% \key{marginbox} at the same time, as this is surely not what you +% want and the package will silently use the last one in the list. +% +% +% \begin{quote} +% \textbf{Warning}: \pkg{keyval} treats commas and equal signs as +% separator and assignment signs which in turn means that if you +% want to typeset either of them, they \emph{must}---and believe me, +% it's really important---be enclosed in braces. In short: +% \begin{description} +% \item[{\makebox[3em][l]{Good}}] \texttt{[left=\{(A,B)=(1,0)\}]} +% \item[{\makebox[3em][l]{Bad}}] \texttt{[left=(A,B)=(1,0)]} +% \end{description} +% \end{quote} +% +% \begin{codesyntax} +% \SpecialUsageIndex{\empheqset}\cs{empheqset}\marg{markup instructions} +% \end{codesyntax} +% \FeatureRequest{Uwe Siart}{2004/01/13} +% You can also set the keys globally\footnote{Or rather: outside the +% scope of the \env{empheq} environment. The settings will still +% obey scoping rules.} with the command +% \cs{empheqset}. This means that +% \begin{verbatim} +% \empheqset{marginbox=\psframebox} +% \end{verbatim} +% will force a |box=\psframebox| in all occurrences of the +% \env{empheq} environment, but an explicitly given \key{box} or +% \key{marginbox} will override this setting. You can only use the +% keys listed in this section as arguments to \cs{empheqset}; not +% the \AmS\ environments. +% +% +% +% \subsection{What won't work in the \env{empheq} environment} +% +% \begin{codesyntax} +% \SpecialUsageIndex{intertext}\cs{intertext}\marg{text}\\ +% \SpecialUsageIndex{displaybreak}\cs{displaybreak}\oarg{num} +% \end{codesyntax} +% Now we've seen some of the things that work in the \env{empheq} +% environment but we also have to take note of what won't work. As +% this package provides a way to box multi line math displays it can +% come as no surprise that using either \cs{intertext} or +% \cs{displaybreak} inside the \env{empheq} environment makes no +% sense. Should you however happen to try them anyway, you'll +% experience that \cs{intertext} issues an error message and +% \cs{displaybreak} issues a warning. The reason only \cs{intertext} +% gives an error message is that you'll get output very different +% from what you expect, and that is not the case (so much at least) +% with \cs{displaybreak}. But of course, you'll never see either +% message because you read the manual! +% +% +% +% \subsection{Special delimiters} +% +% As you've seen a few pages back, it's possible to add material on +% both sides of the math display. When doing so you often need a +% delimiter that scales to fit the entire display, so it comes as no +% surprise that \pkg{empheq} provides such delimiters. +% \begin{codesyntax} +% \cs{empheql}\meta{delim_name} \cs{empheqbigl}\meta{delim_name}\\ +% \cs{empheqr}\meta{delim_name} \cs{empheqbigr}\meta{delim_name} +% \end{codesyntax} +% For example one might need a large brace like the one in the +% \env{cases} environment: +% \begin{verbatim} +% \begin{empheq}[left=\empheqlbrace, right=\empheqrbrace]{align} +% E&=mc^2 \\ +% Y&= \sum_{n=1}^\infty \frac{1}{n^2} +% \end{empheq} +% \end{verbatim} +% \begin{empheq}[left=\empheqlbrace, right=\empheqrbrace]{align} +% E&=mc^2 \\ +% Y&= \sum_{n=1}^\infty \frac{1}{n^2} +% \end{empheq} +% The naming scheme is \cs{empheq}\meta{delimiter name} and +% \cs{empheqbig}\meta{delimiter name}. Thus \cs{empheqrbrace} +% produces an auto-scaling right brace with same size as the math +% display while \cs{empheqbigrbrace} produces an even bigger version +% that spans the inner box plus the math display inside it. For a +% complete list of supported delimiters see Table +% \vref{tab:delimiters}. +% +% \begin{table} +% \centering +% \begin{tabular}{lllc} \toprule +% \multicolumn{3}{c}{\textbf{Delimiter}}\\ \cmidrule{1-3} +% \multicolumn{1}{c}{Original} & \multicolumn{1}{c}{Normal} & +% \multicolumn{1}{c}{Bigger} & Symbol\\ \midrule +% \DescribeDelimiter{lbrace} \DescribeDelimiter{rbrace} +% \DescribeDelimiter{lbrack} \DescribeDelimiter{rbrack} \midrule +% \DescribeDelimiter{langle} \DescribeDelimiter{rangle} +% \DescribeDelimiter{lparen} \DescribeDelimiter{rparen} \midrule +% \DescribeDelimiter{lvert} \DescribeDelimiter{rvert} +% \DescribeDelimiter{lVert} \DescribeDelimiter{rVert} \midrule +% \DescribeDelimiter{lfloor} \DescribeDelimiter{rfloor} +% \DescribeDelimiter{lceil} \DescribeDelimiter{rceil} \bottomrule +% \end{tabular} +% \caption{The supported auto-scaling delimiters in +% \pkg{empheq}}\label{tab:delimiters} +% \end{table} +% +% +% +% \section{Taking things a little further} +% +% So far we have covered the basic functions of \pkg{empheq}: the +% markup instructions and the predefined auto-scaling delimiters. +% There is more to \pkg{empheq} however, and we'll cover that in +% this section. +% +% \subsection{Loading the package} +% +% The package has two main requirements: One is the +% \pkg{mathtools}\footnote{By the same author and is distributed +% with \pkg{empheq}. See its documentation for more information.} +% package which provides \pkg{empheq} with a lot of necessary tools +% for doing its thing. The other one is \pkg{amsmath} of course, and +% to make the loading procedure as easy as possible, you can simply +% substitute +% \begin{verbatim} +% \usepackage[leqno,fleqn,intlimits]{amsmath} +% \end{verbatim} +% with +% \begin{verbatim} +% \usepackage[leqno,fleqn,intlimits]{empheq} +% \end{verbatim} +% \pkg{empheq} makes sure that the \pkg{amsmath} options are passed +% on and loaded by \pkg{amsmath}. The same goes for the options +% provided by \pkg{mathtools}. +% +% +% \subsubsection{Compatibility with the old version} +% +% The current version (\fileversion) of \pkg{empheq} is incompatible with +% versions prior to and including~0.7d. If you have documents produced +% with versions prior to~0.7d, then you have to load the package +% \pkg{empheq07} instead. \pkg{empheq07} now exists as a separate package +% package with its own documentation, but I strongly recommend switching +% to the new version because it is so much better. +% +% \subsection{Package options} +% +% In addition to the \pkg{amsmath} options, \pkg{empheq} itself +% provides a string of options listed in Table \vref{tab:options}. +% +% \begin{table}[ht] +% \centering +% \begin{tabular}{lp{21em}} \toprule +% Option & Short description \tabularnewline \midrule +% \TabDescribeOption[]{overload} +% {Lets you use the \pkg{empheq} visual markup extensions +% transparently in an existing document.} +% \TabDescribeOption[]{overload2} +% {A wild version of \opt{overload}. Use with care.} +% \TabDescribeOption[]{ntheorem} +% {A support module for users of \pkg{ntheorem} and its +% \opt{thmmarks} and \opt{thref} options.} +% \TabDescribeOption[]{newmultline} +% {With v2.10 of \pkg{empheq} the syntax for \env{multline} and +% \env{multlined} has been improved immensely.} +% \TabDescribeOption[]{oldmultline} +% {Support for the somewhat strange syntax for \env{multline} and +% \env{multlined} in v2.00.} +% \bottomrule +% \end{tabular} +% \caption{Supported options in the \pkg{empheq} package} +% \label{tab:options} +% \end{table} +% +% +% \begin{codesyntax} +% \SpecialOptIndex{ntheorem}\opt{ntheorem} +% \end{codesyntax} +% The \pkg{ntheorem} package is supported by means of the +% \opt{ntheorem} option. In order for this to work properly, an +% \pkg{amsmath} bug\footnote{See the \LaTeX{} Bugs Database +% \url{http://www.latex-project.org/cgi-bin/ltxbugs2html} under +% \AmS\LaTeX{} problem report 3624.} is fixed. For more information +% on this option see \S \vref{sec:ntheorem-support}. +% +% \subsubsection{Using \env{multline}} +% +% \begin{codesyntax} +% \SpecialOptIndex{newmultline}\opt{newmultline}\\ +% \SpecialOptIndex{oldmultline}\opt{oldmultline} +% \end{codesyntax} +% Those familiar with v2.00 of this package will recognize the +% somewhat weird syntax for using \env{multline} and +% \env{multlined}. The good news is that since v2.10 there is now a +% much improved syntax available. The option \opt{newmultline} +% (default) selects this better interface, while the old interface +% is provided for compatibility reasons by the \opt{oldmultline} +% option. +% +% +% \begin{codesyntax} +% \SpecialUsageIndex{\shoveleft}\cs{shoveleft}\oarg{dimen}\marg{arg}\\ +% \SpecialUsageIndex{\shoveright}\cs{shoveright}\oarg{dimen}\marg{arg} +% \end{codesyntax} +% With the new interface you also get an extended syntax for +% \cs{shoveleft} and \cs{shoveright} as shown in the example below. +% \begin{verbatim} +% \begin{empheq}{multline} +% \framebox[.65\columnwidth]{First line} \\ +% \framebox[.5\columnwidth]{Second line} \\ +% \shoveleft{L+E+F+T} \\ +% \shoveright{R+I+G+H+T} \\ +% \shoveleft[1cm]{L+E+F+T} \\ +% \shoveright[\widthof{$R+I+G+H+T$}]{R+I+G+H+T} \\ +% \framebox[.65\columnwidth]{Last line} +% \end{empheq} +% \end{verbatim} +% \begin{empheq}{multline} +% \framebox[.65\columnwidth]{First line} \\ +% \framebox[.5\columnwidth]{Second line} \\ +% \shoveleft{L+E+F+T} \\ +% \shoveright{R+I+G+H+T} \\ +% \shoveleft[1cm]{L+E+F+T} \\ +% \shoveright[\widthof{$R+I+G+H+T$}]{R+I+G+H+T} \\ +% \framebox[.65\columnwidth]{Last line} +% \end{empheq} +% +% +% There are however a few differences in the output between the +% original \pkg{amsmath} version of \env{multline} and the one +% \pkg{empheq} provides. In \pkg{amsmath} a centered line in +% \env{multline} is centered on the page without taking into account +% the \cs{multlinegap}, \cs{multlinetaggap}, and the tag width. Thus +% \pkg{amsmath} can sometimes give you horrible output without +% giving you any warning as shown below. +% \begin{verbatim} +% \begin{multline} +% \framebox[.65\columnwidth]{First line} \\ +% \framebox[.9\columnwidth]{Loooong line} \\ +% \framebox[.65\columnwidth]{Last line} \tag{wide tag} +% \end{multline} +% \end{verbatim} +% \begin{AmSmultline} +% \framebox[.65\columnwidth]{First line} \\ +% \framebox[.9\columnwidth]{Loooong line} \\ +% \framebox[.65\columnwidth]{Last line} \tag{wide tag} +% \end{AmSmultline} +% In \pkg{empheq} these parameters are taken into account, so the +% same input will produce this in \pkg{empheq}: +% \begin{verbatim} +% \begin{empheq}{multline} +% \framebox[.65\columnwidth]{First line} \\ +% \framebox[.9\columnwidth]{Loooong line} \\ +% \framebox[.65\columnwidth]{Last line} \tag{wide tag} +% \end{empheq} +% \end{verbatim} +% \begin{multline*} +% \framebox[.65\columnwidth]{First line} \\ +% \framebox[.9\columnwidth]{Loooong line} \\ +% \framebox[.65\columnwidth]{Last line} \tag{wide tag} +% \end{multline*} +% This results in an +% \begin{verbatim} +% Overfull \hbox (30.03783pt too wide) in paragraph ... +% \end{verbatim} +% message in the log file, indicating a visual problem. I think this +% behavior is more sensible than the one the original \env{multline} +% environment provides. +% +% \begin{codesyntax} +% \SpecialEnvIndex{MTmultlined}\cs{begin}\arg{MTmultlined}\oarg{pos}\oarg{width} +% \meta{contents} \cs{end}\arg{MTmultlined} +% \end{codesyntax} +% When you choose the \opt{oldmultline} option you may still want to +% use the much improved \env{multlined} environment defined in +% \pkg{mathtools} but unfortunately there will be a name clash. +% Instead you can access it under the name \env{MTmultlined}. +% +% +% +% \subsubsection{The \opt{overload} option}\label{sec:overload} +% +% \begin{codesyntax} +% \SpecialOptIndex{overload}\opt{overload}\\ +% \SpecialOptIndex{overload2}\opt{overload2} +% \end{codesyntax} +% \FeatureRequest{Lars Madsen}{2004/03/25} +% The \opt{overload} option redefines the original \AmS{} +% environments so that they take an optional argument. +% \begin{codesyntax} +% \cs{begin}\marg{\AmS{} env_name}\oarg{markup instructions}\\ +% \meta{contents of \AmS{} environment}\\ +% \cs{end}\marg{\AmS{} env_name} +% \end{codesyntax} +% For example +% \begin{verbatim} +% \begin{gather}[box=\widefbox] +% a = b +% \end{gather} +% \end{verbatim} +% is then actually short for +% \begin{verbatim} +% \begin{empheq}[box=\widefbox]{gather} +% a = b +% \end{empheq} +% \end{verbatim} +% All the \AmS{} environments are supported by this option except +% for the pseudo environment |\[ ... \]| (it's not really an +% environment), \footnote{With the option \opt{oldmultline} the +% \env{multline} and \env{multline*} environments aren't supported +% either because their syntax in \pkg{empheq} then differ from their +% syntax in \pkg{amsmath}.} because a)~you don't really need markup +% instructions for a one line display, and b)~would you really like +% a syntax like +% \begin{verbatim} +% \[[box=\fbox] a=b \] +% \end{verbatim} +% where its difficult to see whether or not there is a typo? +% Choosing \opt{overload} is meant for people who don't want to +% change their entire document into \pkg{empheq} syntax. I have no +% problems with that; just be careful when you fiddle with +% \cs{empheqset} as it will affect \emph{all} math displays! +% +% +% There is of course a catch (well, two actually): These redefined +% environments don't run as fast as the regular ones (about three +% times as slow), but in this day and age I seriously doubt you'll +% be able to tell the difference unless you have a vast number of +% equations. The other catch is that you cannot use \cs{intertext} +% and \cs{displaybreak} as described earlier. If you find yourself +% wanting to use one of these features in say, an \env{align} +% environment, you have to use the original \env{align} environment. +% Luckily it is available if you call it like this: +% \begin{codesyntax} +% \cs{begin}\arg{AmS\meta{\rmfamily \AmS{} env_name}} \\ +% \texttt{~~}\meta{contents of \AmS{} environment}\\ +% \cs{end}\arg{AmS\meta{\rmfamily \AmS{} env_name}} +% \end{codesyntax} +% For example the original \env{align} environment could be selected +% with +% \begin{verbatim} +% \begin{AmSalign} +% ... +% \end{AmSalign} +% \end{verbatim} +% These original versions with prefix \texttt{AmS} exist for all the +% environments. +% +% +% The option \opt{overload2} activates the overloading feature +% for the pseudo environment |\[ ... \]|, although I doubt you'll +% find it useful. Beware that this definition is fragile unless you +% have \eTeX{} as \LaTeX{} engine.\footnote{\eTeX{} has been the +% default engine for \LaTeX{} in most major distributions since +% 2003.} Not surprisingly \opt{overload2} activates +% \opt{overload}. +% +% +% +% Before you get all excited about these options, you should take +% note of some aspects of centered math displays in \pkg{amsmath}. +% In certain circumstances truly centering the display is not always +% the best solution as in this example: +% \begin{center} +% \mbox{}\hfill +% \framebox[.75\linewidth]{Wide math display; not adjusted}% +% \hfill\mbox{}% +% \makebox[0pt][r]{Wide Tag} +% \end{center} +% Instead centering the display in the available space works pretty +% well: +% \begin{gather*} +% \framebox[.75\linewidth]{Wide math display; adjusted}% +% \tag*{Wide Tag} +% \end{gather*} +% This is what \pkg{amsmath} does normally, but in the \env{gather} +% environment it does it on a per line basis. This means that we get +% results like +% \begin{AmSgather*} +% \framebox[.75\linewidth]{Wide math display; adjusted}% +% \tag*{Wide Tag} \\ +% \framebox[.75\linewidth]{Wide math display; not adjusted} \tag{i}% +% \end{AmSgather*} +% whether we like it or not. Inside the \env{empheq} environment we +% need to have the same adjustment for all lines else the boxing +% process will not work properly, so when activating the +% \opt{overload} option the above two-line \env{gather} will +% instead look like this: +% \begin{empheq}{gather*} +% \framebox[.75\linewidth]{Wide math display; adjusted}% +% \tag*{Wide Tag} \\ +% \framebox[.75\linewidth]{Wide math display; adjusted} \tag*{i}% +% \end{empheq} +% I leave it to you to choose whether or not this is better (I think +% it is better). +% +% +% +% \subsection{A note on boxed displays} +% +% When browsing a 400+ pages textbook with at least twice the number +% of displayed formulae, some of them are surely more important than +% others. Thus the author of the book (in cooperation with the +% designer) should make sure that such formulae are easily found +% again i.e., they should be easily distinguishable from the rest of +% the pack. One way of doing this is putting the formula into a box +% which is something we've seen \pkg{empheq} being capable of. There +% are however a few things to keep in mind: +% \begin{itemize} +% \item Don't overdo it. If you do it on half of them there's no +% point in doing it at all. I don't see much reason for applying +% this technique to more than 10\% of the formulae. +% \item Choose the type of box carefully. You want to draw +% attention to it so it might as well look good. +% \end{itemize} +% The latter point can be illustrated by defining a macro similar to +% \cs{fbox} only with a little more space to the right and left of +% the argument. +% \begin{verbatim} +% \newcommand*\widefbox[1]{\fbox{\hspace{1em}#1\hspace{1em}}} +% \end{verbatim} +% If we replace the \cs{fbox} from the \key{box} example before, we +% get this display: +% \begin{verbatim} +% \begin{empheq}[box=\widefbox]{align} +% a&=b\\ +% E&=mc^2 + \int_a^a x\, dx +% \end{empheq} +% \end{verbatim} +% \begin{empheq}[box=\widefbox]{align} +% a&=b\\ +% E&=mc^2 + \int_a^a x\, dx +% \end{empheq} +% Compare it with +% \begin{empheq}[box=\fbox]{align} +% a&=b\\ +% E&=mc^2 + \int_a^a x\, dx +% \end{empheq} +% and see which one you prefer. +% +% Similarly one might be tempted to use colored boxes: +% \begin{verbatim} +% \definecolor{myblue}{rgb}{.8, .8, 1} +% \newcommand*\mybluebox[1]{% +% \colorbox{myblue}{\hspace{1em}#1\hspace{1em}}} +% \end{verbatim} +% We know the drill by now. +% \begin{verbatim} +% \begin{empheq}[box=\mybluebox]{align} +% a&=b\\ +% E&=mc^2 + \int_a^a x\, dx +% \end{empheq} +% \end{verbatim} +% \begin{empheq}[box=\mybluebox]{align} +% a&=b\\ +% E&=mc^2 + \int_a^a x\, dx +% \end{empheq} +% There is more on boxes later in this manual. If you're into the +% \pkg{fancybox} package then remember to read \S +% \vref{sec:fancybox_support}. +% +% \section{Support for other packages} +% +% With the multitude of packages for \LaTeX, it is not always easy +% to be a PWWO package (``Plays Well With Others''), but +% \pkg{empheq} tries really hard to do so. This section lists the +% packages where \pkg{empheq} has to provide workarounds and they +% can be divided into two categories. +% \begin{description} +% \item[Compatibility] Some packages affect \LaTeX' labelling +% mechanism and since \pkg{empheq} internally has to turn off +% labels and related code temporarily, hooks must be provided for +% these packages. Examples of such packages are \pkg{hyperref} and +% \pkg{showkeys}. +% +% \item[Enhancements] Other packages provide useful features that +% for some reason may not work directly or optimally with +% \pkg{empheq}. In these cases the problematic commands are +% redefined so that they not only work with \pkg{empheq}, but +% also give the same if not better output. An example of this +% would be the \cs{shadowbox} command from \pkg{fancybox} +% (described below). +% \end{description} +% % +% \subsection{Support for \pkg{fancybox}}\label{sec:fancybox_support} +% +% The \pkg{fancybox} package provides various boxes and you can use +% them with \pkg{empheq} as well. Here's \cs{ovalbox}: +% \begin{verbatim} +% \begin{empheq}[box=\ovalbox]{align} +% E&=mc^2 \\ +% Y&= \sum_{n=1}^\infty \frac{1}{n^2} +% \end{empheq} +% \end{verbatim} +% \begin{empheq}[box=\ovalbox]{align} +% E&=mc^2 \\ +% Y&= \sum_{n=1}^\infty \frac{1}{n^2} +% \end{empheq} +% +% +% \begin{codesyntax} +% \SpecialUsageIndex{\shadowbox}\SpecialUsageIndex{\shadowbox*} +% \cs{shadowbox*}\marg{arg} \\ +% \SpecialColorIndex{shadowcolor} \texttt{shadowcolor} +% \end{codesyntax} +% The only problem with using the \pkg{fancybox} boxes in +% conjunction with the \env{empheq} environment is \cs{shadowbox}, +% as this macro typesets the shadow on the baseline and for the +% equation numbers to be placed correctly, the box command must set +% its argument on the baseline. Thus the normal \cs{shadowbox} +% produces \shadowbox{\meta{arg}}, but we need this instead: +% \shadowbox*{\meta{arg}}. Therefore \pkg{empheq} will detect if +% \pkg{fancybox} is loaded and in that case it'll enhance +% \cs{shadowbox} in two ways: +% \begin{itemize} +% \item It defines a starred version \cs{shadowbox*} which +% typesets its argument on the baseline. +% +% \item The color \texttt{shadowcolor} is introduced. The default +% color is black. +% \end{itemize} +% \begin{verbatim} +% \definecolor{shadowcolor}{rgb}{0,.5,.5} +% \setlength\shadowsize{2pt} +% Line of text for \shadowbox*{testing of \Verb|f#&%\| verbatim} and +% showing the shadow color. +% \end{verbatim} +% \begin{quote} +% \definecolor{shadowcolor}{rgb}{0,.5,.5} +% \setlength\shadowsize{2pt} +% Line of text for \shadowbox*{testing of \Verb|f#&%\| verbatim} and +% showing the shadow color. +% \end{quote} +% +% The point is that if you want a \cs{shadowbox} around your math +% display then you must use the starred version: +% \begin{verbatim} +% \begin{empheq}[box=\shadowbox*]{align} +% E&=mc^2 \\ +% Y&= \sum_{n=1}^\infty \frac{1}{n^2} +% \end{empheq} +% \end{verbatim} +% \begin{empheq}[box=\shadowbox*]{align} +% E&=mc^2 \\ +% Y&= \sum_{n=1}^\infty \frac{1}{n^2} +% \end{empheq} +% +% See \S \vref{stunning} if you want +% to make a fancy box yourself. +% +% +% \subsection{Support for \pkg{ntheorem}}\label{sec:ntheorem-support} +% +% \changes{v2.00}{2004/04/14}{Added description of the +% \opt{ntheorem} option} +% \changes{v1.05}{2004/02/16}{Added support for the end-of-theorem +% marker mechanism of \pkg{ntheorem}} +% +% \begin{codesyntax} +% \SpecialOptIndex{ntheorem}\opt{ntheorem} +% \end{codesyntax} +% The \pkg{ntheorem} package is supported by the means of the +% \opt{ntheorem} option of \pkg{empheq}. This loads a set of +% extra macros which fixes various compatibility problems between +% \pkg{ntheorem} and \pkg{amsmath} and furthermore introduces +% special (internal) macros for optimum positioning of +% end-of-theorem markers, while retaining a user friendly interface. +% +% +% When you want to use the automatic end-of-theorem marker mechanism +% from \pkg{ntheorem} you sometimes run into problems as you would +% want the marker to be placed aligned at the bottom of the math +% display but still keeping the tags in their proper place. In +% \mode{leqno} mode this is not that much of a problem as the tags +% and the marker are set on either side of the math display like +% in Figure \vref{fig:markerI}. +% \changes{v1.05a}{2004/02/17}{Added explanatory drawings for +% \pkg{ntheorem}} +% +% \begin{figure}[btp]\centering +% \unitlength2.5pt \thicklines +% \begin{picture}(90,30)(-30,40) +% \put(0,50){\framebox(25,20){Math Height}} +% \put(0,40){\framebox(25,10){Math Depth}} +% \put(-30,50){\framebox(20,10){Tag height}} +% \put(-30,45){\framebox(20,5){Tag depth}} +% \put(40,40){\framebox(20,10){Marker}} +% \multiput(26,40)(2,0){7}{\line(1,0){1}} +% \end{picture} +% \caption{Marker placement in \mode{leqno} mode} +% \label{fig:markerI} +% \end{figure} +% +% \begin{codesyntax} +% \SpecialUsageIndex{\mintagvsep}\cs{mintagvsep} +% \end{codesyntax} +% Unfortunately things are not this easy in \mode{reqno} mode. There +% are two possible situations as shown in Figure \vref{fig:markerII}. +% \begin{figure}[btp] +% \unitlength2.5pt \thicklines +% \begin{picture}(60,45)(0,25) +% \put(0,50){\framebox(25,20){Math Height}} +% \put(0,25){\framebox(25,25){Math Depth}} +% \put(40,50){\framebox(20,10){Tag height}} +% \put(40,45){\framebox(20,5){Tag depth}} +% \put(40,25){\framebox(20,10){Marker}} +% \put(50,35){\vector(0,1){10}} +% \put(50,45){\vector(0,-1){10}} +% \put(50,39){\ \ $>\delta$} +% \multiput(26,25)(2,0){7}{\line(1,0){1}} +% \end{picture} \hfill\vrule\hfill +% \begin{picture}(60,45)(0,25) +% \put(0,50){\framebox(25,20){Math Height}} +% \put(0,40){\framebox(25,10){Math Depth}} +% \put(40,50){\framebox(20,10){Tag height}} +% \put(40,45){\framebox(20,5){Tag depth}} +% \put(40,28){\framebox(20,10){Marker}} +% \put(50,38){\vector(0,1){7}} +% \put(50,45){\vector(0,-1){7}} +% \put(50,40){\ \ $=\delta$} +% \end{picture} +% \caption{The two possible situations for end marks in \mode{reqno} +% mode} +% \label{fig:markerII} +% \end{figure} +% If possible we want the bottom of the marker to be aligned with +% the bottom of the math display, but at the same time we want to +% ensure a minimum vertical separation $\delta$ between marker and +% tag. In \pkg{empheq} this is controlled by the length parameter +% \cs{mintagvsep} which by default is 5\,pt. +% +% The good news is that this is where \pkg{empheq} sets in. +% Basically all you need to do is to use the \env{empheq} +% environment to type set your equations inside the theorem +% environments: +% \begin{verbatim} +% \begin{Theorem} +% Some text at first and then a math display +% \begin{empheq}{align} +% a&=b\\ +% E&=mc^2 + \int_a^a x\, dx +% \end{empheq} +% \end{Theorem} +% \end{verbatim} +% Then the tag placement and the end-of-theorem marker will be set +% properly (after a couple of runs as usual). +% +% To ensure the correct outcome remember to load the packages like +% this: +% \begin{verbatim} +% \usepackage[ntheorem]{empheq} % this loads amsmath as well +% \usepackage[thmmarks,amsmath]{ntheorem} +% \end{verbatim} +% Remember that if you use the \opt{overload} option you +% can just use the regular math environments to get the desired +% result with the end mark. The exception is the |\[ ... \]| +% environment which will only work if you use the option +% \opt{overload2}. +% +% \clearpage +% +% \EmphEqpart{Advanced user's guide} +% +% The \pkg{empheq} package has more to offer than you have seen, but +% I found some of the functionality so dangerous it was best to hide +% it for a little while. The commands you have encountered so far in +% this manual all have one thing in common: They have only lower +% case letters in their names. Now it's time to reveal those that +% have \emph{mixed-case} names, thus implying that you should take +% great care when using them. +% +% \section{Delimiters revisited} +% Let's go back to delimiters, shall we? +% +% \subsection{Creating your own delimiters} +% As a convenience for the user, this interface is extended in a +% more general way so that it is also possible to declare delimiters +% with the following two commands: \SpecialUsageIndex{\DeclareLeftDelimiter} +% \SpecialUsageIndex{\DeclareRightDelimiter} +% \begin{codesyntax} +% \cs{DeclareLeftDelimiter}\oarg{space adjustment}\marg{delimiter}\\ +% \cs{DeclareRightDelimiter}\oarg{space adjustment}\marg{delimiter} +% \end{codesyntax} +% While \pkg{empheq} provides auto-scaling versions of the most +% common delimiters, you may sometimes want some new ones. Say for +% instance you have loaded the \pkg{stmaryrd} package and you want +% to use the double bracket commands \cs{llbracket} and +% \cs{rrbracket} with \pkg{empheq}. Then you simply do this: +% \begin{verbatim} +% \DeclareLeftDelimiter{\llbracket} +% \DeclareRightDelimiter{\rrbracket} +% \end{verbatim} +% This defines the new delimiters \cs{empheqllbracket}, +% \cs{empheqbigllbracket}, \cs{empheqrrbracket} and +% \cs{empheqbigrrbracket}. +% +% You can use \cs{big...} delimiters as well if you don't like the +% automatic scaling. There are however ways to fine-tune if you +% really want it. +% +% \subsection{Fine-tuning of delimiters} +% +% \TeX{} provides two primitives to control the scaling of +% delimiters produced with \cs{left} and \cs{right}, namely the +% dimension \cs{delimitershortfall} (denoted by $\delta$ here) and +% the integer \cs{delimiterfactor} ($f$). The idea is that the +% sub-formula inside the \cs{left}-\cs{right} pair is to be +% vertically centered and given its height $h_1$ and its depth $h_2$ +% we want to produce a delimiter with total height $h$, where $h = +% 2 \max(h_1,h_2)$. \TeX' rules on this is that the minimum +% delimiter size $h_{\min}$ must meet the requirements +% \[ +% h_{\min}\geq h \frac{f}{1000} \quad\land \quad h_{\min}\geq h-\delta +% \] +% \LaTeX{} sets $\cs{delimitershortfall} = \text{\the\delimitershortfall} $ +% and $\cs{delimiterfactor} = \the\delimiterfactor$, but in our case +% we will almost always want a delimiter that spans the entire +% \cs{left}-\cs{right} pair (the math display), thus a change of +% these settings is needed. +% +% \begin{codesyntax} +% \SpecialUsageIndex{\EmphEqdelimitershortfall} +% \cs{EmphEqdelimitershortfall}\\ +% \SpecialUsageIndex{\EmphEqdelimiterfactor} +% \cs{EmphEqdelimiterfactor} +% \end{codesyntax} +% However it is a bad idea to just change these two settings without +% thinking of the effect it'll have on the rest of the mathematics +% in your document. Therefore \pkg{empheq} provides the parameters +% \cs{EmphEqdelimitershortfall} (default setting is +% \the\EmphEqdelimitershortfall) and \cs{EmphEqdelimiterfactor} +% (default is \the\EmphEqdelimiterfactor) to cater for this. +% +% +% \subsection{Scaling material yourself} +% +% The attentive reader may have noticed that I still haven't +% revealed how I managed to get the right size of that big +% exclamation mark in the first example of this manual, so I guess +% it's about time. +% \begin{codesyntax} +% \SpecialUsageIndex{\EmphEqdisplayheight}\cs{EmphEqdisplayheight} \\ +% \SpecialUsageIndex{\EmphEqdisplaydepth}\cs{EmphEqdisplaydepth} +% \end{codesyntax} +% The height of the math display plus the surrounding inner box is +% given by \cs{EmphEqdisplayheight} and the depth by +% \cs{EmphEqdisplaydepth}. These can be used when constructing +% something that should scale to fit the display and can't be done +% with ``auto-scaling'' commands like \cs{vrule} or \cs{left} or +% \cs{right}. There is a catch however: If you do any horizontal +% resizing of the material you want to scale, then you must specify +% the width \emph{manually}:\footnote{The +% \cs{fontdimen22}\cs{textfont2} in the \meta{length} argument of +% \cs{raisebox} is the \emph{math axis} of the font. It is needed in +% order to get the vertical positioning of the oversized exclamation +% mark just right.} +% \begin{verbatim} +% \begin{empheq}[ +% box=\colorbox{myblue}, +% right={\; +% \makebox[.9em]{% +% $\raisebox{-.5\totalheight+\fontdimen22\textfont2} +% {\resizebox{!}{% +% \EmphEqdisplayheight+\EmphEqdisplaydepth}{!}}$% +% }}, +% left={X=Y\Rightarrow} +% ]{alignat=3} +% A_1&=b_1 & \qquad c_1&=d_1 & \qquad e_1&= f_1 +% \tag*{\_A\raisebox{1ex}{silly}\raisebox{-1ex}{tag}\_}\\ +% A_2&=b_2 & \qquad c_2&=d_2 & \qquad e_2&= f_2 \\ +% A_3&=b_3 & \qquad c_3&=d_3 & \qquad e_3&= f_3 +% \end{empheq} +% \end{verbatim} +% +% Here's another example. We want to be able to put a \cs{parbox} +% with some descriptive text top-aligned on the side of the display. +% \begin{verbatim} +% \begin{empheq}[ +% left={\parbox[c][\EmphEqdisplayheight+\EmphEqdisplaydepth][t] +% {4.5cm} +% {You may find this kind of description useful.}\enspace}] +% {align} +% a&=\int_0^1 x\,dx +\frac{foo + bar}{baz}\\ +% E&= mc^2 +% \end{empheq} +% \end{verbatim} +% \begin{empheq}[ +% left={\parbox[c][\EmphEqdisplayheight+\EmphEqdisplaydepth][t] +% {4.5cm} +% {You may find this kind of description useful.}\enspace}] +% {align} +% a&=\int_0^1 x\,dx +\frac{foo + bar}{baz}\\ +% E&= mc^2 +% \end{empheq} +% +% \section{Creating something new} +% +% You can create your own environments and boxes to go with +% \pkg{empheq}, but there are certain things that must be fulfilled +% to get it to work properly. +% +% \subsection{New \env{empheq}-like environments} +% +% \begin{codesyntax} +% \SpecialEnvIndex{EmphEqMainEnv}\env{EmphEqMainEnv}\\ +% \SpecialUsageIndex{\EmphEqMainEnv}\cs{EmphEqMainEnv}\\ +% \SpecialUsageIndex{\endEmphEqMainEnv}\cs{endEmphEqMainEnv} +% \end{codesyntax} +% Although the real work in \pkg{empheq} is done by an environment +% (\env{EmphEqMainEnv}), you cannot use it like that yourself when +% you want to define an \env{empheq}-like environment. Due to +% technical reasons (see~\cite{Ams99}), you have to use a slightly +% different syntax: +% \begin{codesyntax} +% \cs{newenvironment} +% \marg{env_name} \oarg{num} \oarg{default}\\ +% \texttt{~~}\arg{\meta{other commands} \cs{EmpheqMainEnv}}\\ +% \texttt{~~}\arg{\cs{endEmpheqMainEnv}} +% \end{codesyntax} +% In the above environment the \meta{other commands} part must +% contain certain things before it'll work. +% \begin{codesyntax} +% \SpecialKeyFamilyIndex{EmphEqEnv}\keyfam{EmphEqEnv}\\ +% \SpecialKeyFamilyIndex{EmphEqOpt}\keyfam{EmphEqOpt} +% \end{codesyntax} +% Before your homemade environment will work you must set at least +% one key. The key family \keyfam{EmphEqOpt} is for all the markup +% instructions like \key{left} and \key{box}, while +% \keyfam{EmphEqEnv} controls the type of \AmS{} environment. You +% must set the \keyfam{EmphEqEnv} family before \cs{EmhpEqMainEnv} +% else you'll get an error message. +% +% One example could be something like this: +% \begin{verbatim} +% \newenvironment{important}[2][]{% +% \setkeys{EmphEqEnv}{#2}% +% \setkeys{EmphEqOpt}{box=\mybluebox,#1}% +% \EmphEqMainEnv}% +% {\endEmphEqMainEnv} +% \end{verbatim} +% Thus +% \begin{verbatim} +% \begin{important}{gather} +% a = b + c +d \\ e = f +% \end{important} +% \end{verbatim} +% produces +% \begin{important}{gather} +% a = b + c +d \\ e = f +% \end{important} +% while +% \begin{verbatim} +% \begin{important}[left={A=B \Rightarrow \empheqlbrace}]{alignat=2} +% a &= b &\quad c &= d \\ +% \text{this} &= \text{that} &\quad \mathit{fish}&\neq fish +% \end{important} +% \end{verbatim} +% produces +% \begin{important}[left={A=B \Rightarrow \empheqlbrace}]{alignat=2} +% a &= b &\quad c &= d \\ +% \text{this} &= \text{that} &\quad \mathit{fish}&\neq fish +% \end{important} +% +% +% \subsection{Creating fancy boxes}\label{stunning} +% +% As a final example I will show you how to create complicated +% displays involving (vertically) asymmetrical boxes like +% \cs{shadowbox*}. In order to get the correct output, the contents +% of the box must be placed on the baseline as in \fbox{\cs{fbox}}. +% In this example we want to put a set of equations into a bright +% yellow box and then add another box with some explanatory text at +% the top of the yellow box making them overlap. +% +% First we define the colors used and allocate the boxes. We could +% probably use scratch boxes, but this is safer. +% \begin{verbatim} +% \definecolor{shadecolor}{cmyk}{0,0,0.41,0} +% \definecolor{light-blue}{cmyk}{0.25,0,0,0} +% \newsavebox{\mysaveboxM} % M for math +% \newsavebox{\mysaveboxT} % T for text +% \end{verbatim} +% Save the display body in \cs{mysaveboxM} and the text argument in +% \cs{mysaveboxT}. +% \begin{verbatim} +% \newcommand*\Garybox[2][Example]{% +% \sbox{\mysaveboxM}{#2}% +% \sbox{\mysaveboxT}{\fcolorbox{black}{light-blue}{#1}}% +% \end{verbatim} +% Then typeset the math display in a \cs{parbox} where we control +% the height and save it in \cs{mysaveboxM}. +% \begin{verbatim} +% \sbox{\mysaveboxM}{% +% \parbox[b][\ht\mysaveboxM+.5\ht\mysaveboxT+.5\dp\mysaveboxT][b]{% +% \wd\mysaveboxM}{#2}% +% }% +% \end{verbatim} +% We put it into the colored box with the desired width. +% \begin{verbatim} +% \sbox{\mysaveboxM}{% +% \fcolorbox{black}{shadecolor}{% +% \makebox[\linewidth-10em]{\usebox{\mysaveboxM}}% +% }% +% }% +% \end{verbatim} +% Then finally we get to the real typesetting. We just insert the +% math display and then make a box of zero width right next to it. +% In that box we lift the text argument and center it at the top of +% the display. +% \begin{verbatim} +% \usebox{\mysaveboxM}% +% \makebox[0pt][r]{% +% \makebox[\wd\mysaveboxM][c]{% +% \raisebox{\ht\mysaveboxM-0.5\ht\mysaveboxT +% +0.5\dp\mysaveboxT-0.5\fboxrule}{\usebox{\mysaveboxT}}% +% }% +% }% +% } +% \end{verbatim} +% Let's see what it looks like. +% \begin{verbatim} +% \begin{empheq}[box=\Garybox]{align} +% \sum \mathbf{F} &= \mathbf{0} \\ +% \sum F_{x} \,\mathbf{i} + \sum F_{y} \,\mathbf{j} +% + \sum F_{z} \,\mathbf{k} &= \mathbf{0} \\ +% \sum F_{x} &= 0 \\ \sum F_{y} &= 0 \\ \sum F_{z} &= 0 +% \end{empheq} +% \end{verbatim} +% \begin{subequations} +% \begin{empheq}[box=\Garybox]{align} +% \sum \mathbf{F} &= \mathbf{0} \\ +% \sum F_{x} \,\mathbf{i} + \sum F_{y} \,\mathbf{j} + \sum F_{z} +% \,\mathbf{k} &= \mathbf{0}\\ +% \sum F_{x} &= 0 \\ \sum F_{y} &= 0 \\ \sum F_{z} &= 0 +% \end{empheq} +% If we use the optional argument of \cs{Garybox} we have to enclose +% the entire argument of \key{box} in braces because we're in +% \env{empheq}'s optional argument (as described in \cite[page +% 167]{Lamp94}): +% \begin{verbatim} +% \begin{empheq}[box={\Garybox[Same old example again]}]{align} +% a&=b\\ +% E&=mc^2 + \int_a^a x\, dx +% \end{empheq} +% \end{verbatim} +% \begin{empheq}[box={\Garybox[Same old example again]}]{align} +% a&=b\\ +% E&=mc^2 + \int_a^a x\, dx +% \end{empheq} +% \end{subequations} +% +% +% +% +% \section{Contact information} +% +% Should you have any feature request, suggestions, or bug reports +% then feel free to contact me at +% \begin{quote} +% \email{moho01ab@student.cbs.dk} +% \end{quote} +% Please put `empheq' in the subject line. +% +% \subsection*{Contributors} +% +% \begin{itemize} +% \item In November 2002 Lars Madsen (\email{daleif@imf.au.dk}) +% asked for some features that wasn't readily available with +% \pkg{amsmath} or any other package. This was the start of +% \pkg{empheq}. +% +% \item Gary Gray (\email{gray@engr.psu.edu}) gave me some bug +% reports on the old version (v0.7) which convinced me to rewrite +% the package completely. The \cs{Garybox} example is inspired by +% a wish from Gary. +% +% \item Uwe Siart (\email{uwe.siart@tum.de}) has been a thorough +% beta-tester on v1.00 of the package. +% +% \item Bernard Alfonsi (\email{alfonsi@math.u-psud.fr}) reported +% a problem with the \opt{ntheorem} option. It turned out to be a +% bug in the \pkg{ntheorem} package itself but it's fixed in the +% option. +% +% \item I have received reports on weird behavior from +% \pkg{empheq} when used with the \pkg{color} package on some +% dvi-viewers, which is caused by the lack of color support in +% those dvi-viewers. Both Andrew B.~Collier (\email{colliera@ukzn.ac.za}) +% and Andr\'e M.~de Roos (\email{aroos@science.uva.nl}) have +% notified me of this. The solution is to either upgrade you +% dvi-viewer if possible or convert the document in question to +% PDF or PS. +% \end{itemize} +% Thank you all. +% +% +% \begin{thebibliography}{99} +% \bibitem{Lamp94} +% Leslie Lamport, +% \emph{LaTeX User's Guide and Reference Manual}, 2nd edition, +% Addison-Wesley, Reading, Massachusetts, +% 1994. +% \bibitem{Goos-etal94} +% Michel Goossens, Frank Mittelbach, and Alexander Samarin, +% \emph{The \LaTeX\ Companion}, +% Addison-Wesley, Reading, Massachusetts, +% 1994. +% \bibitem{Knut86} +% Donald Ervin Knuth, +% \emph{The \TeX book}, +% Addison-Wesley, Reading, Mas\-sa\-chu\-setts, +% 1986. +% \bibitem{Ams99} +% American Mathematical Society and Michael Downes, +% \emph{Technical notes on the \pkg{amsmath} package} Version 2.0, +% 1999/10/29. +% (Available from CTAN as file \texttt{technote.tex}.) +% \bibitem{Ams00} +% Frank Mittelbach, Rainer Sch\"opf, Michael Downes, and David M.~Jones, +% \emph{The \pkg{amsmath} package} Version 2.13, +% 2000/07/18. +% (Available from CTAN as file \texttt{amsmath.dtx}.) +% +% \changes{v1.05b}{2004/02/18}{Added \pkg{fancybox} and +% \pkg{ntheorem} to the \refname} +% \bibitem{fancybox} +% Timothy Van Zandt, +% \emph{The \pkg{fancybox} package} Version 1.3, +% 2000/09/19 +% (Available from CTAN as file \texttt{fancybox.sty}.) +% +% \bibitem{Raht03} +% Sebastian Rahtz, +% \emph{Hypertext marks in \LaTeX} Version v6.74m, +% 2003/11/30. +% (Available from \url{http://www.tug.org/applications/hyperref} as file +% \texttt{hyperref.dtx}.) +% +% \bibitem{Carl99} +% David Carlisle, +% \emph{The \pkg{keyval} Package}, +% Version 1.13, 1999/03/16. +% (Available from CTAN as file \texttt{keyval.dtx}.) +% +% \changes{v1.06}{2004/03/13}{Added \pkg{calc} to the \refname} +% \bibitem{Thorup:calc:1998} +% Kresten~Krab Thorup, Frank Jensen, and Chris Rowley. +% \emph{The {\pkg{calc}} package}, Version 4.1b, 1998/07/07, +% (Available from CTAN as file \texttt{calc.dtx}.) +% +% \bibitem{ntheorem} +% Wolfgang May and Andreas Schlechte, +% \emph{The \pkg{ntheorem} package} Version 1.203, +% 2002/01/07, +% (Available from CTAN as file \texttt{ntheorem.dtx}.) +% +% \changes{v2.10}{2004/07/26}{Added \pkg{showkeys} to the \refname} +% \bibitem{Carlisle:showkeys:1997} +% David Carlisle. \emph{The {\pkg{showkeys}} package}, v3.12, +% 1997/06/12, (Available from CTAN as file \texttt{showkeys.dtx}.) +% +% \end{thebibliography} +% +% \StopEventually{} +% +% \EmphEqpart{Implementation} +% +% \section{Requirements, Options, and Strategy} +% Lets start the package. We'll need the tools from \pkg{mhsetup}. +% \begin{macrocode} +%<*empheq> +% \end{macrocode} +% \begin{macrocode} +\RequirePackage{mhsetup}[2004/10/10] +\MHInternalSyntaxOn +% \end{macrocode} +% +% +% \subsection{Requirements, Options, and Allocation} +% +% The \opt{overload} option allows the user to type +% \begin{verbatim} +% \begin{gather}[box=\fbox] +% a = b +% \end{gather} +% \end{verbatim} +% when they really mean +% \begin{verbatim} +% \begin{empheq}{gather}[box=\fbox] +% a = b +% \end{empheq} +% \end{verbatim} +% \begin{macrocode} +\MH_new_boolean:n {overload_ams} +\DeclareOption{overload}{ + \MH_set_boolean_T:n {overload_ams} +} +\MH_new_boolean:n {overload_amsII} +\DeclareOption{overload2}{ + \MH_set_boolean_T:n {overload_ams} + \MH_set_boolean_T:n {overload_amsII} +} +% \end{macrocode} +% Old crappy \env{multline} interface or the new dazzling? +% \begin{macrocode} +\MH_new_boolean:n {good_mult} +\DeclareOption{oldmultline}{\MH_set_boolean_F:n {good_mult}} +\DeclareOption{newmultline}{\MH_set_boolean_T:n {good_mult}} +% \end{macrocode} +% +% +% Load the \pkg{ntheorem} support file. +% \begin{macrocode} +\DeclareOption{ntheorem}{\AtEndOfPackage{\input{ntheorem.fix}}} +% \end{macrocode} +% Pass other options to \pkg{mathtools}. +% \begin{macrocode} +\DeclareOption*{ + \PassOptionsToPackage{\CurrentOption}{mathtools} +} +\ExecuteOptions{newmultline} +\ProcessOptions\relax +% \end{macrocode} +% The name of the game is \pkg{amsmath} so we'll need that of +% course. Since v2.10 that is now taken care of in the +% \pkg{mathtools} package which'll pass on the options to +% \pkg{amsmath}. +% \begin{macrocode} +\MHInternalSyntaxOff +\RequirePackage{mathtools}[2004/10/10] +% \end{macrocode} +% Activate the internal syntax. +% \begin{macrocode} +\MHInternalSyntaxOn +\AtEndOfPackage{\MHInternalSyntaxOff} +% \end{macrocode} +% \changes{v2.00}{2004/04/14}{Changed description of naming +% conventions. Altered \emph{all} private macros; this is not +% mentioned at each macro as this would just be too troublesome} +% +% \begin{macro}{\l_EQ_equationtype_int} +% \begin{macro}{\l_EQ_alignmentmode_int} +% I'll use the following numbering scheme for the equation types, +% and store the value in \cs{l_EQ_equationtype_int}: +% \begin{multicols}{2} +% \begin{enumerate}\setlength{\itemsep}{0pt} +% \item align +% \item align* +% \item gather +% \item gather* +% \item flalign +% \item flalign* +% \item alignat +% \item alignat* +% \end{enumerate} +% \end{multicols} +% As you notice \env{equation} and \env{equation*} are missing. This +% is because \env{gather} and \env{gather*} work the same way, only +% they are `nicer'. Cuts down on the amount of code as well. I will +% add an alias so that a user can use the key \key{equation}, but +% then \key{gather} will kick in instead behind the scenes. Also the +% \env{multline} environments are missing here, but again it's +% because I'm faking it. See \S~\vref{sec:flalign+multline} for +% further details. The value $0$ isn't used for any of the +% environments and thus serves as a checkpoint (see +% page~\pageref{ZeroCheckpoint}). +% +% Similarly I'll use the counter \cs{l_EQ_alignmentmode_int} to +% store the standard options for placement of math displays and +% equation numbering. +% \begin{multicols}{2} +% \begin{enumerate}\setlength{\itemsep}{0pt} +% \item reqno +% \item leqno +% \item fleqn, reqno +% \item fleqn, leqno +% \end{enumerate} +% \end{multicols} +% +% \begin{macrocode} +\newcount\l_EQ_equationtype_int +\newcount\l_EQ_alignmentmode_int +\if@fleqn + \iftagsleft@ + \l_EQ_alignmentmode_int=4 + \else: + \l_EQ_alignmentmode_int=\thr@@ + \fi: +\else: + \iftagsleft@ + \l_EQ_alignmentmode_int=\tw@ + \else: + \l_EQ_alignmentmode_int=\@ne + \fi: +\fi: +% \end{macrocode} +% \end{macro} +% \end{macro} +% \begin{macro}{\l_EQ_totalwidth_dim} +% \begin{macro}{\l_EQ_displaywidth_dim} +% \begin{macro}{\l_EQ_temp_linewidth_dim} +% \begin{macro}{\EmphEqdelimitershortfall} +% \begin{macro}{\EmphEqdelimiterfactor} +% \begin{macro}{\g_EQ_toptag_height_dim} +% \begin{macro}{\g_EQ_bottomtag_depth_dim} +% \begin{macro}{\g_EQ_toprow_height_dim} +% \begin{macro}{\g_EQ_bottomrow_depth_dim} +% \begin{macro}{\g_EQ_widesttag_dim} +% Some lengths we'll need. Could possibly be scratch registers but we +% have to make global assignments so that road is a little +% dangerous. +% \begin{macrocode} +\newdimen\l_EQ_totalwidth_dim +\newdimen\l_EQ_displaywidth_dim +% \end{macrocode} +% Just to make it accessible. +% \begin{macrocode} +\def\EmphEqdisplaywidth{\l_EQ_displaywidth_dim} +\newdimen\l_EQ_temp_linewidth_dim +\newdimen\EmphEqdelimitershortfall +\newcount\EmphEqdelimiterfactor +\EmphEqdelimiterfactor950 +\EmphEqdelimitershortfall\p@ +\newdimen\g_EQ_toptag_height_dim +\newdimen\g_EQ_bottomtag_depth_dim +\newdimen\g_EQ_toprow_height_dim +\newdimen\g_EQ_bottomrow_depth_dim +\newdimen\g_EQ_widesttag_dim +\def\EmphEqtagwidth{\g_EQ_widesttag_dim} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\EQ_outerbox:} +% \begin{macro}{\EQ_innerbox:} +% \begin{macro}{\EQ_left_side:} +% \begin{macro}{\EQ_right_side:} +% The two boxes and the material on either side of the math display. +% \begin{macrocode} +\def\EQ_outerbox:{} +\def\EQ_innerbox:{} +\def\EQ_left_side:{} +\def\EQ_right_side:{} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \subsection{Strategy} +% +% In non-\mode{fleqn} math displays are centered---even when having +% tags. However this can look rather appalling when either the tag +% or the math display are very wide like in the following example. +% \begin{center} +% \makebox[\linewidth][s]{\mbox{}\hfill \mbox{$\displaystyle +% a+b+c+d+e+f+g+h+i+j+k+l+m+n+o$} \hfill\mbox{} \llap{(wide tag)}} +% \end{center} +% Not exactly pleasing to look at. \pkg{amsmath} takes care to do +% this adjustment for us, so the user instead obtains the far better +% \begin{gather*} +% a+b+c+d+e+f+g+h+i+j+k+l+m+n+o \tag{wide tag} +% \end{gather*} +% So \pkg{amsmath} handles this quite well. That's good. It looks +% like \pkg{amsmath} has an internal threshold that matches the +% width of the math display against the width of the tags. But what +% if we have a multiple line display and one of the lines causes an +% adjustment to kick in while the others don't need it? Then we +% cannot keep track of the complete display anymore. Furthermore we +% may want to add material on either side of the math display making +% the whole thing even more complicated, if not impossible to do +% without some sort of different approach. +% +% Luckily we have such an approach. The idea that comes to mind is +% to see if one can typeset the labels and the math displays +% \emph{separately}, store them in separate boxes and then put them +% back together again afterwards. Is this really possible? Yes. +% Come, I'll show you. +% +% \subsection{The Main Environment} +% \begin{macro}{\EQ_mathdisplay_box} +% \begin{macro}{\EmphEqdisplayheight} +% \begin{macro}{\EmphEqdisplaydepth} +% \begin{macro}{\EQ_tag_box} +% Okay, we'll start by allocating two box registers. +% \begin{macrocode} +\newsavebox\EQ_mathdisplay_box +\def\EmphEqdisplayheight{\ht\EQ_mathdisplay_box} +\def\EmphEqdisplaydepth{\dp\EQ_mathdisplay_box} +\newsavebox\EQ_tag_box +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\EQ_complete_mathdisplay:} +% \begin{macro}{\EQ_getbody:n} +% \begin{environment}{EmphEqMainEnv} +% The \env{EmphEqMainEnv} is (as the name implies) the main +% environment. I decided to go with the environment form because +% that's what \pkg{amsmath} users are accustomed to. But the code +% will require the contents of the environment to be handled as an +% argument to a command, so we use \cs{collect@body} from +% \pkg{amsmath} itself to collect it. +% \begin{macrocode} +\def\EQ_complete_mathdisplay:{} +\def\EQ_getbody:n #1{% + \def\EQ_complete_mathdisplay:{}\def\EQ_mathbody:{#1}} +\newenvironment{EmphEqMainEnv}{\collect@body\EQ_getbody:n}{% +% \end{macrocode} +% If the user didn't specify the mandatory argument we will catch it +% because \cs{l_EQ_equationtype_int} is zero. An error is +% issued\label{ZeroCheckpoint}. +% \begin{macrocode} + \if_num:w \l_EQ_equationtype_int=\z@ %ZeroCheckpoint + \EQ_upgrade_error: + \else: +% \end{macrocode} +% Those that read the manual get the reward here: The package will +% actually work! +% \begin{macrocode} + \EQ_post_process: + \ignorespacesafterend + \fi:} +% \end{macrocode} +% \end{environment} +% \end{macro} +% \end{macro} +% \subsection{Post Processing} +% \begin{macro}{\EQ_post_process:} +% I know: it almost looked easy for a while didn't it? Sadly the +% post-processing step of the code is also by far the most +% complicated. +% \begin{macrocode} +\def\EQ_post_process:{% +% \end{macrocode} +% First a hook where we initialize a few things like storing the +% line width for later manipulation. Also we want to measure the +% height of the top row and the depth of the bottom row for best +% possible placement of the math display and the boxes around it +% (same with the tags). Those four dimensions are globally set +% during the code, hence this assignment. Most other stuff is local. +% \begin{macrocode} + \EQ_initialize: +% \end{macrocode} +% Then we proceed by completing the input. We store it in the +% control sequence \cs{EQ_complete_mathdisplay}. +% \cs{EQ_begin_equation:} adds the start of the environment and +% \cs{EQ_end_equation:} adds the corresponding end. +% \begin{macrocode} + \EQ_begin_equation: +% \end{macrocode} +% In case we face a \env{multline} we add what's necessary. +% \begin{macrocode} + \MH_if_boolean:nT {outer_mult}{ + \setkeys{\MT_options_name:}{ + firstline-afterskip=0pt, + lastline-preskip=0pt, + multlined-width=0pt, + } + \ifodd \l_EQ_alignmentmode_int + \setkeys{\MT_options_name:}{multlined-pos=b} + \else: + \setkeys{\MT_options_name:}{multlined-pos=t} + \fi: + \g@addto@macro\EQ_complete_mathdisplay:{ + \begin{MTmultlined}\relax} + } + \g@addto@macro\EQ_complete_mathdisplay:\EQ_mathbody: + \MH_if_boolean:nT {outer_mult}{ + \g@addto@macro\EQ_complete_mathdisplay:{\end{MTmultlined}} + } + \EQ_end_equation: +% \end{macrocode} +% Save the value of the \pkg{hyperref} link counter +% \cs{Hy@linkcounter}. +% \begin{macrocode} + \edef\EQ_hyperref_link_fint{\number\Hy@linkcounter} +% \end{macrocode} +% Firstly we call \cs{EQ_typeset_tags:} which suppresses all +% output from the equations with the exception of the \cs{tag}'s. +% This also allows us to find the widest tag which we'll need for +% the environments that set's the math displays flush to the +% margins, namely the \env{flalign} family. We save the counters +% first though. As an extra treat we're also able to measure the +% height and depth of the tags and the math display. +% \begin{macrocode} + \savecounters@ + \EQ_typeset_tags: +% \end{macrocode} +% \changes{v1.05d}{2004/02/26}{Removed one instance of +% \cs{EQ_typeset_display:}} +% Then find the widest tag. In an earlier implementation it was +% necessary to typeset the display twice---a very costly procedure! +% Now we save roughly 2120 lines of output from \cs{tracingall} on a +% simple \env{gather} and 2600 lines with \env{align}. That's a +% little more than 21\% saved\ldots +% \changes{v2.10}{2004/07/26}{Removed \cs{find_widesttag:}} +% \changes{v2.10}{2004/07/26}{Added check for equation number to +% make sure the labelling/printing mechanism of \pkg{mathtools} work +% properly} +% Then we restore the counters and measure the extra material. +% Save the value of the equation counter for later in case the +% special equation numbering scheme from \pkg{mathtools} is in +% effect. +% \begin{macrocode} + \edef\l_EQ_equation_fint{\number\c@equation} + \restorecounters@ +% \end{macrocode} +% Restore the value of the \pkg{hyperref} link counter +% \cs{Hy@linkcounter}. +% \begin{macrocode} + \Hy@linkcounter=\EQ_hyperref_link_fint + \settowidth\l_EQ_totalwidth_dim{% + $\EQ_left_side:\EQ_innerbox:{}\EQ_right_side:$}% +% \end{macrocode} +% Then call the appropriate \cs{EQ_modify_linewidth_}\meta{num}\texttt{:} +% where \meta{num} is taken from the numbering scheme shown earlier. +% \begin{macrocode} + \MH_if_boolean:nTF {outer_mult} + { \def\EQ_next:{_mult} } + { \def\EQ_next:{} } + \@nameuse{EQ_modify_linewidth_ + \romannumeral\l_EQ_equationtype_int\EQ_next: :}% +% \end{macrocode} +% We can then typeset the display knowing that all modifications +% have been made correctly. \cs{EQ_typeset_display:} gobbles the +% \cs{tag}'s, which in turn is equivalent to setting the display +% centered in non-\mode{fleqn} mode. +% \begin{macrocode} + \EQ_typeset_display: +% \end{macrocode} +% Call the appropriate \cs{find_displaywidth_}\meta{num}\texttt{:} +% which extracts the display width (\cs{l_EQ_displaywidth_dim}). +% \begin{macrocode} + \@nameuse{find_displaywidth_ + \romannumeral\l_EQ_equationtype_int\EQ_next: :} + \MH_addtolength:dn + \l_EQ_totalwidth_dim{\l_EQ_displaywidth_dim} +% \end{macrocode} +% We save the math display in a box of the correct size. +% \begin{macrocode} + \savebox\EQ_mathdisplay_box[\l_EQ_totalwidth_dim][c]{% + $\EQ_left_side: + \EQ_innerbox:{% + \if_case:w \l_EQ_alignmentmode_int\or: +% \end{macrocode} +% If the equation is centered we make the box centered +% \begin{macrocode} + \makebox[\l_EQ_displaywidth_dim][c] + {\usebox{\EQ_mathdisplay_box}}% + \or: + \makebox[\l_EQ_displaywidth_dim][c] + {\usebox{\EQ_mathdisplay_box}}% + \or: +% \end{macrocode} +% Else we set it in a left aligned box and take care of the +% \cs{@mathmargin} unless we're in \env{flalign} or \env{flalign*}. +% \begin{macrocode} + \makebox[\l_EQ_displaywidth_dim][l]{% + \if_num:w \l_EQ_equationtype_int=5 \else: + \if_num:w \l_EQ_equationtype_int=6 \else: + \kern-\@mathmargin + \fi: + \fi: + \usebox{\EQ_mathdisplay_box}}% + \or: + \makebox[\l_EQ_displaywidth_dim][l]{% + \if_num:w \l_EQ_equationtype_int=5 \else: + \if_num:w \l_EQ_equationtype_int=6 \else: + \kern-\@mathmargin + \fi: + \fi: + \usebox{\EQ_mathdisplay_box}}% + \fi:}% + \EQ_right_side:$}% +% \end{macrocode} +% Then we're ready for typesetting. We just use an ordinary +% |\begin{equation*}| | ... | |\end{equation*}| construction. +% \changes{v2.00}{2004/04/14}{Used a saved definition of +% \env{equation*} instead to allow overloading} +% With v2.00 this changed to using a copy of the original +% \env{equation*} environment. All this because of the +% \opt{overload} option. +% \begin{macrocode} + \begin{AmSequation*} + \@nameuse{EQ_place_display_ + \romannumeral\l_EQ_equationtype_int\EQ_next: :} +% \end{macrocode} +% \cs{tag} must have a non-zero width argument in order to function +% properly, so we make sure there is a tag before we try to typeset +% it. Also make sure that the boolean |show_manual_tags| is true +% just for this tag. +% \begin{macrocode} + \if_dim:w \g_EQ_widesttag_dim>\z@ + \MH_set_boolean_T:n {show_manual_tags} +% \end{macrocode} +% Set the tag in a left aligned box when in \mode{leqno} mode and +% right aligned when in \mode{reqno} mode. +% \begin{macrocode} + \if_case:w \l_EQ_alignmentmode_int + \or: \EQ_place_tag:N r %#1 + \or: \EQ_place_tag:N l %#2 + \or: \EQ_place_tag:N r %#3 + \or: \EQ_place_tag:N l %#4 + \fi: + \fi: + \end{AmSequation*} +% \end{macrocode} +% \changes{v2.11}{2004/08/03}{Use raw \TeX{} commands to speed it up} +% Restore the equation counter. +% \begin{macrocode} + \global\c@equation=\l_EQ_equation_fint\relax +} +% \end{macrocode} +% \end{macro} +% +% \subsubsection{Initializing the Equations} +% +% \begin{macro}{\EQ_initialize:} +% We save all the initializations in this hook: +% \begin{macrocode} +\def\EQ_initialize:{% + \m@th +% \end{macrocode} +% More support for \pkg{ntheorem}. We use special versions of +% the tag setting commands in order to produce the correct result. +% For instance in \mode{leqno} mode you would still want the end of +% theorem symbol at the bottom of the math display. +% \begin{macrocode} + \MH_let:NwN\SetTagPlusEndMark\EQ_tag_plus_endmark: + \MH_let:NwN\SetOnlyEndMark\EQ_only_endmark: + \l_EQ_temp_linewidth_dim\linewidth + \g_EQ_toprow_height_dim\z@ + \g_EQ_bottomrow_depth_dim\z@ + \g_EQ_toptag_height_dim\z@ + \g_EQ_bottomtag_depth_dim\z@ + \g_EQ_widesttag_dim\z@ +% \end{macrocode} +% \changes{v2.11}{2004/08/03}{Added a \cs{g_EQ_latest_nonzerodepth_row_fint}} +% \begin{macrocode} + \xdef\g_EQ_latest_nonzerodepth_row_fint{\z@} + \edef\EQ_restore_tex_delimiter:{% + \delimiterfactor\the\delimiterfactor + \delimitershortfall\the\delimitershortfall\relax}% + \g@addto@macro\EQ_complete_mathdisplay: + \EQ_restore_tex_delimiter: + \delimitershortfall\EmphEqdelimitershortfall + \delimiterfactor\EmphEqdelimiterfactor +% \end{macrocode} +% Disable \cs{intertext} and issue an error message. Using the +% normal error message for an invalid \cs{intertext} would be less +% than great because it would say +% \begin{verbatim} +% ! Package amsmath Error: Invalid use of \intertext. +% +% See the amsmath package documentation for explanation. +% Type H <return> for immediate help. +% ... +% \end{verbatim} +% That's not good enough, so we redefine things a bit. In +% \pkg{amsmath} the command \cs{intertext@} is called inside the +% math environments and defines \cs{intertext}. We hook into this. +% \begin{macrocode} + \MH_let:NwN\intertext@\EQ_intertext: + \EQ_displaybreak:} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\EQ_intertext:} +% Then we issue a suitable error message. +% \begin{macrocode} +\def\EQ_intertext:{% + \def\intertext##1{\PackageError{empheq}{% + You~cannot~use~\string\intertext\space inside~the~`empheq' + \MessageBreak + environment,~as~`empheq'~creates~an~unbreakable~box}\@eha}} +\def\EQ_displaybreak:{% + \def\dspbrk@[##1]{\PackageWarning{empheq}{% + You~cannot~use~\string\displaybreak\space inside~the~`empheq'% + \MessageBreak + environment,~as~`empheq'~creates~an~unbreakable~box.}}} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\EQ_new_equationtype:nnn} +% \begin{macro}{\EQ_new_equationtype_arg:nnn} +% We have to inform \env{EmphEqMainEnv} which equation type we're +% using, so we define an interface for that. +% \begin{macrocode} +\def\EQ_new_equationtype:nnn #1#2#3{% + \define@key{#1}{#2}[true]{% + \l_EQ_equationtype_int=#3\relax + \def\EQ_begin_equation: + {\g@addto@macro{\EQ_complete_mathdisplay:}{\begin{#2}}}% + \def\EQ_end_equation: + {\g@addto@macro{\EQ_complete_mathdisplay:}{\end{#2}}}}} +\def\EQ_new_equationtype_arg:nnn #1#2#3{% + \define@key{#1}{#2}{% + \l_EQ_equationtype_int=#3\relax + \def\EQ_begin_equation: + {\g@addto@macro{\EQ_complete_mathdisplay:}{\begin{#2}{##1}}}% + \def\EQ_end_equation: + {\g@addto@macro{\EQ_complete_mathdisplay:}{\end{#2}}}}} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \subsubsection{Separating Tags and Display} +% +% \begin{macro}{\EQ_typeset_tags:} +% Typesetting the tags without the display. +% \begin{macrocode} +\def\EQ_typeset_tags:{% + \sbox\EQ_tag_box{% + \parbox{.5\maxdimen}{% + \hbadness\@M +% \end{macrocode} +% Make sure all skips are zero ands support \pkg{ntheorem}. +% \changes{v1.05a}{2004/02/17}{Forgot to support \pkg{ntheorem} in +% both \cs{EQ_typeset_tags:} and \cs{EQ_typeset_display:}.} +% \begin{macrocode} + \EQ_prevent_vertical_space: +% \end{macrocode} +% Support for \pkg{ntheorem}. This package patches \cs{endgather} +% and \cs{endalign} with the commands \cs{TagsPlusEndmarks} and +% \cs{RestoreTags} but we do not want them disturbing our output so +% we disable them when typesetting the display. +% \begin{macrocode} + \EQ_typeset_tags_hook: +% \end{macrocode} +% Then use our own versions of \cs{set@gather@field} and +% \cs{set@field}. +% \begin{macrocode} + \MH_let:NwN\set@gather@field\EQ_set_gather_field: + \MH_let:NwN\set@field\EQ_set_align_field: +% \end{macrocode} +% Next two lines are for measuring of the first and last row of a +% display of the \env{align}, \env{alignat} or \env{flalign} family. +% \begin{macrocode} + \MH_set_boolean_T:n {continue_measuring} + \global\g_EQ_temprow_int\m@ne + \MH_let:NwN \EQ_saved_maketag:n \maketag@@@ + \def\maketag@@@##1{ + \EQ_maketag:Nn \EQ_saved_maketag:n {##1}} +% \end{macrocode} +% Then typeset the display. +% \begin{macrocode} + \EQ_complete_mathdisplay:}}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\EQ_predisplay_adjustment:} +% \changes{v1.05c}{2004/02/25}{Added \cs{EQ_predisplay_adjustment:}} +% +% \changes{v2.00}{2004/04/14}{Added a missing \cs{normallineskip} in +% case of extremely big tag height} +% +% For adjusting vertical spacing in the display. +% \begin{macrocode} +\def\EQ_predisplay_adjustment:{% + \if_dim:w \g_EQ_toprow_height_dim<\baselineskip + \vskip\g_EQ_toprow_height_dim + \vskip-\baselineskip + \else: + \vskip-\normallineskip + \fi: + \if_dim:w \g_EQ_toptag_height_dim>\g_EQ_toprow_height_dim + \if_dim:w \g_EQ_toptag_height_dim>\baselineskip + \vskip-\g_EQ_toptag_height_dim + \vskip\baselineskip + \vskip-\normallineskip + \fi: + \fi:} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\EQ_postdisplay_adjustment:} +% \changes{v1.05c}{2004/02/25}{Added \cs{EQ_postdisplay_adjustment:}} +% Name says it all. +% \begin{macrocode} +\def\EQ_postdisplay_adjustment:{% + \if_dim:w \g_EQ_bottomrow_depth_dim<\dp\strutbox + \vskip\g_EQ_bottomrow_depth_dim + \vskip-\dp\strutbox + \fi: + \if_dim:w \g_EQ_bottomtag_depth_dim>\g_EQ_bottomrow_depth_dim + \if_dim:w \g_EQ_bottomtag_depth_dim>\dp\strutbox + \vskip-\g_EQ_bottomtag_depth_dim + \vskip\dp\strutbox + \fi: + \fi:} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\EQ_typeset_display:} +% \changes{v1.05c}{2004/02/25}{Now takes two arguments: Either both +% empty or \cs{EQ_predisplay_adjustment:} \& +% \cs{EQ_postdisplay_adjustment:}} +% \changes{v1.05d}{2004/02/26}{Changed again. Uses only +% \cs{EQ_predisplay_adjustment:} \& \cs{EQ_postdisplay_adjustment:}} +% We typeset the display without the tags and save it in a box. +% \begin{macrocode} +\def\EQ_typeset_display:{% + \sbox\EQ_mathdisplay_box{% + \parbox{\l_EQ_temp_linewidth_dim}{% +% \end{macrocode} +% We adjust the vertical spacing if needed: +% \begin{macrocode} + \EQ_predisplay_adjustment: + \EQ_prevent_vertical_space: +% \end{macrocode} +% Support for \pkg{ntheorem}. This package patches \cs{endgather} +% and \cs{endalign} with the commands \cs{TagsPlusEndmarks} and +% \cs{RestoreTags} but we do not want them disturbing our output so +% we disable them when typesetting the display. +% \begin{macrocode} + \EQ_typeset_display_hook: +% \end{macrocode} +% Instead of gobbling the tags it's better to use \cs{phantom} since +% a tall tag will ruin the vertical spacing. We use a special +% version of \cs{phantom} to help us with other things as well. +% \begin{macrocode} + \def\maketag@@@##1{\EQ_maketag:Nn \vphantom{##1}}% + \EQ_complete_mathdisplay: +% \end{macrocode} +% More space adjustment. +% \begin{macrocode} + \EQ_postdisplay_adjustment:}}} +% \end{macrocode} +% \end{macro} +% We need a few little helpers: +% \begin{macro}{\EQ_prevent_vertical_space:} +% \changes{v2.00}{2004/04/14}{Used \cs{nointerlineskip} instead} +% As we typeset the math display inside a \cs{parbox} the math +% environment will add \cs{abovedisplayskip} at the top and +% \cs{belowdisplayskip} at the bottom. Also we suppress interline +% skip with \cs{nointerlineskip}. +% \begin{macrocode} +\def\EQ_prevent_vertical_space:{% + \nointerlineskip + \abovedisplayskip\z@ \belowdisplayskip\z@\relax} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\EQ_maketag:Nn} +% \changes{v1.05d}{2004/02/26}{Changed name from +% \cs{EmphEqphantom} to \cs{EmphEqMaketag}} +% This takes care of two things: We need to store the height of the +% top tag and the depth of the bottom tag for later, but we also +% need to use a \cs{vphantom} of the tag as it may be taller than +% the line of math it is attached to (say, if you are using node +% connectors from \pkg{pstricks} or some other weird stuff). +% \begin{macrocode} +\def\EQ_maketag:Nn #1#2{% + \setboxz@h{#2}% + \if_num:w \row@=\@ne + \global \g_EQ_toptag_height_dim = \ht\z@ + \fi: +% \end{macrocode} +% Similarly the depth of the last row is determined by measuring the +% depth of box zero for each row and then using the last of the +% values. +% \begin{macrocode} + \global \g_EQ_bottomtag_depth_dim=\dp\z@ +% \end{macrocode} +% \changes{v2.11}{2004/08/03}{Added a check for being in the last row.} +% Save the row number for later as the \opt{ntheorem} option will need +% it. +% \begin{macrocode} + \xdef\g_EQ_latest_nonzerodepth_row_fint{\number\row@} + \@tempdima=\wd\z@ + \if_dim:w \@tempdima > \g_EQ_widesttag_dim + \global \g_EQ_widesttag_dim = \@tempdima + \fi: + #1{#2}% +} +% \end{macrocode} +% \end{macro} +% +% \subsubsection{Measuring \env{gather}} +% \begin{macro}{\EQ_set_gather_field:} +% Box zero (\cs{z@}) contains the entire line of math in a +% \env{gather}, so instead of typesetting it we typeset the phantom +% of it and call \cs{EQ_measure_gather:}. +% \begin{macrocode} +\def\EQ_set_gather_field:{% + \iftagsleft@ + \global\lineht@\ht\z@ + \else: + \global\lineht@\dp\z@ + \fi: + \kern\eqnshift@ + %\boxz@ % Original amsmath version + \EQ_measure_gather: + \phantom{\boxz@}% + \hfil} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\EQ_measure_gather:} +% Measuring the height of the individual lines in a \env{gather} is +% fairly easy. If \cs{row@} is equal to one, we're in the first +% line, and the height of the top row is simply given by the height +% of box zero. +% \begin{macrocode} +\def\EQ_measure_gather:{% + \if_num:w \row@=\@ne + \g_EQ_toprow_height_dim=\ht\z@ + \fi: +% \end{macrocode} +% Similarly the depth of the last row is determined by measuring the +% depth of box zero for each row and then using the last of the +% values. +% \begin{macrocode} + \g_EQ_bottomrow_depth_dim=\dp\z@ + \global\g_EQ_toprow_height_dim\g_EQ_toprow_height_dim + \global\g_EQ_bottomrow_depth_dim\g_EQ_bottomrow_depth_dim} +% \end{macrocode} +% \end{macro} +% +% \subsubsection{Measuring \env{align}, \env{alignat} and \env{flalign}} +% \begin{macro}{\EQ_set_align_field:} +% Same technique as for \cs{EQ_set_gather_field}. Only this time +% we have to stop the underlying \cs{start@align} from going over +% the measuring phase twice. That's when the conditional +% \bool{continue_measuring} comes into the picture. +% \begin{macrocode} +\def\EQ_set_align_field:{% + \column@plus + \iftagsleft@ + \if_dim:w \ht\z@>\lineht@ + \global\lineht@\ht\z@ + \fi: + \else: + \if_dim:w \dp\z@>\lineht@ + \global\lineht@\dp\z@ + \fi: + \fi: + %\boxz@ % Original amsmath version + \MH_if_boolean:nT {continue_measuring}{ \EQ_measure_align: } + \phantom{\boxz@}} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\EQ_measure_align:} +% We have to measure every single field of the \cs{align@} \ldots\@ +% Oh well, here it comes: +% \begin{macrocode} +\newcount\g_EQ_temprow_int +\MH_new_boolean:n {still_in_samerow} +\MH_new_boolean:n {continue_measuring} +\def\EQ_measure_align:{% + \if_num:w \g_EQ_temprow_int=\row@ + \MH_set_boolean_T:n {still_in_samerow} + \else: + \if_num:w \g_EQ_temprow_int>\row@ + \global\MH_set_boolean_F:n {continue_measuring} + \fi: + \MH_set_boolean_F:n {still_in_samerow} + \global\@tempdimc=\@tempdimb + \global\@tempdimb=\g_EQ_bottomrow_depth_dim + \fi: + \MH_if_boolean:nTF {continue_measuring}{ + \global\g_EQ_temprow_int=\row@ + \@tempcnta=\row@ + \if_num:w \@tempcnta=\z@ + \@tempdima=\g_EQ_toprow_height_dim + \g_EQ_toprow_height_dim=\ht\z@\relax + \if_dim:w \g_EQ_toprow_height_dim<\@tempdima + \g_EQ_toprow_height_dim\@tempdima + \fi: + \fi: + \MH_if_boolean:nTF {still_in_samerow}{ + \@tempdima=\g_EQ_bottomrow_depth_dim + \g_EQ_bottomrow_depth_dim=\dp\z@\relax + \if_dim:w \g_EQ_bottomrow_depth_dim<\@tempdima + \g_EQ_bottomrow_depth_dim\@tempdima + \fi: + }{ + \g_EQ_bottomrow_depth_dim\dp\z@\relax + } + }{ + \global\g_EQ_bottomrow_depth_dim=\@tempdimc + } + \global\g_EQ_toprow_height_dim\g_EQ_toprow_height_dim + \global\g_EQ_bottomrow_depth_dim\g_EQ_bottomrow_depth_dim} +% \end{macrocode} +% \end{macro} +% \subsubsection{Typesetting the Tags} +% \begin{macro}{\EQ_place_tag:N} +% Fool \LaTeX\ into thinking the tag is only as wide as the widest +% tag (remember the real width of the \cs{EQ_tag_box} is +% $0.5$\cs{maxdimen}. +% \begin{macrocode} +\def\EQ_place_tag:N #1{% + \tag*{\makebox[\g_EQ_widesttag_dim][#1]{% + \EQ_vertical_tag_adjustment:n {\usebox{\EQ_tag_box}}}}} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\EQ_vertical_tag_adjustment:n} +% \changes{v2.00}{2004/04/14}{Added a missing \cs{normallineskip} in +% case of extremely big tag height} +% This is a little tricky. We have measured the height of the top +% row and top tag and the depth of the bottom row and bottom tag. +% Now we have to adjust the vertical spacing so it comes out just +% right. Remember we have separated the tags and the math display +% but we would still like to have them line up as they should! We do +% it all inside a group so we can use the scratch dimensions safely. +% \begin{macrocode} +\def\EQ_vertical_tag_adjustment:n #1{{% + \@tempdima\z@\@tempdimb\z@ + \@tempdimc=\dp\strutbox + \if_dim:w \g_EQ_toprow_height_dim<\baselineskip + \MH_setlength:dn + \@tempdima{\g_EQ_toprow_height_dim-\baselineskip} + \else: + \MH_setlength:dn \@tempdima{-\normallineskip} + \fi: + \if_dim:w \g_EQ_toptag_height_dim>\g_EQ_toprow_height_dim + \if_dim:w \g_EQ_toptag_height_dim>\baselineskip + \MH_addtolength:dn \@tempdima + {-\g_EQ_toptag_height_dim+\baselineskip-\normallineskip} + \fi: + \fi: + \if_dim:w \g_EQ_bottomrow_depth_dim<\@tempdimc + \MH_setlength:dn \@tempdimb + {\g_EQ_bottomrow_depth_dim-\@tempdimc} + \fi: +% \end{macrocode} +% \changes{v2.00}{2004/04/14}{Fixed minor bug} +% If the last condition is fulfilled we also need to cancel the +% first condition. +% \begin{macrocode} + \if_dim:w \g_EQ_bottomtag_depth_dim>\g_EQ_bottomrow_depth_dim + \if_dim:w \g_EQ_bottomtag_depth_dim<\@tempdimc + \else: + \MH_addtolength:dn \@tempdimb + {-\g_EQ_bottomtag_depth_dim+\@tempdimc} + \fi: + \fi: + \raisebox{-0.5\@tempdima+0.5\@tempdimb}{#1}}}% +% \end{macrocode} +% \end{macro} +% \section{Adding the Equation Types} +% Adding an equation type is fairly easy. The outline is this: +% \begin{list}{}{\leftmargin2em} +% \item[]|\EQ_new_equationtype{EmphEqEnv}|\marg{\AmS\ +% env}\marg{arabic num}\texttt{:} +% \item[]|\def\EQ_modify_linewidth_|\meta{roman num}\texttt{:}\\ +% \hspace*{2em}\marg{Optionally alter \cs{l_EQ_temp_linewidth_dim}} +% \item[]|\def\find_displaywidth_|\meta{roman num}\texttt{:}\\ +% \hspace*{2em}\marg{Set \cs{l_EQ_displaywidth_dim}} +% \item[]|\def\EQ_place_display_|\meta{roman num}\texttt{:}\\ +% \hspace*{2em}\marg{Make use of \cs{EQ_use_mathdisplay:}} +% \end{list} +% \begin{macro}{\EQ_use_mathdisplay:} +% A shorthand. +% \begin{macrocode} +\def\EQ_use_mathdisplay:{% + \EQ_outerbox:{\usebox{\EQ_mathdisplay_box}}} +% \end{macrocode} +% \end{macro} +% \begin{macrocode} +\def\EQ_options_name:{EmphEqOpt} +% \end{macrocode} +% \subsection{The \env{equation} Family} +% Just a few aliases because \env{equation} and \env{equation*} +% behave strangely. Much better to use \env{gather} instead as this +% is easier to measure. Besides it's less work (for us, not the +% compiler). ;-) +% \begin{macrocode} +\MH_keyval_alias_with_addon:nnnn {EmphEqEnv}{equation}{gather} + {\EQ_disable_linebreak:} +\MH_keyval_alias_with_addon:nnnn {EmphEqEnv}{equation*}{gather*} + {\EQ_disable_linebreak:} +% \end{macrocode} +% \begin{macro}{\EQ_disable_linebreak:} +% \changes{v1.05c}{2004/02/25}{Introduced +% \cs{EQ_disable_linebreak:} to prevent multi line +% \env{equation}'s} +% \changes{v1.05c}{2004/02/25}{Fixed it so that it works better} +% Disable the line breaks in \env{equation} as these are actually +% possible now, since we're in a \env{gather}! \cs{Let@} does it in +% the environment, so that's the place to hack. +% \begin{macrocode} +\def\EQ_disable_linebreak:{% + \MH_let:NwN \EQ_saved_Let: \Let@ + \def\Let@{\def\\{% + \PackageError{empheq}{You~ cannot~ use~ \string\\~ in~ equation!} + {\@eha}} +% \end{macrocode} +% Then restore the meaning of \cs{Let@} in case there is a +% \env{gathered} or alike coming up. +% \begin{macrocode} + \MH_let:NwN \Let@ \EQ_saved_Let: + }% +} +% \end{macrocode} +% \end{macro} +% +% \subsection{The \env{align} Family} +% \begin{macrocode} +\EQ_new_equationtype:nnn {EmphEqEnv}{align}{1} +\EQ_new_equationtype:nnn {EmphEqEnv}{align*}{2} +% \end{macrocode} +% \begin{macrocode} +\def\EQ_modify_linewidth_i:{% +% \end{macrocode} +% If $\cs{maxfields@}=2$ we're in a single column \env{align} and +% thus there is no flexible space. +% \begin{macrocode} + \if_num:w \maxfields@=\tw@ + \else: +% \end{macrocode} +% But if there is any flexible space we would very much like to +% adjust it because we add material to the right and left of the +% math display. +% \begin{macrocode} + \setlength{\l_EQ_temp_linewidth_dim}{% + \linewidth-\l_EQ_totalwidth_dim-\widthof{\EQ_outerbox:{}}}% + \fi:} +\def\EQ_modify_linewidth_ii:{\EQ_modify_linewidth_i:} +\def\find_displaywidth_i:{% + \MH_setlength:dn \l_EQ_displaywidth_dim + {\l_EQ_temp_linewidth_dim-\alignsep@} + \if_case:w \l_EQ_alignmentmode_int + \or: % #1: + \MH_addtolength:dn \l_EQ_displaywidth_dim{-\alignsep@}% + \or: % #2: + \MH_addtolength:dn \l_EQ_displaywidth_dim{-\alignsep@}% + \or: % #3: + \MH_addtolength:dn \l_EQ_displaywidth_dim{-\@mathmargin}% + \or: % #4: + \MH_addtolength:dn \l_EQ_displaywidth_dim{-\@mathmargin}% + \fi:} +\def\find_displaywidth_ii:{\find_displaywidth_i:} +\def\EQ_place_display_i: {\EQ_use_mathdisplay:} +\def\EQ_place_display_ii:{\EQ_place_display_i:} +% \end{macrocode} +% +% \subsection{The \env{gather} Family} +% This is a gem. Notice how easy it is once we got the framework for +% it. +% \begin{macrocode} +\EQ_new_equationtype:nnn {EmphEqEnv}{gather}{3} +\EQ_new_equationtype:nnn {EmphEqEnv}{gather*}{4} +\def\EQ_modify_linewidth_iii:{} +\def\EQ_modify_linewidth_iv:{\EQ_modify_linewidth_iii:} +\def\find_displaywidth_iii:{% + \MH_setlength:dn \l_EQ_displaywidth_dim{\totwidth@}% + \if_case:w \l_EQ_alignmentmode_int \or: \or: % #1 & #2: + \or: % #3: + \MH_addtolength:dn \l_EQ_displaywidth_dim{-\@mathmargin}% + \or: % #4: + \MH_addtolength:dn \l_EQ_displaywidth_dim{-\@mathmargin}% + \fi:} +\def\find_displaywidth_iv:{\find_displaywidth_iii:} +\def\EQ_place_display_iii:{\EQ_use_mathdisplay:} +\def\EQ_place_display_iv: {\EQ_place_display_iii:} +% \end{macrocode} +% +% \subsection{The \env{flalign} Family}\label{sec:flalign+multline} +% This was fairly easy, but then I had to take care of \ldots +% +% \subsubsection{The \env{multline} Family} +% This was quite a pickle. Its implementation in \pkg{amsmath} is +% very strange indeed; for instance the tag is typeset in the +% measuring phase! So instead I thought I could fake it, but how +% should I do it? +% +% The basic idea of \env{multline} is to typeset the first line +% flush left, the last line flush right and the rest centered. +% ``Aha,'' I thought, ``what if I make three columns, fool \LaTeX{} +% into thinking the contents of the columns take no space and then +% just put each line into a column?'' Thus the \env{flalign} +% environment came to mind. I also distinctly remembered to have +% seen an article about the equivalent of \cs{rlap} and \cs{llap} in +% math mode, namely an article by Alexander R.~Perlis. This works +% pretty well, and so does the same trick for producing a +% \env{multlined} environment. That one uses an \env{alignedat} with +% three columns. +% +% \changes{v1.05c}{2004/02/25}{Makes use of +% \cs{MakeKeyvalAliasAddon} now} +% Then we make \env{multline} into an alias for {flalign} but with +% an extra switch \cs{ifEQ_multline:} set to true. +% \begin{macrocode} +\MH_keyval_alias_with_addon:nnnn {EmphEqEnv}{multline} + {flalign}{\MH_set_boolean_T:n {multline}} +\MH_keyval_alias_with_addon:nnnn {EmphEqEnv}{multline*} + {flalign*}{\MH_set_boolean_T:n {multline}} +% \end{macrocode} +% \begin{macro}{\if_EQ_multline:} +% \begin{macro}{\EQ_generic_multline:nnnnn} +% We make a general command that'll provide the correct spacing and +% then just define the user commands in terms of that single generic +% one. +% \begin{macrocode} +\MH_new_boolean:n {multline} +% \end{macrocode} +% \begin{macro}{\EQ_multline_modify_linewidth_tag:} +% \begin{macro}{\EQ_multline_modify_linewidth_notag:} +% There is a big difference between the spacing in \env{multline} +% depending on the presence of a tag. Therefore we split it up in +% two cases. I made this choice because we need these adjustments +% inside the adjustments for \env{flalign} and that makes it +% incredibly difficult to see what happens. +% \begin{macrocode} +\def\EQ_multline_modify_linewidth_tag:{% + \if_case:w \l_EQ_alignmentmode_int + \or: % #1: + \MH_addtolength:dn \l_EQ_temp_linewidth_dim{% + -\g_EQ_widesttag_dim-\multlinetaggap-\multlinegap}% + \or: + \MH_addtolength:dn \l_EQ_temp_linewidth_dim{% + -\g_EQ_widesttag_dim-\multlinetaggap-\multlinegap}% + \or: + \MH_addtolength:dn \l_EQ_temp_linewidth_dim{% + -\@mathmargin-\g_EQ_widesttag_dim-\multlinetaggap}% + \or: + \MH_addtolength:dn + \l_EQ_temp_linewidth_dim{-\@mathmargin-\multlinegap}% + \fi: +} +\def\EQ_multline_modify_linewidth_notag:{% + \if_case:w \l_EQ_alignmentmode_int\or: + \MH_addtolength:dn \l_EQ_temp_linewidth_dim{-2\multlinegap} + \or: + \MH_addtolength:dn \l_EQ_temp_linewidth_dim{-2\multlinegap} + \or: + \MH_addtolength:dn + \l_EQ_temp_linewidth_dim{-\@mathmargin-\multlinegap}% + \or: + \MH_addtolength:dn + \l_EQ_temp_linewidth_dim{-\@mathmargin-\multlinegap}% + \fi: +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{environment}{MTmultlined} +% Save the superior \env{multlined} from \pkg{mathtools} under a new +% name. +% \begin{macrocode} +\MH_let:NwN \MTmultlined \multlined +\MH_let:NwN \endMTmultlined \endmultlined +% \end{macrocode} +% \end{environment} +% We make a choice here: the good \env{multline} or the bad? +% \begin{macrocode} +\MH_if_boolean:nTF {good_mult}{ +% \end{macrocode} +% The good: +% \begin{macrocode} +\MH_keyval_alias_with_addon:nnnn {EmphEqEnv}{multline}{gather} + {\MH_set_boolean_T:n {outer_mult}} +\MH_keyval_alias_with_addon:nnnn {EmphEqEnv}{multline*}{gather*} + {\MH_set_boolean_T:n {outer_mult}} +\def\EQ_modify_linewidth_iii_mult:{ + \setlength{\l_EQ_temp_linewidth_dim}{% + \linewidth-\widthof{\EQ_outerbox:{}}}% + \if_dim:w \g_EQ_widesttag_dim>\z@ + \EQ_multline_modify_linewidth_tag: + \else: + \EQ_multline_modify_linewidth_notag: + \fi: + \MH_setlength:dn \l_MT_multwidth_dim{\l_EQ_temp_linewidth_dim} +} +\def\EQ_modify_linewidth_iv_mult:{\EQ_modify_linewidth_iii_mult:} +\def\find_displaywidth_iii_mult:{% + \MH_setlength:dn \l_EQ_displaywidth_dim{\totwidth@}% + \if_case:w \l_EQ_alignmentmode_int \or: \or: % #1 & #2: + \or: % #3: + \MH_addtolength:dn \l_EQ_displaywidth_dim{-\@mathmargin}% + \or: % #4: + \MH_addtolength:dn \l_EQ_displaywidth_dim{-\@mathmargin}% + \fi:} +\def\find_displaywidth_iv_mult:{\find_displaywidth_iii_mult:} +\def\EQ_place_display_iii_mult:{ + \if_case:w \l_EQ_alignmentmode_int + \or: % #1: + \if_dim:w \g_EQ_widesttag_dim>\z@ + \abovedisplayshortskip=\abovedisplayskip + \rlap{ + \kern-.5\linewidth + \kern\multlinegap + \EQ_use_mathdisplay: + } + \else: + \EQ_use_mathdisplay: + \fi: + \or: % #2: + \if_dim:w \g_EQ_widesttag_dim>\z@ + \llap{ + \EQ_use_mathdisplay: + \kern-.5\linewidth + \kern\multlinegap + }% + \else: + \EQ_use_mathdisplay: + \fi: + \or: % #3: + \EQ_use_mathdisplay: + \or: % #4: + \EQ_use_mathdisplay: + \fi: +} +\def\EQ_place_display_iv_mult: {\EQ_place_display_iii_mult:} +% \end{macrocode} +% \begin{macrocode} +}{ +% \end{macrocode} +% The bad +% \begin{macrocode} +\def\EQ_generic_multline:nnnnn #1#2#3#4#5{% +% \end{macrocode} +% This is a very tricky little detail. If we're in \mode{leqno} mode +% we need just a we little width inside the \env{flalign}, so we put +% in the smallest possible amount. Otherwise we wind up in a +% \begin{verbatim} +% ! Arithmetic overflow. +% <recently read> \count@ +% +% l.304 % \end{empheq} +% \end{verbatim} +% If you scroll past this error it will be typeset correctly, but +% how many users can fix this by themselves? +% \begin{macrocode} + \hskip1sp#2#3{{}#5}#4% + \if:w *#1\relax\else:\notag\fi:} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \begin{macro}{\multleft} +% \begin{macro}{\multcenter} +% \begin{macro}{\multright} +% Then the commands that use \cs{EQ_generic_multline:nnnnn}. The +% first three are the general purpose ones that also have a starred +% version. The other three are for normal use. +% \begin{macrocode} +\def\multleft{\@ifstar{% + \MH_if_boolean:nTF {multlined}{ + \def\EQ_next:{\EQ_multlined_left:n} + }{ + \def\EQ_next:{ + \EQ_generic_multline:nnnnn {*}{}{\mathrlap}{&&&&&}} + } + \EQ_next:}{% + \MH_if_boolean:nTF {multlined}{ + \def\EQ_next:{\EQ_multlined_left:n}% + }{ + \def\EQ_next:{ + \EQ_generic_multline:nnnnn {}{}{\mathrlap}{&&&&&}} + } + \EQ_next:}}% +\def\multcenter{\@ifstar{% + \MH_if_boolean:nTF {multlined}{ + \def\EQ_next:{\EQ_multlined_center:n}% + }{ + \def\EQ_next:{ + \EQ_generic_multline:nnnnn {*}{&&}{\mathclap}{&&&}} + } + \EQ_next:}{% + \MH_if_boolean:nTF {multlined}{ + \def\EQ_next:{\EQ_multlined_center:n }% + }{ + \def\EQ_next:{ + \EQ_generic_multline:nnnnn {}{&&}{\mathclap}{&&&}} + } + \EQ_next:}}% +\def\multright{\@ifstar{% + \MH_if_boolean:nTF {multlined}{ + \def\EQ_next:{\EQ_multlined_right:n }% + }{ + \def\EQ_next:{ + \EQ_generic_multline:nnnnn {*}{&&&&&}{\mathllap}{}} + } + \EQ_next:}{% + \MH_if_boolean:nTF {multlined}{ + \def\EQ_next:{\EQ_multlined_right:n }% + }{ + \def\EQ_next:{ + \EQ_generic_multline:nnnnn {}{&&&&&}{\mathllap}{}} + } + \EQ_next:}} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \begin{macro}{\multfirst} +% \begin{macro}{\multmiddle} +% \begin{macro}{\multlast} +% If we're using the \mode{leqno} option, the equation number should +% be placed in the first line. +% \begin{macrocode} +\def\multfirst{% + \MH_if_boolean:nTF {multlined}{ + \def\EQ_next:{\EQ_multlined_left:n }% + }{ + \if_case:w \l_EQ_alignmentmode_int + \or: % #1: + \def\EQ_next:{\multleft}% + \or: % #2: + \def\EQ_next:{\multleft*}% + \or: % #3: + \def\EQ_next:{\multleft}% + \or: % #4: + \def\EQ_next:{\multleft*}% + \fi: + } + \EQ_next:} +% \end{macrocode} +% Pretend the star was never there. +% \begin{macrocode} +\def\multmiddle{% + \def\EQ_next:{% + \MH_if_boolean:nTF {multlined}{ + \expandafter\EQ_multlined_center:n + }{ + \expandafter\multcenter + } + }% + \@ifstar{\EQ_next:}{\EQ_next:}} +% \end{macrocode} +% If we're using the \mode{reqno} option, the equation number +% should be placed in the last line. +% \begin{macrocode} +\def\multlast{% + \MH_if_boolean:nTF {multlined}{ + \def\EQ_next:{\EQ_multlined_right:n }% + }{ + \if_case:w \l_EQ_alignmentmode_int + \or: % #1: + \def\EQ_next:{\multright*}% + \or: % #2: + \def\EQ_next:{\multright}% + \or: % #3: + \def\EQ_next:{\multright*}% + \or: % #4: + \def\EQ_next:{\multright}% + \fi: + } + \EQ_next:} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \begin{macro}{\multlinedwidth} +% Here begins the code for \env{multlined}. +% \begin{macrocode} +\MH_new_boolean:n {multlined} +\newdimen\multlinedwidth +\MH_setlength:dn \multlinedwidth{.7\linewidth} +% \end{macrocode} +% \end{macro} +% \begin{environment}{multlined} +% \changes{v2.10}{2004/07/26}{Disallow spaces before optional +% arguments.} +% \begin{macro}{\EQ_multlined_I:w} +% \begin{macro}{\EQ_multlined_II:w} +% \begin{macro}{\EQ_multlined_III:nn} +% Some trickery as we want to scan for two optional arguments that +% may be interchanged. +% \begin{macrocode} +\renewenvironment{multlined}% + {\MH_nospace_ifnextchar:Nnn [ {\EQ_multlined_I:w} + {\EQ_multlined_I:w[c]} + } + { \endaligned } +\def\EQ_multlined_I:w[#1]{% + \MH_nospace_ifnextchar:Nnn[ {\EQ_multlined_II:w[#1]} + {\EQ_multlined_II:w[#1][\multlinedwidth]}} +\def\EQ_multlined_II:w[#1][#2]{% +% \end{macrocode} +% We tell \LaTeX\ that we're in \env{multlined}. +% \begin{macrocode} + \MH_set_boolean_T:n {multlined} +% \end{macrocode} +% \changes{v2.10}{2004/07/26}{Fixed restoration of \cmd{\\}} +% Restore the meaning of \cmd{\\} inside \env{multlined}, else it +% wouldn't work in the \env{equation} environment. +% \begin{macrocode} + \MH_let:NwN \Let@\MT_saved_Let: +% \end{macrocode} +% Then check the first optional argument and call +% \cs{EQ_multlined_III:w}, which sets \cs{multlinewidth} if +% specified and calls \cs{start@aligned} (an \env{alignedat} with +% three columns). +% \begin{macrocode} + \if:w t#1\relax \EQ_multlined_III:nn {#1}{#2}% + \else: + \if:w b#1\relax \EQ_multlined_III:nn {#1}{#2}% + \else: + \if:w c#1\relax \EQ_multlined_III:nn {#1}{#2}% + \else: + \EQ_multlined_III:nn {#2}{#1}% + \fi: + \fi: + \fi: + \mkern-\thinmuskip + \EQ_next:} +\def\EQ_multlined_III:nn #1#2{% + \def\EQ_next:{\setlength\multlinedwidth{#2}% + \start@aligned{#1}{\thr@@}}} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{environment} +% \begin{macro}{\EQ_multlined_left:n} +% \begin{macro}{\EQ_multlined_center:n} +% \begin{macro}{\EQ_multlined_right:n} +% The internal versions of \cs{multleft} etc.\ adapted for +% \env{multlined}. +% \begin{macrocode} +\def\EQ_multlined_left:n #1{% + \mathrlap{#1}&\hskip.5\multlinedwidth&&\hskip.5\multlinedwidth&&} +\def\EQ_multlined_center:n #1{% + &\hskip.5\multlinedwidth&&\mathclap{#1}\hskip.5\multlinedwidth&&} +\def\EQ_multlined_right:n #1{% + &\hskip.5\multlinedwidth&&\hskip.5\multlinedwidth&&\mathllap{#1}} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% End of bad multline. +% \begin{macrocode} +} +% \end{macrocode} +% +% \subsubsection{The Code for \env{flalign} \& \env{multline}} +% \begin{macrocode} +\EQ_new_equationtype:nnn {EmphEqEnv}{flalign}{5} +\EQ_new_equationtype:nnn {EmphEqEnv}{flalign*}{6} +\def\EQ_modify_linewidth_v:{% + \setlength{\l_EQ_temp_linewidth_dim}{% + \linewidth-\l_EQ_totalwidth_dim-\widthof{\EQ_outerbox:{}}}% + \if_dim:w \g_EQ_widesttag_dim>\z@ + \MH_if_boolean:nTF {multline}{ + \EQ_multline_modify_linewidth_tag: + }{ + \if_case:w \l_EQ_alignmentmode_int + \or: % #1: + \MH_addtolength:dn \l_EQ_temp_linewidth_dim + {-\g_EQ_widesttag_dim-\mintagsep} + \or: % #2: + \MH_addtolength:dn \l_EQ_temp_linewidth_dim + {-\g_EQ_widesttag_dim-\mintagsep}% + \or: % #3: + \MH_addtolength:dn \l_EQ_temp_linewidth_dim + {-\g_EQ_widesttag_dim-\mintagsep} + \or: % #4: + \MH_addtolength:dn \l_EQ_temp_linewidth_dim + {-\@mathmargin} + \fi: + } + \else: + \MH_if_boolean:nT {multline}{ + \EQ_multline_modify_linewidth_notag: + } + \fi:} +\def\EQ_modify_linewidth_vi:{\EQ_modify_linewidth_v:} +\def\find_displaywidth_v:{% + \MH_setlength:dn + \l_EQ_displaywidth_dim{\l_EQ_temp_linewidth_dim}} +\def\find_displaywidth_vi:{\find_displaywidth_v:} +\def\EQ_place_display_v:{% + \if_case:w \l_EQ_alignmentmode_int + \or: % #1: + \if_dim:w \g_EQ_widesttag_dim>\z@ + \MH_if_boolean:nTF {multline}{ + \rlap{\kern\multlinegap \kern-.5\linewidth + \EQ_use_mathdisplay: + \kern-\mintagsep \kern\multlinetaggap}% + }{ + \rlap{\kern-.5\linewidth\EQ_use_mathdisplay:}% + } + \else: + \EQ_use_mathdisplay: + \fi: + \or: % #2: + \if_dim:w \g_EQ_widesttag_dim>\z@ + \MH_if_boolean:nTF {multline}{ + \llap{\kern-\mintagsep \kern\multlinetaggap + \EQ_use_mathdisplay: + \kern\multlinegap \kern-.5\linewidth}% + }{ + \llap{\EQ_use_mathdisplay:\kern-.5\linewidth}% + } + \else: + \EQ_use_mathdisplay: + \fi: + \or: % #3: + \MH_if_boolean:nF {multline}{ \kern-\multlinetaggap } + \EQ_use_mathdisplay: + \or: % #4: + \if_dim:w \g_EQ_widesttag_dim>\z@ + \else: + \MH_if_boolean:nF {multline}{ \kern-\@mathmargin } + \fi: + \EQ_use_mathdisplay: + \fi: + \MH_set_boolean_F:n {multline}} +\def\EQ_place_display_vi:{\EQ_place_display_v:} +% \end{macrocode} +% +% \subsection{The \env{alignat} Family} +% This is just as easy as \env{gather}. Actually only one line is +% different from \env{gather}! +% \begin{macrocode} +\EQ_new_equationtype_arg:nnn {EmphEqEnv}{alignat}{7} +\EQ_new_equationtype_arg:nnn {EmphEqEnv}{alignat*}{8} +\def\EQ_modify_linewidth_vii:{} +\def\EQ_modify_linewidth_viii:{\EQ_modify_linewidth_vii:} +\def\find_displaywidth_vii:{% + \MH_setlength:dn \l_EQ_displaywidth_dim{\totwidth@}% + \if_case:w \l_EQ_alignmentmode_int + \or: % #1: + \or: % #2: + \or: % #3: + \MH_addtolength:dn \l_EQ_displaywidth_dim{-\eqnshift@}% + \or: % #4: + \MH_addtolength:dn \l_EQ_displaywidth_dim{-\@mathmargin}% + \fi:} +\def\find_displaywidth_viii:{\find_displaywidth_vii:} +\def\EQ_place_display_vii:{\EQ_use_mathdisplay:} +\def\EQ_place_display_viii:{\EQ_place_display_vii:} +% \end{macrocode} +% \section{The User Interface} +% The different keys. +% \begin{macrocode} +\define@key{\EQ_options_name:}{box}{\def\EQ_outerbox:{#1}} +\MH_keyval_alias:nnn {\EQ_options_name:}{outerbox}{box} +% \end{macrocode} +% \begin{macro}{\EQ_marginbox:nn} +% The margin box. Uwe Siart wanted it. +% \begin{macrocode} +\def\EQ_marginbox:nn #1#2{% + \settowidth{\@tempdima}{#2}% + \makebox[\z@]{\hspace{\@tempdima}#1{#2}}} +\define@key{\EQ_options_name:}{marginbox}{% + \def\EQ_outerbox:{\EQ_marginbox:nn {#1}}} +% \end{macrocode} +% \end{macro} +% Almost self-explanatory, isn't? +% \begin{macrocode} +\define@key{\EQ_options_name:}{innerbox}{\def\EQ_innerbox:{#1}} +\define@key{\EQ_options_name:}{left}{\def\EQ_left_side:{#1}} +\define@key{\EQ_options_name:}{right}{\def\EQ_right_side:{#1}} +% \end{macrocode} +% \begin{macro}{\empheqset} +% Just a user friendly way to set keys. Uwe Siart again. +% \begin{macrocode} +\newcommand*\empheqset[1]{\setkeys{\EQ_options_name:}{#1}} +% \end{macrocode} +% \end{macro} +% The old keys from the original version are no longer supported. +% Instead they give an error message (RM): +% \begin{macrocode} +\def\EQ_upgrade_error:{% + \PackageError{empheq} + {You~ are~ using~ the~ old~ syntax!\MessageBreak + The~ `empheq'~ environment~ takes~ a~ mandatory~ + argument~ now.\MessageBreak + You~ need~ to~ exit~ and~ change~ your~ source~ file.} + {It~ won't~ work,~ trust me.~ Press~ `X'~ now.}} +\define@key{\EQ_options_name:}{boxtype}{\EQ_upgrade_error:} +\define@key{\EQ_options_name:}{Left}{\EQ_upgrade_error:} +\define@key{\EQ_options_name:}{Right}{\EQ_upgrade_error:} +% \end{macrocode} +% \begin{environment}{empheq} +% The environment. +% \begin{macrocode} +\newenvironment{empheq}[2][]{% + \setkeys{EmphEqEnv}{#2}\setkeys{\EQ_options_name:}{#1}% + \EmphEqMainEnv}{\endEmphEqMainEnv} +% \end{macrocode} +% \end{environment} +% \begin{macro}{\DeclareLeftDelimiter} +% \begin{macro}{\EQ_declare_left_delimiter:nnnn} +% \begin{macro}{\DeclareRightDelimiter} +% \begin{macro}{\EQ_declare_right_delimiter:nnnn} +% The delimiter interface. +% \changes{v0.7}{2003/05/11}{Introduced delimiter interface} +% \changes{v1.05d}{2004/02/26}{Changed the definitions.} +% We now use the \cs{EQ_tag_box} to calculate the height but +% adjust the vertical spacing. All this to prevent running +% \cs{EQ_typeset_display:} twice. +% \begin{macrocode} +\newcommand*\DeclareLeftDelimiter[2][]{% + \EQ_declare_left_delimiter:nnnn {#1}{#2}{}{}% + \EQ_declare_left_delimiter:nnnn {#1}{#2}{big}{\EQ_innerbox:}} +\def\EQ_declare_left_delimiter:nnnn #1#2#3#4{% + \@namedef{empheq#3\expandafter\@gobble\string#2}{% + \left#2% + \mkern-\thinmuskip + \vphantom{#4{\parbox{.5\maxdimen}{% + \EQ_predisplay_adjustment: + \EQ_prevent_vertical_space: + \usebox{\EQ_tag_box}% + \EQ_postdisplay_adjustment:}}}% + \right.% + \kern-\nulldelimiterspace #1}} +\newcommand*\DeclareRightDelimiter[2][]{% + \EQ_declare_right_delimiter:nnnn {#1}{#2}{}{}% + \EQ_declare_right_delimiter:nnnn {#1}{#2}{big}{\EQ_innerbox:}} +\def\EQ_declare_right_delimiter:nnnn #1#2#3#4{% + \@namedef{empheq#3\expandafter\@gobble\string#2}{% + \kern-\nulldelimiterspace + #1% + \left.% + \vphantom{#4{\parbox{.5\maxdimen}{% + \EQ_predisplay_adjustment: + \EQ_prevent_vertical_space: + \usebox{\EQ_tag_box}% + \EQ_postdisplay_adjustment:}}}% + \mkern-\thinmuskip + \right#2}} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% The actual declarations. +% \begin{macrocode} +\DeclareLeftDelimiter{\lbrace} +\DeclareRightDelimiter{\rbrace} +\DeclareLeftDelimiter{\lbrack} +\DeclareRightDelimiter{\rbrack} +\DeclareLeftDelimiter{\langle} +\DeclareRightDelimiter{\rangle} +\DeclareLeftDelimiter{\lvert} +\DeclareRightDelimiter{\rvert} +\DeclareLeftDelimiter{\lVert} +\DeclareRightDelimiter{\rVert} +\DeclareLeftDelimiter{\lfloor} +\DeclareRightDelimiter{\rfloor} +\DeclareLeftDelimiter{\lceil} +\DeclareRightDelimiter{\rceil} +\DeclareLeftDelimiter{\lparen} +\DeclareRightDelimiter{\rparen} +% \end{macrocode} +% +% \section{Support for Other Packages} +% +% Support for various other packages is found in this section. The +% \pkg{ntheorem} package now has a dedicated section (\S +% \vref{sec:impl:ntheorem}), as it now a module. +% +% +% +% \begin{macrocode} +\def\EQ_typeset_tags_hook:{} +\def\EQ_typeset_display_hook:{} +% \end{macrocode} +% +% \subsection{\pkg{showkeys}} +% \changes{v2.10}{2004/07/26}{Added support for the \pkg{showkeys} +% package} +% We just disable \pkg{showkeys} when typesetting the labels. +% \begin{macrocode} +\g@addto@macro\EQ_typeset_display_hook:{ + \def\SK@@label#1>#2\SK@{} +} +% \end{macrocode} +% If we overload the \AmS{} equation types we should still be able +% to use \pkg{showkeys}. +% \begin{macrocode} +\@namedef{SK@AmSequation} {\SK@equationtrue} +\@namedef{SK@AmSequation*} {\SK@equationtrue} +\@namedef{SK@AmSalign} {\SK@equationtrue} +\@namedef{SK@AmSalign*} {\SK@equationtrue} +\@namedef{SK@AmSalignat} {\SK@equationtrue} +\@namedef{SK@AmSalignat*} {\SK@equationtrue} +\@namedef{SK@AmSgather} {\SK@equationtrue} +\@namedef{SK@AmSgather*} {\SK@equationtrue} +\@namedef{SK@AmSmultline} {\SK@equationtrue} +\@namedef{SK@AmSmultline*} {\SK@equationtrue} +\@namedef{SK@AmSflalign} {\SK@equationtrue} +\@namedef{SK@AmSflalign*} {\SK@equationtrue} +% \end{macrocode} +% +% \subsection{\pkg{hyperref}} +% +% +% A little trick to avoid the (in)famous warning +% \begin{verbatim} +% ! pdfTeX warning (ext4): destination with the same identifier +% (name{equation.1a }) has been already used, duplicate ignored +% <to be read again> +% \endgroup \set@typeset@protect +% \end{verbatim} +% This doesn't require \pkg{hyperref}. +% \begin{macrocode} +\AtBeginDocument{ + \@ifundefined{Hy@linkcounter}{\newcount\Hy@linkcounter}{} +} +\g@addto@macro\EQ_typeset_display_hook:{ + \MH_let:NwN \hyper@refstepcounter\@gobble +} +% \end{macrocode} +% +% +% \subsection{Basic \pkg{ntheorem} support} +% \begin{macrocode} +\g@addto@macro\EQ_typeset_tags_hook:{ + \MH_let:NwN\TagsPlusEndmarks\relax + \MH_let:NwN\RestoreTags\relax +} +\g@addto@macro\EQ_typeset_display_hook:{ + \MH_let:NwN\TagsPlusEndmarks\relax + \MH_let:NwN\RestoreTags\relax +} +% \end{macrocode} +% \subsection{Basic \LaTeXe{} support} +% Gobble the \cs{ltx@label} and disable most error messages. +% \changes{v2.00}{2004/04/14}{Make a special label-gobbling command +% to support \pkg{ntheorem} even more} +% \begin{macrocode} +\g@addto@macro\EQ_typeset_display_hook:{ + \MH_let:NwN\ltx@label\MT_gobblelabel:w + \MH_let:NwN \GenericError \@gobblefour +} +% \end{macrode} +% \subsection{Support for \pkg{fancybox}} +% First check if \pkg{fancybox} is loaded and then see if +% \pkg{color} is loaded. If the latter is loaded we define +% \texttt{shadowcolor} else we let \cs{textcolor} gobble the first +% argument (the color). +% \begin{macrocode} +\AtBeginDocument{% + \@ifpackageloaded{fancybox}{% + \@ifpackageloaded{color}{\definecolor{shadowcolor}{rgb}{0,0,0}}% + {\newcommand*\textcolor[2]{\normalcolor{#2}}}% +% \end{macrocode} +% \begin{macro}{\shadowbox} +% Then define the \cs{shadowbox}. Use a conditional to let us know if +% it was starred or not. +% \begin{macrocode} + \MH_new_boolean:n {shadowbox_star} + \renewcommand*\shadowbox{% + \@ifstar{\MH_set_boolean_T:n {shadowbox_star} + \VerbBox\EQ_shadowbox:n} + {\MH_set_boolean_F:n {shadowbox_star} + \VerbBox\EQ_shadowbox:n}} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\EQ_shadowbox:n} +% The internal version of \cs{shadowbox}. +% \begin{macrocode} + \def\EQ_shadowbox:n #1{% + \sbox{\z@}{\fbox{#1}}% +% \end{macrocode} +% The difference between the two versions is that \cs{shadowbox} +% aligns the bottom of the shadow at the baseline whereas +% \cs{shadowbox*} aligns the argument on the baseline, so for the +% starred version the trick is to raise the box by the depth of the +% argument plus the size of the shadow. +% \begin{macrocode} + \MH_if_boolean:nTF {shadowbox_star}{ + \MH_setlength:dn \@tempdima{\z@}% + }{ + \MH_setlength:dn \@tempdima{\dp\z@+\shadowsize}% + } + \raisebox{\@tempdima}{% + \makebox[\z@][l]{% + \kern\shadowsize \textcolor{shadowcolor}{% + \rule[-\dp\z@-\shadowsize]{\wd\z@}{\shadowsize}}% + }% + \usebox\z@\textcolor{shadowcolor}{% + \rule[-\dp\z@-\shadowsize]{\shadowsize}{\ht\z@+\dp\z@}}}}% + }{}% +} +% \end{macrocode} +% \end{macro} +% +% +% \section{The \opt{overload} option} +% \begin{macro}{\EQ_overload_ams_begin:n} +% A helper for saving snapshots: +% \begin{macrocode} +\def\EQ_overload_ams_begin:n #1{% + \MH_let:cc {AmS#1}{#1}% + \MH_let:cc {AmS#1*}{#1*} +} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\EQ_overload_ams_end:n} +% All but one of the aligned variations must be set to the original +% \begin{macrocode} +\def\EQ_overload_ams_end:n #1{% + \MH_let:cc {endAmS#1}{endAmSalign} +} +% \end{macrocode} +% \end{macro} +% \begin{environment}{AmSequation} +% \begin{environment}{AmSequation*} +% \changes{v2.10}{2004/07/26}{Moved redefinitions to +% \cs{AtBeginDocument} to give \pkg{hyperref} a chance} +% Before we start redefining environments, we'll need a basic +% \env{equation} environment that is not redefined. +% \begin{macrocode} +\AtBeginDocument{ + \EQ_overload_ams_begin:n {equation} + \MH_let:cc {endAmSequation}{endequation} + \MH_let:cc {endAmSequation*}{endequation*} +% \end{macrocode} +% \end{environment} +% \end{environment} +% Lets start overloading. +% \begin{macrocode} + \MH_if_boolean:nT {overload_ams}{ +% \end{macrocode} +% \begin{macro}{\EQ_renew_ams_environment:n} +% \changes{v2.10}{2004/07/26}{Disallow spaces before the optional +% argument.} +% Then we can renew the environments. Syntax is +% \cs{begin}\marg{\AmS{} env}\oarg{markup}. Exception to this rule +% is \env{alignat} (see further down). +% \begin{macrocode} + \def\EQ_renew_ams_environment:n #1{% + \MaybeMHPrecedingSpacesOff + \renewenvironment{#1}[1][]{% + \setkeys{\EQ_options_name:}{##1}% + \setkeys{EmphEqEnv}{AmS#1}% + \EmphEqMainEnv + }{\endEmphEqMainEnv} + \MHPrecedingSpacesOn + } +% \end{macrocode} +% \end{macro} +% Add equation type: \emph{Must} have same number as original type! +% \begin{macrocode} + \EQ_new_equationtype:nnn {EmphEqEnv}{AmSalign} {1} + \EQ_new_equationtype:nnn {EmphEqEnv}{AmSalign*} {2} + \EQ_new_equationtype:nnn {EmphEqEnv}{AmSgather} {3} + \EQ_new_equationtype:nnn {EmphEqEnv}{AmSgather*} {4} + \EQ_new_equationtype:nnn {EmphEqEnv}{AmSflalign} {5} + \EQ_new_equationtype:nnn {EmphEqEnv}{AmSflalign*}{6} + \EQ_new_equationtype_arg:nnn {EmphEqEnv}{AmSalignat} {7} + \EQ_new_equationtype_arg:nnn {EmphEqEnv}{AmSalignat*}{8} +% \end{macrocode} +% Then overload by saving the snapshots of the old definitions. We +% do it via \cs{AtBeginDocument}, because a package like +% \pkg{ntheorem} redefines \cs{endgather} etc. +% +% First the \env{gather} and \env{equation} families. +% \begin{macrocode} + \EQ_overload_ams_begin:n {gather} + \MH_let:cc {endAmSgather}{endgather} + \MH_let:cc {endAmSgather*}{endAmSgather} + \EQ_renew_ams_environment:n {gather} + \EQ_renew_ams_environment:n {gather*} + \EQ_overload_ams_begin:n {equation} + \MH_keyval_alias_with_addon:nnnn {EmphEqEnv} {AmSequation} + {AmSgather}{\EQ_disable_linebreak:} + \MH_keyval_alias_with_addon:nnnn {EmphEqEnv}{AmSequation*} + {AmSgather*}{\EQ_disable_linebreak:} + \EQ_renew_ams_environment:n {equation} + \EQ_renew_ams_environment:n {equation*} +% \end{macrocode} +% The \env{align} family. +% \begin{macrocode} + \EQ_overload_ams_begin:n {align} + \MH_let:cc {endAmSalign}{endalign} + \EQ_overload_ams_end:n {align*} + \EQ_renew_ams_environment:n {align} + \EQ_renew_ams_environment:n {align*} +% \end{macrocode} +% The \env{flalign} family. +% \begin{macrocode} + \EQ_overload_ams_begin:n {flalign} + \EQ_overload_ams_end:n {flalign} + \EQ_overload_ams_end:n {flalign*} + \EQ_renew_ams_environment:n {flalign} + \EQ_renew_ams_environment:n {flalign*} +% \end{macrocode} +% The \env{alignat} family. +% \begin{macrocode} + \EQ_overload_ams_begin:n {alignat} + \EQ_overload_ams_end:n {alignat} + \EQ_overload_ams_end:n {alignat*} +% \end{macrocode} +% \begin{macro}{\EQ_alignat_optional:w} +% \changes{v2.10}{2004/07/26}{Disallow spaces before the optional +% argument.} +% \begin{environment}{alignat} +% \begin{environment}{alignat*} +% This one is a little different because we want a syntax like +% \cs{begin\{alignat\}}\linebreak[0]\marg{cols}\oarg{markup}, so we +% have to make a separate command for testing the trailing optional +% argument. +% \begin{macrocode} + \MaybeMHPrecedingSpacesOff + \newcommand*\EQ_alignat_optional:w [1][]{ + \setkeys{\EQ_options_name:}{#1} + \EmphEqMainEnv} + \MHPrecedingSpacesOn + \renewenvironment{alignat}[1]{ + \setkeys{EmphEqEnv}{AmSalignat=#1} + \EQ_alignat_optional:w} + {\endEmphEqMainEnv} + \renewenvironment{alignat*}[1]{% + \setkeys{EmphEqEnv}{AmSalignat*=#1}% + \EQ_alignat_optional:w}% + {\endEmphEqMainEnv} +% \end{macrocode} +% \end{environment} +% \end{environment} +% \end{macro} +% \begin{macro}{\[} +% \begin{macro}{\]} +% Then restore \cs{[} and \cs{]}. +% \begin{macrocode} + \DeclareRobustCommand{\[}{\begin{AmSequation*}} + \DeclareRobustCommand{\]}{\end{AmSequation*}} +% \end{macrocode} +% \end{macro} +% \end{macro} +% Finally a string of aliases so that we can blend \opt{overload} +% syntax with regular syntax. +% \begin{macrocode} + \MH_keyval_alias:nnn {EmphEqEnv}{gather} {AmSgather} + \MH_keyval_alias:nnn {EmphEqEnv}{gather*} {AmSgather*} + \MH_keyval_alias:nnn {EmphEqEnv}{align} {AmSalign} + \MH_keyval_alias:nnn {EmphEqEnv}{align*} {AmSalign*} + \MH_keyval_alias:nnn {EmphEqEnv}{flalign} {AmSflalign} + \MH_keyval_alias:nnn {EmphEqEnv}{flalign*}{AmSflalign*} + \MH_keyval_alias:nnn {EmphEqEnv}{alignat} {AmSalignat} + \MH_keyval_alias:nnn {EmphEqEnv}{alignat*}{AmSalignat*} + \MH_if_boolean:nT {good_mult}{ + \EQ_overload_ams_begin:n {multline} + \MH_let:cc {endAmSmultline}{endmultline} + \MH_let:cc {endAmSmultline*}{endAmSmultline} + \MH_keyval_alias_with_addon:nnnn {EmphEqEnv}{AmSmultline} + {AmSgather}{\MH_set_boolean_T:n {outer_mult}} + \MH_keyval_alias_with_addon:nnnn {EmphEqEnv}{AmSmultline*} + {AmSgather*}{\MH_set_boolean_T:n {outer_mult}} + \EQ_renew_ams_environment:n {multline} + \EQ_renew_ams_environment:n {multline*} + } +% \end{macrocode} +% End of \opt{overload}. We go into \opt{overload2}\ldots This +% is dangerous, but will probably work. The macro \cs{[} is now +% fragile except if you're running \eTeX{} as engine for \LaTeX. +% \begin{macrocode} + \MH_if_boolean:nT {overload_amsII}{ + \MH_protected:\def\[#1\]{\begin{equation*} #1\end{equation*}} +% \end{macrocode} +% Then we add the \env{multline} family. +% \begin{macrocode} + \MH_if_boolean:nF {good_mult}{ + \EQ_overload_ams_begin:n {multline} + \MH_keyval_alias_with_addon:nnnn {EmphEqEnv}{AmSmultline} + {AmSflalign}{\MH_set_boolean_T:n {multline}} + \MH_keyval_alias_with_addon:nnnn {EmphEqEnv}{AmSmultline*} + {AmSflalign*}{\MH_set_boolean_T:n {multline}} + \EQ_renew_ams_environment:n {multline} + \EQ_renew_ams_environment:n {multline*} + } + } + } +} +% \end{macrocode} +% End of \cs{AtBeginDocument} additions. +% \begin{macrocode} +%</empheq> +% \end{macrocode} +% +% +% \section{Patching Things up for \pkg{ntheorem}} +% \label{sec:impl:ntheorem} +% +% Although \pkg{ntheorem} provides a lot of useful features it +% does however ruin things in the \pkg{amsmath} environments, +% because of the alternative syntax of its \cs{label} command. +% \begin{macro}{\default_raisetag} +% \begin{macro}{\raisetag} +% \begin{macro}{\raise@tag} +% \changes{v1.06}{2004/03/13}{Fixed \pkg{amsmath} bug \# 3624} +% This corrects a bug\footnote{See +% \url{http://www.latex-project.org/cgi-bin/ltxbugs2html?pr=amslatex/3624}} +% in \pkg{amsmath} that could cause tags to cross page boundaries +% without warning. The \cs{nobreak} is the addition. +% \begin{macrocode} +%<*ntheorem> +\def\default_raisetag:{\nobreak} +\def\raisetag#1{ + \skip@#1\relax + \xdef\raise@tag{\default_raisetag: + \vskip\iftagsleft@\else:-\fi:\the\skip@\relax}} +\MH_let:NwN\raise@tag\default_raisetag: +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \begin{macro}{\displ@y@} +% Patch it so that it doesn't set \cs{raise@tag} to \cs{@empty} +% globally. +% \begin{macrocode} +\def\displ@y@{\@display@init{% + \global\column@\z@ \global\dspbrk@lvl\m@ne + \global\tag@false \global\MH_let:NwN\raise@tag\default_raisetag: +}} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\MT_gobblelabel:w} +% \changes{v2.00}{2004/04/14}{Added \cs{MT_gobblelabel:w}} +% \begin{macro}{\EQ_gobbleoptional:w} +% \changes{v2.00}{2004/04/14}{Added \cs{EQ_gobbleoptional:w}} +% Macros for gobbling the `unorthodox' \cs{label} syntax of +% \pkg{ntheorem}. Also overrides the normal \cs{label}-gobbling. +% \begin{macrocode} +\def\MT_gobblelabel:w #1{\@ifnextchar[{\EQ_gobbleoptional:w}{}} +\def\EQ_gobbleoptional:w [#1]{} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \subsection{Fixing \env{gather}} +% The measuring phase of \env{gather} is patched by letting +% \cs{label} be a copy of the internal \cs{MT_gobblelabel:w} +% instead of \cs{@gobble}. +% \begin{macrocode} +\def\gmeasure@#1{% + \begingroup + \measuring@true + \totwidth@\z@ + \global\MH_let:NwN\tag@lengths\@empty + \savecounters@ + \setbox\@ne\vbox{% + \everycr{\noalign{\global\tag@false +% \end{macrocode} +% The patch for \cs{raisetag}. +% \begin{macrocode} + \global\MH_let:NwN\raise@tag\default_raisetag: + \global\column@\z@}}% +% \end{macrocode} +% The patch for \cs{label}. +% \begin{macrocode} + \MH_let:NwN\label\MT_gobblelabel:w + \halign{% + \setboxz@h{$\m@th\displaystyle{##}$}% + \if_dim:w \wdz@>\totwidth@ + \global\totwidth@\wdz@ + \fi: + &\setboxz@h{\strut@{##}}% + \savetaglength@ + \crcr + #1% + \math@cr@@@ + }% + }% + \restorecounters@ + \if@fleqn + \global\advance\totwidth@\@mathmargin + \fi: + \iftagsleft@ + \if_dim:w \totwidth@>\displaywidth + \global\MH_let:NwN\gdisplaywidth@\totwidth@ + \else: + \global\MH_let:NwN\gdisplaywidth@\displaywidth + \fi: + \fi: + \endgroup +} +% \end{macrocode} +% +% \subsection{Fixing \env{align}, \env{alignat}, and \env{flalign}} +% Just copy the definition of \cs{measure@} from \pkg{amsmath} and +% change one (1!) line like we did for \env{gather}. +% \begin{macrocode} +\def\measure@#1{% + \begingroup + \measuring@true + \global\eqnshift@\z@ + \global\alignsep@\z@ + \global\MH_let:NwN\tag@lengths\@empty + \global\MH_let:NwN\field@lengths\@empty + \savecounters@ + \global\setbox0\vbox{% + \MH_let:NwN\math@cr@@@\math@cr@@@align@measure + \everycr{\noalign{\global\tag@false +% \end{macrocode} +% The patch for \cs{raisetag}. +% \begin{macrocode} + \global\MH_let:NwN\raise@tag\default_raisetag: + \global\column@\z@}}% +% \end{macrocode} +% The patch. +% \begin{macrocode} + \MH_let:NwN\label\MT_gobblelabel:w + \global\row@\z@ + \tabskip\z@ + \halign{\span\align@preamble\crcr + #1% + \math@cr@@@ + \global\column@\z@ + \add@amps\maxfields@\cr + }% + }% + \restorecounters@ + \ifodd\maxfields@ + \global\advance\maxfields@\@ne + \fi: + \if_num:w \xatlevel@=\tw@ + \if_num:w \maxfields@<\thr@@ + \MH_let:NwN\xatlevel@\z@ + \fi: + \fi: + \setbox\z@\vbox{% + \unvbox\z@ \unpenalty \global\setbox\@ne\lastbox + }% + \global\totwidth@\wd\@ne + \if@fleqn \global\advance\totwidth@\@mathmargin \fi: + \global\MH_let:NwN\maxcolumn@widths\@empty + \begingroup + \MH_let:NwN\or:\relax + \loop + \global\setbox\@ne\hbox{% + \unhbox\@ne \unskip \global\setbox\thr@@\lastbox + }% + \ifhbox\thr@@ + \xdef\maxcolumn@widths{ \or: \the\wd\thr@@ \maxcolumn@widths}% + \repeat + \endgroup + \dimen@\displaywidth + \advance\dimen@-\totwidth@ + \if_case:w \xatlevel@ + \global\alignsep@\z@ + \MH_let:NwN\minalignsep\z@ + \@tempcntb\z@ + \if@fleqn + \@tempcnta\@ne + \global\eqnshift@\@mathmargin + \else: + \@tempcnta\tw@ + \global\eqnshift@\dimen@ + \global\divide\eqnshift@\@tempcnta + \fi: + \or: + \@tempcntb\maxfields@ + \divide\@tempcntb\tw@ + \@tempcnta\@tempcntb + \advance\@tempcntb\m@ne + \if@fleqn + \global\eqnshift@\@mathmargin + \global\alignsep@\dimen@ + \global\divide\alignsep@\@tempcnta + \else: + \global\advance\@tempcnta\@ne + \global\eqnshift@\dimen@ + \global\divide\eqnshift@\@tempcnta + \global\alignsep@\eqnshift@ + \fi: + \or: + \@tempcntb\maxfields@ + \divide\@tempcntb\tw@ + \global\advance\@tempcntb\m@ne + \global\@tempcnta\@tempcntb + \global\eqnshift@\z@ + \global\alignsep@\dimen@ + \if@fleqn + \global\advance\alignsep@\@mathmargin\relax + \fi: + \global\divide\alignsep@\@tempcntb + \fi: + \if_dim:w \alignsep@<\minalignsep\relax + \global\alignsep@\minalignsep\relax + \if_dim:w \eqnshift@>\z@ + \if@fleqn\else: + \global\eqnshift@\displaywidth + \global\advance\eqnshift@-\totwidth@ + \global\advance\eqnshift@-\@tempcntb\alignsep@ + \global\divide\eqnshift@\tw@ + \fi: + \fi: + \fi: + \if_dim:w \eqnshift@<\z@ + \global\eqnshift@\z@ + \fi: + \calc@shift@align + \global\tagshift@\totwidth@ + \global\advance\tagshift@\@tempcntb\alignsep@ + \if@fleqn + \if_num:w \xatlevel@=\tw@ + \global\advance\tagshift@-\@mathmargin\relax + \fi: + \else: + \global\advance\tagshift@\eqnshift@ + \fi: + \iftagsleft@ \else: + \global\advance\tagshift@-\displaywidth + \fi: + \dimen@\minalignsep\relax + \global\advance\totwidth@\@tempcntb\dimen@ + \if_dim:w \totwidth@>\displaywidth + \global\MH_let:NwN\displaywidth@\totwidth@ + \else: + \global\MH_let:NwN\displaywidth@\displaywidth + \fi: + \endgroup +} +% \end{macrocode} +% +% \subsection{Fixing \env{multline}} +% \begin{macro}{\EQ_multline_labelhack:n} +% \begin{macro}{\EQ_multline_labelhack_opt:nw} +% As \pkg{ntheorem} defines \cs{label} to have the syntax +% \cs{label}\marg{label}\oarg{name}, we need to make sure that it +% has that inside \env{multline} as well. Especially since the +% measuring phase of \env{multline} \emph{defines} \cs{label} as +% well. +% \begin{macrocode} +\def\EQ_multline_labelhack:n #1{% + \begingroup\measuring@false\label@in@display{#1}\endgroup} +\def\EQ_multline_labelhack_opt:nw #1[#2]{% + \begingroup\measuring@false\label@in@display{#1}[#2]\endgroup} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \begin{macro}{\multline@} +% Patching \env{multline} takes more work because it does its +% processing differently, so we need to apply hooks twice: One in +% the measuring phase \cs{mmeasure@} where \cs{label} is redefined +% and one in the production phase \cs{multline@} where the ordinary +% \cs{label} is gobbled (we use \cs{MT_gobblelabel:w} as +% before). First the typesetting phase. +% \begin{macrocode} +\def\multline@#1{% + \Let@ + \@display@init{\global\advance\row@\@ne \global\dspbrk@lvl\m@ne}% + \chardef\dspbrk@context\z@ + \restore@math@cr + \MH_let:NwN\tag\tag@in@align +% \end{macrocode} +% The patch for \cs{raisetag}. +% \begin{macrocode} + \global\tag@false \global\MH_let:NwN\raise@tag\default_raisetag: + \mmeasure@{#1}% + \MH_let:NwN\tag\gobble@tag +% \end{macrocode} +% The patch. +% \begin{macrocode} + \MH_let:NwN\label\MT_gobblelabel:w + \tabskip \if@fleqn \@mathmargin \else: \z@skip \fi: + \totwidth@\displaywidth + \if@fleqn + \advance\totwidth@-\@mathmargin + \fi: + \halign\bgroup + \hbox to\totwidth@{% + \if@fleqn + \hskip \@centering \relax + \else: + \hfil + \fi: + \strut@ + $\m@th\displaystyle{}##\endmultline@math + \hfil + }% + \crcr + \if@fleqn + \hskip-\@mathmargin + \def\multline@indent{\hskip\@mathmargin}% put it back + \else: + \hfilneg + \def\multline@indent{\hskip\multlinegap}% + \fi: + \iftagsleft@ + \iftag@ + \begingroup + \ifshifttag@ + \rlap{\vbox{% + \normalbaselines + \hbox{% + \strut@ + \make@display@tag + }% + \vbox to\lineht@{}% + \raise@tag + }}% + \multline@indent + \else: + \setbox\z@\hbox{\make@display@tag}% + \dimen@\@mathmargin \advance\dimen@-\wd\z@ + \if_dim:w \dimen@<\multlinetaggap + \dimen@\multlinetaggap + \fi: + \box\z@ \hskip\dimen@\relax + \fi: + \endgroup + \else: + \multline@indent + \fi: + \else: + \multline@indent + \fi: + #1% +} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\mmeasure@} +% Then redefine the label correctly. +% \begin{macrocode} +\def\mmeasure@#1{% + \begingroup + \measuring@true +% \end{macrocode} +% The patch. +% \begin{macrocode} + \def\label##1{% + \@ifnextchar[ + {\EQ_multline_labelhack_opt:nw {##1}} + {\EQ_multline_labelhack:n {##1}} + } + \def\math@cr@@@{\cr}% + \MH_let:NwN\shoveleft\@iden \MH_let:NwN\shoveright\@iden + \savecounters@ + \global\row@\z@ + \setbox\@ne\vbox{% + \global\MH_let:NwN\df@tag\@empty + \halign{% + \setboxz@h{\@lign$\m@th\displaystyle{}##$}% + \iftagsleft@ + \if_num:w \row@=\@ne + \global\totwidth@\wdz@ + \global\lineht@\ht\z@ + \fi: + \else: + \global\totwidth@\wdz@ + \global\lineht@\dp\z@ + \fi: + \crcr + #1% + \crcr + }% + }% + \if_meaning:NN + \df@tag\@empty + \else: + \global\tag@true + \fi: + \if@eqnsw\global\tag@true\fi: + \iftag@ + \setboxz@h{% + \if@eqnsw + \stepcounter{equation}% + \tagform@\theequation + \else: + \df@tag + \fi: + }% + \global\tagwidth@\wdz@ + \dimen@\totwidth@ + \advance\dimen@\tagwidth@ + \advance\dimen@\multlinetaggap + \iftagsleft@\else: + \if@fleqn + \advance\dimen@\@mathmargin + \fi: + \fi: + \if_dim:w \dimen@>\displaywidth + \global\shifttag@true + \else: + \global\shifttag@false + \fi: + \fi: + \restorecounters@ + \endgroup +} +% \end{macrocode} +% \end{macro} +% +% \subsection{Setting End Marks Correctly} +% +% \begin{macro}{\mintagvsep} +% \changes{v1.05}{2004/02/16}{Introduced \cs{mintagvsep} to +% support the \pkg{ntheorem} package} +% \begin{macro}{\EQ_only_endmark:} +% \changes{v1.05}{2004/02/16}{Introduced \cs{EQ_only_endmark:} +% to support the \pkg{ntheorem} package} +% \changes{v2.11}{2004/08/03}{Make sure the tag is printed even with the +% \pkg{mathtools} key \key{showonlyrefs} activated} +% \begin{macro}{\EQ_tag_plus_endmark:} +% \changes{v1.05}{2004/02/16}{Introduced +% \cs{EQ_tag_plus_endmark:} to support the \pkg{ntheorem} package} +% \pkg{ntheorem} provides an extension to the theorem environment +% and also supports automatic end of theorem marks. To do so it must +% redefine parts of the \pkg{amsmath} code and it eventually ends up +% in problems when the tags and the marker are all typeset at the +% right margin. +% +% There are basically two different possibilities: +% \begin{center}\hfill +% \unitlength2.5pt \thicklines +% \begin{picture}(60,45)(0,25) +% \put(0,50){\framebox(25,20){Math Height}} +% \put(0,25){\framebox(25,25){Math Depth}} +% \put(40,50){\framebox(20,10){Tag height}} +% \put(40,45){\framebox(20,5){Tag depth}} +% \put(40,25){\framebox(20,10){Marker}} +% \put(50,35){\vector(0,1){10}} +% \put(50,45){\vector(0,-1){10}} +% \put(50,39){\ \ $\delta>0$} +% \multiput(26,25)(2,0){7}{\line(1,0){1}} +% \end{picture} \hfill\vrule\hfill +% \begin{picture}(60,45)(0,25) +% \put(0,50){\framebox(25,20){Math Height}} +% \put(0,40){\framebox(25,10){Math Depth}} +% \put(40,50){\framebox(20,10){Tag height}} +% \put(40,45){\framebox(20,5){Tag depth}} +% \put(40,28){\framebox(20,10){Marker}} +% \put(50,38){\vector(0,1){7}} +% \put(50,45){\vector(0,-1){7}} +% \put(50,40){\ \ $\delta=0$} +% \end{picture}\hfill\mbox{} +% \end{center} +% Let's look closer at this. $h_M$ is the height of the end of +% theorem marker, which we'll try to place so that its baseline +% aligns with the bottom of the math display. $d_D$ is the depth of +% the the last line of the math display including the depth of the +% surrounding boxes while $d_T$ is the depth of the tag. Also we let +% $m$ denote the minimum vertical distance between tag and marker +% and $\delta$ is some positive length that may be added to $m$ +% depending on the other values. To ensure a ``proper'' placement of +% the marker we simply test the inequality +% \begin{gather} +% h_M + d_T + m > d_D \label{eq:tag_placement} +% \end{gather} +% If the test is true we're done and just have to set the marker so +% that the top of it is placed at a distance of $m$ from the bottom +% of the tag. If it's not we can safely put the marker at the bottom +% of the display. +% \begin{macrocode} +\newlength\mintagvsep +\mintagvsep5pt +\def\EQ_only_endmark:{% + \MH_set_boolean_T:n {show_manual_tags} + \global\tag@true + \iftagsleft@ + \gdef\df@tag{% + \hbox to \displaywidth{% + \hss +% \end{macrocode} +% If the tags are set to the left we just have to lower the end mark +% by the total depth of the display including its surrounding box. +% Also we have to take care of \cs{normallineskip}. +% \begin{macrocode} + \raisebox{-\normallineskip + -\depthof{\EQ_outerbox:{}} + -\heightof{\EQ_outerbox:{}} + -\dp\EQ_mathdisplay_box + -\ht\EQ_mathdisplay_box} + [0pt][0pt]{\PotEndMark{\maketag@@@}}}} + \else: + \gdef\df@tag{% + \raisebox{-\dp\EQ_mathdisplay_box + -\depthof{\EQ_outerbox:{}}} + {\PotEndMark{\maketag@@@}}}% + \fi:} +% \end{macrocode} +% \changes{v2.00}{2004/04/14}{Fixed another bug in placement of the +% marker} +% \changes{v2.10}{2004/07/26}{Fixed horizontal spacing in \env{equation}} +% In v2.00 I fixed another bug I had overlooked. This is getting +% embarrassing. The outer box must be taken into account as well. +% \begin{macrocode} +\def\EQ_tag_plus_endmark:{% + \iftagsleft@ + \gdef\maketag@@@##1{% +% \end{macrocode} +% The following fixes a bug when there is a wide tag in an +% \env{equation} environment and was reported by Bernard +% Alfonsi.\footnote{\email{alfonsi@math.u-psud.fr}} The problem +% arises when \pkg{ntheorem} tries to typeset a tag and an end mark, +% because the tag is set at the left margin and the end mark at the +% right margin and \pkg{ntheorem} over-simplifies this and forgets +% to take the displayed math into account! The right solution is to +% wrap the tag in a box of the correct size, namely |\widthof{##1}| +% and then push the end mark to the right margin. Then the displayed +% math is set correcly. +% \begin{macrocode} + \hfuzz\displaywidth + \makebox[\widthof{##1}][l]{% + \hbox to \displaywidth{\m@th\normalfont##1\hss + \raisebox{-\dp\EQ_mathdisplay_box + -\depthof{\EQ_outerbox:{}}} + {\PotEndMark{\hss}}}}}% + \else: + \gdef\maketag@@@##1{% + \hbox{\m@th\normalfont##1\llap{\hss\PotEndMark{% + \settoheight{\@tempdima}{\@nameuse{\InTheoType Symbol}}% + \MH_addtolength:dn \@tempdima + {\g_EQ_bottomtag_depth_dim+\mintagvsep} + \setlength{\@tempdimb} + {\g_EQ_bottomrow_depth_dim+\depthof{\EQ_outerbox:{}} + +\depthof{\EQ_innerbox:{}}} + \if_dim:w \@tempdima>\@tempdimb + \MH_setlength:dn \@tempdima{-\dp\EQ_mathdisplay_box + -\@tempdima+\g_EQ_bottomrow_depth_dim} + \addtolength{\@tempdima}{\depthof{\EQ_innerbox:{}}}% + \def\EQ_next:{\raisebox{\@tempdima}}% + \else: +% \end{macrocode} +% \changes{v1.06}{2004/03/13}{Fixed bug in placement of the marker +% and re-arranged some code} +% In v1.06 I fixed a stupid bug regarding placement of the marker. +% If I had done a proper test I would have discovered it +% immediately! +% \begin{macrocode} + \def\EQ_next:{ + \raisebox{-\dp\EQ_mathdisplay_box + -\depthof{\EQ_outerbox:{}}}}% + \fi:\EQ_next:}}}}% + \fi:} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\MT_nonumber:} +% \begin{macrocode} +\MH_let:NwN \MT_nonumber: \nonumber +% \end{macrocode} +% \end{macro} +% \begin{macro}{\nonumber} +% Redefine \cs{nonumber} to reset depth of bottom tag. +% \begin{macrocode} +\def\g_EQ_latest_nonzerodepth_row_fint{\z@} +\renewcommand*\nonumber{ + \@tempcnta=\row@ + \if_num:w \l_EQ_equationtype_int=\thr@@ + \advance\@tempcnta\m@ne + \else: + \if_num:w \l_EQ_equationtype_int=4\relax + \advance\@tempcnta\m@ne + \fi: + \fi: + \if_num:w \g_EQ_latest_nonzerodepth_row_fint=\@tempcnta + \else: + \global\g_EQ_bottomtag_depth_dim=-\baselineskip + \fi: + \MT_nonumber: +} +% \end{macrocode} +% \end{macro} +% +% End of \pkg{ntheorem} patches. +% \begin{macrocode} +%</ntheorem> +% \end{macrocode} +% \Finale +\endinput |