diff options
author | Karl Berry <karl@freefriends.org> | 2013-03-18 22:33:15 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2013-03-18 22:33:15 +0000 |
commit | 475f7084e5da1822a284e68a4212bf535be7f3ca (patch) | |
tree | 9fe3516e5afe3b7c6acf64c18dcdc12e39f80a3c /Master/texmf-dist/source/latex/eqparbox | |
parent | a9682d5de4862ec688defed3cc52e0df721351a5 (diff) |
eqparbox (17mar13)
git-svn-id: svn://tug.org/texlive/trunk@29419 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/source/latex/eqparbox')
-rw-r--r-- | Master/texmf-dist/source/latex/eqparbox/eqparbox.dtx | 1245 | ||||
-rw-r--r-- | Master/texmf-dist/source/latex/eqparbox/eqparbox.ins | 4 |
2 files changed, 913 insertions, 336 deletions
diff --git a/Master/texmf-dist/source/latex/eqparbox/eqparbox.dtx b/Master/texmf-dist/source/latex/eqparbox/eqparbox.dtx index df63e1cce1f..3a91ea1b2e5 100644 --- a/Master/texmf-dist/source/latex/eqparbox/eqparbox.dtx +++ b/Master/texmf-dist/source/latex/eqparbox/eqparbox.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 2010 Scott Pakin <scott+eqp@pakin.org> +% Copyright (C) 2013 Scott Pakin <scott+eqp@pakin.org> % ---------------------------------------------------- % % This package may be distributed and/or modified under the @@ -20,14 +20,19 @@ %<package>\NeedsTeXFormat{LaTeX2e}[1999/12/01] %<package>\ProvidesPackage{eqparbox} %<*package> - [2010/01/01 v3.1 Create equal-widthed boxes] + [2013/03/15 v4.0 Create equal-widthed boxes] %</package> % %<*driver> \documentclass{ltxdoc} \usepackage{eqparbox} \usepackage{calligra} -\usepackage{hyperref} +\usepackage{array} +\usepackage{boxedminipage} +\usepackage{needspace} +\usepackage{ifmtarg} +\usepackage[subrefformat=parens,labelformat=parens]{subfig} +\usepackage[bookmarksopen]{hyperref} \EnableCrossrefs \CodelineIndex \RecordChanges @@ -37,8 +42,19 @@ %\OnlyDescription \begin{document} + \sloppy \DocInput{eqparbox.dtx} + \Needspace{10\baselineskip} + \phantomsection\addcontentsline{toc}{section}{Change History} \PrintChanges + \makeatletter + \let\orig@index@prologue=\index@prologue + \def\index@prologue{% + \phantomsection\addcontentsline{toc}{section}{Index} + \orig@index@prologue + }% + \makeatother + \Needspace{12\baselineskip} \PrintIndex \end{document} %</driver> @@ -46,7 +62,7 @@ % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % -% \CheckSum{203} +% \CheckSum{474} % % \CharacterTable % {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z @@ -72,12 +88,17 @@ % % \GetFileInfo{eqparbox.dtx} % -% \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{\\} +% \DoNotIndex{\@auxout,\@cons,\@ifnextchar,\@ifundefined,\@ne} +% \DoNotIndex{\@tempdima,\@tempboxa} +% \DoNotIndex{\advance,\begin,\begingroup,\bgroup,\box} +% \DoNotIndex{\csname,\DeclareRobustCommand,\def} +% \DoNotIndex{\egroup,\else,\end,\endcsname,\endgroup,\expandafter} +% \DoNotIndex{\fi,\gdef,\global} +% \DoNotIndex{\hbox,\ifdim,\ifx,\immediate,\let,\m@ne,\mbox} % \DoNotIndex{\newcommand,\newdimen,\newif,\newlength,\noexpand} -% \DoNotIndex{\relax,\setbox,\space,\string,\the,\wd,\xdef,\z@} +% \DoNotIndex{\relax,\romannumeral} +% \DoNotIndex{\sbox,\setbox,\space,\string,\the,\wd,\xdef,\z@} % % ^^A The following environment, which typesets a declaration of a command % ^^A in a box set out into the margin, was copied almost verbatim from @@ -144,13 +165,14 @@ % \end{abstract} % % \section{Motivation} +% \label{sec: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: +% Figure~\ref{fig:quotations}, in which the names of the quotations' +% authors are left-justified relative to each other but as a group abut +% the right margin? 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 @@ -159,30 +181,69 @@ % \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}[htbp] +% \centering +% \makeatletter +% \newcommand{\showquote}[2]{^^A +% \begin{flushright} +% ---~\eqparbox{quotebox}{\sffamily#1}^^A +% \@ifnotmtarg{#2}{\\ +% \mbox{}\phantom{---}~\eqparbox{quotebox}{\sffamily\itshape#2}^^A +% }^^A +% \end{flushright}^^A +% \par +% } +% \makeatother +% \begin{boxedminipage}{\linewidth} +% The only medicine for suffering, crime, and all other woes of mankind, +% is wisdom. Teach a man to read and write, and you have put into his +% hands the great keys of the wisdom box. But it is quite another thing +% to open the box. +% \showquote{Thomas Huxley}{} +% +% I would like a simple life \\ +% yet all night I am laying \\ +% poems away in a long box. \par +% \bigskip +% It is my immortality box, \\ +% my lay-away plan, \\ +% my coffin. +% \showquote{Anne Sexton}{The Ambition Bird} +% +% \bigskip +% +% We have four boxes with which to defend our freedom: the soap box, the +% ballot box, the jury box, and the cartridge box. +% \showquote{Larry McDonald}{} +% +% \bigskip +% +% I saw the Count lying within the box upon the earth, some of which the +% rude falling from the cart had scattered over him. He was deathly +% pale, just like a waxen image, and the red eyes glared with the +% horrible vindictive look which I knew so well. +% \showquote{Bram Stoker}{Dracula} +% +% \bigskip +% +% Life in a box is better than no life at all, I expect. You'd +% have a chance, at least. You could lie there thinking, ``Well, +% at least I'm not dead.'' +% \showquote{Tom Stoppard}{Rosencrantz~\& Guildenstern Are Dead} +% +% \bigskip +% +% Alla fin del gioco tanto va nel sacco il re quanto la pedina. \\ +% \textit{(After the game, the king and pawn go into the same box.)} +% \showquote{Italian proverb}{} +% \end{boxedminipage} +% \caption{Quotations with left-aligned attributions} +% \label{fig:quotations} +% \end{figure} % -% \begin{figure} +% \begin{figure}[htbp] % \bigskip\noindent\rule{\linewidth}{1pt}\bigskip\par -% \noindent% +% \noindent % \eqparbox{place}{\textbf{Widgets, Inc.}} \hfill % \eqparbox{title}{\textbf{Senior Widget Designer}} \hfill % \eqparbox{dates}{\textbf{1/95--present}} @@ -194,7 +255,7 @@ % \item Made widget management ten times more cost-effective. % \end{itemize} % -% \noindent% +% \noindent % \eqparbox{place}{\textbf{Thingamabobs, Ltd.}} \hfill % \eqparbox{title}{\textbf{Lead Engineer}} \hfill % \eqparbox{dates}{\textbf{9/92--12/94}} @@ -212,23 +273,21 @@ % \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: +% blocks of text into equal-widthed boxes. If the author names in +% Figure~\ref{fig:quotations} are placed within a |flushright| +% environment and in |\parbox|es as wide as the widest text +% (``Rosencrantz~\& Guildenstern Are Dead''), they will appear as +% desired. 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. +% Considering for now just Figure~\ref{fig:resume-excerpt}, 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} @@ -260,26 +319,31 @@ % document. % % \section{Usage} +% \label{sec:usage} % % \begin{decl} % |\eqparbox| \oarg{pos} \oarg{height} \oarg{inner-pos} \marg{tag} \marg{text} \\ % |\eqmakebox| \oarg{tag} \oarg{pos} \marg{text} \\ % |\eqframebox| \oarg{tag} \oarg{pos} \marg{text} \\ -% |\eqsavebox| \marg{cmd} \oarg{tag} \oarg{pos} \marg{text} +% |\eqsavebox| \marg{cmd} \oarg{tag} \oarg{pos} \marg{text} \\[1ex] +% |\begin{eqminipage}| \oarg{pos} \oarg{height} \oarg{inner-pos} \marg{tag} \\ +% \quad \meta{text} \\ +% |\end{eqminipage}| % \end{decl} % -% These macros are almost identical to |\parbox|, |\makebox|, -% |\framebox|, and |\savebox|, respectively. The key difference is -% that the \meta{width} argument is replaced by a \meta{tag} argument. -% (For a description of the remaining arguments, look up |\parbox|, -% |\makebox|, |\framebox|, and |\savebox| in any \LaTeXe\ book or in the +% These are almost identical to, respectively, the |\parbox|, +% |\makebox|, |\framebox|, and |\savebox| macros and the |minipage| +% environment. The key difference is that the \meta{width} argument is +% replaced by a \meta{tag} argument. (For a description of the +% remaining arguments, look up |\parbox|, |\makebox|, |\framebox|, +% |\savebox|, and |minipage| in any \LaTeXe\ book or in the % \texttt{usrguide.pdf} file that comes with all \TeX\ distributions.) % \meta{tag} can be any valid identifier. All boxes produced using the % same tag are 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. +% same document, and any number of boxes 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. % % \begin{decl} % |\eqboxwidth| @@ -295,14 +359,19 @@ % 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} +% 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. +% +% Section~\ref{sec:tabular-l-p} presents a more general version of this +% approach that doesn't require cells to be divided explicitly into +% |\eqparbox| cells and |\parbox| cells. +% +% \begin{table}[htbp] % \centering % \caption{A \texttt{tabular} that stretches to fit some cells while % forcing others to wrap} @@ -321,20 +390,72 @@ % \MakeShortVerb{\|} % \end{table} % +% \begin{decl} +% |\eqsetminwidth| \marg{tag} \marg{width} \\ +% |\eqsetmaxwidth| \marg{tag} \marg{width} +% \end{decl} +% +% These macros override the width calculation for boxes associated with +% tag \meta{tag}, ensuring that they are no narrower than a given +% minimum (|\eqsetminwidth|) and no wider than a given maximum +% (|\eqsetmaxwidth|). +% +% \begin{decl} +% |\eqsetminwidthto| \marg{tag} \marg{text} \\ +% |\eqsetmaxwidthto| \marg{tag} \marg{text} +% \end{decl} +% +% These macros are analogous to |\eqsetminwidth| and |\eqsetmaxwidth| +% but automatically compute the natural width of the given text and use +% that as the minimum (|\eqsetminwidthto|) or maximum +% (|\eqsetmaxwidthto|) width for boxes using tag \meta{tag}. +% +% % \section{Examples} +% \label{sec:examples} +% +% This section presents some sample uses of the macros described in +% Section~\ref{sec:usage}. +% +% \subsection{Figures and tables from previous sections} +% \label{sec:prev-figs-tabs} +% +% Figure~\ref{fig:quotations} was typeset using an |\eqparbox|-based +% helper macro, |\showquote|: +% +% \begin{verbatim} +% \usepackage{ifmtarg} +% \makeatletter +% \newcommand{\showquote}[2]{% +% \begin{flushright} +% ---~\eqparbox{quotebox}{\sffamily#1}% +% \@ifnotmtarg{#2}{\\ +% \mbox{}\phantom{---}~\eqparbox{quotebox}{\sffamily\itshape#2}% +% }% +% \end{flushright}% +% \par +% } +% \makeatother +% \end{verbatim} +% \centerline{$\vdots$} +% \begin{verbatim} +% Alla fin del gioco tanto va nel sacco il re quanto la pedina. \\ +% \textit{(After the game, the king and pawn go into the same box.)} +% \showquote{Italian proverb}{} +% \end{verbatim} % % Figure~\ref{fig:resume-excerpt}'s headings were typeset with the % following code: % % \begin{verbatim} -% \noindent% +% \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% +% \noindent % \eqparbox{place}{\textbf{Thingamabobs, Ltd.}} \hfill % \eqparbox{title}{\textbf{Lead Engineer}} \hfill % \eqparbox{dates}{\textbf{9/92--12/94}} @@ -342,35 +463,6 @@ % \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: % @@ -387,16 +479,96 @@ % \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 that typesets its labels with |\eqparbox| this is -% fairly straightforward: +% \subsection{Lists within \texttt{tabular}s} +% \label{sec:lists-tabulars} +% +% List environments (|itemize|, |enumerate|, etc.) cannot appear +% directly within a |tabular| cell. Instead, they must be wrapped +% within a |\parbox|. The problem is that the |\parbox| width must be +% specified; it can't be determined automatically. Fortunately, as of +% version~4.0 of \pkgname{eqparbox}, the |\eqparbox| macro can contain +% list environments, and these are automatically sized to their widest +% item, just like any other |\eqparbox| contents. +% Table~\ref{tbl:lists-tabular} presents an example of |enumerate| lists +% appearing within |tabular| cells. The code for this is +% straightforward, thanks to \pkgname{eqparbox}: +% +% \begin{table}[tbp] +% \centering +% \caption{Lists within a \texttt{tabular}} +% \label{tbl:lists-tabular} +% \begin{tabular}{c|c} +% \textbf{Meeting date} & \textbf{Topics discussed} \\ +% \hline +% 2013-02-22 +% & \eqparbox{topiclist}{^^A +% \begin{enumerate} +% \item Hardware upgrades +% \item Barbara's retirement +% \item Revised 27B/6 paperwork +% \end{enumerate} +% }^^A +% \\ \hline +% 2013-03-01 +% & \eqparbox{topiclist}{^^A +% \begin{enumerate} +% \item Printer low on toner +% \item Message from the V.P. +% \end{enumerate} +% }^^A +% \\ \hline +% 2013-03-08 +% & \eqparbox{topiclist}{^^A +% \begin{enumerate} +% \item Product to ship next week +% \item Floors to be recarpeted +% \item Too many meetings +% \end{enumerate} +% }^^A +% \end{tabular} +% \end{table} % -% \begin{figure}[tbp] ^^A NOT "here" (in case the default is changed) +% \begin{verbatim} +% 2013-02-22 & \eqparbox{topiclist}{% +% \begin{enumerate} +% \item Hardware upgrades +% \item Barbara's retirement +% \item Revised 27B/6 paperwork +% \end{enumerate} +% } \\ \hline +% \end{verbatim} +% +% \subsection{Hanging indentation} +% \label{sec:hang-indent} +% +% 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. By using a custom |list| +% environment that typesets its labels with |\eqparbox| this is fairly +% straightforward: +% +% \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} +% +% \begin{figure}[htbp] % \rule{\linewidth}{1pt} % \begin{list}{}{^^A % \renewcommand{\makelabel}[1]{\eqparbox[b]{listlab}{#1}}^^A @@ -431,39 +603,23 @@ % \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} -% -% Finally, consider line-by-line transcription of a piece of text as -% illustrated by the mockup in Figure~\ref{fig:line-by-line}. The idea is -% to juxtapose a scanned piece of handwritten text with its typeset -% version (or, similarly, to typeset a piece of text in one language -% alongside a line-by-line translation into another language). The -% challenge is in ensuring that (1)~the same words appear on -% corresponding lines of text and that (2)~the typeset text is fully -% justified. While the \pkgname{parallel} package can typeset fully -% justified paragraphs aligned in parallel columns, it does not support -% the alignment of individual lines. |tabular| and |minipage| -% environments provide control of line breaks but do not support full -% justification of the text when explicit line breaks are used. -% -% \begin{figure} +% \subsection{Justified, parallel text} +% \label{sec:parallel-text} +% +% Consider line-by-line transcription of a piece of text as illustrated +% by the mockup in Figure~\ref{fig:line-by-line}. The idea is to +% juxtapose a scanned piece of handwritten text with its typeset version +% (or, similarly, to typeset a piece of text in one language alongside a +% line-by-line translation into another language). The challenge is in +% ensuring that (1)~the same words appear on corresponding lines of text +% and that (2)~the typeset text is fully justified. While the +% \pkgname{parallel} package can typeset fully justified paragraphs +% aligned in parallel columns, it does not support the alignment of +% individual lines. |tabular| and |minipage| environments provide +% control of line breaks but do not support full justification of the +% text when explicit line breaks are used. +% +% \begin{figure}[htbp] % \centering % \DeleteShortVerb{\|} % \newsavebox{\tstretchbox} @@ -555,18 +711,150 @@ % \end{tabular} % \end{verbatim} % +% \subsection{Combining \texttt{l} and \texttt{p} column properties in a \texttt{tabular}} +% \label{sec:tabular-l-p} +% +% In a |tabular| environment, |l|~columns, which automatically fit the +% column to its contents, are good for short pieces of text. Long +% pieces of text are best set within a |p|~column, which wraps text +% within a specified width. But which column type should you use to +% typeset text whose width is unknown (e.g.,~if the text is generated +% programmatically)? With the help of \pkgname{eqparbox}'s +% |\eqsetmaxwidth| macro (and the \pkgname{array} package's +% |\newcolumntype| macro), it is possible to define a column type that +% behaves like~|l| for short pieces of text and like~|p| for long pieces +% of text: +% +% \begin{verbatim} +% \newcolumntype{M}[1]{% +% >{\begin{lrbox}{\csname#1box\endcsname}}% +% l% +% <{\end{lrbox}% +% \eqparbox[t]{#1}{\unhcopy\csname#1box\endcsname\strut}}% +% } +% \end{verbatim} +% +% This can then be used as follows to produce the output shown in +% Figure~\subref*{fig:maxwd-narrow}: +% +% \begin{verbatim} +% \eqsetmaxwidth{maybebig}{0.5\linewidth} +% \newsavebox{\maybebigbox} +% \begin{tabular}{|M{maybebig}|l|} +% \hline +% Very short & Good \\ +% A little bit longer & Okay \\ +% \end{tabular} +% \end{verbatim} +% +% \noindent +% Because the text in the first column is narrower than half the line +% width, the column behaves like an |l|~column. Now observe what +% happens if we add a long piece of text to the column: +% +% \begin{verbatim} +% \eqsetmaxwidth{maybebig}{0.5\linewidth} +% \newsavebox{\maybebigbox} +% \begin{tabular}{|M{maybebig}|l|} +% \hline +% Very short & Good \\ +% A little bit longer & Okay \\ +% Almost certainly excessively long, even given the point we're +% trying to make about box widths & Bad \\ +% \end{tabular} +% \end{verbatim} +% +% \noindent +% As Figure~\subref*{fig:maxwd-wide} shows, the first column now behaves +% like a |p|~column, specifically |p{0.5\linewidth}|. +% +% \begin{figure}[htbp] +% \centering +% \subfloat[Output when the text is narrow\label{fig:maxwd-narrow}]{% +% \begin{tabular}{|l|l|} +% \hline +% Very short & Good \\ +% A little bit longer & Okay \\ +% \hline +% \end{tabular}% +% } +% \par +% \subfloat[Output when the text is wide\label{fig:maxwd-wide}]{% +% \begin{tabular}{|p{0.5\linewidth}|l|} +% \hline +% Very short & Good \\ +% A little bit longer & Okay \\ +% Almost certainly excessively long, even given the point we're +% trying to make about box widths & Bad \\ +% \hline +% \end{tabular}% +% } +% \caption{Combining the features of \texttt{l} and \texttt{p} columns} +% \label{fig:maxwd} +% \end{figure} +% +% \subsection{Centering a column of right-justified data} +% \label{tbl:center-justified} +% +% The data in each of the Sales columns in Table~\ref{tbl:sales-data} +% are centered relative to their column header. However, they are also +% right-justified relative to each other. To achieve this effect we +% simply need to put the data in each column in a right-justified box +% using |\eqmakebox|\oarg{tag}|[r]|\marg{text} and center that: +% +% \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 & \eqmakebox[oct][r]{ 55.2} & +% \eqmakebox[nov][r]{\bfseries 89.2} & +% \eqmakebox[dec][r]{ 57.9} \\ +% Doohickeys & \eqmakebox[oct][r]{\bfseries 65.0} & +% \eqmakebox[nov][r]{\tiny N/A} & +% \eqmakebox[dec][r]{ 9.3} \\ +% Thingamabobs & \eqmakebox[oct][r]{ 10.4} & +% \eqmakebox[nov][r]{ 8.0} & +% \eqmakebox[dec][r]{\bfseries 109.7} \\ \hline +% \end{tabular} +% \end{verbatim} +% +% \begin{table}[htbp] +% \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 & \eqmakebox[oct][r]{ 55.2} & +% \eqmakebox[nov][r]{\bfseries 89.2} & +% \eqmakebox[dec][r]{ 57.9} \\ +% Doohickeys & \eqmakebox[oct][r]{\bfseries 65.0} & +% \eqmakebox[nov][r]{\tiny N/A} & +% \eqmakebox[dec][r]{ 9.3} \\ +% Thingamabobs & \eqmakebox[oct][r]{ 10.4} & +% \eqmakebox[nov][r]{ 8.0} & +% \eqmakebox[dec][r]{\bfseries 109.7} \\ \hline +% \end{tabular} +% \end{table} +% % % \section{Limitations} +% \label{sec:limitations} % % Unfortunately, \pkgname{eqparbox}'s macros have a number of % limitations not exhibited by the corresponding \LaTeXe\ commands. % First, \pkgname{eqparbox}'s macros internally typeset 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 an -% \pkgname{eqparbox} macro. As a corollary, \pkgname{eqparbox}'s macros -% can appear only where a |tabular| is also acceptable. +% Consequently, commands not valid within such a |tabular| +% (e.g.,~|verbatim| environments) are also not valid within the +% \meta{text} argument of an \pkgname{eqparbox} macro. As a corollary, +% the macros defined by the \pkgname{eqparbox} package can appear only +% where a |tabular| is also acceptable. % % A second limitation is that \pkgname{eqparbox}'s macros typeset their % \meta{text} argument \emph{twice}: once within a |tabular| to @@ -576,41 +864,10 @@ % 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 \pkgname{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 box of the width associated with -% the given tag. (Feature requested by Bernd Schandl.) -% -% \item Get \pkgname{eqparbox} to work properly within an -% \pkgname{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 box, 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 box 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. -% } +% \StopEventually{} % % \section{Implementation} +% \label{sec:implementation} % % The one-sentence summary of the implementation is, ``As % \pkgname{eqparbox} goes along, it keeps track of the maximum width of @@ -619,11 +876,14 @@ % with that summary, then read no further. Otherwise, get ready to % tackle the following annotated code listing. % +% \subsection{Preliminaries} +% % \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} +\newlength{\eqp@tempdima} +\newlength{\eqp@tempdimb} % \end{macrocode} % \end{macro} % \end{macro} @@ -649,57 +909,42 @@ % \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|. +% The |\eqp@settowidth| macro requires the \pkgname{array} package's +% ability to inject code into every cell. % \begin{macrocode} -\AtEndDocument{% - \begingroup +\RequirePackage{array} % \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{macro}{\eqp@tabular@box} +% \begin{macro}{\eqp@list@box} +% The |\eqp@settowidth| macro requires a box, |\eqp@tabular@box|, in +% which to store the entire input text. |\eqp@settowidth| also requires +% a box, |\eqp@list@box|, in which to store nested |list| environments. % \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 +\newsavebox{\eqp@tabular@box} +\newsavebox{\eqp@list@box} % \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. +% \end{macro} +% \end{macro} +% +% \begin{macro}{\eqp@list@indent} +% The |\eqp@settowidth| macro stores the accumulated |list| indentation +% in |\eqp@list@indent|. % \begin{macrocode} - \ifeqp@must@rerun - \@latex@warning@no@line{Rerun to correct eqparbox widths} - \fi -} +\newlength{\eqp@list@indent} % \end{macrocode} % \end{macro} % +% The |eqminipage| environment requires the \pkgname{environ} package's +% |\Collect@Body|, which passes the body of an environment to a macro as +% a single argument. +% \begin{macrocode} +\RequirePackage{environ} +% \end{macrocode} +% +% +% \subsection{Width calculation} +% % \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 @@ -720,12 +965,6 @@ % \end{macro} % \end{macro} % -% The following macro (|\eqp@settowidth|) requires the \pkgname{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 @@ -733,20 +972,229 @@ % 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|. +% +% One catch is that lists cannot be included directly within a +% |tabular|. True, they can be placed within a |\parbox| that itself is +% within a |tabular| cell, but the whole point is that we're trying to +% calculate how wide that |\parbox| should be, The trick we use here, +% therefore, is to redefine the |list| environment as a single-column +% |tabular| plus space for |\labelwidth| and |\labelsep|---we ignore all +% other list-formatting parameters---and |\item| as~|\\|. There will be +% an extra row at the beginning, but all we care about here is computing +% a width, not a height, so that's acceptable. % \changes{v2.0}{2004/08/01}{Modified to store and restore the font % across \texttt{\string\string\string\\}~boundaries (suggested by % Mike Shell)} +% \changes{v4.0}{2013/03/09}{Added support for list environments} +% \changes{v4.0}{2013/03/15}{Added support for multi-paragraph input} % \begin{macrocode} \newcommand{\eqp@settowidth}[2]{% - \settowidth{#1}{{% - \eqp@storefont - \begin{tabular}{@{}>{\eqp@restorefont}l<{\eqp@storefont}@{}}% - #2% - \end{tabular}% - }}% + \begingroup + \global\setbox\eqp@tabular@box=\hbox{% +% \end{macrocode} +% \begin{macro}{\eqp@endings} +% Unfortunately, we can't simply redefine the |list| environment, which +% underlies |itemize|, |enumerate|, and |description| lists, because +% their definitions in the standard classes do not include a proper +% |\begin{list}|\dots\linebreak[0]|\end{list}|. Instead, those parent +% environments call |\list| directly and +% |\let\end|\{|itemize|,\linebreak[0]|enumerate|,\linebreak[0]|description|\}|=\endlist|. +% Our workaround is to reissue those |\let| bindings after redefining +% |\list| and |\endlist| ourselves. +% \begin{macrocode} + \def\eqp@endings{}% + \ifx\enditemize\endlist + \g@addto@macro\eqp@endings{\let\enditemize=\endlist}% + \fi + \ifx\endenumerate\endlist + \g@addto@macro\eqp@endings{\let\endenumerate=\endlist}% + \fi + \ifx\enddescription\endlist + \g@addto@macro\eqp@endings{\let\enddescription=\endlist}% + \fi +% \end{macrocode} +% \begin{environment}{list} +% As described above, we locally redefine the |list| environment as a +% single-column |tabular| and the |\item| macro as~|\\|. We begin by +% copying a block of code from |ltlists.dtx| that sets the default +% formatting parameters for a list of the current depth. This is +% important because |trivlist| environments (e.g.,~|center| and +% |flushleft|) reset some of the parameters, which would otherwise screw +% up our width calculation. +% \begin{macrocode} + \renewenvironment{list}[2]{% + \ifnum \@listdepth >5\relax + \@toodeep + \else + \global\advance\@listdepth\@ne + \fi + \rightmargin\z@ + \listparindent\z@ + \itemindent\z@ + \csname @list\romannumeral\the\@listdepth\endcsname + ##2\relax +% \end{macrocode} +% \begin{macro}{\item} +% We locally redefine |\item| to start a new row of the |tabular|, then +% flush any nested lists from the previous |\item| at the current +% nesting level, and finally adjust the current indentation based on +% the item's label. +% \begin{macrocode} + \renewcommand*{\item}[1][]{% + \mbox{}\\ + \box\eqp@list@box\mbox{} \\ + \sbox\@tempboxa{\makelabel{####1}}% + \ifdim\wd\@tempboxa>\labelwidth + \advance\eqp@list@indent by -\labelwidth + \advance\eqp@list@indent by \wd\@tempboxa + \fi + \hspace*{\eqp@list@indent}% + }% +% \end{macrocode} +% To measure the width of a |list| we introduce a single-column +% |tabular| that includes |\eqp@list@indent|'s worth of padding ($\sum$ +% |\leftmargin|~$+$ |\rightmargin|~$+$ |\itemindent|) to mimic the width +% of the original |list| environment. +% \begin{macrocode} + \hspace*{-\eqp@list@indent}% + \advance\eqp@list@indent by \leftmargin + \advance\eqp@list@indent by \rightmargin + \advance\eqp@list@indent by \itemindent + \global\setbox\eqp@list@box=\hbox\bgroup + \begin{tabular}{@{}l@{}}% + }{% + \item[]% + \end{tabular}% + \egroup + \global\advance\@listdepth\m@ne + }% + \eqp@endings +% \end{macrocode} +% Finally, we place the given text---list or not---within a |tabular| so +% the preceding |\settowidth| can measure its width. Because the text +% may contain paragraph breaks we redefine |\par| as~|\\| to turn them +% into line breaks and restore |\par|'s original definition when the +% |tabular| ends. +% \begin{macrocode} + \global\let\eqp@par=\par + \eqp@storefont + \begin{tabular}{@{}>{\eqp@restorefont}l<{\eqp@storefont}@{}}% + \global\@setpar{\\}% + #2% + \\ \box\eqp@list@box + \end{tabular}% + \global\@restorepar + }% + \endgroup +% \end{macrocode} +% Now that we've constructed a |tabular| with lines of the input text as +% cells we can use \LaTeX's |\settowidth| macro to take its width. +% \begin{macrocode} + \settowidth{#1}{\box\eqp@tabular@box}% } % \end{macrocode} % \end{macro} +% \end{environment} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\eqp@compute@width} +% The following function does all the real work for the +% \pkgname{eqparbox} package. It takes two parameters---\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. It ends by passing \meta{tag} +% and \meta{text} to the |\eqp@produce@box| command, which was defined +% by the calling macro to produce a box using one of the existing +% \LaTeXe\ commands. +% +% To keep track of box widths, |\eqp@compute@width| 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, \pkgname{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)} +% \changes{v3.1}{2010/01/01}{Restructured the package to make all +% user-callable functions eventually call +% \texttt{\string\string\string\eqp@compute@width}, which does the +% bulk of the work} +% \begin{macrocode} +\long\def\eqp@compute@width#1#2{% + \eqp@settowidth{\eqp@tempdimb}{#2}% +% \end{macrocode} +% We first clamp the box width, currently in |\eqp@tempdimb|, to the +% range [|\eqp@minwd@|\meta{tag}, |\eqp@maxwd@|\meta{tag}]. As these +% bounds are not necessarily defined we first have to check for their +% existence. +% \begin{macrocode} + \@ifundefined{eqp@minwd@#1}{}{% + \ifdim\eqp@tempdimb<\csname eqp@minwd@#1\endcsname + \eqp@tempdimb=\csname eqp@minwd@#1\endcsname + \fi + }% + \@ifundefined{eqp@maxwd@#1}{}{% + \ifdim\eqp@tempdimb>\csname eqp@maxwd@#1\endcsname + \eqp@tempdimb=\csname eqp@maxwd@#1\endcsname + \fi + }% + \expandafter + \ifx\csname eqp@this@#1\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@#1\endcsname{\the\eqp@tempdimb}% + \expandafter\xdef\csname eqp@next@#1\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@#1\endcsname\relax + \ifdim\eqp@tempdima<\eqp@tempdimb + \expandafter\xdef\csname eqp@this@#1\endcsname{\the\eqp@tempdimb}% + \global\eqp@must@reruntrue + \fi +% \end{macrocode} +% \begin{macrocode} + \eqp@tempdima=\csname eqp@next@#1\endcsname\relax + \ifdim\eqp@tempdima<\eqp@tempdimb + \expandafter\xdef\csname eqp@next@#1\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@#1}{% + \expandafter\gdef\csname eqp@seen@#1\endcsname{}% + \@cons\eqp@taglist{{#1}}% + }{}% +% \end{macrocode} +% +% Finally, we can call |\eqp@produce@box|. We pass it +% |\eqp@this@|\meta{tag} for its \meta{width} argument and |#2| for its +% \meta{text} argument. +% \begin{macrocode} + \eqp@tempdima=\csname eqp@this@#1\endcsname\relax + \eqp@produce@box{\eqp@tempdima}{#2}% +} +% \end{macrocode} +% \end{macro} +% +% \subsection{Author macros} % % \begin{macro}{\eqparbox} % We want |\eqparbox| to take the same arguments as |\parbox|, with the @@ -809,7 +1257,7 @@ % |\eqp@produce@box|. % \begin{macrocode} \def\eqparbox@iii[#1][#2][#3]{% - \gdef\eqp@produce@box##1##2{% + \long\gdef\eqp@produce@box##1##2{% \parbox[#1][#2][#3]{##1}{##2}% }% \eqp@compute@width @@ -818,6 +1266,88 @@ % \end{macro} % \end{macro} % +% \begin{environment}{eqminipage} +% The |eqminipage| environment is implemented almost exactly like the +% |\eqparbox| macro above. Just like |\eqparbox|, |eqminipage| takes an +% optional \meta{pos} argument that defaults to~|c|. It passes the +% value of this argument to |\eqminipage@i|. +% \changes{v4.0}{2013/03/14}{Introduced this environment} +% \begin{macrocode} +\DeclareRobustCommand{\eqminipage}{% + \@ifnextchar[%] + {\eqminipage@i}% + {\eqminipage@iii[c][\relax][s]}% +} +\let\endeqpminipage=\relax +% \end{macrocode} +% \end{environment} +% +% \begin{macro}{\eqminipage@i} +% |\eqminipage@i| takes a \meta{pos} argument followed by an optional +% \meta{height} argument that defaults to~|\relax|. It passes both +% \meta{pos} and \meta{height} to |\eqminipage@ii|. +% \begin{macrocode} +\long\def\eqminipage@i[#1]{% + \@ifnextchar[%] + {\eqminipage@ii[#1]}% + {\eqminipage@iii[#1][\relax][s]}% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\eqminipage@ii} +% |\eqminipage@ii| takes \meta{pos} and \meta{height} arguments followed +% by an optional \meta{inner-pos} argument that defaults to \meta{pos}. +% It passes \meta{pos}, \meta{height}, and \meta{inner-pos} to +% |\eqminipage@iii|. +% \begin{macrocode} +\def\eqminipage@ii[#1][#2]{% + \@ifnextchar[%] + {\eqminipage@iii[#1][#2]}% + {\eqminipage@iii[#1][#2][#1]}% +} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\eqminipage@iii} +% This is where |eqminipage| differs from |\eqparbox|. Like +% |\eqparbox@iii|, |\eqminipage@iii| takes \meta{pos}, \meta{height} and +% \meta{inner-pos} arguments. However, while |\eqparbox@iii| expects to +% be followed by a tag and text, |\eqminipage@iii| consumes the tag +% itself. |\eqminipage@iii| then uses \pkgname{environ}'s +% |\Collect@Body| macro to collect everything up to the +% |\end{eqminipage}| into a single argument, which it passes to +% |\eqminipage@iv|. +% \begin{macrocode} +\def\eqminipage@iii[#1][#2][#3]#4{% +% \end{macrocode} +% \begin{macro}{\eqminipage@iv} +% \begin{macro}{\eqp@produce@box} +% This code is a bit confusing due to the definition of a macro within a +% macro within a macro. |\eqminipage@iv|, which is invoked by +% |\collect@body|, is passed the body of the |eqminipage| environment as +% an argument. In then defines an |\eqp@produce@box| macro with the +% parameter list that |\eqp@compute@width| expects: a width (|####1|) +% and text (|####2|). |\eqp@produce@box| typesets a |minipage| with +% that width and text and the formatting parameters provided to +% |\eqminipage@iii| (|#1|, |#2|, and~|#3|). Finally, |\eqminipage@iv| +% invokes |\eqp@compute@width| with the tag passed to |\eqminipage@iii| +% as~|#4| and the text passed to |\eqminipage@iv| as~|##1|. +% \begin{macrocode} + \long\def\eqminipage@iv##1{% + \long\gdef\eqp@produce@box####1####2{% + \begin{minipage}[#1][#2][#3]{####1}% + ####2% + \end{minipage}% + }% + \eqp@compute@width{#4}{##1}% + }% + \Collect@Body\eqminipage@iv +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% % \begin{macro}{\eqmakebox} % |\eqmakebox| provides an automatic-width analogue to \LaTeX's % |\makebox|. It takes the same arguments as |\makebox| with the same @@ -898,7 +1428,7 @@ % |\eqp@produce@box|. % \begin{macrocode} \def\eqlrbox@ii#1[#2][#3]{% - \gdef\eqp@produce@box##1##2{% + \long\gdef\eqp@produce@box##1##2{% #1[##1][#3]{##2}% }% \eqp@compute@width{#2}% @@ -907,120 +1437,167 @@ % \end{macro} % \end{macro} % -% \begin{macro}{\eqp@compute@width} -% The following function does all the real work for the -% \pkgname{eqparbox} package. It takes two parameters---\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. It ends by passing \meta{tag} -% and \meta{text} to the |\eqp@produce@box| command, which was defined -% by the calling macro to produce a box using one of the existing -% \LaTeXe\ commands. -% -% To keep track of box widths, |\eqp@compute@width| 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, \pkgname{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)} -% \changes{v3.1}{2010/01/01}{Restructured the package to make all -% user-callable functions eventually call -% \texttt{\string\string\string\eqp@compute@width}, which does the -% bulk of the work} -% \begin{macrocode} -\def\eqp@compute@width#1#2{% - \eqp@settowidth{\eqp@tempdimb}{#2}% - \expandafter - \ifx\csname eqp@this@#1\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{macro}{\eqboxwidth} +% For the times that the user wants to make something other than a box to +% 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 +% \pkgname{calc} package's \texttt{\string\string\string\setlength} +% command (problem initially reported by Gary L. Gray and narrowed +% down by Martin Vaeth)} % \begin{macrocode} - \global\eqp@must@reruntrue - \expandafter\xdef\csname eqp@this@#1\endcsname{\the\eqp@tempdimb}% - \expandafter\xdef\csname eqp@next@#1\endcsname{\the\eqp@tempdimb}% - \else +\newcommand*{\eqboxwidth}[1]{% + \@ifundefined{eqp@this@#1}{0pt}{\csname eqp@this@#1\endcsname}% +} % \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. +% \end{macro} +% +% \begin{macro}{\eqsetminwidth} +% The |\eqsetminwidth| macro accepts a tag and a length and records that +% the user wants the associated box to be no narrower than the given +% length. +% \changes{v4.0}{2013/03/04}{Introduced this macro} % \begin{macrocode} - \eqp@tempdima=\csname eqp@this@#1\endcsname\relax - \ifdim\eqp@tempdima<\eqp@tempdimb - \expandafter\xdef\csname eqp@this@#1\endcsname{\the\eqp@tempdimb}% - \global\eqp@must@reruntrue - \fi +\newcommand{\eqsetminwidth}[2]{% + \@tempdima=#2\relax + \expandafter\xdef\csname eqp@minwd@#1\endcsname{\the\@tempdima}% +} % \end{macrocode} +% \end{macro} +% +% \begin{macro}{\eqsetmaxwidth} +% The |\eqsetmaxwidth| macro accepts a tag and a length and records that +% the user wants the associated box to be no wider than the given +% length. +% \changes{v4.0}{2013/03/04}{Introduced this macro} % \begin{macrocode} - \eqp@tempdima=\csname eqp@next@#1\endcsname\relax - \ifdim\eqp@tempdima<\eqp@tempdimb - \expandafter\xdef\csname eqp@next@#1\endcsname{\the\eqp@tempdimb}% - \fi - \fi +\newcommand{\eqsetmaxwidth}[2]{% + \@tempdima=#2\relax + \expandafter\xdef\csname eqp@maxwd@#1\endcsname{\the\@tempdima}% +} % \end{macrocode} +% \end{macro} % -% 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{macro}{\eqsetminwidthto} +% The |\eqsetminwidthto| macro accepts a tag and a piece of text and +% records that the user wants the associated box to be no narrower than +% the text, typeset at its natural width. +% \changes{v4.0}{2013/03/04}{Introduced this macro} % \begin{macrocode} - \@ifundefined{eqp@seen@#1}{% - \expandafter\gdef\csname eqp@seen@#1\endcsname{}% - \@cons\eqp@taglist{{#1}}% - }{}% +\newcommand{\eqsetminwidthto}[2]{% + \eqp@settowidth{\@tempdima}{#2}% + \expandafter\xdef\csname eqp@minwd@#1\endcsname{\the\@tempdima}% +} % \end{macrocode} +% \end{macro} % -% Finally, we can call |\eqp@produce@box|. We pass it -% |\eqp@this@|\meta{tag} for its \meta{width} argument and |#2| for its -% \meta{text} argument. +% \begin{macro}{\eqsetmaxwidthto} +% The |\eqsetmaxwidthto| macro accepts a tag and a piece of text and +% records that the user wants the associated box to be no wider than +% the text, typeset at its natural width. +% \changes{v4.0}{2013/03/04}{Introduced this macro} % \begin{macrocode} - \eqp@tempdima=\csname eqp@this@#1\endcsname\relax - \eqp@produce@box{\eqp@tempdima}{#2}% +\newcommand{\eqsetmaxwidthto}[2]{% + \eqp@settowidth{\@tempdima}{#2}% + \expandafter\xdef\csname eqp@maxwd@#1\endcsname{\the\@tempdima}% } % \end{macrocode} % \end{macro} % -% \begin{macro}{\eqboxwidth} -% For the times that the user wants to make something other than a box to -% 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 -% \pkgname{calc} package's \texttt{\string\string\string\setlength} -% command (problem initially reported by Gary L. Gray and narrowed -% down by Martin Vaeth)} +% \subsection{End-of-document processing} +% +% 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} -\newcommand*{\eqboxwidth}[1]{% - \@ifundefined{eqp@this@#1}{0pt}{\csname eqp@this@#1\endcsname}% +\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)} +% \changes{v4.0}{2013/03/04}{Modified to honor minimum and maximum +% text widths, as set by +% \texttt{\string\string\string\eqset}\{\texttt{max},\texttt{min}\}\texttt{width} and +% \texttt{\string\string\string\eqset}\{\texttt{max},\texttt{min}\}\texttt{widthto}} +% \begin{macrocode} + \def\@elt#1{% +% \end{macrocode} +% Complain if the tag's minimum width is greater than its maximum width. +% \begin{macrocode} + \@ifundefined{eqp@minwd@#1}{}{% + \@ifundefined{eqp@maxwd@#1}{}{% + \ifdim\csname eqp@minwd@#1\endcsname>\csname eqp@maxwd@#1\endcsname + \PackageWarning{eqparbox}{For tag `#1', + minimum width (\csname eqp@minwd@#1\endcsname) > + maximum width (\csname eqp@maxwd@#1\endcsname)}% + \fi + }% + }% +% \end{macrocode} +% Make the |.aux| file define |\eqp@this@|\meta{tag} to the current +% value of |\eqp@next@|\meta{tag} and |\eqp@next@|\meta{tag} to |0pt|. +% \begin{macrocode} + \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}% + }% +% \end{macrocode} +% Also make the |.aux| file define |\eqp@minwd@|\meta{tag} and +% |\eqp@maxwd@|\meta{tag} to their current value, if any. +% \begin{macrocode} + \@ifundefined{eqp@minwd@#1}{}{% + \immediate\write\@auxout{% + \string\expandafter\string\gdef\string\csname\space + eqp@minwd@#1\string\endcsname{% + \csname eqp@minwd@#1\endcsname + }% + }% + }% + \@ifundefined{eqp@maxwd@#1}{}{% + \immediate\write\@auxout{% + \string\expandafter\string\gdef\string\csname\space + eqp@maxwd@#1\string\endcsname{% + \csname eqp@maxwd@#1\endcsname + }% + }% + }% + }% + \eqp@taglist + \endgroup +% \end{macrocode} +% We output a 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} % -% \DeleteShortVerb{\|} -% \MakeShortVerb{\!} -% \paragraph{Per-tag memory usage} -% The \pkgname{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{\|} -% % \Finale \endinput diff --git a/Master/texmf-dist/source/latex/eqparbox/eqparbox.ins b/Master/texmf-dist/source/latex/eqparbox/eqparbox.ins index aced0885ae3..86de23ab898 100644 --- a/Master/texmf-dist/source/latex/eqparbox/eqparbox.ins +++ b/Master/texmf-dist/source/latex/eqparbox/eqparbox.ins @@ -3,7 +3,7 @@ %% driver files from the doc files in this package when run through %% LaTeX or TeX. %% -%% Copyright (C) 2010 Scott Pakin <scott+eqp@pakin.org> +%% Copyright (C) 2013 Scott Pakin <scott+eqp@pakin.org> %% ------------------------------------------------------- %% %% This package may be distributed and/or modified under the @@ -26,7 +26,7 @@ This is a generated file. -Copyright (C) 2010 Scott Pakin <scott+eqp@pakin.org> +Copyright (C) 2013 Scott Pakin <scott+eqp@pakin.org> ------------------------------------------------------- This package may be distributed and/or modified under the |