Sharing alignment between equations in two different items
This is absolutely insane, but it works:
\documentclass{article}
\usepackage{amsmath}
\begin{document}
This is a list.
\begin{itemize}
\item First item.
\begin{align*}
f(x) &= \begin{cases} 0 & \text{now} \\ 1 & \text{then} \end{cases}
\intertext{\item Second item.}
g(x) &= \begin{cases} 0 & \text{here and there} \\ 1 & \text{to and fro} \end{cases}
\end{align*}
\end{itemize}
After the list.
\end{document}
The amsmath
alignment environments allow \intertext
to insert non-alignment non-math text inside without exiting. The alignment is preserved across the insertion, which is what you want.
Caveat: the first \item
must not be an \intertext
, or else \itemize
complains. The others, as you see, can be.
Example output:
I have encountered this situation a lot and the following method can be adapted to almost all cases. Similar to Barbara's solution, this involves deciding what is the largest text and using \makebox
to set the type into a box equal to the width of the largest string.
If also inserted a few \phantoms
to get exact alignment of the cases.
\documentclass{article}
\usepackage{amstext}
\newcommand*{\LongestText}{fermentum fringilla mauris }%
\newlength{\LargestSize}%
\settowidth{\LargestSize}{\LongestText}%
\newcommand*{\MakeBox}[1]{\makebox[\LargestSize][l]{#1}}%
\newcommand*{\MakeBoxText}[1]{\text{\MakeBox{#1}}}%
\begin{document}
\begin{itemize}
\item Lorem ipsum dolor sit amet, consectetur adipiscing elit:
\begin{equation}
f(x) = \left\{
\begin{array}{l l}
1\phantom{-} & \MakeBoxText{ nisl justo, hendrerit} \\
0\phantom{-} & \MakeBoxText{ sagittis condimentum}
\end{array} \right.
\end{equation}
\item Duis magna nunc, ultrices at fringilla non, feugiat sed massa:
\begin{equation}
g(x) = \left\{
\begin{array}{l l}
-1 & \MakeBoxText{ fermentum fringilla mauris eget} \\
\phantom{-}0 & \MakeBoxText{ gravida ipsum vitae}
\end{array} \right.
\end{equation}
\end{itemize}
\end{document}
Update: 2011-09-23: In order to be able to handle a general case you can use the technique shown above to each element of the function separately:
- the function name
- the case values
- the case text
Then each portion gets places in a fixed width box and everything lines up exactly even with more complicated expressions:
Below, I have three macros which are to be used for each of the portions. I have chosen a [r]
alignment for the function name, and a [l]
alignment for the case values and case text.
\documentclass{article}
\usepackage{amsmath}
\newcommand*{\LongestName}{\ensuremath{h(x)+g(x)}}% function name
\newcommand*{\LongestValue}{\ensuremath{-1}}% function value
\newcommand*{\LongestText}{fermentum fringilla mauris }%
\newlength{\LargestNameSize}%
\newlength{\LargestValueSize}%
\newlength{\LargestTextSize}%
\settowidth{\LargestNameSize}{\LongestName}%
\settowidth{\LargestValueSize}{\LongestValue}%
\settowidth{\LargestTextSize}{\LongestText}%
% Choose alignment of the various elements here: [r], [l] or [c]
\newcommand*{\MakeBoxName}[1]{{\makebox[\LargestNameSize][r]{\ensuremath{#1}}}}%
\newcommand*{\MakeBoxValue}[1]{\ensuremath{\makebox[\LargestValueSize][l]{\ensuremath{#1}}}}%
\newcommand*{\MakeBoxText}[1]{\makebox[\LargestTextSize][l]{#1}}%
\begin{document}
\begin{itemize}
\item Lorem ipsum dolor sit amet, consectetur adipiscing elit:
\begin{equation}
\MakeBoxName{f(x)} = \left\{
\begin{array}{l l}
\MakeBoxValue{1} & \MakeBoxText{ nisl justo, hendrerit} \\
\MakeBoxValue{0} & \MakeBoxText{ sagittis condimentum}
\end{array} \right.
\end{equation}
\item Duis magna nunc, ultrices at fringilla non, feugiat sed massa:
\begin{equation}
\MakeBoxName{g(x)} = \left\{
\begin{array}{l l}
\MakeBoxValue{-1} & \MakeBoxText{ fermentum fringilla mauris eget}\\
\MakeBoxValue{\phantom{-}0} & \MakeBoxText{ gravida ipsum vitae}
\end{array} \right.
\end{equation}
\item Duis magna nunc, ultrices at fringilla non, feugiat sed massa:
\begin{equation}
\MakeBoxName{h(x)+g(x)} = \left\{
\begin{array}{l l}
\MakeBoxValue{\sin x} & \MakeBoxText{ fermentum fringilla mauris eget} \\
\MakeBoxValue{0} & \MakeBoxText{ gravida ipsum vitae}
\end{array} \right.
\end{equation}
\end{itemize}
\end{document}
Not sure how you prefer to have the function values aligned, but this is how I have been aligning them. You can remove the \phantom{-}
and and adjust the alignments as desired.
Let me submit a second answer that also addresses the issue of aligning across paragraphs. It is equally insane...
\documentclass{article}
% \usepackage{showframe}
\usepackage{amsmath}
% It's like {align}, but simple!
\newenvironment{SimpleAlign}
{%
\let\\=\cr
\tabskip 0pt plus 1fil\relax
\halign\bgroup
&\hfil$\displaystyle ##$\tabskip 0pt\relax
&$\displaystyle {}##$\hfil\tabskip 0pt plus 1fil\relax\cr
}
{%
\crcr\egroup
}
% Saves its contents typeset like SimpleAlign. You can give it a name.
\newenvironment{AlignAgain}[1][AlignBox]
{%
\expandafter\let\expandafter\AlignAgainBox\csname #1\endcsname
\setbox\AlignAgainBox=\vbox\bgroup\SimpleAlign
}
{%
\endSimpleAlign\egroup
\ReBox\AlignAgainBox
}
\newbox\AlignBox
% Prints the lines from {AlignAgain} one-by-one, with or without equation numbers as starred. If you named the {AlignAgain}, use it here.
\makeatletter
\newcommand\ALineAgain{%
\@ifstar
{\AlignAgainStartrue\@ALineAgain}
{\AlignAgainStarfalse\@ALineAgain}%
}
\newcommand\@ALineAgain[1][AlignBox]{%
\expandafter\let\expandafter\AlignAgainBox\csname #1\endcsname
\begin{equation*}
\PutFirstBox\ifAlignAgainStar\AlignAgainBox
\end{equation*}
}
\makeatother
\newif\ifAlignAgainStar
% Reboxes a box in the format: {[1][2]...[n]} -> {[1]{[2]{...}[n]}}
% {...} = \hbox
\newcommand{\ReBox}[1]
{%
% To enter internal vertical mode, where \lastbox is valid
\setbox0=\vbox{%
\unvbox#1\relax
\global\setbox#1=\hbox{\hbox{}}
\loop
\unskip
%\box0 is the box currently at the end of #1
\setbox0=\lastbox
\ifvoid0\relax
\else
\global\setbox#1=\hbox{\box0\box#1}%
\repeat
}%
}
% Puts the first box in a nested-box list into the display, saving the rest back in #1
% Optionally places an equation number
\newcommand{\PutFirstBox}[2]{%
\hbox to \displaywidth{%
\unhbox#2\relax
\global\setbox#2=\lastbox
\setbox0=\lastbox
\unhbox0%
#1\else\refstepcounter{equation}\llap{(\theequation)}\fi
}%
}
\begin{document}
\begin{AlignAgain}
a &= b & c &= d \\
f(x) &= g(x) & h(x) &= e^{-1/x^2}
\end{AlignAgain}
This is a paragraph with a lot of redundant words whose only purpose is to extend it onto a new line or two so it's dramatic when I display this equation:
\ALineAgain*
and then follow it with a bunch more text.
And also a new paragraph, just for good measure. I wonder if the two equations will line up? I sure hope so!
\ALineAgain
This is sort of fun.
\end{document}
My first thought was to hack apart the result of an {align}
and dole out the lines one-by-one wherever you want them. Alas, {align}
produces a list of considerable complexity and it is not worth the effort to unravel it (if that's even possible).
So I made my own alignment environment that, as far as I can tell, does what you'd want {align*}
to do but produces a very simple list. My macro \ALineAgain
then picks that list apart and drops the lines one at a time wherever you ask.
Because the lines are not printed where the alignment is actually given, it makes no sense to have an {AlignAgain*}
; it never prints equation numbers. Instead, the \ALineAgain
macro takes a star that suppresses the addition of an equation number.