summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/pbox/pbox.dtx
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /macros/latex/contrib/pbox/pbox.dtx
Initial commit
Diffstat (limited to 'macros/latex/contrib/pbox/pbox.dtx')
-rw-r--r--macros/latex/contrib/pbox/pbox.dtx392
1 files changed, 392 insertions, 0 deletions
diff --git a/macros/latex/contrib/pbox/pbox.dtx b/macros/latex/contrib/pbox/pbox.dtx
new file mode 100644
index 0000000000..e437175d78
--- /dev/null
+++ b/macros/latex/contrib/pbox/pbox.dtx
@@ -0,0 +1,392 @@
+% \iffalse meta-comment
+% pbox.dtx - DocStrip source code for the pbox package
+% Copyright (C) 2003,2011 Simon Law
+%
+% This program is free software: you can redistribute it and/or modify
+% it under the terms of the GNU General Public License as published by
+% the Free Software Foundation, either version 3 of the License, or
+% (at your option) any later version.
+%
+% This program is distributed in the hope that it will be useful,
+% but WITHOUT ANY WARRANTY; without even the implied warranty of
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+% GNU General Public License for more details.
+%
+% You should have received a copy of the GNU General Public License
+% along with this program. If not, see <http://www.gnu.org/licenses/>.
+%
+% \fi
+% \iffalse
+%<style>\NeedsTeXFormat{LaTeX2e}
+%<style>\ProvidesPackage{pbox}[2011/12/07 v1.2 Dynamic parboxes]
+%<*driver>
+\NeedsTeXFormat{LaTeX2e}[1995/12/01]
+\documentclass{ltxdoc}
+\usepackage{pbox}
+\usepackage{url}
+\usepackage{textcomp}
+\usepackage{fancyvrb}
+\newlength{\ExampleWidth}
+\setlength{\ExampleWidth}{3.5cm}
+\fvset{gobble=6,numbersep=3pt,frame=single,
+ numbers=left,xleftmargin=5mm,xrightmargin=0pt}
+\fvset{xrightmargin=\ExampleWidth}
+\EnableCrossrefs
+ %\DisableCrossrefs % Say \DisableCrossrefs if index is ready
+\CodelineIndex
+\RecordChanges % Gather update information
+ %\OnlyDescription % comment out for implementation details
+ \OldMakeindex % use if your MakeIndex is pre-v2.9
+ %\setlength\hfuzz{15pt} % don't make so many
+ %\hbadness=7000 % over and under full box warnings
+\begin{document}
+ \DocInput{pbox.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \StopEventually{\PrintIndex \PrintChanges}
+% \CheckSum{77}
+%
+% \DoNotIndex{\begin}
+% \DoNotIndex{\columnwidth}
+% \DoNotIndex{\DeclareRobustCommand,\def}
+% \DoNotIndex{\end,\equal}
+% \DoNotIndex{\ifthenelse}
+% \DoNotIndex{\lengthtest}
+% \DoNotIndex{\makebox}
+% \DoNotIndex{\newcommand,\newlength}
+% \DoNotIndex{\parbox}
+% \DoNotIndex{\relax,\RequirePackage}
+% \DoNotIndex{\setlength,\settowidth}
+% \setcounter{IndexColumns}{2}
+%
+% \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.1}{2011/11/24}{Switch to GPLv3.}
+% \changes{v1.0}{2003/03/19}{Initial release.}
+%
+% \GetFileInfo{pbox.sty}
+%
+% \title{The \textsf{pbox} package\thanks{Version \fileversion,
+% last revised \filedate}}
+% \author{Simon Law \\ \url{sfllaw@sfllaw.ca}}
+% \maketitle
+%^^A \tableofcontents
+%
+% \section{Introduction}
+%
+% Most skilled \LaTeX{} users are familiar with the various box
+% commands. These commands include |\makebox|, |\framebox|, |\savebox|,
+% and |\parbox|. These boxes takes a parameter that specifies the
+% width of box to create. To simplify matters, there are the |\mbox|,
+% |\fbox|, and |\sbox| commands that fit the box created to the size of
+% its contents. Conspicuously absent, however, is a |\pbox| command.
+%
+% \section{A variable-width \texttt{\textbackslash parbox}}
+%
+% At first glance, it seems quite inappropriate to create a |\pbox|
+% command. After all, the size of a multi-line box will most likely be
+% limited by the |\textwidth| or |\columnwidth| of the text it encloses.
+% When a line of text is too long, it will be wrapped by \TeX{}'s own
+% line-breaking algorithms. However, there are certain circumstances
+% where one would want a variable-width |\parbox|.
+%
+% For example, you may want to align the top and bottom lines of
+% multi-line boxes. The simplest way to do this is with |parbox|
+% commands with an arbitrary width.
+% \makeatletter
+% \begingroup\center
+% \begin{minipage}[c]{\ExampleWidth-5mm}
+% \parbox[b]{1.5cm}{Hello\\World!}^^A
+% \parbox[t]{1.5cm}{Bonjour\\monde!}
+% \end{minipage}
+% \begin{minipage}{\textwidth-\ExampleWidth}
+% \fvset{xrightmargin=0pt}
+% \begin{Verbatim}
+% \parbox[b]{1.5cm}{Hello\\World!}%
+% \parbox[t]{1.5cm}{Bonjour\\monde!}
+% \end{Verbatim}
+% \end{minipage}
+% \endcenter\endgroup
+% \makeatother
+%
+% \begin{DescribeMacro}{\pbox}
+% However, this is not convenient. It may take several attempts to
+% guess the correct width; and if there was ever a need to change the
+% contents of the boxes, then the hard-coded widths must be changed as
+% well. It would ideal to have a box that would collapse to the
+% minimal required width.
+% \makeatletter
+% \begingroup\center
+% \begin{minipage}[c]{\ExampleWidth-5mm}
+% \pbox[b]{0.5\textwidth}{Hello\\World!}^^A
+% \pbox[t]{0.5\textwidth}{Bonjour\\monde!}
+% \end{minipage}
+% \begin{minipage}{\textwidth-\ExampleWidth}
+% \fvset{xrightmargin=0pt}
+% \begin{Verbatim}
+% \pbox[b]{0.5\textwidth}{Hello\\World!}%
+% \pbox[t]{0.5\textwidth}{Bonjour\\monde!}
+% \end{Verbatim}
+% \end{minipage}
+% \endcenter\endgroup
+% \makeatother
+% Notice how the exclaimation mark and the capital B have no extra
+% space between each other, implying that |\pbox| creates minimal-width
+% boxes.
+%
+% If the provided width argument is smaller than the minimal-width,
+% then |\pbox| acts just like a regular |\parbox|. By minimal-width,
+% we mean the width of the unwrapped piece of text. You will have to
+% put in line breaks, to make |\pbox| create the tightest bounding box.
+%
+% For instance, the following example tries to get |\pbox| to wrap its
+% lines automatically.
+% \makeatletter
+% \begingroup\center
+% \begin{minipage}[c]{\ExampleWidth-5mm}
+% \pbox[b]{1.5cm}{Hello World!}^^A
+% \pbox[t]{1.5cm}{Bonjour monde!}
+% \end{minipage}
+% \begin{minipage}{\textwidth-\ExampleWidth}
+% \fvset{xrightmargin=0pt}
+% \begin{Verbatim}
+% \pbox[b]{1.5cm}{Hello World!}%
+% \pbox[t]{1.5cm}{Bonjour monde!}
+% \end{Verbatim}
+% \end{minipage}
+% \endcenter\endgroup
+% \makeatother
+% \end{DescribeMacro}
+%
+% \section{Determining minimum widths}
+%
+% This is all well and good, but how does one measure the width of one
+% of these boxes? Well, a rather painful way would be to use
+% |\settowidth| in conjunction with a |\parbox|. But it is far easier
+% to do it with the new width commands.
+%
+% \begin{DescribeMacro}{\settominwidth}
+% The |\settominwidth| command works very similarly to the standard
+% |\settowidth| command.
+% \begin{description}
+% \item
+% |\settowidth[|\textit{max\_width}|]{|\textit{cmd}|}{|\textit{text}|}|
+% sets the value of the a length command \textit{cmd} equal to the width
+% of the multi-line \textit{text}. The optional argument
+% \textit{max\_width} allows you to specify the maximum width that will
+% be returned; it defaults to |\columnwidth|.
+% \end{description}
+% \end{DescribeMacro}
+%
+% \begin{DescribeMacro}{\widthofpbox}
+% To provide completeness for the \textsf{calc} package, the
+% |\widthofpbox| command was implemented to complement the |\widthof|
+% command.
+% \begin{description}
+% \item
+% |\widthofpbox{|\textit{text}|}| returns the width of the multi-line
+% \textit{text}.
+% \end{description}
+% Here is an example:
+% \makeatletter
+% \begingroup\center
+% \begin{minipage}[c]{\ExampleWidth-5mm}
+% I\\
+% need\\
+% support\\
+% \rule{\widthofpbox{I\\need\\support}}{0.4pt}
+% \end{minipage}
+% \begin{minipage}{\textwidth-\ExampleWidth}
+% \fvset{xrightmargin=0pt}
+% \begin{Verbatim}
+% I\\
+% need\\
+% support\\
+% \rule{\widthofpbox{I\\need\\support}}{0.4pt}
+% \end{Verbatim}
+% \end{minipage}
+% \endcenter\endgroup
+% \makeatother
+% \end{DescribeMacro}
+%
+% \section{Limitations}
+%
+% Unfortunately, there are some limitations in this package. One of the
+% intrinsic limitations is that you cannot do anything in a |\pbox| that
+% you could not do in a |\parbox|. This seems quite reasonable, so
+% it should not be a hardship.
+%
+% Since |\pbox| is implemented using the \textbf{tabular} environment,
+% there are some things that cannot, and should not be used. You should
+% note that errant |&| characters within a |\pbox| do not generate
+% meaningful error messages. As well, it is unfortunate that
+% |\linebreak| and |\newline| do not work as expected.
+%
+% Since it is a box, you cannot use the \textbf{verbatim} environment
+% within. I recommend that you use the \textsf{fancyvrb} package which
+% contains the \textbf{BVerbatim} and \textbf{LVerbatim} environments
+% for typesetting boxed verbatim text.
+%
+% Alas, I have also discovered that certain uses of |\widthof| and
+% |\widthofpbox| do not work within the \textsf{docstrip} environment.
+%
+% \newpage
+% \section{Implementation}
+% \iffalse
+%<*style>
+% \fi
+%
+% I use the standard \textsf{calc} package for general math. As well,
+% I wish % to support a |\widthofpbox| command, so I will demand that the
+% |\widthof| command exists as well.
+% \begin{macrocode}
+\RequirePackage{calc}
+% \end{macrocode}
+%
+% In order to perform |\lengthtest|s and |\equal|ity tests, I need to
+% include the standard \textsf{ifthen} package. This also provides me
+% with simple conditionals.
+% \begin{macrocode}
+\RequirePackage{ifthen}
+% \end{macrocode}
+%
+% \begin{macro}{\settominwidth}
+% \changes{v1.1}{2011/11/24}{Always return a robust value.}
+% \changes{v1.2}{2011/12/07}{Really fix the result.}
+% The minimum length is determined by the clever use of the
+% \textbf{tabular} environment. It knows how to calculate the minimum
+% requisite width for a column, and the way determines the end of a
+% column is with its end of row command |\\| .
+% This command is conveniently similar to the command typically used to
+% break lines.
+%
+% As you can see, |#1| defaults to the width of a column. This will
+% either be |\textwidth| or the width defined by the \textbf{twocolumn}
+% option, or even the \textsf{multicol} package.
+% \begin{macrocode}
+\newcommand{\settominwidth}[3][\columnwidth]{%
+% \end{macrocode}
+% Here, I set the length command |#2|. Notice the argument to the
+% \textbf{tabular} environment. I use |@{}| to eliminate any horizontal
+% padding, and use the |l| alignment to grab the width of the text in
+% |#3|.
+% \begin{macrocode}
+ \settowidth{#2}{\begin{tabular}{@{}l@{}}#3\end{tabular}}%
+% \end{macrocode}
+% Finally, I wish to make sure that the length I have set in |#2| is
+% not larger than the maximum stored in |#1|.
+% \begin{macrocode}
+ \ifthenelse{\lengthtest{#1<#2}}{\setlength{#2}{#1}}{}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\widthofpbox}
+% In order to find the width of a |\pbox|, I use the same
+% \textbf{tabular} trick from |\settominwidth|. I use the |\widthof|
+% command in order to preserve its semantics instead of trying to
+% emulate them using my |\settominwidth| command.
+%
+% I do \emph{not} check against a maximum length here. Restricting this
+% command to a maximum length would mean that I throw away length
+% information if the text is too long.
+% \begin{macrocode}
+\newcommand{\widthofpbox}[1]{%
+ \widthof{\begin{tabular}{@{}l@{}}#1\end{tabular}}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\pbox}
+% \begin{macro}{\pb@xi}
+% \begin{macro}{\pb@xii}
+% It is not possible to implement |\pbox| in a simple way. The command
+% definition commands in \LaTeX{} don't afford you more than one
+% optional parameter; however, |\parbox| has three.
+%
+% In order to faithfully simulate the three optional arguments, I must
+% trick \LaTeX{} in to catching three optional
+% arguments~\cite{fto:optargs}. Therefore |\pbox|,
+% |\pb@xi|, and |\pb@xii| are used to capture the optional arguments in
+% the |\pb@xargi|, |\pb@xargii|, and |\pb@xargiii| commands. These are
+% then passsed to |\pb@xiii| for actual processing.
+% \begin{macrocode}
+\DeclareRobustCommand*{\pbox}[1][]{%
+ \def\pb@xargi{#1}%
+ \pb@xi}
+\DeclareRobustCommand*{\pb@xi}[1][]{%
+ \def\pb@xargii{#1}%
+ \pb@xii}
+\DeclareRobustCommand*{\pb@xii}[1][]{%
+ \def\pb@xargiii{#1}%
+ \pb@xiii}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\pb@xiii}
+% In order to create the final paragraph box, I parse out the two
+% manditory arguments. I then use the provided maximal length |#1| to
+% determine the actual width of the |\parbox|.
+% \begin{macrocode}
+\newlength{\pb@xlen}
+\DeclareRobustCommand{\pb@xiii}[2]{%
+ \settominwidth[#1]{\pb@xlen}{#2}%
+% \end{macrocode}
+%
+% Since the default optional arguments are all empty, I should be able
+% to just pass them to |\parbox|. However, |\parbox| interprets empty
+% optional values differently than just non-existant optional values.
+% So, I must make complicated decisions; if an optional argument is
+% empty, then I will just skip it..
+% \begin{macrocode}
+ \ifthenelse{\equal{\pb@xargi}{}}
+ {\parbox{\pb@xlen}{#2}}
+ {\ifthenelse{\equal{\pb@xargii}{}}
+ {\ifthenelse{\equal{\pb@xargiii}{}}
+ {\parbox[\pb@xargi]{\pb@xlen}{#2}}
+ {\parbox[\pb@xargi][][\pb@xargiii]{\pb@xlen}{#2}}}
+ {\ifthenelse{\equal{\pb@xargiii}{}}
+ {\parbox[\pb@xargi][\pb@xargii]{\pb@xlen}{#2}}
+ {\parbox[\pb@xargi][\pb@xargii][\pb@xargiii]{\pb@xlen}{#2}}}}%
+% \end{macrocode}
+%
+% Finally, I must clean up the optional arguments and remove their
+% special meaning. As well, I will terminate the |\parbox| I have
+% created with an empty |\makebox| in order to prevent the
+% |\def\pb@x...\relax| commands from interfering with other commands
+% that expect |\pbox| to solely consist of a box.
+% \begin{macrocode}
+ \def\pb@xargi\relax
+ \def\pb@xargii\relax
+ \def\pb@xargiii\relax
+ \makebox[0pt]{}}
+% \end{macrocode}
+% \end{macro}
+% \iffalse
+%</style>
+% \fi
+% \begin{thebibliography}{99}
+% \bibitem{fto:optargs} Robin Fairbanks.
+% ``A command with two optional arguments.''
+% \emph{\TeX{} Frequently Asked Questions.}
+% \url{http://www.tex.ac.uk/cgi-bin/texfaq2html?label=twooptarg}
+% (current 6 April 2003.)
+% \end{thebibliography}
+% \Finale
+\endinput