8

pdflatex returns on below document

\documentclass[a4paper]{article}
\usepackage{hyperref}
\let\code\texttt
\begin{document}
\section{\texttt{first}}
\section{\code{second}}
\end{document}

following error:

! Argument of \@sect has an extra }.
<inserted text> 
                \par 
l.6     \section{\code{second}}

I like semantic command naming, thus I use my own short commands instead of \texttt and such, Moreover, unless I introduce some new parts in them, I prefer to use \let, which is more efficient than \def/\newcommand (which works fine in this case).

Question

Why hyperref doesn't like commands set via \let in section titles?

Supplementary question

If there is anything wrong with

\let\code\texttt

then how it should be fixed?

  • BTW: It is generally a good idea to use \protect for macros inside \section etc. macros. I might know this and just don't use it to keep the example minimal. – Martin Scharrer Jul 3 '11 at 16:38
11

Hyperref has to remove all formatting commands and special characters before putting the string into the PDF outline (which has special requirements).

You can fix it like this:

\pdfstringdefDisableCommands{%
    \let\code\relax
}

Which treats \code specially only for the places where a "pdf string" is needed (primarily, the outline).

| improve this answer | |
  • 2
    +1 Thanks, I was just looking for a possibility to add macros to the \pdfstringdef list. However \let\code\@firstofone would be more correct. It strips the {..} around the content and is also done by hyperref itself for \texttt. Because these extra commands are added after \texttt has been set to \@firstofone you also could simply repeat the assignment \let\code\texttt (which saves you \makeatother .. \makeatletter). – Martin Scharrer Jul 3 '11 at 16:41
  • @Martin's remark applied to your fix, Lev, seems like the best solution. Thank you guys! BTW to avoid repeating myself, I'll rather go with \def\commandlets{...} and use it in both places (outside and inside \pdfstringdefDisableCommands). – przemoc Jul 3 '11 at 16:49
  • @przemoc: Indeed, \commandlets would be preferable. I was thinking about to suggest this by myself. – Martin Scharrer Jul 3 '11 at 16:54
8

Use \def\code{\texttt} instead. It is a little less efficient but this won't make any real difference for your document. To explain what happens: When used in a sectioning command the macro is not just used in the text (or the ToC if present) but also for the PDF bookmarks. However there you can't use different fonts AFAIK. The internally used \pdfstringdef macro from hyperref takes care that normal font macros like \texttt are set to be void while expanding the text for the bookmarks, i.e. by setting \let\texttt\@firstofone. If you use \let than this change will not affect your \code macro which creates trouble. A general alternative is to use \texorpdfstring internally to make your formatting macros void in PDF mode used for the bookmarks.

| improve this answer | |

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.