如何在章节标题中将 \newrobustcmd 和 \NewDocumentCommand 与 hyperref 结合使用

如何在章节标题中将 \newrobustcmd 和 \NewDocumentCommand 与 hyperref 结合使用

如何在启用的情况下在章节标题中使用\newrobustcmd?下面的 MWE 显示,虽然呈现的 PDF 看起来正确,但书签不显示宏内容。NewDocumentCommandhyperref

\documentclass[11pt]{article}

\usepackage{hyperref}
\usepackage{xparse}
\usepackage{etoolbox}

\newcommand{\testA}[0]{world}
\newrobustcmd{\testB}[0]{world}
\NewDocumentCommand{\testC}{}{world}

\begin{document}
    \section{Hello \testA}
    \section{Hello \testB}
    \section{Hello \testC}
\end{document}

生成的 pdf

MWE.out文件如下所示。

\BOOKMARK [1][-]{section.1}{Hello world}{}% 1
\BOOKMARK [1][-]{section.2}{Hello }{}% 2
\BOOKMARK [1][-]{section.3}{Hello }{}% 3

答案1

使用时,\newcommand您定义一个可扩展的宏(\def),而使用\newrobustcmd和时,\NewDocumentCommand您定义一个受引擎保护的宏(\protected\def)。在构建书签字符串时,书签的内容会扩展,但受保护的宏无法扩展,因此 MWE 中的标记\testB\testC最终会像在书签中一样。hyperref不知道如何处理它们,所以它会丢弃它们。

Package hyperref Warning: Token not allowed in a PDF string (PDFDocEncoding):
(hyperref)                removing `\testB' on input line 13.


Package hyperref Warning: Token not allowed in a PDF string (PDFDocEncoding):
(hyperref)                removing `\testC' on input line 14.

因此,如果您确实需要受保护的宏,您有两个选择:

  • \section{Hello \texorpdfstring{\testB}{world}}在文档中使用或
  • 加载后在序言中添加更简单的可扩展定义hyperref,将在书签中使用

    \pdfstringdefDisableCommands{%
      \def\testB{world}%
      \def\testC{wor‌​ld}%
    }
    

相关内容