8

How can \newrobustcmd and NewDocumentCommand be used in section titles with hyperref enabled? The MWE below shows that, while the rendered PDF looks correct, the bookmarks do not show the macro contents.

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

resulting pdf

The MWE.out file looks as follows.

\BOOKMARK [1][-]{section.1}{Hello world}{}% 1
\BOOKMARK [1][-]{section.2}{Hello }{}% 2
\BOOKMARK [1][-]{section.3}{Hello }{}% 3
2
  • The purpose of \newrobustcmd is to not expand the macro in \edef, which is what hyperref does for bookmarks; \NewDocumentCommand does the same. So what you get is expected. Why should you define those macros as robust?
    – egreg
    Apr 12 '17 at 13:20
  • Perhaps \section{Hello \protect\testa} for the \newcommand version is a bypass in order to prevent breaking apart during the writing process to the .aux file concerning the ToC and still having the expanded \testa in the bookmarks (assuming that \testa expands to valid content for the bookmarks, however)
    – user31729
    Apr 12 '17 at 13:39
6

With \newcommand you define an expandable macro (\def) while with \newrobustcmd and \NewDocumentCommand you define an engine-protected macro (\protected\def). The content of bookmarks gets expanded while the bookmark strings are being built but protected macros can't get expanded so the tokens \testB and \testC in your MWE end up as they are in the bookmarks. hyperref doesn't know what to do with them so it discards them.

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.

So if you really need protected macros you have two choices:

  • use \section{Hello \texorpdfstring{\testB}{world}} in the document or
  • add simpler expandable definitions in the preamble after loading hyperref which will be used in the bookmarks

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.