5

I am trying to have the lipsum text fill the two cells to the right of the vertical ruler, without exceeding the table.

My code is now:

\documentclass[a4paper,11pt]{article}
\usepackage{lipsum}
\usepackage{tabularx}
\usepackage{calc}

\newlength{\mylength}

\begin{document}

\begin{tabularx}{\textwidth}{l | X X}
\hline
Short \setlength{\mylength}{\hsize} & \textbf{This text is a little bit longer} & And here is some more and more \\
& \multicolumn{2}{p{\textwidth-2\tabcolsep-\mylength}}{\lipsum[1]} \\
Short & \textbf{This text is a little bit longer} & And here is some more and more \\
& \multicolumn{2}{p{\textwidth-2\tabcolsep-\mylength}}{\lipsum[2]} \\
\end{tabularx}

\end{document}

Which yields this:

enter image description here

asvela
  • 53

3 Answers3

4

Set \mylength to the width of Short (or whaterver you use)

\newlength{\mylength}
\settowidth{\mylength}{Short}

and then

p{\textwidth-4\tabcolsep-\arrayrulewidth-\mylength\relax}

should do it.

\documentclass[a4paper,11pt]{article}
\usepackage{lipsum}
\usepackage{tabularx}
\usepackage{calc}

\newlength{\mylength}
\settowidth{\mylength}{Short}

\begin{document}
\noindent
\begin{tabularx}{\textwidth}{l | X X}
\hline
Short & \textbf{This text is a little bit longer} & And here is some more and more \\
& \multicolumn{2}{p{\textwidth-4\tabcolsep-\arrayrulewidth-\mylength\relax}}{\lipsum[1]} \\
Short & \textbf{This text is a little bit longer} & And here is some more and more \\
& \multicolumn{2}{p{\textwidth-4\tabcolsep-\arrayrulewidth-\mylength\relax}}{\lipsum[2]} \\
\end{tabularx}

\end{document}

enter image description here

Without tabularx (According to David, to save some memory) you can do this (Since we do manual calculations anyway):

\documentclass[a4paper,11pt]{article}
\usepackage{lipsum}
\usepackage{array}
\usepackage{calc}

\newlength{\mylength}
\settowidth{\mylength}{Short}

\begin{document}
\noindent
\begin{tabular}{l | *{2}{p{(\dimexpr\textwidth-\mylength-6\tabcolsep-\arrayrulewidth\relax)/2}}}
\hline
Short & \textbf{This text is a little bit longer} &  And here is some more and more \\
& \multicolumn{2}{p{\textwidth-4\tabcolsep-\arrayrulewidth-\mylength\relax}}{\lipsum[1]} \\
Short & \textbf{This text is a little bit longer} & And here is some more and more \\
& \multicolumn{2}{p{\textwidth-4\tabcolsep-\arrayrulewidth-\mylength\relax}}{\lipsum[2]} \\
\end{tabular}

\end{document}

You cam get rid of those 2 bad boxes by using \raggeright in

\begin{tabular}{l | *{2}{>{\raggedright\arraybackslash}p{(\dimexpr\textwidth-\mylength-6\tabcolsep-\arrayrulewidth\relax)/2}}}
\hline
  • If doing that calculation by hand, you have pre-calculated the X width so you could save tex a lot of work and use tabular an p columns rather than tabularx – David Carlisle Mar 31 '15 at 08:14
  • @DavidCarlisle You are right. I will make some addition. –  Mar 31 '15 at 08:17
3

Here are two ways of getting around the problem.

  1. Your usage is correct, but you're not counting the number of \tabcolseps correctly. There are 6 within your table stemming from the tabularx preamble {l | X X}. Let's denote a \tabcolsep using t, then you'd have {tlt|tXttXt}. Moreover, the calculation of \hsize is for the entire "tlt-column", so it already includes 2 \tabcolseps. So, what you need in your calculation is to remove 8 \tabcolseps:

    \noindent
    \begin{tabularx}{\textwidth}{l | X X}
      \hline
      Short\setlength{\mylength}{\hsize} & \textbf{This text is a little bit longer} & And here is some more and more \\
      & \multicolumn{2}{p{\dimexpr\textwidth-8\tabcolsep-\mylength}}{\lipsum*[1]} \\
      Short & \textbf{This text is a little bit longer} & And here is some more and more \\
      & \multicolumn{2}{p{\dimexpr\textwidth-8\tabcolsep-\mylength}}{\lipsum*[2]} \\
    \end{tabularx}
    

    I've dropped the use of the calc package, hence the visible \dimexpr. Also note that I've removed the space between Short and \setlength, as this actually influences the size of \hsize.

  2. Capture the column content, store it in a box and measure it all during tabularx's measuring phase (...not all that necessary, but still):

    \newcommand{\capturemaxwidth}[1]{%
      % https://tex.stackexchange.com/q/227142/5764
      \ifdim\hfuzz=\maxdimen\relax% trial run
        \setbox9=\hbox{#1}% Store content in box
        \ifdim\mylength>\wd9\relax% Measure box width...
          \setlength{\mylength}{\wd9}% ...and possibly store width
        \fi
      \fi  
      #1% final run
    }
    
    ...
    
    \noindent
    \begin{tabularx}{\textwidth}{L | X X}
      \hline
      Short & \textbf{This text is a little bit longer} & And here is some more and more \\
      & \multicolumn{2}{p{\dimexpr\textwidth-8\tabcolsep-\mylength}}{\lipsum*[1]} \\
      Short & \textbf{This text is a little bit longer} & And here is some more and more \\
      & \multicolumn{2}{p{\dimexpr\textwidth-8\tabcolsep-\mylength}}{\lipsum*[2]}
    \end{tabularx}
    

The second option removes some of the construction from your code, placing it in the preamble. As such, the code might be slightly better to read. Your choice. Both have an output resembling:

enter image description here

\documentclass{article}
\usepackage{lipsum,tabularx}
\usepackage{collcell}
\newcolumntype{L}{>{\collectcell\capturemaxwidth}l<{\endcollectcell}}

\newlength{\mylength}
\newcommand{\capturemaxwidth}[1]{%
  % https://tex.stackexchange.com/q/227142/5764
  \ifdim\hfuzz=\maxdimen
    \setbox9=\hbox{#1}% trial run
    \ifdim\mylength>\wd9
      \setlength{\mylength}{\wd9}%
    \fi
  \fi  
  #1% final run
}
\begin{document}

\sloppypar% Just for this example, due to lipsum

\noindent
\begin{tabularx}{\textwidth}{l | X X}
  \hline
  Short\setlength{\mylength}{\hsize} & \textbf{This text is a little bit longer} & And here is some more and more \\
  & \multicolumn{2}{p{\dimexpr\textwidth-8\tabcolsep-\mylength}}{\lipsum*[1]} \\
  Short & \textbf{This text is a little bit longer} & And here is some more and more \\
  & \multicolumn{2}{p{\dimexpr\textwidth-8\tabcolsep-\mylength}}{\lipsum*[2]} \\
\end{tabularx}

\noindent
\begin{tabularx}{\textwidth}{L | X X}
  \hline
  Short & \textbf{This text is a little bit longer} & And here is some more and more \\
  & \multicolumn{2}{p{\dimexpr\textwidth-8\tabcolsep-\mylength}}{\lipsum*[1]} \\
  Short & \textbf{This text is a little bit longer} & And here is some more and more \\
  & \multicolumn{2}{p{\dimexpr\textwidth-8\tabcolsep-\mylength}}{\lipsum*[2]}
\end{tabularx}

\end{document}
Werner
  • 603,163
  • If doing that calculation by hand, you have pre-calculated the X width so you could save tex a lot of work and use tabular an p columns rather than tabularx – David Carlisle Mar 31 '15 at 08:14
1

You can just use X which gives you the basic unit width for an expanding column, but you need to double it and allow for the 2\tabcolsep in the middle.

enter image description here

\documentclass[a4paper,11pt]{article}
\usepackage{lipsum}
\usepackage{tabularx}
\usepackage{calc}



\begin{document}

\begin{tabularx}{\textwidth}{l | X X}
\hline
Short & \textbf{This text is a little bit longer} & And here is some more and more \\
& \multicolumn{2}{>{\setlength\hsize{2\hsize+2\tabcolsep}}X}{\lipsum[1]} \\
Short & \textbf{This text is a little bit longer} & And here is some more and more \\
& \multicolumn{2}{>{\setlength\hsize{2\hsize+2\tabcolsep}}X}{\lipsum[2]} \\
\end{tabularx}

\end{document}
David Carlisle
  • 757,742