% \iffalse meta-comment
%
% Copyright (C) 2004 Scott Pakin <scott+eqp@pakin.org>
% ----------------------------------------------------
%
% This package may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either version 1.2
% 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.2 or later is part of all distributions of LaTeX
% version 1999/12/01 or later.
%
% \fi
% \iffalse
%% File: eqparbox.dtx Copyright (C) 2004 Scott Pakin <scott+eqp@pakin.org>
%
%<package>\NeedsTeXFormat{LaTeX2e}
%<package>\ProvidesPackage{eqparbox}
%<package>         [2004/08/02 v2.1 Create equal-widthed parboxes]
%
%<*driver>
\documentclass{ltxdoc}
\usepackage{eqparbox}
\EnableCrossrefs
\CodelineIndex
\RecordChanges

% Uncomment the following line if you don't want to include a
% source-code listing.
%\OnlyDescription

% Give LaTeX some more leeway in placing floats
% (suggested by Donald Arseneau <asnd@triumf.ca>).
\renewcommand{\topfraction}{0.85}
\renewcommand{\bottomfraction}{0.7}
\renewcommand{\textfraction}{0.15}
\renewcommand{\floatpagefraction}{0.66}
\renewcommand{\dbltopfraction}{0.66}
\renewcommand{\dblfloatpagefraction}{0.66}
\setcounter{topnumber}{9}
\setcounter{bottomnumber}{9}
\setcounter{totalnumber}{20}
\setcounter{dbltopnumber}{9}

% Because we put table captions *above* tables, we should add a
% little extra space between the caption and the table.
\setlength{\belowcaptionskip}{2ex}

\begin{document}
\DocInput{eqparbox.dtx}
\end{document}
%</driver>
% \fi
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% \CheckSum{169}
% \GetFileInfo{eqparbox.sty}
%
% \title{The \textsf{eqparbox} package\thanks{This file
%         has version number \fileversion, last
%         revised \filedate.}}
% \author{Scott Pakin \\ \textit{scott+eqp@pakin.org}}
% \date{\filedate}
% \maketitle
%
% \changes{v1.0}{2001/04/19}{Initial version}
% \changes{v2.0}{2004/07/31}{Rewrote to use only two \meta{dimen}s total
%   and the rest macros (problem reported by Gilles P\'erez-Lambert and
%   Plamen Tanovski; solution suggested by David Kastrup and Donald
%   Arseneau)}
%
% \DoNotIndex{\@auxout,\@ifnextchar,\@ifundefined}
% \DoNotIndex{\begin,\begingroup,\csname,\DeclareRobustCommand,\def}
% \DoNotIndex{\else,\end,\endcsname,\endgroup,\expandafter,\fi,\gdef,\global}
% \DoNotIndex{\hbox,\ifdim,\ifx,\immediate,\let}
% \DoNotIndex{\newcommand,\newdimen,\newif,\newlength,\noexpand}
% \DoNotIndex{\relax,\setbox,\space,\string,\the,\wd,\xdef,\z@}
%
% \begin{abstract}
%   The \textsf{eqparbox} package makes it easy to define a group of
%   \verb|\parbox|es whose members all have the same width, the natural
%   width of the widest member.  A document can contain any number of
%   groups, and each group can contain any number of members.  This
%   simple, equal-width mechanism can be used for a variety of alignment
%   purposes, as is evidenced by the examples in this document.
% \end{abstract}
%
% \section{Motivation}
%
% Let's start with a little test.  How would you typeset
% Table~\ref{tbl:sales-data}, in which the numbers are right-justified
% relative to each other but centered as a group within each column.
% And second, how would you typeset the r\'esum\'e excerpt shown in
% Figure~\ref{fig:resume-excerpt} while meeting the following
% requirements:
%
% \begin{enumerate}
%   \item The header columns must be left-justified relative to each
%         other.
%   \item The headers columns should be evenly spaced across the page.
%   \item Page breaks should be allowed within the r\'esum\'e.
% \end{enumerate}
%
% \begin{table}[tp]
% \centering
% \caption{Sample sales data}
% \label{tbl:sales-data}
% \begin{tabular}{@{}lccc@{}} \hline
%   & \multicolumn{3}{c}{Sales (in millions)} \\ \cline{2-4}
%   \multicolumn{1}{c}{\raisebox{1ex}[2ex]{Product}} &
%   October & November & December \\ \hline
%
%   Widgets      & \eqparbox{oct}{\raggedleft         55.2 } &
%                  \eqparbox{nov}{\raggedleft\textbf{ 89.2}} &
%                  \eqparbox{dec}{\raggedleft         57.9 } \\
%   Doohickeys   & \eqparbox{oct}{\raggedleft\textbf{ 65.0}} &
%                  \eqparbox{nov}{\raggedleft         64.1 } &
%                  \eqparbox{dec}{\raggedleft          9.3 } \\
%   Thingamabobs & \eqparbox{oct}{\raggedleft         10.4 } &
%                  \eqparbox{nov}{\raggedleft          8.0 } &
%                  \eqparbox{dec}{\raggedleft\textbf{109.7}} \\ \hline
% \end{tabular}
% \end{table}
%
% \begin{figure}
% \bigskip\noindent\rule{\linewidth}{1pt}\bigskip\par
% \noindent%
% \eqparbox{place}{\textbf{Widgets, Inc.}} \hfill
% \eqparbox{title}{\textbf{Senior Widget Designer}} \hfill
% \eqparbox{dates}{\textbf{1/95--present}}
%
% \begin{itemize}
%   \item Supervised the development of the new orange and blue widget lines.
%   \item Improved the design of various widgets, making them less sticky
%         and far less likely to explode.
%   \item Made widget management ten times more cost-effective.
% \end{itemize}
%
% \noindent%
% \eqparbox{place}{\textbf{Thingamabobs, Ltd.}} \hfill
% \eqparbox{title}{\textbf{Lead Engineer}} \hfill
% \eqparbox{dates}{\textbf{9/92--12/94}}
%
% \begin{itemize}
%   \item Found a way to make thingamabobs run on solar power.
%   \item Drafted a blueprint for a new doohickey-compatibility module for
%         all cool-mint thingamabobs.
%   \item Upgraded superthingamabob specification document from Microsoft
%         Word to \LaTeXe.
% \end{itemize}
% \noindent\rule{\linewidth}{1pt}
% \caption{Excerpt from a sample r\'esum\'e}
% \label{fig:resume-excerpt}
% \end{figure}
%
% The two questions can be answered the same way: by putting various
% blocks of text into equal-widthed boxes.  if the data in
% Table~\ref{tbl:sales-data} are put into equal-sized |\parbox|es, each
% containing a |\raggedleft| for right-justification, the |\parbox|es
% can then be centered to achieve the desired result.  Similarly, if the
% company names in Figure~\ref{fig:resume-excerpt} are both put in a
% |\parbox| as wide as ``Thingamabobs, Ltd.,'' the job titles in a
% |\parbox| as wide as ``Senior Widget Designer,'' and the dates in a
% |\parbox| as wide as ``1/95--present,'' then they can be spaced evenly
% by separating them with |\hfill|s.
%
% The problem is in choosing the width for each set of |\parbox|es.  For
% Table~\ref{tbl:sales-data}, this isn't too difficult, because digits
% are the same width as each other in most fonts.  Each |\parbox|,
% therefore, need be only as wide as the largest sequence of digits
% expected.  Figure~\ref{fig:resume-excerpt} is more of a bother.  The
% user must typeset the r\'esum\'e once to see which entry in each
% column is the widest and then assign lengths appropriately:
%
% \begin{verbatim}
%     \newlength{\placewidth}
%     \settowidth{\placewidth}{Thingamabobs, Ltd.}         % Employment 2
%     \newlength{\jobtitlewidth}
%     \settowidth{\jobtitlewidth}{Senior Widget Designer}  % Employment 1
%     \newlength{\dateswidth}
%     \settowidth{\dateswidth}{1/95--present}              % Employment 1
% \end{verbatim}
%
% \noindent
% Every time a piece of information changes, it must be changed in two
% places: in the r\'esum\'e itself and in the |\settowidth|
% command.  When employment information is added or deleted, the
% |\settowidth| commands must be modified to reflect the new
% maximum-widthed entry in each column.  If only there were a simpler
% way to keep a set of |\parbox|es as wide as the widest entry in the
% set\,\dots
%
% That simpler way is the \textsf{eqparbox} package.  \textsf{eqparbox}
% exports a macro, |\eqparbox|, which works just like |\parbox|, except
% that instead of specifying the width of the box, one specifies the
% group that the box belongs to.  All boxes in the same group will be
% typeset as wide as the widest member of the group.  In that sense, an
% |\eqparbox| behaves like a cell in an~|l|, |c|, or~|r| column in a
% |tabular|; |\eqparbox|es in the same group are analogous to
% cells in the same column.
%
% \section{Usage}
%
% \DescribeMacro{\eqparbox}
% The primary macro in the \textsf{eqparbox} package is |\eqparbox|.
% Usage is almost identical to that of |\parbox|:
%
% \begin{center}
% |\eqparbox| \oarg{pos} \oarg{height} \oarg{inner-pos}
% \marg{tag} \marg{text}
% \end{center}
%
% \noindent
% The only difference is that, where |\parbox| has its \meta{width}
% argument, |\eqparbox| has \meta{tag}.  (For a description of the
% remaining arguments, look up |\parbox| in any \LaTeXe\ book or in
% the \texttt{usrguide.tex} file that comes with \LaTeXe.)  \meta{tag}
% can be any valid identifier.  All |\eqparbox|es with the same tag
% will be typeset in a box wide enough to hold the widest of them.
% Discounting \TeX's limitations, any number of tags can be used in the
% same document, and any number of |\eqparbox|es can share a tag.
%
% The only catch is that \texttt{latex} will need to be run a second
% time for the various box widths to stabilize.
%
% \bigskip
%
% \DescribeMacro{\eqboxwidth}
% It is sometimes useful to take the width of an |\eqparbox| to use in
% other \LaTeX{} commands.  While the width can be determined by
% creating an |\eqparbox| and using |\settowidth| to measure it, the
% \textsf{eqparbox} package defines a convenience routine called
% |\eqboxwidth| that achieves the same result.
%
% |\eqboxwidth| makes it easy to typeset something like
% Table~\ref{tbl:mixed-tabular}.  Table~\ref{tbl:mixed-tabular}'s only
% column expands to fit the widest cell in the column, excluding the
% final cell.  The final cell's text word-wraps within whatever space is
% allocated to it.  In a sense, the first four cells behave as if they were
% typeset in an~|l| column, while the final cell behaves as if it were
% typeset in a~|p| column.  In actuality, the column is an~|l| column;
% an |\eqparbox| for the first four cells ensures the column stretches
% appropriately, while a |\parbox| of width |\eqboxwidth{|\meta{tag}|}|
% in the final cell ensures that the final cell word-wraps.
%
% \begin{table}
% \centering
% \caption{A \texttt{tabular} that stretches to fit some cells while
% forcing others to wrap}
% \label{tbl:mixed-tabular}
% \DeleteShortVerb{\|}
% \begin{tabular}{|@{}l@{}|}
%   \hline
%   \eqparbox[b]{wtab}{Wide} \\ \hline
%   \eqparbox[b]{wtab}{Wider} \\ \hline
%   \eqparbox[b]{wtab}{Wider than that} \\ \hline
%   \eqparbox[b]{wtab}{This is a fairly wide cell} \\ \hline
%   \parbox[b]{\eqboxwidth{wtab}}{\strut
%     While this cell's text wraps, the previous cells (whose text
%     doesn't wrap) determine the width of the column.} \\ \hline
% \end{tabular}
% \MakeShortVerb{\|}
% \end{table}
%
% \section{Examples}
%
% Figure~\ref{fig:resume-excerpt}'s headings were typeset with the
% following code:
%
% \begin{verbatim}
%     \noindent%
%     \eqparbox{place}{\textbf{Widgets, Inc.}} \hfill
%     \eqparbox{title}{\textbf{Senior Widget Designer}} \hfill
%     \eqparbox{dates}{\textbf{1/95--present}}
% \end{verbatim}
% \centerline{$\vdots$}
% \begin{verbatim}
%     \noindent%
%     \eqparbox{place}{\textbf{Thingamabobs, Ltd.}} \hfill
%     \eqparbox{title}{\textbf{Lead Engineer}} \hfill
%     \eqparbox{dates}{\textbf{9/92--12/94}}
% \end{verbatim}
% \centerline{$\vdots$}
% \bigskip
%
% \noindent
% Table~\ref{tbl:sales-data} was entered as follows:
%
% \begin{verbatim}
%     \begin{tabular}{@{}lccc@{}} \hline
%       & \multicolumn{3}{c}{Sales (in millions)} \\ \cline{2-4}
%       \multicolumn{1}{c}{\raisebox{1ex}[2ex]{Product}} &
%       October & November & December \\ \hline
%
%       Widgets      & \eqparbox{oct}{\raggedleft         55.2 } &
%                      \eqparbox{nov}{\raggedleft\textbf{ 89.2}} &
%                      \eqparbox{dec}{\raggedleft         57.9 } \\
%       Doohickeys   & \eqparbox{oct}{\raggedleft\textbf{ 65.0}} &
%                      \eqparbox{nov}{\raggedleft         64.1 } &
%                      \eqparbox{dec}{\raggedleft          9.3 } \\
%       Thingamabobs & \eqparbox{oct}{\raggedleft         10.4 } &
%                      \eqparbox{nov}{\raggedleft          8.0 } &
%                      \eqparbox{dec}{\raggedleft\textbf{109.7}} \\ \hline
%     \end{tabular}
% \end{verbatim}
%
% \noindent
% Note that the above can be simplified by defining a macro that
% combines |\eqparbox| and |\raggedleft|.  Furthermore, because the
% numeric data being typeset are all approximately the same width, a
% single tag could reasonably replace |oct|, |nov|, and |dec|.  As it
% stands, the code serves more as an illustration than as an optimal way
% to typeset Table~\ref{tbl:sales-data}.
%
% Finally, Table~\ref{tbl:mixed-tabular} was typeset using the
% following code:
%
% \begin{verbatim}
%     \begin{tabular}{|@{}l@{}|}
%       \hline
%       \eqparbox[b]{wtab}{Wide} \\ \hline
%       \eqparbox[b]{wtab}{Wider} \\ \hline
%       \eqparbox[b]{wtab}{Wider than that} \\ \hline
%       \eqparbox[b]{wtab}{This is a fairly wide cell} \\ \hline
%       \parbox[b]{\eqboxwidth{wtab}}{\strut
%         While this cell's text wraps, the previous cells (whose text
%         doesn't wrap) determine the width of the column.} \\ \hline
%     \end{tabular}
% \end{verbatim}
%
% As an additional example, consider the paragraphs depicted in
% Figure~\ref{fig:hang-indent}.  We'd like the paragraph labels set on
% the left, as shown, but we'd also like to allow both intra-~and
% inter-paragraph page breaks.  Of course, if the labels are made wider
% or narrower, we'd like the paragraph widths to adjust automatically.
% (Can any word processor do that, incidentally?)  By using a custom
% |list| environment which typesets its labels with |\eqparbox|, this is
% fairly straightforward:
%
% \begin{figure}[tbp]    ^^A NOT "here" (in case the default is changed)
% \rule{\linewidth}{1pt}
% \begin{list}{}{^^A
%   \renewcommand{\makelabel}[1]{\eqparbox[b]{listlab}{#1}}^^A
%   \setlength{\labelwidth}{\eqboxwidth{listlab}}^^A
%   \setlength{\labelsep}{2em}^^A
%   \setlength{\parsep}{2ex plus 2pt minus 1pt}^^A
%   \setlength{\itemsep}{0pt}^^A
%   \setlength{\leftmargin}{\labelwidth}^^A
%   \addtolength{\leftmargin}{\labelsep}^^A
%   \setlength{\rightmargin}{0pt}}
%
%   \item[Stuff about me] I am great.  Blah, blah, blah, blah, blah,
%   blah, blah, blah, blah, blah, blah, blah, blah, blah, blah, blah,
%   blah, blah, blah, blah, blah, blah, blah, blah, blah, blah, blah,
%   blah, blah, blah, blah, blah, blah, blah, blah, blah, blah, blah,
%   blah.
%
%   \item[More stuff] I am wonderful.  Blah, blah, blah, blah, blah,
%   blah, blah, blah, blah, blah, blah, blah, blah, blah, blah, blah,
%   blah, blah, blah, blah, blah, blah, blah, blah, blah, blah, blah,
%   blah.
%
%   Did I mention that blah, blah, blah, blah, blah, blah, blah, blah,
%   blah, blah, blah, blah, blah, blah, blah?
%
%   \item[The final exciting thing] I am fantastic.  Blah, blah, blah,
%   blah, blah, blah, blah, blah, blah, blah, blah, blah, blah, blah,
%   blah, blah, blah, blah, blah, blah, blah, blah, blah.
% \end{list}
% \rule{\linewidth}{1pt}
% \caption{Paragraphs with hanging indentation}
% \label{fig:hang-indent}
% \end{figure}
%
% \begin{verbatim}
%     \begin{list}{}{%
%       \renewcommand{\makelabel}[1]{\eqparbox[b]{listlab}{#1}}%
%       \setlength{\labelwidth}{\eqboxwidth{listlab}}%
%       \setlength{\labelsep}{2em}%
%       \setlength{\parsep}{2ex plus 2pt minus 1pt}%
%       \setlength{\itemsep}{0pt}%
%       \setlength{\leftmargin}{\labelwidth+\labelsep}%
%       \setlength{\rightmargin}{0pt}}
%
%       \item[Stuff about me]  I am great.  Blah, blah, blah, ...
%
%       \item[More stuff]  I am wonderful.  Blah, blah, blah, ...
%
%       \item[The final exciting thing]  I am fantastic.  Blah,
%          blah, blah, ...
%     \end{list}
% \end{verbatim}
%
%
% \section{Limitations}
%
% Unfortunately, |\eqparbox| has a number of limitations not exhibited
% by the original |\parbox| command.  First, |\eqparbox| internally
% typesets the given text within a |tabular| environment---specifically,
% using ``|@{}l@{}|'' as the template---in order to determine the text's
% natural width.  Consequently, commands not valid within such a
% |tabular| (e.g.,~list environments) are also not valid within the
% \meta{text} argument of |\eqparbox|.  As a corollary, an |\eqparbox|
% can appear only where a |tabular| is also acceptable.
%
% A second limitation is that |\eqparbox| typesets its \meta{text}
% argument \emph{twice}: once within a |tabular| to determine the
% natural width and again within a parbox large enough to hold all text
% associated with tag \meta{tag}.  This approach may cause unexpected
% results if \meta{text} is non-idempotent (i.e.,~has side
% effects).  For example, if \meta{text} increments a counter, the
% counter will be incremented twice per invocation of |\eqparbox|.
%
%
% \StopEventually{^^A
%   \section{Future Work}
%
%   The following are some of the features people have requested I implement
%   in \textsf{eqparbox}:
%
%   \begin{itemize}
%     \item Evalaute \texttt{\string\eqparbox}'s \meta{text} argument
%       exactly once in case it contains side effects.  Currently,
%       \meta{text} is evaluated twice: once to determine its natural
%       size and once to put it in a parbox of the width associated with
%       the given tag.  (Feature requested by Bernd Schandl.)
%
%     \item Get \textsf{eqparbox} to work properly within an
%       \textsf{algorithmic} environment.  (Feature requested by Mike
%       Shell.)
%
%     \item Support pre-1999 \LaTeXe.  (Feature requested by Mike Shell.)
%   \end{itemize}
%
% One idea I've been toying with that may resolve the first two items in
% that list is to typeset \meta{text} within a parbox, then check
% \texttt{\string\badness} to see if the box was too small for
% \meta{text}.  If not (i.e.,~the box was not overfull), then the
% initial parbox can be reused directly without needing to re-typeset
% \meta{text}.  With this approach, \texttt{\string\eqparbox} will work
% anywhere \texttt{\string\parbox} works.  Unfortunately, I don't know
% how to get at the \texttt{\string\badness} of the
% \texttt{\string\hbox}es that comprise the \texttt{\string\vbox}
% utilized by \texttt{\string\parbox}.  If anyone has a suggestion, I'm
% all ears.
%
%   \PrintChanges
%   \PrintIndex
% }
%
% \section{Implementation}
%
% The one-sentence summary of the implementation is, ``As
% \textsf{eqparbox} goes along, it keeps track of the maximum width of
% each box type, and when it's finished, it writes those widths to
% the~|.aux| file for use on subsequent runs.''  If you're satisfied
% with that summary, then read no further.  Otherwise, get ready to
% tackle the following annotated code listing.
%
%    \begin{macrocode}
%<*package>
%    \end{macrocode}
%
% \begin{macro}{\eqp@tempdima}
% \begin{macro}{\eqp@tempdimb}
% Define a couple temporary \meta{dimen}s for use in a variety of locations.
%    \begin{macrocode}
\newlength{\eqp@tempdima} \newlength{\eqp@tempdimb}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\eqp@taglist}
% Define a list of all of the tags we encountered in the author's document.
%    \begin{macrocode}
\def\eqp@taglist{}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\ifeqp@must@rerun}
% \begin{macro}{\eqp@must@reruntrue}
% \begin{macro}{\eqp@must@rerunfalse}
% If an |eqparbox| is wider than the maximum-width |eqparbox| with the
% same tag, we need to store the new maximum width and request that the
% user re-run |latex|.  We use |\ifeqp@must@rerun| and |\eqp@must@reruntrue|
% to assist with this.
%    \begin{macrocode}
\newif\ifeqp@must@rerun
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
% At the |\end{document}|, for each tag \meta{tag} we see if
% |\eqp@next@|\meta{tag}, which was initialized to~|0.0pt|, is different
% from |\eqp@this@|\meta{tag}, which was initialized to the maximum box
% width from the previous run.  If so, we issue an informational
% message.  In any case, we initialize the next run's
% |\eqp@this@|\meta{tag} to |\eqp@next@|\meta{tag} and the next run's
% |\eqp@next@|\meta{tag} to |0pt|.
%    \begin{macrocode}
\AtEndDocument{%
  \begingroup
%    \end{macrocode}
% \begin{macro}{\@elt}
% The |\eqp@taglist| list is of the form ``|\@elt| |{|\meta{tag$_1$}|}|
% |\@elt| |{|\meta{tag$_2$}|}|~\ldots''.  We therefore locally define
% |\@elt| to take the name of a tag and perform all of the checking
% described above and then merely execute |\eqp@taglist|.
% \changes{v2.0}{2004/08/01}{Modified to allow numbers in tag names
%   (suggested by Martin Vaeth)}
%    \begin{macrocode}
    \def\@elt#1{%
      \eqp@tempdima\csname eqp@this@#1\endcsname\relax
      \eqp@tempdimb\csname eqp@next@#1\endcsname\relax
      \ifdim\eqp@tempdima=\eqp@tempdimb
      \else
        \@latex@warning@no@line{Rerun to correct the width of eqparbox `#1'}%
      \fi
      \immediate\write\@auxout{%
        \string\expandafter\string\gdef\string\csname\space
        eqp@this@#1\string\endcsname{%
          \csname eqp@next@#1\endcsname
        }%
        ^^J%
        \string\expandafter\string\gdef\string\csname\space
         eqp@next@#1\string\endcsname{0pt}%
      }%
    }%
    \eqp@taglist
  \endgroup
%    \end{macrocode}
% We output the generic ``rerun |latex|'' message if we encountered a
% tag that was not present on the previous run.  (This is always the
% case on the first run or the first run after deleting the
% corresponding |.aux| file.
%    \begin{macrocode}
  \ifeqp@must@rerun
    \@latex@warning@no@line{Rerun to correct eqparbox widths}
  \fi
}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\eqp@storefont}
% \begin{macro}{\eqp@restorefont}
% To find the natural width of a piece of text, we put it in a table and
% take the width of that.  The problem is that font changes are not
% preserved across line breaks (table cells).  We therefore define an
% |\eqp@storefont| macro which itself defines an |\eqp@restorefont|
% macro that restores the current font and font size to its current
% state.
%    \begin{macrocode}
\newcommand*{\eqp@storefont}{%
  \xdef\eqp@restorefont{%
    \noexpand\usefont{\f@encoding}{\f@family}{\f@series}{\f@shape}%
    \noexpand\fontsize{\f@size}{\f@baselineskip}%
    \noexpand\selectfont
  }%
}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% The following macro (|\eqp@settowidth|) requires the \textsf{array}
% package's ability to inject code into every cell.
%    \begin{macrocode}
\RequirePackage{array}
%    \end{macrocode}
%
% \begin{macro}{\eqp@settowidth}
% This macro is just like |\settowidth|, but it puts its argument in a
% |tabular|, which means that it can contain |\\|.  We use the
% \textsf{array} package's ``|>|'' and ``|<|'' template parameters to
% inject an |\eqp@restorefont| at the start of every cell and an
% |\eqp@storefont| at the end of every cell.  Doing so preserves fonts
% and font sizes across |\\| boundaries, just like |\parbox|.
% \changes{v2.0}{2004/08/01}{Modified to store and restore the font
%   across \texttt{\string\string\string\\}~boundaries (suggested by
%   Mike Shell)}
%    \begin{macrocode}
\newcommand{\eqp@settowidth}[2]{%
  \settowidth{#1}{{%
    \eqp@storefont
    \begin{tabular}{@{}>{\eqp@restorefont}l<{\eqp@storefont}@{}}%
      #2%
    \end{tabular}%
  }}%
}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\eqparbox}
% \begin{macro}{\eqparbox@i}
% \begin{macro}{\eqparbox@ii}
% We want |\eqparbox| to take the same arguments as |\parbox|, with the
% same default values for the optional arguments.  The only difference
% in argument processing is that |\eqparbox| has a \meta{tag} argument
% where |\parbox| has \meta{width}.
%
% Because |\eqparbox| has more than one optional argument, we can't use
% a single function defined by |\DeclareRobustCommand|.  Instead, we
% have to split |\eqparbox| into the following four macros:
%
% \begin{description}
%   \item[\texttt{\string\eqparbox}] Takes zero or more optional arguments.
%   First optional argument defaults to~|c|.  Calls |\eqparbox@i|.
%
%   \item[\texttt{\string\eqparbox@i}] Takes one or more optional arguments.
%   Second optional argument defaults to~|\relax|.  Calls |\eqparbox@ii|.
%
%   \item[\texttt{\string\eqparbox@ii}] Takes two or more optional arguments.
%   Third optional argument defaults to~|s| if either of the first two
%   arguments is absent or to the first argument if both are present.
%   Calls |\eqparbox@iii|.
%
%   \item[\texttt{\string\eqparbox@iii}] Takes three optional arguments
%   and two mandatory arguments.  Does all the work for |\eqparbox|.
% \end{description}
%
% \noindent
% Note the direct correspondence between these macros and
% |ltboxes.dtx|'s |\parbox|, |\@iparbox|, |\@iiparbox|, and
% |\@iiiparbox| macros.
%    \begin{macrocode}
\DeclareRobustCommand\eqparbox{%
  \@ifnextchar[%]
    {\eqparbox@i}%
    {\eqparbox@iii[c][\relax][s]}%
}
\def\eqparbox@i[#1]{%
  \@ifnextchar[%]
    {\eqparbox@ii[#1]}%
    {\eqparbox@iii[#1][\relax][s]}%
}
\def\eqparbox@ii[#1][#2]{%
  \@ifnextchar[%]
    {\eqparbox@iii[#1][#2]}%
    {\eqparbox@iii[#1][#2][#1]}%
}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\eqparbox@iii}
% The following function does all the real work for |\eqparbox|.  It takes
% five parameters---\meta{pos}, \meta{height}, \meta{inner-pos},
% \meta{tag}, and \meta{text}---and ensures that all boxes with the same
% tag will be as wide as the widest box with that tag.
%
% To keep track of box widths, |\eqparbox| makes use of two global
% variables for each tag: |\eqp@this@|\meta{tag} and
% |\eqp@next|\meta{tag}.  |\eqp@this@|\meta{tag} is the maximum width
% ever seen for tag \meta{tag}, including in previous |latex| runs.
% |\eqp@next@|\meta{tag} works the same way but is always initialized
% to~|0.0pt|.  It represents the maximum width to assume in
% \emph{subsequent} |latex| runs.  It is needed to detect whether the
% dest text with tag \meta{tag} has been removed/shrunk.  At the end of
% a run, \textsf{eqparbox} prepares the next run (via the~|.aux| file)
% to initialize |\eqp@this@|\meta{tag} to the final value of
% |\eqp@next@|\meta{tag}.
% \changes{v2.0}{2004/07/30}{Removed extraneous \texttt{\string\string\string\global}s
%   (suggested by David Kastrup)}
%    \begin{macrocode}
\def\eqparbox@iii[#1][#2][#3]#4#5{%
  \eqp@settowidth{\eqp@tempdimb}{#5}%
  \expandafter
  \ifx\csname eqp@this@#4\endcsname\relax
%    \end{macrocode}
% If we get here, then we've never encountered tag \meta{tag}, even in a
% previous |latex| run.  We request that the user re-run |latex| This is
% not always necessary (e.g., when all uses of the |\eqparbox| with tag
% \meta{tag} are left-justified), but it's better to be safe than sorry.
%    \begin{macrocode}
    \global\eqp@must@reruntrue
    \expandafter\xdef\csname eqp@this@#4\endcsname{\the\eqp@tempdimb}%
    \expandafter\xdef\csname eqp@next@#4\endcsname{\the\eqp@tempdimb}%
  \else
%    \end{macrocode}
% If we get here, then we \emph{have} previously seen tag \meta{tag}.
% We just have to keep track of the maximum text width associated with
% it.
%    \begin{macrocode}
    \eqp@tempdima=\csname eqp@this@#4\endcsname\relax
    \ifdim\eqp@tempdima<\eqp@tempdimb
      \expandafter\xdef\csname eqp@this@#4\endcsname{\the\eqp@tempdimb}%
      \global\eqp@must@reruntrue
    \fi
%    \end{macrocode}
%    \begin{macrocode}
    \eqp@tempdima=\csname eqp@next@#4\endcsname\relax
    \ifdim\eqp@tempdima<\eqp@tempdimb
      \expandafter\xdef\csname eqp@next@#4\endcsname{\the\eqp@tempdimb}%
    \fi
  \fi
%    \end{macrocode}
%
% The first time we encounter tag \meta{tag} in the current document we
% ensure \LaTeX{} will notify the user if he needs to re-run |latex| on
% account of that tag.
%    \begin{macrocode}
  \@ifundefined{eqp@seen@#4}{%
    \expandafter\gdef\csname eqp@seen@#4\endcsname{}%
    \@cons\eqp@taglist{{#4}}%
  }{}%
%    \end{macrocode}
%
% Finally, we can call |\parbox|.  We pass it \meta{pos}, \meta{height},
% \meta{inner-pos}, and \meta{text} directly, and we pass it
% |\eqp@this@|\meta{tag} for its \meta{width} argument.
%    \begin{macrocode}
  \eqp@tempdima=\csname eqp@this@#4\endcsname\relax
  \parbox[#1][#2][#3]{\eqp@tempdima}{#5}%
}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\eqboxwidth}
% For the times that the user wants to make something other than a box
% match an |\eqparbox|'s width, we provide |\eqboxwidth|.  |\eqboxwidth|
% returns the width of a box corresponding to a given tag.  More
% precisely, if |\eqp@this@|\meta{tag} is defined, it's returned.
% Otherwise,~|0pt| is returned.
% \changes{v2.1}{2004/08/02}{Rewrote so as to be compatible with the
%   \textsf{calc} package's \texttt{\string\string\string\setlength}
%   command (problem initially reported by Gary L. Gray and narrowed
%   down by Martin Vaeth)}
%    \begin{macrocode}
\newcommand*{\eqboxwidth}[1]{%
  \@ifundefined{eqp@this@#1}{0pt}{\csname eqp@this@#1\endcsname}%
}
%    \end{macrocode}
% \end{macro}
%
% \DeleteShortVerb{\|}
% \MakeShortVerb{\!}
% \paragraph{Per-tag memory usage}
% The \textsf{eqparbox} package defines three macros for each unique
% tag: !\eqp@this@!\meta{tag}, !\eqp@next@!\meta{tag}, and
% !\eqp@seen@!\meta{tag}.  Consequently, each unique tag subtracts three
% strings from \TeX's string pool and three multiletter control
% sequences from that pool.  In addition, each unique tag \meta{tag}
% subtracts $|!\eqp@this@!| + |\meta{tag}| + |!\eqp@next@!| +
% |\meta{tag}| + |!\eqp@seen@!| + |\meta{tag}| = 27 + 3 \times
% |\meta{tag}|$ string characters from \TeX's pool of string characters.
% For example, a document that invokes !\eqparbox!  with tags
% ``!hello!'' and ``!goodbye!'' will utilize $3 \times 2 = 6$ strings,
% $3 \times 2 = 6$ multiletter control sequences, and $(27 + 3 \times 5)
% + (27 + 3 \times 7) = 90$ \TeX{} string characters.
% \DeleteShortVerb{\!}
% \MakeShortVerb{\|}
%
%    \begin{macrocode}
%</package>
%    \end{macrocode}
%
% \Finale
%
