在 beamer 类中,如何删除 itemize 环境之前的额外垂直空间?

在 beamer 类中,如何删除 itemize 环境之前的额外垂直空间?

在投影仪幻灯片上,我想制作类似

我使用以下 LaTeX 代码,该代码在 LaTeX 中与文章类配合良好。

\begin{minipage}[t]{1.4cm}
Questions:
\end{minipage}\nobreak
\begin{minipage}[t]{9cm}
\begin{itemize}
\item 1st question;
\item 2nd question.
\end{itemize}
\end{minipage}

但是,使用 beamer 类时,我无法正确获得水平对齐:itemize 环境上方有一些额外的垂直空间,我无法将其删除。(是一些\topsep还是\partopsep?我尝试了 enumitem 包,但这只会让事情变得更糟。)

有什么好方法可以解决这个问题? 有解决办法吗itemize?还是我应该使用完全不同的方法?

编辑1:

好的,在 Juan 的帮助下,我终于找到了问题所在。首先,让我详细说明一下剩下的对齐问题是什么:是的,Juan,你说得对,乍一看,它似乎是像素完美的。但如果你真的放大(3000% 左右),然后你会发现不是。如果将“第一个问题”更改为“第一个问题 $(*)$”,情况会变得更糟,也更容易看到。如果将“第一个问题”更改为“问题:”,则可以获得完美的对齐效果(真的很有帮助……)。所以第一个内容\item真的很重要。

我已经检查过文章类;那里的对齐是 100% 完美的。一件非常有趣的事情:在这种情况下,你一定不能使用\vspace{0pt}hack 因为它会破坏所需的对齐。

编辑2:

Juan 的回答很好地解决了我的问题,但对我来说,这似乎不是最终的解决方案。beamer 类的这种奇怪行为是错误还是功能?

答案1

我花了两年时间:-),但现在我知道发生了什么以及如何修复它。要点是\begin{minipage}[t]创建一个\vtop框,它负责顶部对齐。现在需要阅读 TeXbook,第 81 页底部:

最终高度 x[的 \vtop 盒子]被定义为零,除非新 vbox 内的第一个项目是一个盒子;在后一种情况下,x 是该盒子的高度。

这意味着:如果小页面以一些文本开始(可能被分成几行,TeX 已将其放入\hboxes 中),那么框的垂直对齐\vtop不会发生在框的最顶部,而是发生在基线框中第一行文本的对齐方式。这正是我们想要的,即基线对齐(红色):

第一行基线的对齐

然而,如果 minipage不是从一个框开始,但是例如改变颜色,则无法获得基线的对齐;相反,“Questions”一词的基线与第二个小页面的顶部对齐,如下所示:

“问题”的基线与第二个小页面的顶部对齐

如何修复该问题

根据上述对 行为的解释\vtop,解决方案是确保框内的第一个项目\vtop\hbox包含第一行文本的 。因此,我们必须避免\kern在小页面顶部出现任何 s、颜色变化等。在下面的代码中,我粗略地解释了主要思想。该代码通过各种叠加命令和手动颜色更改组合进行了测试。

\documentclass{beamer}
\makeatletter
\def\beamer@callorigitem{%
  \@ifnextchar[
    \beamer@@callorigitem
    {\beamer@origitem
     \if@minipage\else
       \kern0pt  % don't put the \kern at the top of a \minipage
     \fi
     \ignorespaces
    }%
  }
\newcommand*\if@minipage@and@vmode[2]{%
  \let\mini@vmode 0%
  \if@minipage\ifvmode
    \let\mini@vmode 1%
  \fi\fi
  \if\mini@vmode 1 #1\else #2\fi
}
% Redefine \beamerorig@set@color, \pgfsys@begininvisible and \pgfsys@endinvisible
% such that they don't act at the top of a \minipage;
% instead save the corresponding commands in \set@minipage@color ...
\def\set@minipage@color{}%
\let\save@beamerorig@set@color\beamerorig@set@color
\def\beamerorig@set@color{%
  \if@minipage@and@vmode{%
    \begingroup
    \def\reset@color{\relax}%
    \xdef\addto@minipage@color{\save@beamerorig@set@color}%
    \endgroup
    \expandafter\g@addto@macro\expandafter\set@minipage@color
                              \expandafter{\addto@minipage@color}%
    \aftergroup\reset@color
  }{%
    \save@beamerorig@set@color
  }%
}
\let\save@pgfsys@begininvisible\pgfsys@begininvisible
\let\save@pgfsys@endinvisible\pgfsys@endinvisible
\def\pgfsys@begininvisible{%
  \if@minipage@and@vmode
    {\g@addto@macro\set@minipage@color{\save@pgfsys@begininvisible}}
    {\save@pgfsys@begininvisible}%
}
\def\pgfsys@endinvisible{%
  \if@minipage@and@vmode
    {\g@addto@macro\set@minipage@color{\save@pgfsys@endinvisible}}
    {\save@pgfsys@endinvisible}%
}
% ... and execute them at the beginning of the first paragraph of the minipage
% (where \everypar issues \@minipagefalse).
\let\save@minipagefalse\@minipagefalse
\def\@minipagefalse{%
  \set@minipage@color
  \gdef\set@minipage@color{}%
  \save@minipagefalse
}
\makeatother
\begin{document}
\begin{frame}
\begin{minipage}[t]{1.6cm}
Questions:
\end{minipage}\nobreak
\begin{minipage}[t]{9cm}
\begin{itemize}
\item 1st question;
\item 2nd question.
\end{itemize}
\end{minipage}
\end{frame}
\end{document}

如果用以下方法编译

\tracingoutput=2
\showboxbreadth=\maxdimen \showboxdepth=\maxdimen

在序言中,然后在日志文件中可以找到以下几行

.....\vbox(7.43904+18.72917)x256.0748
......\hbox(7.43904+2.12917)x234.17474, glue set 87.88736fil, shifted 21.90005

这说明第二个小页面是 ,其高度\vbox7.43904pt,深度为18.72917,并且 中的第一个项目\vbox\hbox。如果我不重新定义\beamer@callorigitem\beamerorig@set@color和,人们会发现\pgfsys@begininvisible\pgfsys@endinvisible

.....\vbox(0.0+26.16821)x256.0748
......\pdfcolorstack 0 push {0 g 0 G}
......\kern 0.0

在日志文件中。这意味着第二个小页面是\vbox高度0pt(并且可以看到颜色变化和\kern对此负责!)。

如何“正式”修复

问题并不beamer具体,除了\kern0ptfrom 中的\beamer@callorigitem。如果在 minipage 顶部使用 ,beamerbaseoverlay.sty则会出现与文档类相同的错位。对 的更改(即到by )和 到最适合该包;对 和的更改应转到。article\color{red}\beamerorig@set@color\let\set@colorbeamer\@minipagefalsexcolor\pgfsys@begininvisible\pgfsys@endinvisiblepgfsys.code.tex

答案2

我不知道为什么,但下面的似乎解决了这个问题

\begin{minipage}[t]{2cm}\vspace{0pt}
Questions:
\end{minipage}\nobreak
\begin{minipage}[t]{5cm}
\begin{itemize}
\item 1st question;
\item 2nd question.
\end{itemize}
\end{minipage}

请注意在第一个小页面开头添加的\vspace。问题实际上不是 之前的空格itemize(您可以通过将每个小页面包装在 上来查看这个问题\fbox),但不知何故,Beamer 为带有 的小页面和itemize以常规段落开头的小页面获取了不同的“顶部”,导致它们看起来未对齐。也许对 Beamer 内部结构更有经验的人可以弄清楚发生了什么?

编辑:上述解决方案几乎可行,但并不完全可行。它似乎受到我称之为“Beamer 的垂直对齐问题”的影响。问题似乎是,在某些情况下,Beamer 会对齐文本的绝对“顶部”。例如,“aaa”和“ttt”的顶部位于非常不同的水平,如果对齐顶部,基线就会错位。一种解决方案是使用\vphantom并将每段文本的“顶部”伪造为一个共同的最大值。例如,下面的方法似乎可行。

\begin{minipage}[t]{1.4cm}\vspace{0pt}
Questions:\vphantom{(}
\end{minipage}\nobreak
\begin{minipage}[t]{9cm}
\begin{itemize}
\item 1st question $(*)$;
\item 2nd question.
\end{itemize}
\end{minipage}

答案3

我刚刚遇到这个问题,只是有点不同。我没有两个要对齐的迷你页面,但有一个要与普通文本对齐的迷你页面。因此示例是text\begin{minipage}[t]{3cm}\begin{itemize}\item text\end{itemize}\end{minipage}。使用\fbox,我可以看到迷你页面的顶部与文本的中点对齐。Juan 的答案不适用,因为这会弄乱第一的minipage,这在我的场景中不存在。另外,Juan 的答案是将第一个 minipage 向下推以匹配第二个,而不是将第二个 minipage 向上推以匹配第一个。

这是我的解决方案。我不知道它有多强大。它的工作原理是,如果 minipage 没有从类似环境的东西开始,问题就会消失itemize。所以我们从其他东西开始,以使外部对齐正确。但这会改变内部对齐,所以我们必须删除它。但由于我们可以完全控制我们开始的“其他东西”,所以我们确切地知道要删除多少。

实现方法很简单,就是将其放在\vphantom{}\vskip-\baselineskipminipage 的开头。可以将一些实质性的内容放在 中\vphantom。这样做会改变 TeX 对 minipage 高度的看法。如果 minipage 的内容比周围文本的高度(高于基线)更大,这可能是可取的。

下面是一些示例代码:

\documentclass{beamer}

\begin{document}
\begin{frame}

\fbox{\begin{minipage}[t]{.5cm}Alg\rule{50pt}{1pt}\end{minipage}}\fbox{\begin{minipage}[t]{2.5cm}\begin{itemize}\item\rule{20pt}{1pt} Alg
\item Alg
\end{itemize}\end{minipage}}
\fbox{\begin{minipage}[t]{2.5cm}\begin{itemize}\item\rule{20pt}{1pt} Alg
\item Alg\end{itemize}\end{minipage}}


\fbox{\begin{minipage}[t]{.5cm}Alg\rule{27pt}{1pt}\end{minipage}}\fbox{\begin{minipage}[t]{2.5cm}\vphantom{X}\vskip-\baselineskip\begin{itemize}\item\rule{20pt}{1pt} Alg
\item Alg\end{itemize}\end{minipage}}
\fbox{\begin{minipage}[t]{2.5cm}\vphantom{}\vskip-\baselineskip\begin{itemize}\item\rule{20pt}{1pt} a
\item Alg\end{itemize}\end{minipage}}


\fbox{Alg\makebox[0pt][l]{\rule{50pt}{1pt}}}\fbox{\begin{minipage}[t]{2.5cm}\begin{itemize}\item\rule{20pt}{1pt} Alg
\item Alg
\end{itemize}\end{minipage}}
\fbox{\begin{minipage}[t]{2.5cm}\begin{itemize}\item\rule{20pt}{1pt} Alg
\item Alg\end{itemize}\end{minipage}}


\fbox{g\makebox[0pt][l]{\rule{28pt}{1pt}}}\fbox{\begin{minipage}[t]{2.5cm}\vphantom{X}\vskip-\baselineskip\begin{itemize}\item\rule{20pt}{1pt} Alg
\item Alg\end{itemize}\end{minipage}}
\fbox{\begin{minipage}[t]{2.5cm}\vphantom{}\vskip-\baselineskip\begin{itemize}\item\rule{20pt}{1pt} a
\item Alg\end{itemize}\end{minipage}}

\end{frame}
\end{document}

结果:

在 beamer 中使用 itemize 进行 minipages

您可以删除\fboxes 和规则并更改字母以查看其是否合理稳健,但我不知道应该使用哪些其他噩梦组合进行测试。

这似乎甚至在 minipage没有以 so 开始itemize,使用上面相同的限定符,可以重新定义环境minipage以自动插入此代码(我猜测\vskip放入垂直模式,因此\vphantom\vskip-\baselineskip some text作为两个段落,但第二段移至第一段之上)。

在文章模式下,这(自然)是错误的。因此,它应该与某种\ifclassisbeamerbutbeamerarticlenotloaded条件相结合。实际上,\mode<presentation>这样做就行了!

答案4

对于垂直间距,请尝试枚举项包裹:

\begin{itemize}[noitemsep,nolistsep]
\item 1st question;
\item 2nd question.
\end\{itemize}

您可以使用该包中的指令调整垂直和水平间距

相关内容