如何修改列/列环境以使它们自动调整为最大列?

如何修改列/列环境以使它们自动调整为最大列?

这个问题最初是如何向 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。我的新问题是,正如标题所说,columnscolumncolumnminipage如何修改columns/column环境以便它们自动调整为最大列的大小?

对于如何实现这一目标,我的第一个想法如下:

  1. column可能无法一次性将每个列调整为最大列。只有当columns环境关闭时,我们才能知道正确的大小,而那时修改每个列已经太晚了。
  2. 在“关闭”的代码中可以添加一个等于迄今为止column最大尺寸的垂直空间。column
  3. 可以从辅助文件或其他临时文件中写入和读取最大列的大小,以便在第二遍中正确调整所有列的大小。

这些指导方针可能不正确、不合理或难以实施,因为我几乎没有使用 TeX/LaTeX 编码的经验。也欢迎就这些想法提出任何意见。

PS. 我犹豫这个问题是否太具体(或者太宽泛),或者它是否应该成为一个社区维基...

答案1

一种方法是收集整个columns内容,例如使用environ将环境主体存储在中的包\BODY。重新定义column以测量每列的自然高度,并在第一遍中记住最大高度,然后在第二遍中对列进行排版,并\vspace插入正确的调整。

我在这里使用一个计数器将高度存储在唯一的宏中,然后使用这些宏定义\autoheight具有正确数量的宏。这个\autoheight宏必须放在需要额外高度的地方,例如在之前\end{box}。它可以而且应该放在所有的columns 中,并且只\vspace*{0pt}用于最大的column。也可以将此宏添加到所有\end{box},例如使用etoolbox包和\preto{\endbox}{\autoheight}。此外,columns可以重新定义环境而不是使用,acolumns因此根本不需要调整框架代码。然而,这会降低应用程序的灵活性。例如,如果一列中有两个es,则两者都会错误地调整大小。然而,这也可以实现,例如通过计算每个 esbox的数量并相应地扩展高度。(这留给读者练习 ;-) )boxcolumn

限制:

  • 不支持逐字内容,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}

结果

相关内容