我的回答在 Beamer 标题中使用 \alert{} 时出现问题,主题为 metropolis解决了文档中TiKZ
与\title
-ed\protect
内容不兼容的问题。beamer
以下代码失败:
\documentclass{beamer}
\usepackage{tikz}
\title{Hello \protect\alert{World}!} %<- before \begin{document}
\begin{document}
\maketitle
\end{document}
下一个有效
\documentclass{beamer}
\usepackage{tikz}
\begin{document}
\title{Hello \protect\alert{World}!}%<- after \begin{document}
\maketitle
\end{document}
如果标题是\title{Hello World!}
,那么将其放在序言中没有问题。
我通过反复试验找到了答案,因为我记得 TeX.SX 中有一些类似的答案。我想知道为什么会发生错误以及解决方案为什么有效。
当我写这个问题的时候我应该将 \title、\author、\date 放在序言中还是放在 \begin{document} 之后?\maketitle
出现在我的浏览器中。我的结论是,除非有必要,否则title 命令是在前言中还是在文档内部声明都无关紧要。那么我的问题是什么时候重要?仅在beamer
? 使用时\protect
? 使用时TiKZ
? 有没有什么通用的秘诀?
答案1
我认为,最终这里的问题可以归结为两点:
如果你使用
\title
前\begin{document}
,它最终会被纳入 PDF 属性中。之后\begin{document}
再纳入就太晚了。PDF 属性很敏感,因为它们可以处理一些TeX 相关的宏,但不是全部。而且,
beamer
班级为实现其覆盖规范和模板做了很多工作。具体来说,如果在 -and-friends\alert
下使用覆盖规范定义的所有内容\newcommand
最终出现在 PDF 属性中,那么它们肯定会引起问题。
为了检验(1),请考虑以下最小示例:
exampleA.tex
:
\documentclass{beamer}
\title{Hello world!}% title before \begin{document}
\begin{document}
\maketitle
\end{document}
exampleB.tex
:
\documentclass{beamer}
\begin{document}
\title{Hello world!}% title after \begin{document}
\maketitle
\end{document}
exampleA.pdf
两者产生相同的输出,但 PDF属性不同。
而exampleB.pdf
收益
这是因为默认beamer
设置了文档选项\beamer@autopdfinfotrue
beamer.cls
并呼吁
\ifbeamer@autopdfinfo%
\g@addto@macro\beamer@firstminutepatches
{
\begingroup
\let\beamer@saved@hook\pdfstringdefPreHook
\pdfstringdefDisableCommands{%
\let\\=\
\let\newline=\\%
}%
\let\thanks=\@gobble%
\hypersetup{pdftitle={\inserttitle\ifx\insertsubtitle\@empty\else\ - \insertsubtitle\fi}}
\global\let\pdfstringdefPreHook\beamer@saved@hook
\endgroup
}
\fi%
在beamerbasetitle.sty
\hypersetup{pdftitle={...}}
。请注意对\insert
的调用title
。
为了支持 (2),您可以重新定义\alert
为不使用覆盖规范或模板(例如,\def\alert#1{\textcolor{red}{#1}}
),并观察编译期间错误的数量减少(或实际上正在编译)。
这里提出的解决方案是使用以下方法来区分 PDF 相关内容和 TeX 相关内容\texorpdfstring{<tex>}{<pdf>}
:
\documentclass{beamer}
%\usepackage{tikz}% With or without tikz
\title{Hello \texorpdfstring{\protect\alert{world}}{world}!}
\begin{document}
\maketitle
\end{document}
当然,你也可以更进一步,使用
\let\oldalert\alert% Store \alert in \oldalert
\let\alert\relax% Make \alert a null-op
\AtBeginDocument{\let\alert\oldalert}% Restore \alert at \begin{document}
或者对于任何可能在 PDF 属性中包含问题的内容,都类似这样。