![beamer:使用 \note 和框架标签一起创建多重定义的标签](https://linux22.com/image/258046/beamer%EF%BC%9A%E4%BD%BF%E7%94%A8%20%5Cnote%20%E5%92%8C%E6%A1%86%E6%9E%B6%E6%A0%87%E7%AD%BE%E4%B8%80%E8%B5%B7%E5%88%9B%E5%BB%BA%E5%A4%9A%E9%87%8D%E5%AE%9A%E4%B9%89%E7%9A%84%E6%A0%87%E7%AD%BE.png)
这个问题与 这个。但是,由于那里提供的解决方案不能解决我的问题,所以我认为我应该发布我的具体问题。
这是一个说明此问题的最小示例:
\documentclass{beamer}
\setbeameroption{show notes}
\begin{document}
\begin{frame}<1-2>[label=myframe]{Frame Title}
\note<1>{Some notes on the first point.}
\note<2>{Some notes on the second point.}
\begin{itemize}
\item<alert@1> First point.
\item<alert@2> Second point.
\item<alert@3> Third point. %optional
\end{itemize}
\end{frame}
\appendix
\begin{frame}{Appendix}
Some more elaboration.
\end{frame}
\againframe<3>{myframe}
\end{document}
此示例是可编译的,但 LaTeX 告诉我有多个定义的标签。有问题的标签是myframe
、myframe<1>
和myframe<2>
。我推测这是因为当创建笔记页时,笔记页也会“继承”主框架的标签,从而产生这样的问题。如果是这样,我想我们可以以某种方式修补笔记页机制,这样beamer
LaTeX 就不会发出这样的警告了。
有人有解决方案吗?
答案1
我担心,理解问题发生的原因以及如何潜在地解决该问题需要一点技术性。
诊断问题的原因:
- 禁用注释可消除此问题。
- 重新定义
\insertslideintonotes
不做任何事可以消除这个问题:\renewcommand{\insertslideintonotes}[1]{}
。 在带有注释的幻灯片中使用任何形式的
\label
(甚至)都会导致出现问题,而不仅仅是使用框架选项(后者无论如何在内部使用)。\label<1>
label=name
\label
\insertslideintonotes
在 beamer 中的实现:beamer
将每张幻灯片的内容放入名为 的框寄存器中\beamer@framebox
,并将框寄存器复制到\beamer@frameboxcopy
。后者用于注释页面中显示的幻灯片的迷你版本(通过\insertslideintonotes
)。标签命令也以“whatsit”节点的形式存储在这些框中\write
,因此在复制框时会再次写入。
为什么多重定义标签可能会有问题:
多次定义的标签并不总是一致的。LaTeX 中的默认行为是使用最后的定义的标签,而不是忽略相同标签的后续重新定义。这不是理想的行为,因为
beamer
标签将引用注释幻灯片而不是主幻灯片(因为注释幻灯片总是在主幻灯片之后)。以下示例说明了这一点(最后一帧中的引用是错误的):\documentclass{beamer} \setbeameroption{show notes} \begin{document} \begin{frame}<1-2>[label=myframe]{Frame Title} \note<1>{Some notes on the first point.} \note<2>{Some notes on the second point.} \begin{itemize} \item<alert@1> First point. \item<alert@2> Second point. \item<alert@3> Third point. %optional \end{itemize} \end{frame} \appendix \begin{frame}{Appendix} Some more elaboration. I think \texttt{myframe} starts on page \getpagerefnumber{myframe}. \end{frame} \end{document}
解决方案
我问了一个关于删除或停用此类节点的问题这个问题,而 Stephan Lehmke 的解决方案让我想到了以下补丁。这个想法是,通过编辑框以使用
\leaders
,TeX 将忽略这些\write
内容。我会尝试让beamer
维护者考虑将其纳入核心beamer
:补丁代码:
\usepackage{etoolbox} \makeatletter \patchcmd\beamer@framenotesend{\global\setbox\beamer@frameboxcopy=\copy\beamer@framebox}{% \global\setbox\beamer@frameboxcopy=\copy\beamer@framebox \global\setbox\beamer@frameboxcopy=\hbox{\leaders\copy\beamer@frameboxcopy\hskip\wd\beamer@frameboxcopy}%from Stephan Lehmke's comment on https://tex.stackexchange.com/q/82250/17427 }{}{\showtokens{failed to patch \beamer@framenotesend}} \makeatother
修补的 MWE(请注意,
pdfTeX warning (dest)
消息是另一个投影机中的突出问题):\documentclass{beamer} \setbeameroption{show notes} \usepackage{etoolbox} \makeatletter \patchcmd\beamer@framenotesend{\global\setbox\beamer@frameboxcopy=\copy\beamer@framebox}{% \global\setbox\beamer@frameboxcopy=\copy\beamer@framebox \global\setbox\beamer@frameboxcopy=\hbox{\leaders\copy\beamer@frameboxcopy\hskip\wd\beamer@frameboxcopy}%from Stephan Lehmke's comment on https://tex.stackexchange.com/q/82250/17427 }{}{\showtokens{failed to patch \beamer@framenotesend}} \makeatother \begin{document} \begin{frame}<1-2>[label=myframe]{Frame Title} \note<1>{Some notes on the first point.} \note<2>{Some notes on the second point.} \begin{itemize} \item<alert@1> First point. \item<alert@2> Second point. \item<alert@3> Third point. %optional \end{itemize} \end{frame} \appendix \begin{frame}{Appendix} Some more elaboration. I think \texttt{myframe} starts on page \getpagerefnumber{myframe}. \end{frame} \againframe<3>{myframe} \end{document}
可以采取的替代实现
beamer
是在调用时再次重新处理整个框架的内容\insertslideintonotes
,但在某些情况下可能会产生其他不良副作用,因此这应该只作为选项提供给知道自己在做什么的人,而不是改变默认行为!我也不认为这是一件容易的事。您还可以使用序言中的以下补丁来仅保存第一个
\label
,并希望一切顺利。% keep only the first definition of a given label, in contrast to the default LaTeX behaviour (and compile twice to see the difference!) \makeatletter \def\@newl@bel#1#2#3{{% \@ifundefined{#1@#2}% {\global\@namedef{#1@#2}{#3}}% moved this line from always being executed into the 'true' case for \@ifundefined. {\gdef \@multiplelabels {% \@latex@warning@no@line{There were multiply-defined labels. Later redefinitions were ignored}}% \@latex@warning@no@line{Label `#2' multiply defined. Ignoring later redefinitions}}% }} \makeatother