14

I have a two column table with a single multicolumn spanning both of them. The text on that multicolumn is rather long so I need to set its width so it wraps around. I can set the width with \multicolumn{2}{p{whatever}}{text} but what should I set "whatever" to? What is the actual width of a table? Is there a variable holding that value?

I first thought to use \textwidth but that's not it. Building the document on draft mode shows that it's going out a tiny bit. The following table should show my problem. In draft mode will display a black box on its side.

\begin{tabular}{l l}
  \toprule
  \multicolumn{2}{p{\textwidth}}{\lipsum[1]} \\
  \bottomrule
\end{tabular}

I do have more rows, I'm just keeping the example simple. I'm using the memoir document class. The actual text inside the multicolumn is using the seqsplit package.

EDIT: I should have been more specific with the question. The only row that would make the table go over the limit is the one that I'm also trying to limit. And by limit I mean, so I don't get an overfull warning.

So my question can be better rephrased as how to find the available space for a table so it is not overfull?

0

4 Answers 4

14

The space available isp{\dimexpr\textwidth-2\tabcolsep\relax} due to the column padding LaTeX applies, assuming you have \noindent\begin{tabular} otherwise the table itself will be offset by \parindent.

However if the span is wider than the columns it spans, TeX puts all the extra width into the last column. If that is a problem, edit your example to be a complete (small) document that shows the problem.

2
  • 2
    Wouldn't it be better to use \linewidth instead of \textwidth in case the table is used in some other environment such as \itemize where the available horizontal space is reduced. Commented Feb 21, 2013 at 21:52
  • Thank you, this solves my problem. The other rows should be quite small, this is the only one that should have to span multiple rows.
    – carandraug
    Commented Feb 22, 2013 at 0:01
10

Knowledge of the column entries (especially the widest elements) allows you to calculate the width of the \multicolumn accurately:

\documentclass{article}
\usepackage{booktabs,calc,lipsum}% http://ctan.org/pkg/{booktabs,calc,lipsum}
\begin{document}
\begin{tabular}{l l}
  \toprule
  Some text & Some more text \\
  Short & Very super super long \\
  Longer than others & Shrt \\
  \multicolumn
    {2}
    {p{\widthof{Longer than others}+\widthof{Very super super long}+2\tabcolsep}}
    {\lipsum[1]} \\
  \bottomrule
\end{tabular}
\end{document}

calc provides \widthof{<stuff>} that returns the natural width of <stuff>. Each column is padded on both sides by \tabcolsep.

1
  • That's not working for me. I should have been more explicit on the question, but the only row that will take the whole horizontal space of the table, is also the one I'm also trying to limit.
    – carandraug
    Commented Feb 21, 2013 at 23:56
8

The total width of the table is not available until the whole table has been typeset, unless all columns are specified with an explicit width (p columns). TeX chooses the column width only when the whole table has been loaded into memory, and so this makes quite difficult to solve your problem, because a text width has to be specified in order to typeset a paragraph.

For this particular problem, where all the columns must be spanned, there's an automatic solution: first typeset the table ignoring the paragraph spanning the columns to get the width, then retypeset it.

The first argument in \multipar is necessary, because the total number of columns is not available inside a tabular environment.

\documentclass{article}
\usepackage{booktabs,lipsum}
\usepackage{environ}
\newsavebox{\funnytabularbox}
\newlength{\funnytabularwd}

\makeatletter
\NewEnviron{funnytabular}[1]
  {\begin{lrbox}{\funnytabularbox}
   \let\multipar\@gobbletwo
   \begin{tabular}{#1}\BODY\end{tabular}
   \end{lrbox}%
   \setlength{\funnytabularwd}{\wd\funnytabularbox}%
   \addtolength{\funnytabularwd}{-2\tabcolsep}%
   \let\multipar\@multipar
   \begin{tabular}{#1}\BODY\end{tabular}}

\newcommand\@multipar[2]{\multicolumn{#1}{p{\funnytabularwd}}{#2}}
\makeatother

\begin{document}
\begin{funnytabular}{l l}
  \toprule
  Some text & Some more text \\
  \midrule
  Short & Very super super long \\
  \midrule
  Longer than others & Shrt \\
 \midrule
  \multipar{2}{\lipsum*[1]} \\
  \bottomrule
\end{funnytabular}
\end{document}

enter image description here

1
  • thank you for solution. But my problem is actually simpler. My apologies I should have made it more explicit on the question. See my edit and I found my solution with David's answer.
    – carandraug
    Commented Feb 22, 2013 at 0:14
0

I used the following, which may help your case (I needed the multicolumn width for \multirow):

\usepackage{tabularx}
\usepackage{multirow}
...
\begin{tabularx}{\textwidth}{|*{9}{>{\centering\arraybackslash}X|}}
\hline
start
    & \multicolumn{7}{X}{\multirow{3}{\dimexpr(\hsize+2\tabcolsep)*7-2\tabcolsep\relax}{%
      Hello, this can be a long paragraph.}
    & \\
& & \\
& & end\\\hline
\end{tabularx}

The magic is in knowing the values for \hsize and \tabcolsep, with the calculation being done in the \dimexpr command from e-Tex.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .