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?
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.
\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}}$
.ll
and then testing the width of the generated table and chosing teh alternative layout if the table is wider than\textwidth
.