我是新手amsart
。我想给自己一个默认的运行标题。因此,我尝试\title
以显而易见的方式重新定义,如下所示。
\documentclass{amsart}
\let\AmStitle\title
\renewcommand{\title}[2][My default running title]{\AmStitle[#1]{#2}}
\title{Article title here}
\author{Author name here}
\begin{document}
\maketitle
\end{document}
这显然会无限循环下去。这是什么原因造成的?
答案1
\title
中的宏amsart
以非常间接的方式定义:
\renewcommand*{\title}[2][]{\gdef\shorttitle{#1}\gdef\@title{#2}}
\edef\title{\@nx\@dblarg
\@xp\@nx\csname\string\title\endcsname}
这很聪明,但就是不允许您进行重新定义。在这种情况下,\LetLtxMacro
由于这个非标准定义,这甚至都不是好事。
你可以这样做xparse
:
\documentclass{amsart}
\usepackage{xparse}
\makeatletter
\RenewDocumentCommand{\title}{om}{%
\IfNoValueTF{#1}
{\gdef\shorttitle{My default running title}}
{\gdef\shorttitle{#1}}%
\gdef\@title{#2}%
}
\makeatother
\title{Article title here}
\author{Author name here}
\begin{document}
\maketitle
\end{document}
实际上,为什么 的定义是那样的,这有点令人费解\title
。定义这种宏的标准方法是
\def\title{\@dblarg\title@}
\def\title@[#1]#2{%
\gdef\shorttitle{#1}\gdef\@title{#2}%
}
因为\@dblarg
要小心,例如
\title{Title}
将替代Title
和#1
,#2
而调用如下
\title[Short]{Long title}
将执行预期的操作。\title@
可以使用其他任何方法。
中的定义amsart
利用了以下事实:
\renewcommand*{\title}[2][]{\gdef\shorttitle{#1}\gdef\@title{#2}}
定义\title
扩展为
\@protected@testopt\title\\title{}
和\\title
(名称中带有反斜杠的命令)就像
\def\\title[#1]#2{\gdef\shorttitle{#1}\gdef\@title{#2}}
下一个指令,用\@nx
和\@xp
替换为更易理解的\noexpand
和\expandafter
,是
\edef\title{%
\noexpand\@dblarg\expandafter\noexpand\csname\string\title\endcsname
}
这本质上等同于说
\def\title{\@dblarg\\title}
(不同之处在于\\title
需要一些奇怪的技巧才能输入)。所以没有任何好处,因为定义最终是确切地*我之前给出的更简单的一个,只是内部宏(\\title
,这里)对于普通用户来说可能更难获得。
\LetLtxMacro
包中的无法letltxmacro
工作,因为\\title
存在,但\title
未按预期定义,即以 开头\@protected@testopt
,因此会造成混淆。
道路xparse
肯定更加清晰。
答案2
您可以通过在之后添加来更改一篇文章的标题\maketitle
,
\markright{My default running title}
或者,如果你想要两边都这样,
\markboth{My default running title}
这确实有一个缺点,即它不会自动将字符串大写,因此您要么需要完全“大小写”地输入它,要么应用\MakeTextUppercase{...}
。