Como usar \newrobustcmd e \NewDocumentCommand com hyperref nos títulos das seções

Como usar \newrobustcmd e \NewDocumentCommand com hyperref nos títulos das seções

Como pode \newrobustcmde NewDocumentCommandser usado em títulos de seção hyperrefhabilitados? O MWE abaixo mostra que, embora o PDF renderizado pareça correto, os marcadores não mostram o conteúdo da macro.

\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 resultante

O MWE.outarquivo tem a seguinte aparência.

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

Responder1

Com \newcommandvocê define uma macro expansível ( \def) enquanto com \newrobustcmde \NewDocumentCommandvocê define uma macro protegida pelo mecanismo ( \protected\def). O conteúdo dos marcadores é expandido enquanto as strings de marcadores estão sendo construídas, mas as macros protegidas não podem ser expandidas, então os tokens \testBe \testCno seu MWE acabam como estão nos marcadores. hyperrefnão sabe o que fazer com eles, então os descarta.

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.

Portanto, se você realmente precisa de macros protegidas, você tem duas opções:

  • usar \section{Hello \texorpdfstring{\testB}{world}}no documento ou
  • adicione definições expansíveis mais simples no preâmbulo após o carregamento, hyperrefque serão usadas nos marcadores

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

informação relacionada