Как использовать \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). Содержимое закладок расширяется, пока создаются строки закладок, но защищенные макросы не могут расширяться, поэтому токены \testBи \testCв вашем MWE оказываются такими же, как в закладках. 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}%
    }
    

Связанный контент