From e0c6872cf40896c7be36b11dcc744620f10adf1d Mon Sep 17 00:00:00 2001 From: Norbert Preining Date: Mon, 2 Sep 2019 13:46:59 +0900 Subject: Initial commit --- macros/latex/contrib/eqparbox/README | 54 + macros/latex/contrib/eqparbox/eqparbox.dtx | 1650 ++++++++++++++++++++++++++++ macros/latex/contrib/eqparbox/eqparbox.ins | 55 + macros/latex/contrib/eqparbox/eqparbox.pdf | Bin 0 -> 223922 bytes 4 files changed, 1759 insertions(+) create mode 100644 macros/latex/contrib/eqparbox/README create mode 100644 macros/latex/contrib/eqparbox/eqparbox.dtx create mode 100644 macros/latex/contrib/eqparbox/eqparbox.ins create mode 100644 macros/latex/contrib/eqparbox/eqparbox.pdf (limited to 'macros/latex/contrib/eqparbox') diff --git a/macros/latex/contrib/eqparbox/README b/macros/latex/contrib/eqparbox/README new file mode 100644 index 0000000000..a9ca8083ad --- /dev/null +++ b/macros/latex/contrib/eqparbox/README @@ -0,0 +1,54 @@ + +-------------------------------------+ + | EQPARBOX: | + | Create equal-widthed boxes | + | By Scott Pakin, scott+eqp@pakin.org | + +-------------------------------------+ + + +Description +----------- + +LaTeX users sometimes need to ensure that two or more blocks of text +occupy the same horizontal space on the page. To that end, the +eqparbox package defines \eqparbox, \eqmakebox, \eqframebox, and +\eqsavebox macros and an eqminipage environment. These work, +respectively, just like the \parbox, \makebox, \framebox, and \savebox +macros and the minipage environment, except that instead of specifying +a width, one specifies a tag. All boxes with the same tag -- +regardless of where they are in the document -- will stretch to fit +the widest box that uses that tag. This simple, equal-width mechanism +can be used for a variety of alignment purposes, as is evidenced by +the examples in eqparbox's documentation. + + +Installation +------------ + +There's nothing special about building eqparbox: + + latex eqparbox.ins <== Generate eqparbox.sty + latex eqparbox.dtx <== Produce the documentation (eqparbox.dvi) + latex eqparbox.dtx <== Again, to get labels and eqparboxes right + makeindex -s gind.ist eqparbox <== Generate an index + makeindex -s gglo.ist eqparbox.glo -o eqparbox.gls <== Generate a change list + latex eqparbox.dtx <== Incorporate the index into the document + +If you're new to this, see +http://www.tex.ac.uk/cgi-bin/texfaq2html?label=instpackages for more +information on installing packages. + + +Copyright and license +--------------------- + +Copyright (C) 2017 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.3c 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.3c or later is part of all distributions of LaTeX version +2008/05/04 or later. diff --git a/macros/latex/contrib/eqparbox/eqparbox.dtx b/macros/latex/contrib/eqparbox/eqparbox.dtx new file mode 100644 index 0000000000..b8987df56f --- /dev/null +++ b/macros/latex/contrib/eqparbox/eqparbox.dtx @@ -0,0 +1,1650 @@ +% \iffalse meta-comment +% +% Copyright (C) 2017 Scott Pakin +% ---------------------------------------------------- +% +% This package may be distributed and/or modified under the +% conditions of the LaTeX Project Public License, either version 1.3c +% 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.3c or later is part of all distributions of LaTeX +% version 2008/05/04 or later. +% +% \fi +% +% \iffalse +%<*driver> +\ProvidesFile{eqparbox.dtx} +% +%\NeedsTeXFormat{LaTeX2e}[1999/12/01] +%\ProvidesPackage{eqparbox} +%<*package> + [2017/09/03 v4.1 Create equal-widthed boxes] +% +% +%<*driver> +\documentclass{ltxdoc} +\usepackage{eqparbox} +\usepackage{calligra} +\usepackage{array} +\usepackage{boxedminipage} +\usepackage{needspace} +\usepackage{ifmtarg} +\usepackage[subrefformat=parens,labelformat=parens]{subfig} +\usepackage[bookmarksopen]{hyperref} +\EnableCrossrefs +\CodelineIndex +\RecordChanges + +% Uncomment the following line if you don't want to include a +% source-code listing. +%\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} +% +% \fi +% +% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% \CheckSum{536} +% +% \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 +% Lower-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 +% Digits \0\1\2\3\4\5\6\7\8\9 +% Exclamation \! Double quote \" Hash (number) \# +% Dollar \$ Percent \% Ampersand \& +% Acute accent \' Left paren \( Right paren \) +% Asterisk \* Plus \+ Comma \, +% Minus \- Point \. Solidus \/ +% Colon \: Semicolon \; Less than \< +% Equals \= Greater than \> Question mark \? +% Commercial at \@ Left bracket \[ Backslash \\ +% Right bracket \] Circumflex \^ Underscore \_ +% Grave accent \` Left brace \{ Vertical bar \| +% Right brace \} Tilde \~} +% +% \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)} +% +% \GetFileInfo{eqparbox.dtx} +% +% \DoNotIndex{\@auxout,\@cons,\@ifnextchar,\@ifundefined,\@ne,\@tempboxa} +% \DoNotIndex{\@tempdima,\DeclareRobustCommand,\\,\advance,\begin} +% \DoNotIndex{\begingroup,\bgroup,\box,\csname,\def,\egroup,\else,\end} +% \DoNotIndex{\endcsname,\endgroup,\expandafter,\fi,\gdef,\global,\hbox} +% \DoNotIndex{\ifdim,\ifnum,\ifx,\immediate,\let,\long,\m@ne,\mbox} +% \DoNotIndex{\newcommand,\newdimen,\newif,\newlength,\noexpand,\relax} +% \DoNotIndex{\renewcommand,\renewenvironment,\romannumeral,\sbox,\setbox} +% \DoNotIndex{\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 +% ^^A ltxguide.cls. +% \newenvironment{decl}[1][]^^A +% {\par\small\addvspace{4.5ex plus 1ex}^^A +% \vskip -\parskip +% \ifx\relax#1\relax +% \def\@decl@date{}^^A +% \else +% \def\@decl@date{\NEWfeature{#1}}^^A +% \fi +% \noindent\hspace{-\leftmargini}^^A +% \begin{tabular}{|l|}\hline\ignorespaces}^^A +% {\\\hline\end{tabular}\nobreak\@decl@date\par\nobreak +% \vspace{2.3ex}\vskip -\parskip} +% +% ^^A Define a style for typesetting package names. +% \DeclareRobustCommand{\pkgname}[1]{^^A +% \textsf{#1}\index{#1=\textsf{#1} (package)}} +% +% ^^A Give LaTeX some more leeway in placing floats +% ^^A (suggested by Donald Arseneau ). +% \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} +% +% ^^A Because we put table captions *above* tables, we should add a +% ^^A little extra space between the caption and the table. +% \setlength{\belowcaptionskip}{2ex} +% +% ^^A Properly hyphenate Rob Verhoeven's name. +% \hyphenation{Ver-hoe-ven} +% +% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% \title{The \pkgname{eqparbox} package\thanks{This document +% corresponds to \pkgname{eqparbox}~\fileversion, dated \filedate.}} +% \author{Scott Pakin \\ \textit{scott+eqp@pakin.org}} +% \hypersetup{^^A +% pdftitle={The eqparbox package}, +% pdfauthor={Scott Pakin }, +% pdfsubject={LaTeX package for typesetting text in equal-widthed boxes}, +% pdfkeywords={LaTeX2e, parbox, makebox, framebox, savebox, boxes, automatic width, largest} +% } +% +% \maketitle +% +% \begin{abstract} +% The \pkgname{eqparbox} package makes it easy to define a group of +% boxes (such as those produced by |\parbox| or |\makebox|) 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} +% \label{sec:motivation} +% +% Let's start with a little test. How would you typeset +% 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 +% other. +% \item The header columns should be evenly spaced across the page. +% \item Page breaks should be allowed within the r\'esum\'e. +% \end{enumerate} +% +% \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}[htbp] +% \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 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} +% \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 \pkgname{eqparbox} package. +% \pkgname{eqparbox} exports an |\eqparbox| macro that 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. Unlike the cells in a |tabular| column, +% however, a group of |\eqparbox|es can be spread throughout the +% 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} \\[1ex] +% |\begin{eqminipage}| \oarg{pos} \oarg{height} \oarg{inner-pos} \marg{tag} \\ +% \quad \meta{text} \\ +% |\end{eqminipage}| +% \end{decl} +% +% 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 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| \marg{tag} +% \end{decl} +% +% It is sometimes useful to take the width of a box produced by one of +% the preceding commands. While the width can be determined by creating +% an |\eqparbox| and using |\settowidth| to measure it, the +% \pkgname{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. +% +% 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} +% \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} +% +% \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 +% \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 +% +% 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} +% +% \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 +% 2017-02-22 +% & \eqparbox{topiclist}{^^A +% \begin{enumerate} +% \item Hardware upgrades +% \item Barbara's retirement +% \item Revised 27B/6 paperwork +% \end{enumerate} +% }^^A +% \\ \hline +% 2017-03-01 +% & \eqparbox{topiclist}{^^A +% \begin{enumerate} +% \item Printer low on toner +% \item Message from the V.P. +% \end{enumerate} +% }^^A +% \\ \hline +% 2017-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{verbatim} +% 2017-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 +% \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} +% +% \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} +% \newcolumntype{S}[1]{^^A +% >{\begin{lrbox}{\tstretchbox}}^^A +% l^^A +% <{\end{lrbox}^^A +% \eqmakebox[#1][s]{\unhcopy\tstretchbox}}} +% \begin{tabular}{|l|l|} +% \hline +% \calligra +% \begin{tabular}{S{handwritten}} +% Lorem ipsum dolor sit amet, \\ +% consectetur adipiscing elit. \\ +% Phasellus volutpat, nibh sit \\ +% amet mattis convallis, metus \\ +% libero rhoncus justo, sed auctor \\ +% erat mauris sit amet tellus. \\ +% \end{tabular} +% & +% \begin{tabular}{S{typeset}} +% Lorem ipsum dolor sit amet, \\ +% consectetur adipiscing elit. \\ +% Phasellus volutpat, nibh sit \\ +% amet mattis convallis, metus \\ +% libero rhoncus justo, sed auctor \\ +% erat mauris sit amet tellus. \\ +% \end{tabular} \\ +% \hline +% \end{tabular} +% \MakeShortVerb{\|} +% \caption{Line-by-line transcription of text with full justification} +% \label{fig:line-by-line} +% \end{figure} +% +% One solution is to use \pkgname{eqparbox}'s |\eqmakebox| macro. Like +% |\makebox|, |\eqmakebox| supports the ``|s|'' (stretch) value for the +% \meta{pos} argument, which causes the \meta{text} argument to stretch +% to the width of the box. However, while |\makebox| requires the width +% to be specified explicitly, |\eqmakebox| automatically sizes all boxes +% that use the same tag (in this case, each line of the input paragraph) +% to the widest text's natural width. Here's how to use the +% \pkgname{array} package's |\newcolumntype| macro to define a new +% |tabular| column type, ``|S|'', that stretches whitespace as needed to +% fit the widest line in the column: +% +% \begin{verbatim} +% \newsavebox{\tstretchbox} +% \newcolumntype{S}[1]{% +% >{\begin{lrbox}{\tstretchbox}}% +% l% +% <{\end{lrbox}% +% \eqmakebox[#1][s]{\unhcopy\tstretchbox}}} +% \end{verbatim} +% +% \noindent +% That code works by storing the current cell's contents within a box +% called |\tstretchbox| then passing |\tstretchbox|'s contents to +% |\eqmakebox|. (The |tabular| environment does not enable a cell's +% contents to be passed directly to a macro, hence the |lrbox| +% trickery.) Note that the ``|S|'' column type takes an argument, which +% is the tag to pass to |\eqmakebox|. Using the preceding definition we +% can typeset Figure~\ref{fig:line-by-line} as follows. To simulate +% scanned handwriting in the left column we use the Calligra handwriting +% font provided by the \pkgname{calligra} package. +% +% \begin{verbatim} +% \begin{tabular}{|l|l|} +% \hline +% \calligra +% \begin{tabular}{S{handwritten}} +% Lorem ipsum dolor sit amet, \\ +% consectetur adipiscing elit. \\ +% Phasellus volutpat, nibh sit \\ +% amet mattis convallis, metus \\ +% libero rhoncus justo, sed auctor \\ +% erat mauris sit amet tellus. \\ +% \end{tabular} +% & +% \begin{tabular}{S{typeset}} +% Lorem ipsum dolor sit amet, \\ +% consectetur adipiscing elit. \\ +% Phasellus volutpat, nibh sit \\ +% amet mattis convallis, metus \\ +% libero rhoncus justo, sed auctor \\ +% erat mauris sit amet tellus. \\ +% \end{tabular} \\ +% \hline +% \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.,~|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 +% determine the natural width and again within a box wide 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{} +% +% \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 +% 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. +% +% \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} +% \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} +% +% The |\eqp@settowidth| macro requires the \pkgname{array} package's +% ability to inject code into every cell. +% \begin{macrocode} +\RequirePackage{array} +% \end{macrocode} +% +% \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} +\newsavebox{\eqp@tabular@box} +\newsavebox{\eqp@list@box} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\eqp@list@indent} +% The |\eqp@settowidth| macro stores the accumulated |list| indentation +% in |\eqp@list@indent|. +% \begin{macrocode} +\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 +% 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} +% +% \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 +% \pkgname{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|. +% +% 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]{% + \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 +% ($=$~|\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 +% widest 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} +% +% \begin{macro}{\eqp@set@min@width} +% Given a tag and a textual length, ensure that |\eqp@this@|\meta{tag} +% represents a width of at least \meta{length}. +% \changes{v4.1}{2017/09/03}{Introduced this helper macro for +% \texttt{\string\string\string\eqsetminwidth} and +% \texttt{\string\string\string\eqsetminwidthto}} +% \begin{macrocode} +\def\eqp@set@min@width#1#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 assign a value to \meta{tag} and request +% that the user re-run |latex|. +% \begin{macrocode} + \global\eqp@must@reruntrue + \expandafter\xdef\csname eqp@this@#1\endcsname{#2}% + \expandafter\xdef\csname eqp@next@#1\endcsname{#2}% + \else +% \end{macrocode} +% If we get here, then we \emph{have} previously seen tag \meta{tag}. +% We ensure its width is at least~|#2|. +% \begin{macrocode} + \eqp@tempdima=\csname eqp@this@#1\endcsname\relax + \eqp@tempdimb=#2\relax + \ifdim\eqp@tempdima<\eqp@tempdimb + \expandafter\xdef\csname eqp@this@#1\endcsname{\the\eqp@tempdimb}% + \fi + \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 + \@ifundefined{eqp@seen@#1}{% + \expandafter\gdef\csname eqp@seen@#1\endcsname{}% + \@cons\eqp@taglist{{#1}}% + }{}% +} +% \end{macrocode} +% \end{macro} +% +% +% \subsection{Author macros} +% +% \begin{macro}{\eqparbox} +% 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 |\eqparbox|, |\eqparbox@i|, +% |\eqparbox@ii|, and |\eqparbox@iii| macros, which correspond to +% |\parbox|, |\@iparbox|, |\@iiparbox|, and |\@iiiparbox| in +% |ltboxes.dtx|. +% +% |\eqparbox| takes an optional \meta{pos} argument that defaults +% to~|c|. It passes the value of this argument to |\eqparbox@i|. +% \begin{macrocode} +\DeclareRobustCommand{\eqparbox}{% + \@ifnextchar[%] + {\eqparbox@i}% + {\eqparbox@iii[c][\relax][s]}% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\eqparbox@i} +% |\eqparbox@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 |\eqparbox@ii|. +% \begin{macrocode} +\def\eqparbox@i[#1]{% + \@ifnextchar[%] + {\eqparbox@ii[#1]}% + {\eqparbox@iii[#1][\relax][s]}% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\eqparbox@ii} +% |\eqparbox@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 +% |\eqparbox@iii|. +% \begin{macrocode} +\def\eqparbox@ii[#1][#2]{% + \@ifnextchar[%] + {\eqparbox@iii[#1][#2]}% + {\eqparbox@iii[#1][#2][#1]}% +} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\eqparbox@iii} +% \begin{macro}{\eqp@produce@box} +% |\eqparbox@iii| takes \meta{pos}, \meta{height} and \meta{inner-pos} +% arguments. It defines an |\eqp@produce@box| macro that takes a +% \meta{width} argument and a \meta{text} argument and passes all of +% \meta{pos}, \meta{height}, \meta{inner-pos}, \meta{width}, and +% \meta{text} to \LaTeX's |\parbox| macro. |\eqparbox@iii| ends by +% calling |\eqp@compute@width|, which will eventually invoke +% |\eqp@produce@box|. +% \begin{macrocode} +\def\eqparbox@iii[#1][#2][#3]{% + \long\gdef\eqp@produce@box##1##2{% + \parbox[#1][#2][#3]{##1}{##2}% + }% + \eqp@compute@width +} +% \end{macrocode} +% \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 +% default values for the optional arguments. The only difference in +% argument processing is that |\eqmakebox| has a \meta{tag} argument +% where |\makebox| has \meta{width}. Note that if \meta{width} is not +% specified, |\eqmakebox| simply invokes |\makebox|. +% \changes{v3.0}{2010/01/01}{Included Rob Verhoeven's +% \texttt{\string\string\string\eqmakebox} macro} +% \changes{v3.1}{2010/01/01}{Modified the argument processing to match +% \texttt{\string\string\string\makebox}'s} +% \begin{macrocode} +\DeclareRobustCommand{\eqmakebox}{% + \@ifnextchar[%] + {\eqlrbox@i\makebox}% + {\makebox}% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\eqframebox} +% |\eqframebox| provides an automatic-width analogue to \LaTeX's +% |\framebox|. It takes the same arguments as |\framebox| with the same +% default values for the optional arguments. The only difference in +% argument processing is that |\eqframebox| has a \meta{tag} argument +% where |\framebox| has \meta{width}. Note that if \meta{width} is not +% specified, |\eqframebox| simply invokes |\framebox|. +% \changes{v3.1}{2010/01/01}{Introduced this macro} +% \begin{macrocode} +\DeclareRobustCommand{\eqframebox}{% + \@ifnextchar[%] + {\eqlrbox@i\framebox}% + {\framebox}% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\eqsavebox} +% |\eqsavebox| provides an automatic-width analogue to \LaTeX's +% |\savebox|. It takes the same arguments as |\savebox| with the same +% default values for the optional arguments. The only difference in +% argument processing is that |\eqsavebox| has a \meta{tag} argument +% where |\savebox| has \meta{width}. Note that if \meta{width} is not +% specified, |\eqsavebox| simply invokes |\savebox|. +% \changes{v3.1}{2010/01/01}{Introduced this macro} +% \begin{macrocode} +\DeclareRobustCommand{\eqsavebox}[1]{% + \@ifnextchar[%] + {\eqlrbox@i{\savebox{#1}}}% + {\savebox{#1}}% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\eqlrbox@i} +% |\eqlrbox@i| takes a \marg{command} argument (one of |\makebox|, +% |\framebox|, or |\savebox|\marg{cmd}) and a \oarg{tag} argument and +% checks if those arguments are followed by a \oarg{pos} argument. If +% not, then \meta{pos} defaults to ``|c|''. All of \meta{command}, +% \meta{tag}, and \meta{pos} are passed to |\eqlrbox@ii|. +% \begin{macrocode} +\def\eqlrbox@i#1[#2]{% + \@ifnextchar[%] + {\eqlrbox@ii{#1}[#2]}% + {\eqlrbox@ii{#1}[#2][c]}% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\eqlrbox@ii} +% \begin{macro}{\eqp@produce@box} +% |\eqlrbox@i| takes a \marg{command} argument (one of |\makebox|, +% |\framebox|, or |\savebox|\marg{cmd}), a \oarg{tag} argument, and a +% \oarg{pos} argument. It defines |\eqp@produce@box| to take a +% \meta{width} argument and a \meta{text} argument and invoke +% \meta{command}\oarg{width}\oarg{pos}\marg{text}. |\eqlrbox@ii| ends +% by calling |\eqp@compute@width|, which will eventually invoke +% |\eqp@produce@box|. +% \begin{macrocode} +\def\eqlrbox@ii#1[#2][#3]{% + \long\gdef\eqp@produce@box##1##2{% + #1[##1][#3]{##2}% + }% + \eqp@compute@width{#2}% +} +% \end{macrocode} +% \end{macro} +% \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)} +% \begin{macrocode} +\newcommand*{\eqboxwidth}[1]{% + \@ifundefined{eqp@this@#1}{0pt}{\csname eqp@this@#1\endcsname}% +} +% \end{macrocode} +% \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} +% \changes{v4.1}{2017/09/03}{Define +% \texttt{\string\string\string\eqp@this@}\meta{tag} and +% \texttt{\string\string\string\eqp@next@}\meta{tag} appropriately} +% \begin{macrocode} +\newcommand{\eqsetminwidth}[2]{% + \@tempdima=#2\relax + \expandafter\xdef\csname eqp@minwd@#1\endcsname{\the\@tempdima}% + \eqp@set@min@width{#1}{\csname eqp@minwd@#1\endcsname}% +} +% \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} +\newcommand{\eqsetmaxwidth}[2]{% + \@tempdima=#2\relax + \expandafter\xdef\csname eqp@maxwd@#1\endcsname{\the\@tempdima}% +} +% \end{macrocode} +% \end{macro} +% +% \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} +% \changes{v4.1}{2017/09/03}{Define +% \texttt{\string\string\string\eqp@this@}\meta{tag} and +% \texttt{\string\string\string\eqp@next@}\meta{tag} appropriately} +% \begin{macrocode} +\newcommand{\eqsetminwidthto}[2]{% + \eqp@settowidth{\@tempdima}{#2}% + \expandafter\xdef\csname eqp@minwd@#1\endcsname{\the\@tempdima}% + \eqp@set@min@width{#1}{\csname eqp@minwd@#1\endcsname}% +} +% \end{macrocode} +% \end{macro} +% +% \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} +\newcommand{\eqsetmaxwidthto}[2]{% + \eqp@settowidth{\@tempdima}{#2}% + \expandafter\xdef\csname eqp@maxwd@#1\endcsname{\the\@tempdima}% +} +% \end{macrocode} +% \end{macro} +% +% \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} +\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} +% +% \Finale +\endinput diff --git a/macros/latex/contrib/eqparbox/eqparbox.ins b/macros/latex/contrib/eqparbox/eqparbox.ins new file mode 100644 index 0000000000..2aa1fa6834 --- /dev/null +++ b/macros/latex/contrib/eqparbox/eqparbox.ins @@ -0,0 +1,55 @@ +%% +%% This file will generate fast loadable files and documentation +%% driver files from the doc files in this package when run through +%% LaTeX or TeX. +%% +%% Copyright (C) 2017 Scott Pakin +%% ------------------------------------------------------- +%% +%% This package may be distributed and/or modified under the +%% conditions of the LaTeX Project Public License, either version 1.3c +%% 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.3c or later is part of all distributions of LaTeX +%% version 2008/05/04 or later. +%% +%% --------------- start of docstrip commands ------------------ +%% +\input docstrip + +\keepsilent + +\usedir{tex/latex/eqparbox} + +\preamble + +This is a generated file. + +Copyright (C) 2017 Scott Pakin +------------------------------------------------------- + +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.3c or later is part of all distributions of LaTeX +version 2008/05/04 or later. + +\endpreamble + +\generate{\file{eqparbox.sty}{\from{eqparbox.dtx}{package}}} + +\obeyspaces +\Msg{***********************************************************} +\Msg{* To finish the installation, you have to move *} +\Msg{* eqparbox.sty into a directory searched by TeX. *} +\Msg{* *} +\Msg{* To produce the documentation, run eqparbox.dtx *} +\Msg{* through LaTeX. *} +\Msg{* *} +\Msg{* Happy TeXing! *} +\Msg{***********************************************************} + +\endbatchfile diff --git a/macros/latex/contrib/eqparbox/eqparbox.pdf b/macros/latex/contrib/eqparbox/eqparbox.pdf new file mode 100644 index 0000000000..55e85d1e62 Binary files /dev/null and b/macros/latex/contrib/eqparbox/eqparbox.pdf differ -- cgit v1.2.3