9

How to get line-breaking / multirow to work in the caption of my beginner's table?

\caption{this is my first table's captive caption}

I'd like the caption to look sth like this:

this is my first

table's captive caption

How?

\documentclass{article}
\usepackage{tabulary}
\usepackage{threeparttable}
\usepackage{array}
\usepackage{siunitx}
\usepackage{booktabs}
\usepackage{multirow}
\usepackage{pbox}
\usepackage{lipsum}
\usepackage[utf8]{inputenc}\usepackage{textcomp}
\renewcommand{\arraystretch}{1.2}
\sisetup{round-mode=places,round-precision=1, add-decimal-zero=true, add-integer-zero=true, round-integer-to-decimal}

\begin{document}

\lipsum[1]


\begin{table}
\begin{threeparttable}
\caption{this is my first table's captive caption}
\begin{tabulary}{\textwidth}{@{}*{2}{L}*{6}{S[table-format=3.2]}@{}} \toprule
× & TOTALLY bla percentage of bla & {1000} & {2000} & {3000} & 
\multicolumn{1}{c}{\begin{tabular}{@{}c@{}}Bonjour\tabularnewline monde!\end{tabular}} &
 {5000} & {6000\tnote{1}}\\ \midrule
% × & TOTALLY bla percentage of bla & {1000} & {2000} & {3000} & \multirow{2}*{4000 apples and pears \\ and whatnot} & {5000} & {6000\tnote{1}}\\ \midrule
DDD 1 & 47.6 & 29.1 & 1.0 & 0.2 & 1.9 & 15.2 & 0.0\\
UUU & 24.8 & 10.8 & 6.4 & 0.0 & 3.2 & 4.5 & 0.0\\
× & × & × & × & × & × & × & ×\\
Unweighted average: & × & × & × & × & × & × & ×\\
BBB & 33.8 & 11.3 & 9.1 & 0.4 & 1.8 & 11.0 & 0.2\\
GGG & 32.9904 & 8.60325 & 9.3845 & 0.0495 & 1.43225 & 10.79525 & 0.119\\
DDD & 39.4545 & 9.8695 & 15.3365 & 0.6915 & 2.246 & 10.6705 & 0.5105\\ \bottomrule
\end{tabulary}

\begin{tablenotes}
\item [1] the first note ...
\end{tablenotes}

\end{threeparttable}
\end{table}

\lipsum[2]

\end{document}

Edit

trying to center the two-line headings:

\usepackage{caption}
(...)
\begin{table}
  \captionsetup{singlelinecheck=false, justification=centering}
\begin{threeparttable}
\caption{this is my first\newline table's very captive caption}

... the result of this attempt doesn't look quite right ... how to do it right?


Edit 2

  • How could I make the linebreak happen between two particular words (or even characters), but only iff the caption would linebreak in any case?

Meaning, the linebreak would be "dormant" so long as the caption is short enough to fit entirely on one line; as soon as it would have to linebreak, the break occurs at the predefined place.

6

LaTeX uses two passes for the caption. In the first pass the caption is set in an \hbox if the result fits in one line, the caption is set in one line, otherwise it is set in several lines. In your case the caption is too short and fit in one line.

A trick: A line break is set and much horizontal space is added to the caption. In the first pass the line break is ignored, but the horizontal space ensures the caption does not fit in one line. The the caption is set in multi-line mode and the line break is executed, but the horizontal space at the begin of the next line is discarded (\hspace without star):

\documentclass{article}
\begin{document}
\begin{table}
  \caption{this is my first\newline
    \hspace{\linewidth}table's captive caption}
\end{table}
\end{document}

Result

An alternative is package caption it provides option singlelinecheck that allows to disable the first pass that checks the caption length:

\documentclass{article}
\usepackage{caption}
\begin{document}
\begin{table}
  \captionsetup{singlelinecheck=false}
  \caption{this is my first\newline
    table's captive caption}
\end{table}
\end{document}

(The option can also be globally set in the preamble.)

Centering

The following uses an inner tabular (and the default singlelinecheck=true). The with of the table label Table 1: is calculated (\settowidth) and taken into account.

If the optional argument of \caption is not used, the following example also locally redefines \centeredmultilineincaption to get rid of the tabular and the line break for the list of figures.

\documentclass{article}

\makeatletter
\newlength{\@captionlabelwidth}
\DeclareRobustCommand*{\centeredmultilineincaption}[1]{%
  \settowidth{\@captionlabelwidth}{%
    \@nameuse{fnum@\@captype}: %
  }%
  \begin{tabular}[t]{@{\hspace{-\@captionlabelwidth}}c@{}}%
    \hspace{\@captionlabelwidth}\ignorespaces
    #1%
  \end{tabular}%
}

\begin{document}
\begingroup
  \renewcommand*{\centeredmultilineincaption}[1]{%
    \begingroup
      \let\tabularnewline\space
      #1%
    \endgroup
  }%
  \listoftables
\endgroup

\begin{table}
  \caption{%
    \centeredmultilineincaption{%
       this is my first\tabularnewline
       table's captive caption
    }%
  }
\end{table}
\end{document}

Result with centering

Update: This method only works, if the first line is longer.

"Conditional" linebreak

  • Both \\ and \linebreak can be used. In single line mode they vanish, thus there should be set a space before: first line \linebreak second line, not first line\linebreak second line. The latter would become first linesecond line in single-line mode.
  • Both macros are fragile. If the same line break also should occur in the list of tables, then \protect is needed:

    \caption{First line \protect\\second line}
    
  • The optional argument of \caption can be used for the list of tables:

    \caption[Short version]{First line \\second line}
    

    or a different line break in the list of tables:

    \caption[Short\protect\\version]{First line \\second line}
    

The following example defines \captionlinebreak that

  • takes care for the space before,
  • is robust and
  • can be redefined for the list of tables.

If the multi-line caption should also be centered, it becomes more ugly, because \@makecaption needs to be redefined and its definition depends on the class and packages. The example redefines it for the class article without package caption:

\documentclass[a5paper]{article}
\usepackage{varwidth}

\DeclareRobustCommand*{\captionlinebreak}{%
  \leavevmode\unskip\space % one space before
  \\%
}

\makeatletter
\long\def\@makecaption#1#2{%
  \vskip\abovecaptionskip
  \sbox\@tempboxa{#1: #2}%
  \ifdim \wd\@tempboxa >\hsize
    \centerline{%
      \begin{varwidth}{\hsize}%
        #1: #2%
      \end{varwidth}%
    }%
  \else
    \global \@minipagefalse
    \hb@xt@\hsize{\hfil\box\@tempboxa\hfil}%
  \fi
  \vskip\belowcaptionskip
}
\makeatother

\begin{document}
\begingroup
  \let\captionlinebreak\relax
  \listoftables
\endgroup
\begin{table}
\centering
\caption{Lorem ipsum\protect\captionlinebreak
  dolor sit amet, consetetur sadipscing elitr, \dots}
\end{table}
\begin{table}
\centering
\caption{Lorem ipsum\captionlinebreak
  dolor sit amet, \dots}
\end{table}
\end{document}

Result

4

\centering redefines \\ to work correctly, but unfortunately does not redefine \newline. Therefore combining \centering and \newline gives strange results:

\documentclass{article}
\begin{document}
\parbox{\linewidth}{\centering
This is some text\newline And this is some text, too.}
\par\bigskip
\parbox{\linewidth}{\centering
This is some text\\And this is some text, too.}
\end{document}

enter image description here

(Why? Bug in LaTeX? Maybe David Carlisle could turn on the light here?)

So better use \\ in captions or other stuff which should be typeset centered. BTW: When using the caption package a line break typeset with \\ will be replaced by a space character in list entries automatically, so there is usually no need to use an alternative list entry text:

\documentclass{article}
\usepackage[justification=centering]{caption}
\begin{document}
\listoftables
\begin{table}
  \caption{This is my first\\table's captive caption}
\end{table}
\end{document}

enter image description here

Addendum "Conditional line break"

Using \DeclareCaptionStyle one can define different sets of options for "single-line" captions and "long" captions. With \DeclareCaptionOption one can define own options for usage with the caption package.

So as example I define a new conditional called \ifcaptionlinebreak and an appropriate option for usage with the caption package which can be toggled with linebreak=false and linebreak=true:

\documentclass{article}

\usepackage{caption}

% New conditional \ifcaptionlinebreak
\newif\ifcaptionlinebreak

% New caption package option "linebreak" for toggeling \ifcaptionlinebreak
\DeclareCaptionOption{linebreak}{\csname captionlinebreak#1\endcsname}

% New command \captionlinebreak which either typesets a line break or a space,
% depending on \ifcaptionlinebreak
\newcommand\captionlinebreak{\ifcaptionlinebreak\\\else\space\fi}

% Own caption style which turns the linebreak into a space for short captions
% and into a line break for long captions
\DeclareCaptionStyle{mystyle}[linebreak=false]{linebreak=true}
\captionsetup{style=mystyle,justification=centering}

\begin{document}
\listoftables

\begin{table}[!hb]
  \caption{This is my first\\table's captive caption}
\end{table}

\begin{table}[!hb]
  \caption{This is my first\captionlinebreak table's captive caption}
\end{table}

\begin{table}[!hb]
  \caption{This is my first\captionlinebreak table's captive caption.
                 This is my first table's captive caption}
\end{table}

\end{document}

enter image description here

Addendum to the addendum "Conditional line break"

I just introduced \ifsinglelinecaption to the caption package, so starting with the very next version released on CTAN the above example document could be reduced to:

\documentclass{article}

\usepackage[justification=centering]{caption}
\newcommand\captionlinebreak{\ifsinglelinecaption\space\else\\\fi}

\begin{document}
\listoftables

\begin{table}[!hb]
  \caption{This is my first\\table's captive caption}
\end{table}

\begin{table}[!hb]
  \caption{This is my first\captionlinebreak table's captive caption}
\end{table}

\begin{table}[!hb]
  \caption{This is my first\captionlinebreak table's captive caption.
                 This is my first table's captive caption}
\end{table}

\end{document}

(The inpatient one can get the recent version at http://sourceforge.net/p/latex-caption/code/HEAD/tree/trunk/tex/ )

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.