hyperref
hyperref copied to clipboard
MakeUppercase in the contents breaks with hyperref
Brief outline of the bug
In the NTG classes the contentsline for a Part in the rapport1.cls (similar to report) needs to produce the title of the Part in uppercase. This is done by injecting \MakeUppercase in the tocline macro. But when the hyperref package is loaded as well this leads to an unexpected error because this string \hyper@linkstart {link}{\Hy@tocdestname }{\numberline {I}{Deel 1}}\hyper@linkend ends up in the argument of \MakeUpperacase. The error message is:
(./part.toc
! Undefined control sequence.
\find@pdflink ...ode \protected@edef \Hy@testname
{#2}\ifx \Hy@testname \@em...
l.1 ... {part}{\numberline {I}{Deel 1}}{2}{part.1}
%
When I replace this with \upperase the error goes away...
Minimal example showing the bug
\RequirePackage{latexbug}
\documentclass{report}
\usepackage[pdftex]{hyperref}
\makeatletter
\newcommand*\@regtocline[3]{%
\ifnum latex3/latex2e#1>\c@tocdepth
\else
\vskip\z@\@plus.2\p@
{\hangindent\z@ \@afterindenttrue \interlinepenalty\@M
\leftskip10\p@
\rightskip10\p@\@plus 1fil
\parfillskip\z@
\@tempdima10\p@
\parindent\z@
\leavevmode
\hbox{}\hskip -\leftskip\relax
\ifnum#1<0\MakeUppercase{#2}\else
\bfseries#1 latex3/latex2e#2\fi\nobreak
\hskip 1em \nobreak{\slshape latex3/latex2e#3}\par
}%
\fi}
\renewcommand*\l@part{%
\ifnum \c@tocdepth >-2\let\l@@part\relax
\addpenalty{-\@highpenalty}%
\addvspace{2.25em \@plus \p@}%
\def\l@@part{\@regtocline{-1}}%
\fi\l@@part}
\makeatother
\begin{document}
\tableofcontents
\part{Part one}
\chapter{Chapter one}
\section{Secton one}
\end{document}
Log file (required) and possibly PDF file
I'm not sure to what extent this is a LaTeX bug... That breaks because
\MakeUpperacase
does an \edef
in its argument, then \hyper@linkstart
explodes, but \MakeUppercase
hasn't changed recently, so if this used to
work then the problem is most likely at the hyperref
side...
Meanwhile you can work-around the issue by making \hyper@linkstart
a \protected
macro (and use \lowercase
to make the link target right):
\makeatletter
\let\ORG@hyper@linkstart\hyper@linkstart
\protected\def\hyper@linkstart#1#2{%
\lowercase{\ORG@hyper@linkstart{#1}{#2}}}
\makeatother
Your minimal example looks odd, somehow a few stray latex3/latex2e
have been added.
I doubt that that ever worked, but I will be able to test it on an older system only tomorrow.
But imho the \MakeUppercase is misplaced. It would be better to move it to the \part definition. E.g.
\documentclass{report}
\usepackage[pdftex]{hyperref}
\makeatletter
\newcommand*\@regtocline[3]{%
\ifnum #1>\c@tocdepth
\else
\vskip\z@\@plus.2\p@
{\hangindent\z@ \@afterindenttrue \interlinepenalty\@M
\leftskip10\p@
\rightskip10\p@\@plus 1fil
\parfillskip\z@
\@tempdima10\p@
\parindent\z@
\leavevmode
\hbox{}\hskip -\leftskip\relax
\ifnum#1<0 {#2}\else
\bfseries#1 #2\fi\nobreak
\hskip 1em \nobreak{\slshape #3}\par
}%
\fi}
\renewcommand*\l@part{%
\ifnum \c@tocdepth >-2\let\l@@part\relax
\addpenalty{-\@highpenalty}%
\addvspace{2.25em \@plus \p@}%
\def\l@@part{\@regtocline{-1}}%
\fi\l@@part}
\let\MakeUppercaseUnsupportedInPdfStrings\@firstofone
\def\@part[#1]#2{%
\ifnum \c@secnumdepth >-2\relax
\refstepcounter{part}%
\addcontentsline{toc}{part}{\MakeUppercase{\thepart\hspace{1em}#1}}%
\else
\addcontentsline{toc}{part}{\MakeUppercase{#1}}%
\fi
\markboth{}{}%
{\centering
\interlinepenalty \@M
\normalfont
\ifnum \c@secnumdepth >-2\relax
\huge\bfseries \partname\nobreakspace\thepart
\par
\vskip 20\p@
\fi
\Huge \bfseries #2\par}%
\@endpart}
\makeatother
\begin{document}
\tableofcontents
\part{Part one}
\chapter{Chapter one}
\section{Secton one}
\end{document}
this should be resolved in version 7.00u just sent to ctan.