\begin{document} 之后的 \title:什么时候做?

\begin{document} 之后的 \title:什么时候做?

我的回答在 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

我认为,最终这里的问题可以归结为两点:

  1. 如果你使用\title \begin{document},它最终会被纳入 PDF 属性中。之后\begin{document}再纳入就太晚了。

  2. 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@autopdfinfotruebeamer.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 属性中包含问题的内容,都类似这样。

相关内容