[Tex/LaTex] Making memoir Chapter entries in ToC all-caps and Appendix entries regular case, without breaking hyperref

etoolboxhyperrefmemoirtable of contents

I have a thesis style working, but around 10% of my code is a copy of memoir's \def\@chapter that lets me put all regular chapter entries in all caps, and keep appendix entries in regular case. This works, but I'd assume there was an easier way.

Ideally, I'd like to have my students keep using the \chapter command rather than define my own document division.

I've managed to find a split in the logic between chapters and appendices in memoir.cls — chapters call the \l@chapter command, and appendices call the \l@appendix command:

\newcommand*{\l@chapter}[2]{%
  \l@chapapp{#1}{#2}{\cftchaptername}}

\newcommand*{\l@appendix}[2]{%
  \l@chapapp{#1}{#2}{\cftappendixname}}

I've tried adding an \uppercase to the first one as shown below, but doing this breaks hyperrefs — the links are still present, but have a black border and don't link to the right place. Minimal example (comment out the \renewcommand for a ToC with proper links but wrong case, or leave it in for the right case and dead links):

\documentclass{memoir}
\usepackage{lipsum}
\usepackage{hyperref}
\makeatletter
\renewcommand*{\l@chapter}[2]{%
  \l@chapapp{\uppercase{#1}}{#2}{\cftchaptername}}
\makeatother

\begin{document}
\tableofcontents*

\chapter{One}
\lipsum
\chapter{Two}
\lipsum
\appendix \appendixpage
\chapter{Alpha}
\lipsum
\end{document}

ToC with broken links
ToC with links intact


EDIT (2011/02/23): I've had another idea to patch \@chapter instead of copying all its code and making the one change. But that's failing, too. I suspect it's either because I haven't escaped backslashes or other characters properly:

\documentclass{memoir}
\usepackage{lipsum}
\usepackage{etoolbox}
\usepackage{hyperref}

\makeatletter
\ifpatchable*{\@chapter}{\typeout{Chapter can be patched}}{\typeout{Chapter cannot be patched}}
\patchcmd{\@chapter}{\protect\chapternumberline{\thechapter}\f@rtoc}{\protect\chapternumberline{\thechapter}\uppercase\expandafter{\f@rtoc}}{\typeout{Succeeded}}{\typeout{Failed}}
\makeatother

\begin{document}
\tableofcontents*

\chapter{One}
\lipsum
\chapter{Two}
\lipsum
\appendix \appendixpage
\chapter{Alpha}
\lipsum
\end{document}

which returns in the log

Chapter can be patched
Failed

SECOND EDIT (2011/02/23): working etoolbox patch is in this post, but hyperref still interferes.

Best Answer

What follows is only a partial solution because it typesets regular chapter entries in small caps (using \scshape). I'm not aware of an all-caps macro that doesn't take an argument (which doesn't mean there isn't one :-)), and I also suspect that \uppercase is incompatible to hyperref's machinations in a more basic way. (TeX gurus, please coment on this!)

\documentclass{memoir}
\usepackage{lipsum}
\usepackage{hyperref}
\renewcommand{\cftchapterfont}{\scshape}
\makeatletter
\g@addto@macro{\appendixpage}{%
  \addtocontents{toc}{%
    \protect\renewcommand{\protect\cftchapterfont}{}%
  }%
}

\begin{document}
\tableofcontents*

\chapter{One}
\lipsum
\chapter{Two}
\lipsum
\appendix \appendixpage

\chapter{Alpha}
\lipsum
\end{document}