# How to modify columns/column environments so they resize automatically to the largest column ?

This question was originally a duplicate of How can I add vertical space to a beamercolorbox to make it align with another one?. The response to that question was to add a vertical space according to the largest column, as Seamus explains in the comments. I would like, however, to do this in an automatic way.

I rephrase my question.

First, here is the original question, which I leave with minor modifications so that the motivation remains clear. Then, I will analyze and explain the new, rephrased question.

Original question

When using the columns environment in beamer, I sometimes find myself with these situation: two columns with some contents (like a block) whose height are different. The result is that each element appears with its height:

I think that if both columns had the same height (the max of all columns), the presentation would be more elegant (at least with the presentation that I am currently creating).

Normally I add some \vspace with a length determined by trial-and-error. Needless to say, this is an annoying process. I would like to force the contents of a column to have the same height as the largest column.

The example above was generated by this code:

\documentclass{beamer}

\usefonttheme[onlylarge]{structurebold}
\setbeamerfont*{frametitle}{size=\normalsize,series=\bfseries}

\begin{document}

\begin{frame}{A frame}
\begin{columns}[T]
\begin{column}{0.5\linewidth}
\begin{block}{A block}
Hello
\end{block}
\end{column}
\begin{column}{0.5\linewidth}
\begin{block}{Another block}
This one has a larger height since it has an itemize
\begin{itemize}
\item item a
\item item b
\end{itemize}
\end{block}
\end{column}
\end{columns}
\end{frame}

\end{document}


New question

I have examined beamerbaserequires.sty looking for the definition of the columns and column environment. In order to resize each column, I think it is necessary to rewrite part of the code, since a column is implemented as a minipage without a height parameter. My new question is, as the title says, How to modify columns/column environments so they resize automatically to the largest column ?

My first thoughts on how to achieve this are the following:

1. Resizing each column to the largest one may not be possible with one pass. It is only when the columns environment is closed that we could know the correct size and at that time it is too late to modify each column.
2. At the code that "closes" a column could add a vertical space equal to the size of the largest column so far.
3. The size of the largest column could be written and read from the aux file or some other temporal file, so that, in a second pass, all columns are resized correctly.

These guidelines are probably incorrect, implausible or too difficult to implement, since I have nearly no experience coding in TeX/LaTeX. Any comments regarding these ideas are welcome as well.

PS. I hesitate whether this question has become too specific (or even too broad), or if it should become a community wiki...

-
I'm pretty sure we've had this sort of question before. The basic answer was "no, the easiest way is to add vspace manually." But there are smart ways of working out exactly how much vspace to add. For example if it's just text, then add the right number of \baselineskips. It's more complex if you've got itemize etc, but still possible to calculate it. (Or use phantom) –  Seamus Mar 25 '11 at 12:35
Aha: found it IS this a duplicate or do you want to make your question more specific? –  Seamus Mar 25 '11 at 13:16
@Seamus: Ok, I think that I will rewrite my question focusing on how to change the columns/column environment so that it does this automatically. PS: sorry I did not respond earlier, I went away for the weekend –  YuppieNetworking Mar 28 '11 at 9:01
This new question seems worthy of a bounty. Any takers? –  Seamus Jun 22 '11 at 8:41
So, basically you seem to want a vertical version of the eqparbox package? –  Lev Bishop Jun 22 '11 at 16:20

One way to do this is to collect the whole columns content e.g. using the environ package, which stores the environment body in \BODY. Redefine column to measure the natural height of each column as well as remembering the maximum height in a first pass and then typeset the columns in a second pass where a \vspace is inserted with the correct adjustment.

I use here a counter to store the heights in unique macros which are then used to define the \autoheight macro with the right amount. This \autoheight macro must be placed where the extra height is required, e.g. before \end{box}. It can and should be placed in all columns and will be just \vspace*{0pt} for the largest column. It would also be possible to add this macro to all \end{box}, e.g. using the etoolbox package and \preto{\endbox}{\autoheight}. Also the columns environment could be redefined instead of using acolumns so no frame code must be adjusted at all. However, this makes the application less flexible. For example if there are two boxes in one column both would be resized incorrectly. However, this could also be implemented, e.g. by counting the number of boxes per column and spread the height accordantly. (This is left as exercise to the reader ;-) )

### Limitations:

• Does not support verbatim content like lstlistings even when the fragile option is set for the frame.
• Does not support cascaded columns (yet). This is because some values are set globally.

Both of these could be avoided with some extra effort.

\documentclass{beamer}

\usefonttheme[onlylarge]{structurebold}
\setbeamerfont*{frametitle}{size=\normalsize,series=\bfseries}

\usepackage{environ}% Required for \NewEnviron, i.e. to read the whole body of the environment
\makeatletter

\newcounter{acolumn}%  Number of current column
\newlength{\acolumnmaxheight}%   Maximum column height

% column replacement to measure height
\newenvironment{@acolumn}[1]{%
\stepcounter{acolumn}%
\begin{lrbox}{\@tempboxa}%
\begin{minipage}{#1}%
}{%
\end{minipage}
\end{lrbox}
\@tempdimc=\dimexpr\ht\@tempboxa+\dp\@tempboxa\relax
% Save height of this column:
\expandafter\xdef\csname acolumn@height@\roman{acolumn}\endcsname{\the\@tempdimc}%
% Save maximum height
\ifdim\@tempdimc>\acolumnmaxheight
\global\acolumnmaxheight=\@tempdimc
\fi
}

% column wrapper which sets the height beforehand
\newenvironment{@@acolumn}[1]{%
\stepcounter{acolumn}%
% The \autoheight macro contains a \vspace macro with the maximum height minus the natural column height
\edef\autoheight{\noexpand\vspace*{\dimexpr\acolumnmaxheight-\csname acolumn@height@\roman{acolumn}\endcsname\relax}}%
% Call original column:
\orig@column{#1}%
}{%
\endorig@column
}

% Save orignal column environment away
\let\orig@column\column
\let\endorig@column\endcolumn

% columns variant with automatic height adjustment
\NewEnviron{acolumns}[1][]{%
% Init vars:
\setcounter{acolumn}{0}%
\setlength{\acolumnmaxheight}{0pt}%
\def\autoheight{\vspace*{0pt}}%
% Set column environment to special measuring environment
\let\column\@acolumn
\let\endcolumn\end@acolumn
\BODY% measure heights
% Reset counter for second processing round
\setcounter{acolumn}{0}%
% Set column environment to wrapper
\let\column\@@acolumn
\let\endcolumn\end@@acolumn
% Finally process columns now for real
\begin{columns}[#1]%
\BODY
\end{columns}%
}
\makeatother

\begin{document}
\begin{frame}{A frame}
\begin{acolumns}[T]
\begin{column}{0.5\linewidth}
\begin{block}{A block}
Hello
\autoheight
\end{block}
\end{column}
\begin{column}{0.5\linewidth}
\begin{block}{Another block}
This one has a larger height since it has an itemize
\begin{itemize}
\item item a
\item item b
\end{itemize}
\autoheight
\end{block}
\end{column}
\end{acolumns}
\end{frame}

\end{document}


-
Brilliant. That's a contender for the TeX.sx package, surely? –  Seamus Jun 26 '11 at 12:30
@Seamus: Sure. I like to get some suggestions for the to be used user interface. –  Martin Scharrer Jun 26 '11 at 12:48
+1 Excellent! Sorry I've been quiet even though I was the OP, I was away for some weeks. –  YuppieNetworking Jun 27 '11 at 13:22
@MartinScharrer there's a little problem with spaces with your solution, see acolumns environment modifies columns widths. David Carlisle solved it, is it ok if I update your answer? –  capitalaslash May 7 '12 at 10:05
@capitalaslash: Thanks for notifying me. I made the change now. –  Martin Scharrer May 7 '12 at 10:09