使用 beamer 使每一帧(不是幻灯片)都出现在 PDF 书签中

使用 beamer 使每一帧(不是幻灯片)都出现在 PDF 书签中

我已经写了一个beamer演示文稿,我希望所有框架都有相应的 PDF 书签,就像这里的另一个问题一样:Beamer:如何让每一帧都出现在 PDF 目录中?。然而,这个问题的答案似乎让每个人都滑动获取书签,因此\pause具有多个对应幻灯片的带有 s 的框架将获得重复的书签。

(我的理解是,在 中beamer,aframe是逻辑概念,定义为\begin{frame}和之间的所有内容\end{frame}都可以在输出中表示为一个或多个slides。)

根据前面引用的答案,我提供了一个最低限度的说明性示例,我用它编译pdflatex(和我的\beamer@version= 3.20):

\documentclass{beamer}

\usepackage{bookmark}
\usepackage{etoolbox}

\makeatletter
\apptocmd{\beamer@@frametitle}{\bookmark[page=\the\c@page,level=3]{#1}}%
{\message{** patching of \string\beamer@@frametitle succeeded **}}%
{\message{** patching of \string\beamer@@frametitle failed **}}%
\makeatother


\begin{document}

\begin{frame}{Title}
Hello \pause world
\end{frame}
\end{document}

结果:PDF 只有一个框架但有两张幻灯片,并且书签,每人一个滑动. 需要:一个带有一个框架但有两张幻灯片的 PDF,以及书签,每人一个框架

我很惊讶这个例子不起作用,因为我原本以为\frametitle(或者更确切地说是它的\@dblarg助手\beamer@@frametitle)会每帧调用一次,而不是(从结果来看)每张幻灯片调用一次。(有没有 beamer 的实现文档可以帮助我解决这个问题,因为到目前为止我还没有找到它?)

此外,由于我的演示文稿已经写好了,如果可能的话,我想避免到处都用\begin{frame}with替换\begin{myframe}(特别是因为我的一些框架使用语法\frametitle{Title},而其他框架使用\begin{frame}{Title}设置框架标题的语法),而且我知道这种方法会有一些困难。

答案1

\makeatletter
\apptocmd{\beamer@@frametitle}{\only<1>{\bookmark[page=\the\c@page,level=3]{#1}}}%
{\message{** patching of \string\beamer@@frametitle succeeded **}}%
{\message{** patching of \string\beamer@@frametitle failed **}}%
\makeatother

仅为每帧的第一张幻灯片添加书签(或者至少它似乎在你的 MWE 上有效)

答案2

我很高兴找到这个和相关的帖子。这是我最终的解决方案。我不为此承担任何责任。我只是想让一些像我这样的新手 Latex 用户更容易地弄清楚:

  \AtBeginSection{\frame{\tableofcontents[currentsection]}}

  \usepackage{bookmark}
  \usepackage{etoolbox}
  \makeatletter
  % save the current definition of \beamer@@frametitle
  \let\nobookmarkbeamer@@frametitle\beamer@@frametitle
  % then patch it to do the bookmarks and/or TOC entries
  % \apptocmd{\beamer@@frametitle}{%
  \apptocmd{\beamer@@frametitle}{%
  \only<1>{\bookmark[page=\the\c@page,level=3]{#1}}
  }%
  {\message{** patching of \string\beamer@@frametitle succeeded **}}%
  {\message{** patching of \string\beamer@@frametitle failed **}}%

  \pretocmd{\beamer@checknoslide}{%
    % ensure the bookmark is not created if the slide is filtered out
    \let\beamer@@frametitle\nobookmarkbeamer@@frametitle
    }%
    {\message{** patching of \string\beamer@checknoslide succeeded **}}%
    {\errmessage{** patching of \string\beamer@checknoslide failed **}}%

  \makeatother

对于那些使用 markdown pandoc 的人来说:

header-includes: |
  ```{=latex}
  % add bookmark level 2 for PDF
  % from https://tex.stackexchange.com/questions/17230/beamer-how-to-make-each-frame-appear-in-the-pdf-toc

  \AtBeginSection{\frame{\tableofcontents[currentsection]}}

  \usepackage{bookmark}
  \usepackage{etoolbox}
  \makeatletter
  % save the current definition of \beamer@@frametitle
  \let\nobookmarkbeamer@@frametitle\beamer@@frametitle
  % then patch it to do the bookmarks and/or TOC entries
  % \apptocmd{\beamer@@frametitle}{%
  \apptocmd{\beamer@@frametitle}{%
  \only<1>{\bookmark[page=\the\c@page,level=3]{#1}}
  }%
  {\message{** patching of \string\beamer@@frametitle succeeded **}}%
  {\message{** patching of \string\beamer@@frametitle failed **}}%

  \pretocmd{\beamer@checknoslide}{%
    % ensure the bookmark is not created if the slide is filtered out
    \let\beamer@@frametitle\nobookmarkbeamer@@frametitle
    }%
    {\message{** patching of \string\beamer@checknoslide succeeded **}}%
    {\errmessage{** patching of \string\beamer@checknoslide failed **}}%

  \makeatother
  ```

答案3

这是 David Carlisle 的答案的变体,通过使用\pdfbookmark代替获得\bookmark。这里的优点是我们不需要\usepackage{bookmark}

\makeatletter
\apptocmd{\beamer@@frametitle}{\only<1>{\pdfbookmark[3]{#1}{#1}}}
{\message{** patching of \string\beamer@@frametitle succeeded **}}
{\message{** patching of \string\beamer@@frametitle failed **}}
\makeatother

相关内容