我已经写了一个beamer
演示文稿,我希望所有框架都有相应的 PDF 书签,就像这里的另一个问题一样:Beamer:如何让每一帧都出现在 PDF 目录中?。然而,这个问题的答案似乎让每个人都滑动获取书签,因此\pause
具有多个对应幻灯片的带有 s 的框架将获得重复的书签。
(我的理解是,在 中beamer
,aframe
是逻辑概念,定义为\begin{frame}
和之间的所有内容\end{frame}
都可以在输出中表示为一个或多个slide
s。)
根据前面引用的答案,我提供了一个最低限度的说明性示例,我用它编译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