有时,当项目列表太长而无法在幻灯片上容纳时,我会执行以下操作以获得更好的效果(暂时忽略注释行):
\documentclass[t,10pt]{beamer}
\setbeamertemplate{navigation symbols}{}
\setbeamercovered{transparent}
\begin{document}
\begin{frame}
%\begin{itemize}[<+->] \item a \item b \end{itemize}
\begin{enumerate}
\only<1-2>{
%\item We agree that
\item<1>[1.] all men
\item<2>[2.] are
}\only<3->{
\item<3>[3.] equal
}
\end{enumerate}
\end{frame}
\end{document}
得出的结果为:
不幸的是,这种构造不是很强大,从某种意义上说,在取消注释其中一行或两行注释后,我将不得不手动更改项目的编号和覆盖规范。
问题:如果不进行任何手动编号或覆盖指定,是否可以实现相同的结果?
(进一步评论:我试图解决这个问题,这是我得到的答案:
\begin{enumerate}[<+->]
\only<.(1)-.(2)>{
\item All men
\item are
}\only<.(3)>{
\item[3.] equal
}
\end{enumerate}
不幸的是,仍然有很多神奇的数字,我仍然必须手动计算\items
每个数字包含多少个 s 。除此之外,LaTeX 会在没有一个s 处于活动状态的幻灯片上\only
抱怨缺失\item
\only
\clearenumerate
例如,如果有一个命令可以产生上述结果(可能要对枚举环境进行一些重大改变),那么将会非常方便:
\begin{enumerate}[<+->]
\item all men
\item are
\clearenumerate
\item equal
\end{enumerate}
但我假设这样的事情,如果可能的话,需要大量的 TeX/LaTeX 掌握。)
答案1
这是一个使用环境特性的解决方案onlyenv
:它排版其内容,然后扔掉。这意味着即使没有显示任何任务,任务也会执行。因此,通过将第一个\item
s 放入onlyenv
环境中,它们会增加计数器,但(在相关幻灯片上)实际文本会被丢弃。通过的语法,将\item
s 放入onlyenv
环境中变得容易。棘手的部分是正确获取覆盖规范。由于分组,我不得不使用,而我真的不想这样做,这意味着对于迭代列表或在同一框架上使用它的多个列表,这可能不够强大(尽管它确实适用于不同框架上的列表)。也许有人可以稍微改进一下。action
beamer
\gdef
无论如何,这是代码。
\documentclass[t,10pt]{beamer}
%\url{http://tex.stackexchange.com/q/25548/86}
\setbeamertemplate{navigation symbols}{}
\setbeamercovered{transparent}
\def\onlybetween{+-|only@\lbst-\lbend}
\makeatletter
\def\lbend{}
\def\lbst{1}
\newcounter{listbetween}
\def\startlistbetween{%
\setcounter{listbetween}{0}%
\gdef\lbst{1}%
\expandafter\ifx\csname listto\the\value{listbetween}\endcsname\relax
\gdef\lbend{}%
\else
\expandafter\global\expandafter\let\expandafter\lbend\csname listto\the\value{listbetween}\endcsname
\fi
\def\beamer@defaultospec{<\onlybetween>}%
}
\def\listbetween{%
\addtocounter{beamerpauses}{-1}%
\expandafter\xdef\csname listto\the\value{listbetween}\endcsname{\the\value{beamerpauses}}%
\addtocounter{beamerpauses}{1}%
\xdef\lbst{\the\value{beamerpauses}}%
\stepcounter{listbetween}%
\expandafter\ifx\csname listto\the\value{listbetween}\endcsname\relax
\gdef\lbend{}%
\else
\expandafter\global\expandafter\let\expandafter\lbend\csname listto\the\value{listbetween}\endcsname
\fi
}
\makeatother
\begin{document}
\begin{frame}
\begin{enumerate}
\startlistbetween
\item first
\item second
\listbetween
\item third
\item fourth
\item fifth
\listbetween
\item sixth
\item seventh
\end{enumerate}
\end{frame}
\begin{frame}
\begin{enumerate}
\startlistbetween
\item first
\item second
\listbetween
\item third
\item fourth
\item fifth
\listbetween
\item sixth
\item seventh
\end{enumerate}
\end{frame}
\end{document}
枚举环境的默认覆盖规范保存在宏中\beamer@defaultospec
。幸运的是,对于我们来说,它在读入时不会展开。因此,我们可以嵌入一个宏,稍后再计算。这是控制何时onlyenv
停止实际打印其内容的宏。开始时,它被设置为,1-
这实际上意味着“始终打印”(请注意,这是此外覆盖规范+-
是两个都需要满足才能显示项目)。在遍历框架时,我们会记录希望中断的位置,并将其存储在宏中。在第二次遍历框架时(幻灯片 2),我们使用这些宏来决定位何时生效onlyenv
。
因此,它利用了每次制作新幻灯片时处理框架内容这一事实。在第一次运行(第一张幻灯片)时,我们会记下所有想要打破列表的地方。然后在后续运行中,我们会使用该信息来控制显示。
答案2
一种可能的解决方案(可能不是最自动化的解决方案)是使用一个命令来存储enumi
计数器的值,然后使用另一个命令来设置enumi
存储的值;使用这种方法您只需在适当的位置发出命令:
\documentclass[t,10pt]{beamer}
\setbeamertemplate{navigation symbols}{}
\setbeamercovered{transparent}
\newcounter{mycntr}
\newcommand\savecntr{\setcounter{mycntr}{\theenumi}}
\newcommand\usecntr{\setcounter{enumi}{\themycntr}}
\begin{document}
\begin{frame}
\begin{enumerate}
\only<1-2>{
%\item We agree that
\item<1> all men
\item<2> are\savecntr
}\only<3->{\usecntr
\item<3> equal,
\item<4> or not?
}
\end{enumerate}
\end{frame}
\end{document}