3

I have lately been creating custom classes, and found that one of my desired commands, \xpatchcmd, did not work on some occassions. I spotted that loading of package hyperref is the culprit.

For reference, I'm referring to this answer's application of \xpatchcmd, which I implemented in my own MWE:

Intended outcome (without loading hyperref)

In the minimal setup it works as intended, giving the horizontal rule:

\documentclass{article}

\usepackage{xpatch}

\makeatletter \xpatchcmd{\maketitle}{@date}{@date\par\rule{\textwidth}{1pt}}{}{} \makeatother

\begin{document} \title{My Title} \author{My Name} \maketitle \end{document}

horizontal rule is added as expected

Unexpected outcome (with loading hyperref)

If I additionally load hyperref, then the patch does not apply:

\documentclass{article}

\usepackage{xpatch} \usepackage{hyperref}

\makeatletter \xpatchcmd{\maketitle}{@date}{@date\par\rule{\textwidth}{1pt}}{}{} \makeatother

\begin{document} \title{My Title} \author{My Name} \maketitle \end{document}

no horizonal bar. This is not expected.

Further thoughts

  • I have found this behaviour is not limited to documentclass article. The same unexpected results are obtained with e.g. scrbook.
  • I am intentionally loading hyperref as the last package. Even changing the order of xpatch`and hyperref`` did not change the behaviour.
  • I found no incompatibilities between either packages mentioned in their respective documentations.

Question

How can I load hyperref and get the desired patch working?

egreg
  • 1,121,712
marc
  • 701

1 Answers1

5

When hyperref is loaded, the definition of \maketitle changes; this happens for a lot of standard commands. The original meaning is stored in \HyOrg@maketitle.

However, it's not \maketitle that you want to patch, but \@maketitle. Your patch worked just by chance (and actually broke something, not very important, though).

\documentclass{article}

\usepackage{xpatch} \usepackage{hyperref}

\makeatletter \xpatchcmd{@maketitle} {\end{center}} {\[1ex]\rule{\textwidth}{1pt}\end{center}} {}{} \makeatother

\begin{document} \title{My Title} \author{My Name} \maketitle \end{document}

Adjust the vertical space (here 1ex) to suit your taste.

enter image description here

Note that the definition of \maketitle in the article class is

\newcommand\maketitle{\par
  \begingroup
    \renewcommand\thefootnote{\@fnsymbol\c@footnote}%
    [...irrelevant code...]
    \setcounter{footnote}{0}%
    \global\let\thanks\relax
    \global\let\maketitle\relax
    \global\let\@maketitle\relax
    \global\let\@thanks\@empty
    \global\let\@author\@empty
    \global\let\@date\@empty
    \global\let\@title\@empty
    \global\let\title\relax
    \global\let\author\relax
    \global\let\date\relax
    \global\let\and\relax
}

and \@date is not used elsewhere by this code. The command that's really responsible for the typesetting of the title is \@maketitle:

\def\@maketitle{%
  \newpage
  \null
  \vskip 2em%
  \begin{center}%
  \let \footnote \thanks
    {\LARGE \@title \par}%
    \vskip 1.5em%
    {\large
      \lineskip .5em%
      \begin{tabular}[t]{c}%
        \@author
      \end{tabular}\par}%
    \vskip 1em%
    {\large \@date}%
  \end{center}%
  \par
  \vskip 1.5em}
egreg
  • 1,121,712
  • Thank you for clarifying that loading hyperref changes the definition. However, I am not really interested in the article class only, but in working around/with this change in arbitrary classes. Take, e.g. scrbook, where I also want to be able to inject code. There, \maketitle and@maketitleare more convoluted, but yur example for thearticle`` class was sufficient in getting me towards the right path. – marc Aug 05 '22 at 21:46