beamer:使用 \note 和框架标签一起创建多重定义的标签

beamer:使用 \note 和框架标签一起创建多重定义的标签

这个问题与 这个。但是,由于那里提供的解决方案不能解决我的问题,所以我认为我应该发布我的具体问题。

这是一个说明此问题的最小示例:

\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 告诉我有多个定义的标签。有问题的标签是myframemyframe<1>myframe<2>。我推测这是因为当创建笔记页时,笔记页也会“继承”主框架的标签,从而产生这样的问题。如果是这样,我想我们可以以某种方式修补笔记页机制,这样beamerLaTeX 就不会发出这样的警告了。

有人有解决方案吗?

答案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
    

相关内容