/pkg/vignettes/threeparttable.sty
https://code.google.com/ · TeX · 381 lines · 213 code · 48 blank · 120 comment · 3 complexity · b1f6939603eb591618cae0d45a28d460 MD5 · raw file
- % threeparttable.sty (or 3parttable) (or 3parttab on DOS)
- % by Donald Arseneau Updated on June 13, 2003.
- % Three part tables: title, tabular environment, notes
- %
- % This file may be distributed, modified, and used in other works with just
- % one restriction: modified versions must clearly indicate the modification
- % (a name change, or a displayed message, or ?).
- %
- % This package facilitates tables with titles (captions) and notes. The
- % title and notes are given a width equal to the body of the table (a
- % tabular environment). By itself, a threeparttable does not float, but
- % you can put it in a {table} or a {table*} or some other environment.
- % (This causes extra typing, but gives more flexibility.)
- %
- % Inside a threeparttable there should be a caption, followed by a tabular
- % environment (tabular, tabular* or tabularx), possibly followed by a series
- % of itemized "tablenotes". The caption can also go after the tabular.
- %
- % \begin{table}
- % \begin{threeparttable}[b]
- % \caption{...}
- % \begin{tabular}...% or {tabular*}
- % ...42\tnote{1}&....
- % ...
- % \end{tabular}
- % \begin{tablenotes}
- % \item [1] the first note
- % ...
- % \end{tablenotes}
- % \end{threeparttable}
- % \end{table}
- %
- % The {threeparttable} environment takes an optional vertical-placement
- % parameter, [t], [b], or [c]; the default is [t].
- %
- % At present, there is nothing automatic about the notes; you must specify the
- % identifier in the body of the table ("\tnote{a}") and in the notes below
- % ("\item[a]..."). I chose this method because automatic numbering with
- % \footnote would be very hard to use, particularly because many tables make
- % repeated reference to a single note. If someone has a convenient, elegant,
- % automatic system, I'll listen! \tnote commands can be given in the caption
- % too, and they will *NOT* appear in the list of tables.
- %
- % There are several commands which should be redefined for customizing the
- % behavior of threeparttable, especially the table notes. Some options
- % are provided for common variations of the table notes.
- %
- % Options:
- % [para] Notes come one-after-another without line breaks
- % [flushleft] No hanging indentation on notes
- % [online] \item tag is printed normal size, not superscript
- % [normal] restores default formatting
- %
- % These options can be given to the \usepackage command or to each individual
- % {tablenotes} environment. The [normal] option is intended to reverse the
- % whole-document options for a particular table; e.g.
- %
- % \usepackage[para]{threeparttable}
- % ... much document ...
- % \begin{tablenotes}[normal,flushleft]
- %
- % These few options are unlikely to give you a desired specified format,
- % so you should expect to redefine one or more of the configuration
- % commands. Note that mixing options with redefinitions is unlikely
- % to work smoothly. Please submit your redefinitions to be used as
- % options in future versions!
- %
- % Configuration commands:
- % \TPTminimum: command telling minimum caption width. Default "4em";
- % change with \def or \renewcommnd.
- % \TPTrlap: A command with one argument, to make notes go out of
- % the column, into the column separation (for right-aligning)
- % \TPTtagStyle: Command with one argument to set appearance of the tag
- % (number) in \tnote{tag}. It defaults to nil. It could be \textit.
- % \tnote: Yes, you can redefine the \tnote command.
- % \TPTnoteLabel: Command with one argument to format the item label in
- % the tablenotes list (\makelabel); default uses \tnote.
- % \TPTnoteSettings: A command to issue all the list-environment setup
- % commands for the tablenotes.
- % \tablenotes or \TPTdoTablenotes: Yes, you can redefine the whole
- % tablenotes environment. (\tablenotes processes optional
- % parameters, then invokes \TPTdoTablenotes; the [para] option
- % replaces \TPTdoTablenotes.)
- %
- % For figures, there is an equivalent "measuredfigure" environment. It
- % is fairly fragile though, and should be used only for a single graphic
- % above a single caption.
- %
- % Note that the \caption formatting is *not* adjusted by threeparttable.
- % You should use one of the caption-control packages to get captions
- % that work well as table titles. In truth, threeparttable sets
- % \abovecaptionskip to zero for captions above the table, but more
- % complete changes are called for.
-
- \ProvidesPackage{threeparttable}[2003/06/13 \space v 3.0]
-
- \edef\TPTminimum % make a scratch macro for restoring catcodes
- {\catcode\string `\string @=\the\catcode\string`\@
- \catcode\string `\string :=\the\catcode\string`\:
- \catcode\string `\string *=\the\catcode\string`\*}
- \catcode`\@=11
- \catcode`\:=12
- \catcode`\*=11
-
- \@ifundefined{@tempboxb}{\@nameuse{newbox}\@tempboxb}{}
-
- \newenvironment{threeparttable}[1][t]{%
- \relax \ifvmode \noindent \fi
- \TPT@common{threeparttable}{#1}%
- \@ifundefined{@captype}{\def\@captype{table}}{}%
- \let\TPT@LA@label\label
- \let\TPT@LA@caption\@caption \let\@caption\TPT@caption
- \let\TPT@begintabhook\TPT@begintabbox
- \let\TPT@tabarghook\TPT@tabargset
- \TPT@hookin{tabular}%
- \TPT@hookarg{tabular*}%
- \TPT@hookarg{tabularx}%
- \let\TPToverlap\relax}%
- {\TPT@close}
-
-
- \newenvironment{measuredfigure}[1][t]{%
- \relax \ifvmode \noindent \fi
- \TPT@common{measuredfigure}{#1}%
- \let\TPT@figfix\TPT@close % Provide closure if no caption
- \@ifundefined{@captype}{\def\@captype{figure}}{}%
- \let\TPT@LA@caption\@caption \let\@caption\TPT@gr@caption
- \setbox\@tempboxb\hbox\bgroup
- \aftergroup\TPT@measurement
- \color@begingroup\spacefactor994\ignorespaces}
- {\TPT@close \TPT@figfix}
-
- \def\TPT@close{\ifhmode \unskip \fi \color@endgroup \egroup}
- \def\TPT@figfix{}
-
- % Caption for figures:
- \def\TPT@gr@caption#1[#2]#3{\relax
- \ifnum\spacefactor=994\relax % Caption listed first; hold on to it
- \abovecaptionskip\z@skip
- \let\TPT@hsize\@empty % double sure
- \else % Have something to measure, and caption below
- \TPT@close % close hbox. Measurement happens here automatically
- \fi
- \TPT@caption{#1}[{#2}]{#3}%
- }
-
- % "begin" code common for tables and figures
- \def\TPT@common#1#2{%
- \ifx\TPT@LA@caption\relax\else
- \PackageError{threeparttable}%
- {Illegal nested #1 environments}%
- {Maybe you have a missing \string\end{#1}?^^J%
- This cannot work, so type \string"x\string" and fix the problem now.}%
- \fi
- \let\TPT@docapt\@undefined
- \if b#2\relax\vbox\bgroup\else
- \if c#2\relax$\vcenter\bgroup\aftergroup$\else
- \vtop\bgroup \fi\fi
- \parindent\z@
- \color@begingroup
- \def\TPT@sethsize{\TPT@hsize\par}%
- \topsep\z@
- \@enumdepth\z@
- \global\let\TPT@hsize\@empty
- }
-
- % "hookin" hooks into tabular to set the alignment in a box
- % and measure the box.
- % For tabular* and tabularx, we can simply use the supplied "width"
- % argument (using \TPT@hookarg), but for ordinary tabular environments
- % we need to measure the typeset tabular body, using hooks in both the
- % begin and the end code (using \TPT@hookin). The hook-in is defined
- % generically so it is easy to add new supported environments.
- %
- % I will add \TPT@begintabhook and \TPT@endtabhook to \tabular and
- % \endtabular. These will do the measurement at the outer level,
- % but will be no-ops inside.
-
- \def\TPT@unhook{%
- \let\TPT@begintabhook\bgroup
- \let\TPT@tabarghook\@gobble
- }
-
- \let\TPT@endtabhook\egroup
-
- % This is simple -- Hook into tabular types that are given explicit width
- \def\TPT@hookarg#1{% #1 = width
- \expandafter\let\csname TPTsav@#1\expandafter\endcsname\csname #1\endcsname
- \expandafter\edef\csname #1\endcsname##1{\noexpand\TPT@tabarghook{##1}%
- \expandafter\noexpand\csname TPTsav@#1\endcsname{\hsize}}%
- }
-
- \def\TPT@tabargset#1{% Alias \TPT@tabarghook
- \TPT@unhook
- \setlength\hsize{#1}%
- \xdef\TPT@hsize{\hsize\the\hsize \parindent 1em \noexpand\@parboxrestore}%
- \TPT@hsize
- \ifx\TPT@docapt\@undefined\else \TPT@docapt \vskip.2\baselineskip \fi
- \par \aftergroup\TPT@sethsize
- }
-
- % Harder -- Hook into tabular/endtabular to measure the width
- \def\TPT@hookin#1{%
- \expandafter\let\csname TPTsav@#1\expandafter\endcsname\csname #1\endcsname
- \expandafter\let\csname TPTsav@end#1\expandafter\endcsname\csname end#1\endcsname
- \expandafter\edef\csname #1\endcsname{\noexpand\TPT@begintabhook
- \expandafter\noexpand\csname TPTsav@#1\endcsname}%
- \expandafter\edef\csname end#1\endcsname{%
- \expandafter\noexpand\csname TPTsav@end#1\endcsname \TPT@endtabhook}%
- }
-
- \def\TPT@begintabbox{% alias \TPT@begintabhook
- \begingroup
- \TPT@unhook
- \setbox\@tempboxb\hbox\bgroup \aftergroup\TPT@endtabbox
- \let\TPToverlap\TPTrlap % Just \rlap now, but could be smarter
- }
-
- \def\TPT@endtabbox{% Inserted after ending \@tempboxb
- \TPT@measurement
- \endgroup
- \TPT@hsize \aftergroup\TPT@sethsize
- \@ignoretrue
- }
-
- \def\TPT@measurement{%
- \ifdim\wd\@tempboxb<\TPTminimum
- \hsize \TPTminimum
- \else
- \hsize\wd\@tempboxb
- \fi
- \xdef\TPT@hsize{\hsize\the\hsize \noexpand\@parboxrestore}\TPT@hsize
- \ifx\TPT@docapt\@undefined\else
- \TPT@docapt \vskip.2\baselineskip
- \fi \par \box\@tempboxb
- \ifvmode \prevdepth\z@ \fi
- }
-
- \gdef\TPT@hsize{}
- \def\TPT@sethsize{}% Used with \aftergroup, so do this to cover for when a
- % \TPT@sethsize escapes from threeparttable.
-
- % Collecting caption for tables:
- \def\TPT@caption#1[#2]#3{\gdef\TPT@docapt
- {\par\global\let\TPT@docapt\@undefined \TPT@LA@caption{#1}[{#2}]%
- {\strut\ignorespaces#3\ifhmode\unskip\@finalstrut\strutbox\fi}}%
- \ifx\TPT@hsize\@empty \let\label\TPT@gatherlabel \abovecaptionskip\z@skip
- \else \TPT@docapt \fi \ignorespaces}
-
- \let\TPT@LA@caption\relax
-
- % Must also collect any \label that appears after a collected \caption
- \def\TPT@gatherlabel#1{%
- \ifx\TPT@docapt\@undefined \TPT@LA@label{#1}\else
- \g@addto@macro\TPT@docapt{\label{#1}}\fi
- }
-
- \def\tablenotes{\TPT@defaults
- \@ifnextchar[\TPT@setuptnotes\TPTdoTablenotes} % ]
- \let\endtablenotes\endlist
- \def\TPT@setuptnotes [#1]{% process formatting options
- \@for\@tempa:=#1\do{\@nameuse{TPT@opt@\romannumeral-`a\@tempa}}%
- \TPTdoTablenotes
- }
-
- \def\TPTdoTablenotes{%
- \par \prevdepth\z@ \TPT@hsize
- \list{}{\topsep\z@skip \partopsep\z@skip
- \itemsep\z@ \parsep\z@ \itemindent\z@
- \TPTnoteSettings
- \let\makelabel\TPTnoteLabel
- }}
-
-
-
- % \TPToverlap is a hook, to be used in \tnote, for making the note tag
- % hang over the right-edge of the column. It takes different meanings
- % at different places, and it should disappear, like this, outside of
- % a threeparttable environment.
- %
- \def\TPToverlap#1{} % notes in caption will disappear in list of tables!
-
- % \TPTrlap is the meaning of \TPToverlap within the tabular environment.
- % I could do some fancy definition so that it only acts at the right-edge
- % of a column, but it is left simple for compatibility and sanity.
- \let\TPTrlap\rlap
-
- \def\tnote#1{\protect\TPToverlap{\textsuperscript{\TPTtagStyle{#1}}}}%
-
- \def\TPTtagStyle#1{#1}
-
- \def\TPTnoteSettings{%
- \setlength\leftmargin{1.5em}%
- \setlength\labelwidth{.5em}%
- \setlength\labelsep{.2em}%
- \rightskip\tabcolsep \leftskip\tabcolsep
- }
- \def\TPTnoteLabel#1{\tnote{#1}\hfil}
-
- % Package and tablenotes options
-
- \def\TPT@opt@normal{\gdef\TPT@defaults{}}
- \TPT@opt@normal
- \DeclareOption{normal}{}
-
- \def\TPT@opt@online{%
- \def\TPTnoteSettings{\leftmargin1.5em \labelwidth1em \labelsep.5em\relax}%
- \def\TPTnoteLabel##1{\TPTtagStyle{##1}\hfil}%
- }
- \DeclareOption{online}{\g@addto@macro\TPT@defaults{\TPT@opt@online}}
-
- \def\TPT@opt@flushleft{%
- \def\TPTnoteSettings{\labelsep.2em \leftmargin\z@ \labelwidth\z@}%
- \def\TPTnoteLabel##1{\hspace\labelsep\tnote{##1}\hfil}%
- \rightskip\z@skip \leftskip\z@skip
- }
- \DeclareOption{flushleft}{\g@addto@macro\TPT@defaults{\TPT@opt@flushleft}}
-
- \def\TPT@opt@para{\let\TPTdoTablenotes\TPT@doparanotes}
- \def\TPT@doparanotes{\par
- \prevdepth\z@ \TPT@hsize
- \TPTnoteSettings
- \parindent\z@ \pretolerance 8
- \linepenalty 200
- \renewcommand\item[1][]{\relax\ifhmode \begingroup
- \unskip
- \advance\hsize 10em % \hsize is scratch register, based on real hsize
- \penalty -45 \hskip\z@\@plus\hsize \penalty-19
- \hskip .15\hsize \penalty 9999 \hskip-.15\hsize
- \hskip .01\hsize\@plus-\hsize\@minus.01\hsize
- \hskip 1em\@plus .3em
- \endgroup\fi
- \tnote{##1}\,\ignorespaces}%
- \let\TPToverlap\relax
- \def\endtablenotes{\par}%
- }
- \DeclareOption{para}{\g@addto@macro\TPT@defaults{\TPT@opt@para}}
-
- \ProcessOptions
-
-
- \TPTminimum % restore catcode of @, : and * to starting value
-
- \def\TPTminimum{4em}
-
- \endinput
-
- Example:
-
- Here is some paragraph before the table. Note that this table does not
- float because it is not in a {table} or {table*} environment.
-
- \begin{center}
- \begin{threeparttable}
- \caption{The Skewing Angles ($\beta$) for $\fam0 Mu(H)+X_2$ and
- $\fam0 Mu(H)+HX$~\tnote{a}}
- \begin{tabular}{rlcc}
- \hline
- & & $\fam0 H(Mu)+F_2$ & $\fam0 H(Mu)+Cl_2$ \\
- \hline
- &$\beta$(H) & $80.9^\circ\tnote{b}$ & $83.2^\circ$ \\
- &$\beta$(Mu) & $86.7^\circ$ & $87.7^\circ$ \\
- \hline
- \end{tabular}
- \begin{tablenotes}
- \item[a] for the abstraction reaction, $\fam0 Mu+HX \rightarrow MuH+X$.
- \item[b] 1 degree${} = \pi/180$ radians.
- \end{tablenotes}
- \end{threeparttable}
-
- \end{center}
-
- Notes:
-
- May 15, 2001: changed hook-in to use \setbox in a wrapper macro (or
- explicit width of tabular*). I don't remember why I used \everyhbox
- and \lastbox before. Something may break now. At least it works with
- tabularx.
-
- June 13, 2003: Re-wrote a lot, particularly the hook mechanism. Use macros
- and package/environment options for formatting control. Add measuredfigure.