PageRenderTime 82ms CodeModel.GetById 18ms app.highlight 59ms RepoModel.GetById 1ms app.codeStats 1ms

/pkg/vignettes/threeparttable.sty

https://code.google.com/
TeX | 381 lines | 213 code | 48 blank | 120 comment | 3 complexity | b1f6939603eb591618cae0d45a28d460 MD5 | raw file
  1% threeparttable.sty   (or 3parttable) (or 3parttab on DOS)
  2% by Donald Arseneau   Updated on June 13, 2003.
  3% Three part tables: title, tabular environment, notes
  4%
  5% This file may be distributed, modified, and used in other works with just
  6% one restriction: modified versions must clearly indicate the modification
  7% (a name change, or a displayed message, or ?).
  8%
  9% This package facilitates tables with titles (captions) and notes. The
 10% title and notes are given a width equal to the body of the table (a
 11% tabular environment).  By itself, a threeparttable does not float, but
 12% you can put it in a {table} or a {table*} or some other environment.
 13% (This causes extra typing, but gives more flexibility.)
 14%
 15% Inside a threeparttable there should be a caption, followed by a tabular
 16% environment (tabular, tabular* or tabularx), possibly followed by a series
 17% of itemized "tablenotes".  The caption can also go after the tabular. 
 18% 
 19% \begin{table}
 20%  \begin{threeparttable}[b]
 21%   \caption{...}
 22%   \begin{tabular}...% or {tabular*}
 23%    ...42\tnote{1}&....
 24%    ...
 25%   \end{tabular}
 26%   \begin{tablenotes}
 27%    \item [1] the first note
 28%    ...
 29%   \end{tablenotes}
 30%  \end{threeparttable}
 31% \end{table}
 32%
 33% The {threeparttable} environment takes an optional vertical-placement
 34% parameter, [t], [b], or [c]; the default is [t].
 35% 
 36% At present, there is nothing automatic about the notes; you must specify the
 37% identifier in the body of the table ("\tnote{a}") and in the notes below
 38% ("\item[a]...").  I chose this method because automatic numbering with 
 39% \footnote would be very hard to use, particularly because many tables make
 40% repeated reference to a single note.  If someone has a convenient, elegant,
 41% automatic system, I'll listen!  \tnote commands can be given in the caption
 42% too, and they will *NOT* appear in the list of tables.
 43%
 44% There are several commands which should be redefined for customizing the
 45% behavior of threeparttable, especially the table notes.  Some options
 46% are provided for common variations of the table notes.
 47%
 48% Options:
 49%   [para]        Notes come one-after-another without line breaks
 50%   [flushleft]   No hanging indentation on notes
 51%   [online]      \item tag is printed normal size, not superscript
 52%   [normal]      restores default formatting
 53%
 54% These options can be given to the \usepackage command or to each individual
 55% {tablenotes} environment.  The [normal] option is intended to reverse the
 56% whole-document options for a particular table; e.g.
 57%
 58% \usepackage[para]{threeparttable}
 59% ... much document ...
 60% \begin{tablenotes}[normal,flushleft]
 61%
 62% These few options are unlikely to give you a desired specified format,
 63% so you should expect to redefine one or more of the configuration
 64% commands.  Note that mixing options with redefinitions is unlikely
 65% to work smoothly.  Please submit your redefinitions to be used as
 66% options in future versions!
 67%
 68% Configuration commands:
 69%   \TPTminimum: command telling minimum caption width.  Default "4em";
 70%        change with \def or \renewcommnd.
 71%   \TPTrlap: A command with one argument, to make notes go out of
 72%        the column, into the column separation (for right-aligning)
 73%   \TPTtagStyle: Command with one argument to set appearance of the tag
 74%        (number) in \tnote{tag}.  It defaults to nil.  It could be \textit.
 75%   \tnote: Yes, you can redefine the \tnote command.
 76%   \TPTnoteLabel: Command with one argument to format the item label in 
 77%        the tablenotes list (\makelabel); default uses \tnote.
 78%   \TPTnoteSettings: A command to issue all the list-environment setup
 79%        commands for the tablenotes.
 80%   \tablenotes or \TPTdoTablenotes: Yes, you can redefine the whole
 81%        tablenotes environment. (\tablenotes processes optional 
 82%        parameters, then invokes \TPTdoTablenotes; the [para] option
 83%        replaces \TPTdoTablenotes.)
 84%
 85% For figures, there is an equivalent "measuredfigure" environment. It
 86% is fairly fragile though, and should be used only for a single graphic
 87% above a single caption.
 88%
 89% Note that the \caption formatting is *not* adjusted by threeparttable.
 90% You should use one of the caption-control packages to get captions
 91% that work well as table titles.  In truth, threeparttable sets
 92% \abovecaptionskip to zero for captions above the table, but more
 93% complete changes are called for.
 94
 95\ProvidesPackage{threeparttable}[2003/06/13 \space v 3.0]
 96
 97\edef\TPTminimum % make a scratch macro for restoring catcodes
 98  {\catcode\string `\string @=\the\catcode\string`\@
 99   \catcode\string `\string :=\the\catcode\string`\:
100   \catcode\string `\string *=\the\catcode\string`\*}
101\catcode`\@=11
102\catcode`\:=12
103\catcode`\*=11
104
105\@ifundefined{@tempboxb}{\@nameuse{newbox}\@tempboxb}{}
106
107\newenvironment{threeparttable}[1][t]{%
108 \relax \ifvmode \noindent \fi
109 \TPT@common{threeparttable}{#1}%
110 \@ifundefined{@captype}{\def\@captype{table}}{}%
111 \let\TPT@LA@label\label
112 \let\TPT@LA@caption\@caption \let\@caption\TPT@caption
113 \let\TPT@begintabhook\TPT@begintabbox
114 \let\TPT@tabarghook\TPT@tabargset
115 \TPT@hookin{tabular}%
116 \TPT@hookarg{tabular*}%
117 \TPT@hookarg{tabularx}%
118 \let\TPToverlap\relax}%
119{\TPT@close}
120
121
122\newenvironment{measuredfigure}[1][t]{%
123 \relax \ifvmode \noindent \fi
124 \TPT@common{measuredfigure}{#1}%
125 \let\TPT@figfix\TPT@close % Provide closure if no caption
126 \@ifundefined{@captype}{\def\@captype{figure}}{}%
127 \let\TPT@LA@caption\@caption \let\@caption\TPT@gr@caption
128 \setbox\@tempboxb\hbox\bgroup
129  \aftergroup\TPT@measurement
130  \color@begingroup\spacefactor994\ignorespaces}
131{\TPT@close \TPT@figfix}
132
133\def\TPT@close{\ifhmode \unskip \fi \color@endgroup \egroup}
134\def\TPT@figfix{}
135
136%  Caption for figures:
137\def\TPT@gr@caption#1[#2]#3{\relax
138 \ifnum\spacefactor=994\relax % Caption listed first; hold on to it
139  \abovecaptionskip\z@skip
140  \let\TPT@hsize\@empty % double sure
141 \else % Have something to measure, and caption below
142  \TPT@close % close hbox.  Measurement happens here automatically
143 \fi
144 \TPT@caption{#1}[{#2}]{#3}%
145}
146
147%  "begin" code common for tables and figures
148\def\TPT@common#1#2{%
149 \ifx\TPT@LA@caption\relax\else  
150  \PackageError{threeparttable}%
151    {Illegal nested #1 environments}%
152    {Maybe you have a missing \string\end{#1}?^^J%
153     This cannot work, so type \string"x\string" and fix the problem now.}%
154 \fi
155 \let\TPT@docapt\@undefined
156 \if b#2\relax\vbox\bgroup\else
157 \if c#2\relax$\vcenter\bgroup\aftergroup$\else
158        \vtop\bgroup \fi\fi
159 \parindent\z@
160 \color@begingroup
161 \def\TPT@sethsize{\TPT@hsize\par}%
162 \topsep\z@
163 \@enumdepth\z@
164 \global\let\TPT@hsize\@empty
165}
166
167% "hookin" hooks into tabular to set the alignment in a box
168% and measure the box.
169% For tabular* and tabularx, we can simply use the supplied "width"
170% argument (using \TPT@hookarg), but for ordinary tabular environments
171% we need to measure the typeset tabular body, using hooks in both the
172% begin and the end code (using \TPT@hookin).  The hook-in is defined
173% generically so it is easy to add new supported environments.
174%
175% I will add \TPT@begintabhook and \TPT@endtabhook to \tabular and 
176% \endtabular.  These will do the measurement at the outer level, 
177% but will be no-ops inside.
178
179\def\TPT@unhook{%
180 \let\TPT@begintabhook\bgroup
181 \let\TPT@tabarghook\@gobble
182}
183
184\let\TPT@endtabhook\egroup
185
186%  This is simple -- Hook into tabular types that are given explicit width 
187\def\TPT@hookarg#1{% #1 = width
188 \expandafter\let\csname TPTsav@#1\expandafter\endcsname\csname #1\endcsname
189 \expandafter\edef\csname #1\endcsname##1{\noexpand\TPT@tabarghook{##1}%
190     \expandafter\noexpand\csname TPTsav@#1\endcsname{\hsize}}%
191}
192
193\def\TPT@tabargset#1{%  Alias \TPT@tabarghook
194 \TPT@unhook
195 \setlength\hsize{#1}%
196 \xdef\TPT@hsize{\hsize\the\hsize \parindent 1em \noexpand\@parboxrestore}%
197 \TPT@hsize
198 \ifx\TPT@docapt\@undefined\else \TPT@docapt \vskip.2\baselineskip \fi
199 \par \aftergroup\TPT@sethsize
200}
201
202%  Harder -- Hook into tabular/endtabular to measure the width
203\def\TPT@hookin#1{%
204 \expandafter\let\csname TPTsav@#1\expandafter\endcsname\csname #1\endcsname
205 \expandafter\let\csname TPTsav@end#1\expandafter\endcsname\csname end#1\endcsname
206 \expandafter\edef\csname #1\endcsname{\noexpand\TPT@begintabhook
207     \expandafter\noexpand\csname TPTsav@#1\endcsname}%
208 \expandafter\edef\csname end#1\endcsname{%
209     \expandafter\noexpand\csname TPTsav@end#1\endcsname \TPT@endtabhook}%
210}
211
212\def\TPT@begintabbox{% alias \TPT@begintabhook
213 \begingroup
214 \TPT@unhook
215 \setbox\@tempboxb\hbox\bgroup \aftergroup\TPT@endtabbox
216 \let\TPToverlap\TPTrlap % Just \rlap now, but could be smarter
217}
218
219\def\TPT@endtabbox{% Inserted after ending \@tempboxb
220 \TPT@measurement
221 \endgroup 
222 \TPT@hsize  \aftergroup\TPT@sethsize 
223 \@ignoretrue
224}
225
226\def\TPT@measurement{%
227 \ifdim\wd\@tempboxb<\TPTminimum
228  \hsize \TPTminimum
229 \else
230  \hsize\wd\@tempboxb
231 \fi
232 \xdef\TPT@hsize{\hsize\the\hsize \noexpand\@parboxrestore}\TPT@hsize
233 \ifx\TPT@docapt\@undefined\else
234  \TPT@docapt \vskip.2\baselineskip
235 \fi \par \box\@tempboxb
236 \ifvmode \prevdepth\z@ \fi
237}
238
239\gdef\TPT@hsize{}
240\def\TPT@sethsize{}%  Used with \aftergroup, so do this to cover for when a
241                   %  \TPT@sethsize escapes from threeparttable.
242
243% Collecting caption for tables:
244\def\TPT@caption#1[#2]#3{\gdef\TPT@docapt
245 {\par\global\let\TPT@docapt\@undefined \TPT@LA@caption{#1}[{#2}]%
246   {\strut\ignorespaces#3\ifhmode\unskip\@finalstrut\strutbox\fi}}%
247 \ifx\TPT@hsize\@empty \let\label\TPT@gatherlabel \abovecaptionskip\z@skip
248 \else \TPT@docapt \fi \ignorespaces}
249
250\let\TPT@LA@caption\relax
251
252% Must also collect any \label that appears after a collected \caption
253\def\TPT@gatherlabel#1{%
254  \ifx\TPT@docapt\@undefined \TPT@LA@label{#1}\else
255      \g@addto@macro\TPT@docapt{\label{#1}}\fi
256}
257
258\def\tablenotes{\TPT@defaults 
259  \@ifnextchar[\TPT@setuptnotes\TPTdoTablenotes} % ]
260\let\endtablenotes\endlist
261\def\TPT@setuptnotes [#1]{% process formatting options
262  \@for\@tempa:=#1\do{\@nameuse{TPT@opt@\romannumeral-`a\@tempa}}%
263  \TPTdoTablenotes
264}
265
266\def\TPTdoTablenotes{%
267 \par \prevdepth\z@ \TPT@hsize 
268 \list{}{\topsep\z@skip \partopsep\z@skip 
269  \itemsep\z@ \parsep\z@ \itemindent\z@
270  \TPTnoteSettings
271  \let\makelabel\TPTnoteLabel
272}}
273
274
275
276% \TPToverlap is a hook, to be used in \tnote, for making the note tag
277% hang over the right-edge of the column.  It takes different meanings 
278% at different places, and it should disappear, like this, outside of
279% a threeparttable environment.
280%
281\def\TPToverlap#1{} % notes in caption will disappear in list of tables!
282
283% \TPTrlap is the meaning of \TPToverlap within the tabular environment.
284% I could do some fancy definition so that it only acts at the right-edge
285% of a column, but it is left simple for compatibility and sanity. 
286\let\TPTrlap\rlap
287
288\def\tnote#1{\protect\TPToverlap{\textsuperscript{\TPTtagStyle{#1}}}}% 
289
290\def\TPTtagStyle#1{#1}
291
292\def\TPTnoteSettings{%
293 \setlength\leftmargin{1.5em}%
294 \setlength\labelwidth{.5em}%
295 \setlength\labelsep{.2em}%
296 \rightskip\tabcolsep \leftskip\tabcolsep
297}
298\def\TPTnoteLabel#1{\tnote{#1}\hfil}
299
300% Package and tablenotes options
301
302\def\TPT@opt@normal{\gdef\TPT@defaults{}}
303\TPT@opt@normal
304\DeclareOption{normal}{}
305
306\def\TPT@opt@online{%
307 \def\TPTnoteSettings{\leftmargin1.5em \labelwidth1em \labelsep.5em\relax}%
308 \def\TPTnoteLabel##1{\TPTtagStyle{##1}\hfil}%
309}
310\DeclareOption{online}{\g@addto@macro\TPT@defaults{\TPT@opt@online}}
311
312\def\TPT@opt@flushleft{%
313 \def\TPTnoteSettings{\labelsep.2em \leftmargin\z@ \labelwidth\z@}%
314 \def\TPTnoteLabel##1{\hspace\labelsep\tnote{##1}\hfil}%
315 \rightskip\z@skip \leftskip\z@skip
316}
317\DeclareOption{flushleft}{\g@addto@macro\TPT@defaults{\TPT@opt@flushleft}}
318
319\def\TPT@opt@para{\let\TPTdoTablenotes\TPT@doparanotes}
320\def\TPT@doparanotes{\par
321   \prevdepth\z@ \TPT@hsize
322   \TPTnoteSettings
323   \parindent\z@ \pretolerance 8
324   \linepenalty 200
325   \renewcommand\item[1][]{\relax\ifhmode \begingroup
326       \unskip
327       \advance\hsize 10em % \hsize is scratch register, based on real hsize
328       \penalty -45 \hskip\z@\@plus\hsize \penalty-19
329       \hskip .15\hsize \penalty 9999 \hskip-.15\hsize
330       \hskip .01\hsize\@plus-\hsize\@minus.01\hsize 
331       \hskip 1em\@plus .3em
332      \endgroup\fi
333      \tnote{##1}\,\ignorespaces}%
334   \let\TPToverlap\relax
335   \def\endtablenotes{\par}%
336}
337\DeclareOption{para}{\g@addto@macro\TPT@defaults{\TPT@opt@para}}
338
339\ProcessOptions
340
341
342\TPTminimum % restore catcode of @, : and * to starting value
343
344\def\TPTminimum{4em}
345
346\endinput
347
348Example:
349
350Here is some paragraph before the table.  Note that this table does not
351float because it is not in a {table} or {table*} environment.
352
353\begin{center}
354\begin{threeparttable}
355\caption{The Skewing Angles ($\beta$) for $\fam0 Mu(H)+X_2$ and
356   $\fam0 Mu(H)+HX$~\tnote{a}}
357\begin{tabular}{rlcc}
358\hline
359&   & $\fam0 H(Mu)+F_2$ & $\fam0 H(Mu)+Cl_2$ \\
360\hline
361&$\beta$(H)  & $80.9^\circ\tnote{b}$ & $83.2^\circ$ \\
362&$\beta$(Mu) & $86.7^\circ$ & $87.7^\circ$ \\
363\hline
364\end{tabular}
365\begin{tablenotes}
366\item[a] for the abstraction reaction, $\fam0 Mu+HX \rightarrow MuH+X$.
367\item[b] 1 degree${} = \pi/180$ radians.
368\end{tablenotes}
369\end{threeparttable}
370
371\end{center}
372
373Notes:  
374
375May 15, 2001: changed hook-in to use \setbox in a wrapper macro (or
376explicit width of tabular*).  I don't remember why I used \everyhbox
377and \lastbox before.  Something may break now.  At least it works with
378tabularx.
379
380June 13, 2003: Re-wrote a lot, particularly the hook mechanism.  Use macros
381and package/environment options for formatting control.  Add measuredfigure.