Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I would like the parbox width of the text in a multicolumn to be calculated automatically from the combined width of the cells that the multicolumn spans. (Their width will vary in different copies of the table.) Is there a way of doing this?

The details are as follows: One row of my five-column table contains a multicolumn, spanning four of the columns. I want the text in that multicolumn to wrap correctly, but I don't want to specify an actual numerical width. Instead, I want the width to be determined by the actual combined width of columns 2-5 in the previous row. I've written the basic code for the table (simplified for this illustration) this way, using a tentative numerical width of "2in":

\begin{tabular}{c|c|c|c|c|} \cline{2-5}
{\bf A} & first & second & third & fourth, of variable length \\ \cline{2-5}
& \multicolumn{4}{|c|}{\parbox{2in}{fifth, also of highly variable length but
   long enough to need to wrap.}} \\ \cline{2-5}
\end{tabular}

I have used a parbox because the contents of the multicolumn contains images and text that I want to be able to treat as a unit, but I've left those details out here in order to keep the picture simple. The result looks as I want it to, except that the content of the multicolumn has too much space to the left and right, because I used an ill-chosen manual setting for the width.

The point: How can I avoid setting the parbox width manually and instead have it calculated based on the width of the other columns?

[This question was earlier posted on stackoverflow but I was urged to ask it again on this site. Thanks for your patience.]


(EDIT) Martin Scharrer's code, below produces an interesting problem for me: \colwidth seems to become only as big as the first measured column. I find that this only happens when I use certain packages that I need for Chinese in XeLaTeX:

\usepackage{xeCJK}
\usepackage{fontspec,xltxtra,xunicode}

The output becomes:

columns not working

share|improve this question
1  
Could you delete your question on stackoverflow then, otherwise it will most likely be migrated here, causing the exact question to exist twice. –  Martin Scharrer Mar 3 '11 at 7:50
    
Please note that {\bf ...} should not be used in LaTeX2e, but \textbf{...} (or {\bfseries ...} if you really need a macro with doesn't take an argument). Also instead of \multicolumn{4}{|c|}{\parbox{2in}{ you can use \multicolumn{4}{|p{2in}|} instead. –  Martin Scharrer Mar 3 '11 at 7:54

2 Answers 2

up vote 3 down vote accepted

You measure the width of the columns by catching them into a box using the lrbox environment and then measuring and accumulating their width (and the column separation between).

Using special column types defined with the help of the array package makes this actually very easy to handle in the tabular.

\documentclass{article}

\usepackage{array}
\newlength{\mycolwidth}
% First column (re-)sets to width.
\newcolumntype{F}{>{\global\mycolwidth=-\tabcolsep\addmycolwidth}c<{\endaddmycolwidth}}
% All other to be measured cells have type `C` which uses `c` internally:
\newcolumntype{C}{>{\addmycolwidth}c<{\endaddmycolwidth}}
% The `P` type then uses the saved width:
\newcolumntype{P}{p{\mycolwidth}}

\newsavebox{\mycolwidthbox}% box to save cells in
\newenvironment{addmycolwidth}{%
   \begin{lrbox}{\mycolwidthbox}%% catch cell content into a box
}{%
   \end{lrbox}%
   \usebox{\mycolwidthbox}%% place cell content back
   % Add width and column sep: (globally because this code is still executed inside the cell which acts like a group)
   \global\advance\mycolwidth by \wd\mycolwidthbox
   \global\advance\mycolwidth by \tabcolsep
}

\begin{document}
\begin{tabular}{c|F|C|C|C|} \cline{2-5}
\textbf{A} & first & second & third & fourth, of variable length \\ \cline{2-5}
& \multicolumn{4}{P|}{fifth, also of highly variable length but
   long enough to need to wrap.} \\ \cline{2-5}
\end{tabular}

\begin{tabular}{c|F|C|C|C|} \cline{2-5}
\textbf{B} & first & second & third & fourth, of much much longer length \\ \cline{2-5}
&  \multicolumn{4}{P|}{fifth, also of highly variable length but
   long enough to need to wrap.} \\ \cline{2-5}
\end{tabular}
\end{document}

Result:

Resulting tables

share|improve this answer
    
Thank you very much. As it happens, my results were not as expected once I included the packages I need for Chinese with XeLaTeX; I've added a .png file to my original post with an edit. –  brannerchinese Apr 9 '11 at 8:07
1  
@brannerchinese: I fixed it now. The issue is that the original version used \global\addtolength which doesn't work properly with the calc package which is loaded by some of the packages you use. I changed the code to avoid this issue. –  Martin Scharrer Apr 9 '11 at 11:11
\documentclass{article}
\newsavebox\TBox \newlength\TWidth
\def\Tab#1{%
\sbox\TBox{\tabular{@{}c|c|c|c@{}}#1\endtabular}
  \usebox\TBox
  \global\TWidth=\wd\TBox\global\advance\TWidth by -\tabcolsep}  
\begin{document}

\begin{tabular}{c|c|} \cline{2-2}
\bf A & \Tab{first & second & third & fourth, of variable length}\\ \cline{2-2}
      & \parbox{\TWidth}{fifth, also of highly variable length but
                        long enough to need to wrap.}\\ \cline{2-2}
\end{tabular}

\end{document}

enter image description here

share|improve this answer
    
Thank you for your help. I am still experimenting with the results. –  brannerchinese Apr 9 '11 at 8:38

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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