2

I am generating a table from a program with two pairs of name/value columns. Each pair forms a two column tabu table and the two tables are then nested in an overall tabu table to get the effect. I find it does not look so good if any of the cells wrap so in that case I am going to create a differently formatted table. Since the program that generates the table does not know if latex is going to wrap cells it needs to be determined in latex.

To determine if there are any wrapped cells we generate the above table twice --- once with the actual data values and once with each value replaced by just X. If the values are all X the name columns will be so short it won't wrap so if the table when generated with the actual data has the same total height as the same table with just X as the data then we know that nothing has wrapped.

The fly in the ointment is that if we replace each cell with X then the totalheight of the two tables is slightly different even if the table with real data does not wrap. I am concerned that the difference might get even larger if the actual tables were larger.

Is there any way that I can assure that the two will have the same total height if none of the cells wrap?

\documentclass{article}
\usepackage{calc}
\usepackage{colortbl}
\usepackage{tabu}

\newsavebox\bboxA
\newsavebox\bboxB
\newsavebox\bboxElse

\newlength{\thA}
\newlength{\thB}

\begin{document} 
\savebox{\bboxA}{  
\begin{tabu}{X|[blue]X} 
\tabulinesep=4pt\begin{tabu}{>{\bfseries}lX} 
\everyrow{\tabucline[blue]-}
1 & X \\ 
2 & X \\ 
3 & X \\ 
\end{tabu} 
& 
\tabulinesep=4pt\begin{tabu}{>{\bfseries}lX} 
\everyrow{\tabucline[blue]-}
4 & X \\ 
5 & X \\ 
7 & X \\ 
\end{tabu} 
\end{tabu} 
} 
\setlength{\thA}{\totalheightof{\usebox{\bboxA}}} 
\savebox{\bboxB}{  
\begin{tabu}{X|[blue]X} 
\tabulinesep=4pt\begin{tabu}{>{\bfseries}lX} 
\everyrow{\tabucline[blue]-}
1 & 8.3 \\ 
2 & 10.3 \\ 
3 & 19 \\ 
\end{tabu} 
& 
\tabulinesep=4pt\begin{tabu}{>{\bfseries}lX} 
\everyrow{\tabucline[blue]-}
4 & 16 \\ 
5 & 15.6 \\ 
7 & 19.8 \\ 
\end{tabu} 
\end{tabu} 
} 
\setlength{\thB}{\totalheightof{\usebox{\bboxB}}} 

A: \the\thA{}
\begin{center}
\usebox\bboxA
\end{center}

\vspace{5ex}
B: \the\thB{}
\begin{center}
\usebox\bboxB
\end{center}

\end{document} 

Screenshot of output. The A and B numbers shown in points are the total heights of the boxes containing the tables. The objective is that those two numbers be the same but they are not. How can the code be changed so that as long as the data in the cells don't wrap they have identical total heights?

screenshot

ADDED

I have been playing around with this some more since I posted it and it seems that if we add a strut so that all four occurrences of \begin{tabu}{>{\bfseries}lX} are replaced with \begin{tabu}{>{\strut\bfseries}lX} then the two total heights do come out the same. Although it works here I am not sure whether that will work generally to give identical total heights for the two tables provided there is no cell wrapping or if there is anything else that I have to worry about.

ADDED 2

There was an error in this section so I have deleted it and replaced it with the next section.

ADDED 3

Here is a revision of the MWE (1) using Peter Gill's idea to use \vphantom making use of the \mystrut macro defined here: How to detect the length of the tallest letter and that of the deepest letter of the current font size? and (2) also we implemented David Carlisle's idea in bboxA (and also in the new bboxC to illustrate the situation where it does not fit) to use ll format instead of lX and now we show the width as well as the total height of each box. Also at the end we show the \textwidth .

\documentclass{article}
\usepackage{calc}
\usepackage{colortbl}
\usepackage{lipsum}
\usepackage{tabu}

\newsavebox\bboxA
\newsavebox\bboxB
\newsavebox\bboxC

\newlength{\thA}
\newlength{\thB}
\newlength{\thC}

\newlength{\wA}
\newlength{\wB}
\newlength{\wC}

\def\mystrut{\vphantom{Ag}}

\begin{document} 
\savebox{\bboxA}{%
\begin{tabu}{l|[blue]l} 
\tabulinesep=4pt\begin{tabu}{>{\mystrut\bfseries}ll} 
\everyrow{\tabucline[blue]-}
1 & 8.3 \\ 
2 & 10.3 \\ 
3 & 19 \\ 
\end{tabu} 
& 
\tabulinesep=4pt\begin{tabu}{>{\mystrut\bfseries}ll} 
\everyrow{\tabucline[blue]-}
4 & 16 \\ 
5 & 15.6 \\ 
7 & 19.8 \\ 
\end{tabu} 
\end{tabu} 
} 
\setlength{\thA}{\totalheightof{\usebox{\bboxA}}} 
\setlength{\wA}{\widthof{\usebox{\bboxA}}} 

\savebox{\bboxB}{%
\begin{tabu}{X|[blue]X} 
\tabulinesep=4pt\begin{tabu}{>{\mystrut\bfseries}lX} 
\everyrow{\tabucline[blue]-}
1 & 8.3 \\ 
2 & 10.3 \\ 
3 & 19 \\ 
\end{tabu} 
& 
\tabulinesep=4pt\begin{tabu}{>{\mystrut\bfseries}lX} 
\everyrow{\tabucline[blue]-}
4 & 16 \\ 
5 & 15.6 \\ 
7 & 19.8 \\ 
\end{tabu} 
\end{tabu} 
} 
\setlength{\thB}{\totalheightof{\usebox{\bboxB}}} 
\setlength{\wB}{\widthof{\usebox{\bboxB}}} 

\savebox{\bboxC}{%
\begin{tabu}{l|[blue]l} 
\tabulinesep=4pt\begin{tabu}{>{\mystrut\bfseries}ll} 
\everyrow{\tabucline[blue]-}
1 & \lipsum[1] \\ 
2 & 10.3 \\ 
3 & 19 \\ 
\end{tabu} 
& 
\tabulinesep=4pt\begin{tabu}{>{\mystrut\bfseries}ll} 
\everyrow{\tabucline[blue]-}
4 & 16 \\ 
5 & 15.6 \\ 
7 & 19.8 \\ 
\end{tabu} 
\end{tabu} 
} 
\setlength{\thC}{\totalheightof{\usebox{\bboxC}}} 
\setlength{\wC}{\widthof{\usebox{\bboxC}}} 

A: Total height: \the\thA{} Width: \the\wA{}
\begin{center}
\usebox\bboxA
\end{center}

\vspace{5ex}

B: Total height: \the\thB{} Width: \the\wB{}
\begin{center}
\usebox\bboxB
\end{center}

\vspace{5ex}

C: Total height: \the\thC{} Width: \the\wC{}
\begin{center}
\usebox\bboxC
\end{center}

\vspace{5ex}
Text Width: \the\textwidth

\end{document} 

The result is shown below. We see that the width of bboxA is less than the textwidth of 345pt and the width of bboxC is greater.

screenshot

5
  • Yes, a \strut (or \mathstrut in math mode) will ensure that the lines are of equal height, so if you just have text then it should be the same height. The other way to to do this is to add a \vphantom{<tallest object>}. Have a careful look at the output of $\sqrt{a} \sqrt{b} \sqrt{y}$, $\sqrt{a\mathstrut} \sqrt{b\mathstrut} \sqrt{y\mathstrut}$, $\sqrt{a\vphantom{b}} \sqrt{b\vphantom{b}} \sqrt{y\vphantom{b}}$, $\sqrt{a\vphantom{by}} \sqrt{b\vphantom{by}} \sqrt{y\vphantom{by}}$. Commented Aug 12, 2012 at 4:36
  • Also have a look at Problem with vertical space in Memoir title. Commented Aug 12, 2012 at 4:39
  • Using X in this way is rather expensive. A more direct approach would be to force single line by using a column specification of ll and then testing the width of the generated table and chosing teh alternative layout if the table is wider than \textwidth. Commented Aug 12, 2012 at 9:44
  • Thanks, David and Peter. I have added an ADDED 3 section which incorporates both your ideas. Since I can't choose two answers even though I have used both ideas, I have up-voted Peter's answer in tex.stackexchange.com/questions/36460/… and request that David move his comment to an answer. Commented Aug 12, 2012 at 12:08
  • Also, maybe it does not matter but I noticed that the width of bboxB is greater than textwidth. Why is that? Commented Aug 12, 2012 at 12:12

1 Answer 1

2

Just noticed a request that I make a comment an answer.

Using X in this way is rather expensive.

A more direct approach would be to force single line by using a column specification of ll and then testing the width of the generated table and choosing the alternative layout if the table is wider than \textwidth.

You must log in to answer this question.

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