12

In the following MWE, the bookmark produced by hyperref is incorrect:

\documentclass{article} 
\usepackage{hyperref}
\usepackage[capitalize,nameinlink,noabbrev]{cleveref}

\hypersetup{%
    bookmarksnumbered, bookmarksopen=true, bookmarksopenlevel=1,%
}   

\begin{document} 
\section{\label{sec:foo}foo}
\section{Code for \cref{sec:foo}}
\end{document}

The heading of section 2 in the PDF is correct (Code for Section 1), but the bookmarks as shown in Acrobat read:

1 foo
2 Code for sec:foo

Edit: as Micha pointed out, the code also produces a warning:

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

Using the allmighty \protect before the \cref unfortunately did not change anything ;).

2
  • 1
    I've got an comment: Package hyperref Warning: Token not allowed in a PDF string
    – Micha
    Oct 15, 2013 at 11:14
  • 1
    Imho it can't work. \cref is to complicated for the bookmarks. Use something like \section{Code for \texorpdfstring{\cref{sec:foo}}{section \ref{sec:foo}}} Oct 15, 2013 at 12:41

2 Answers 2

11

You have (re)discovered a fundamental limitation of TeX's ability to process certain items that will go into things like bookmarks. Note that this limitation isn't limited to processing \cref instructions.

To get around this limitation, you can employ the (admittedly somewhat kludgy) command \texorpdfstring, which takes two arguments. The first is what should be displayed on the "TeX side" (which comes down to, basically, what should be shown in the body of the text), and the second is what should be displayed on the "pdf side" of things, such as in the bookmarks.

A modified form of your MWE would thus look like this:

\documentclass{article}
\usepackage{hyperref}
\usepackage[capitalize,nameinlink,noabbrev]{cleveref}
\hypersetup{%
    bookmarksnumbered, bookmarksopen=true, bookmarksopenlevel=1,%
}
\begin{document}
\section{foo} \label{sec:foo}
\section{Code for \texorpdfstring{\cref{sec:foo}}{Section \ref{sec:foo}}}
\end{document}

The first argument will generate a hyperlink from the text of the second sectioning header to the first, and the second argument provides information as to what shows up in the bookmarks. With this setup, the bookmark for the second section will read "Code for Section 1".

3
  • 2
    But we loose the point of cref. Why not just type \section{Code for Section \ref{sec:foo}}
    – Arnaud
    Sep 7, 2018 at 11:48
  • @Arnaud - In your proposed solution, only the section number will be part of the hypertarget, i.e., the surface that's a "target" for the mouse to click on. Given that the OP loads cleveref with the options nameinlink and `capitalize, he/she clearly wants the prefix string "Section" that's printed in the sectioning header to be part of the hypertarget.
    – Mico
    Sep 7, 2018 at 11:54
  • 1
    OK I didn't see this subtlety!
    – Arnaud
    Sep 7, 2018 at 11:57
2

Based on Phelype Oleinik's solution: https://tex.stackexchange.com/a/485979/128042 one can use the crossreftools package together with some custom code.

\documentclass{article} 
\usepackage{hyperref}
\usepackage[capitalize,nameinlink,noabbrev]{cleveref}
\usepackage{crossreftools}
\pdfstringdefDisableCommands{%
    \let\Cref\crtCref
    \let\cref\crtcref
}

\hypersetup{%
    bookmarksnumbered, bookmarksopen=true, bookmarksopenlevel=1,%
}


\begin{document} 
    \section{\label{sec:foo}foo}
    \section{Code for \cref{sec:foo}}
\end{document}

This automatically creates the correct pdf bookmarks (in TexXStudio one has to compile it two times). (If you are also interested in removing the color of the links, see Phelype Oleinik's solution: https://tex.stackexchange.com/a/485979/128042.)

PS: This answer was also improved by Ulrike Fischer's comment on https://tex.stackexchange.com/a/504970/128042 (answering the equivalent question automatic \texorpdfstring for \ref in pdf bookmarks (section titles)).

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .