这个问题最初是如何向 beamercolorbox 添加垂直空间以使其与另一个对齐?。对这个问题的回答是根据最大的列添加垂直空间,正如 Seamus 在评论中解释的那样。但是,我想以自动方式执行此操作。
我重新表述了我的问题。
首先,这是原始问题,我对其进行了一些小修改,以便动机仍然清晰。然后,我将分析和解释新的、重新表述的问题。
原始问题
在 beamer 中使用columns
环境时,我有时会遇到以下情况:两列中的某些内容(如 a block
)的高度不同。结果是每个元素都以其高度显示:
我认为,如果两列具有相同的高度(所有列的最大值),则演示效果会更优雅(至少对于我当前正在创建的演示而言)。
通常我会\vspace
通过反复试验来确定添加一些内容的长度。不用说,这是一个令人讨厌的过程。我想强制 a 的内容column
具有与最大列相同的高度。
上面的例子是由以下代码生成的:
\documentclass{beamer}
\usetheme{Darmstadt}
\usefonttheme[onlylarge]{structurebold}
\setbeamerfont*{frametitle}{size=\normalsize,series=\bfseries}
\setbeamertemplate{navigation symbols}{}
\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}
新问题
我已经检查了和环境beamerbaserequires.sty
的定义。为了调整每列的大小,我认为有必要重写部分代码,因为 a被实现为没有高度参数的 a。我的新问题是,正如标题所说,columns
column
column
minipage
如何修改columns/column
环境以便它们自动调整为最大列的大小?
对于如何实现这一目标,我的第一个想法如下:
column
可能无法一次性将每个列调整为最大列。只有当columns
环境关闭时,我们才能知道正确的大小,而那时修改每个列已经太晚了。- 在“关闭”的代码中可以添加一个等于迄今为止
column
最大尺寸的垂直空间。column
- 可以从辅助文件或其他临时文件中写入和读取最大列的大小,以便在第二遍中正确调整所有列的大小。
这些指导方针可能不正确、不合理或难以实施,因为我几乎没有使用 TeX/LaTeX 编码的经验。也欢迎就这些想法提出任何意见。
PS. 我犹豫这个问题是否太具体(或者太宽泛),或者它是否应该成为一个社区维基...
答案1
一种方法是收集整个columns
内容,例如使用environ
将环境主体存储在中的包\BODY
。重新定义column
以测量每列的自然高度,并在第一遍中记住最大高度,然后在第二遍中对列进行排版,并\vspace
插入正确的调整。
我在这里使用一个计数器将高度存储在唯一的宏中,然后使用这些宏定义\autoheight
具有正确数量的宏。这个\autoheight
宏必须放在需要额外高度的地方,例如在之前\end{box}
。它可以而且应该放在所有的column
s 中,并且只\vspace*{0pt}
用于最大的column
。也可以将此宏添加到所有\end{box}
,例如使用etoolbox
包和\preto{\endbox}{\autoheight}
。此外,columns
可以重新定义环境而不是使用,acolumns
因此根本不需要调整框架代码。然而,这会降低应用程序的灵活性。例如,如果一列中有两个es,则两者都会错误地调整大小。然而,这也可以实现,例如通过计算每个 esbox
的数量并相应地扩展高度。(这留给读者练习 ;-) )box
column
限制:
- 不支持逐字内容,
lstlistings
即使fragile
为 设定了选项frame
。 - 尚不支持级联
columns
。这是因为某些值是全局设置的。
只要付出一些额外的努力,就可以避免这两种情况。
\documentclass{beamer}
\usetheme{Darmstadt}
\usefonttheme[onlylarge]{structurebold}
\setbeamerfont*{frametitle}{size=\normalsize,series=\bfseries}
\setbeamertemplate{navigation symbols}{}
\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}