我最近一直在创建自定义类,发现我想要的命令之一,\xpatchcmd
在某些情况下不起作用。我发现加载包hyperref
是罪魁祸首。
作为参考,我指的是这个答案\xpatchcmd
我在自己的 MWE 中实现了的应用:
预期结果(无加载hyperref
)
在最小设置下,它可以按预期工作,给出水平规则:
\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}
意外结果(带加载hyperref
)
如果我另外加载hyperref
,则补丁不适用:
\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}
进一步思考
- 我发现这种行为并不局限于 documentclass
article
。同样的意外例如,结果是通过获得的scrbook
。 - 我故意将其
hyperref
作为最后一个包加载。即使更改 hyperref`` 的顺序也xpatch`and
没有改变行为。 - 我发现各自文档中提到的两个包之间不存在不兼容性。
问题
我如何加载hyperref
和是否得到想要的补丁程序的工作?
答案1
当hyperref
被加载时, 的定义会\maketitle
发生变化;许多标准命令都会发生这种情况。原始含义存储在 中\HyOrg@maketitle
。
然而,这是不是 \maketitle
您想要修补,但是\@maketitle
。您的补丁只是偶然起作用(并且实际上破坏了某些东西,尽管不是很重要)。
\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}
调整垂直空间(此处1ex
)以适合您的喜好。
\maketitle
请注意,类中的定义article
是
\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
}
并且\@date
此代码未在其他地方使用。真正负责标题排版的命令是\@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}