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 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

share|improve this question
    
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}}$. –  Peter Grill Aug 12 '12 at 4:36
    
Also have a look at Problem with vertical space in Memoir title. –  Peter Grill Aug 12 '12 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. –  David Carlisle Aug 12 '12 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. –  user1189687 Aug 12 '12 at 12:08
    
Also, maybe it does not matter but I noticed that the width of bboxB is greater than textwidth. Why is that? –  user1189687 Aug 12 '12 at 12:12
add comment

1 Answer

up vote 2 down vote accepted

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.

share|improve this answer
add comment

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.