在投影仪幻灯片上,我想制作类似
我使用以下 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 已将其放入\hbox
es 中),那么框的垂直对齐\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
这说明第二个小页面是 ,其高度\vbox
为7.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
具体,除了\kern0pt
from 中的\beamer@callorigitem
。如果在 minipage 顶部使用 ,beamerbaseoverlay.sty
则会出现与文档类相同的错位。对 的更改(即到by )和 到最适合该包;对 和的更改应转到。article
\color{red}
\beamerorig@set@color
\let
\set@color
beamer
\@minipagefalse
xcolor
\pgfsys@begininvisible
\pgfsys@endinvisible
pgfsys.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-\baselineskip
minipage 的开头。可以将一些实质性的内容放在 中\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}
结果:
您可以删除\fbox
es 和规则并更改字母以查看其是否合理稳健,但我不知道应该使用哪些其他噩梦组合进行测试。
这似乎甚至在 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}
您可以使用该包中的指令调整垂直和水平间距