重新定义命令以包含其自身(修补在 TeX 用语中)通常使用\let
。这个答案@egreg 说:
绝不在用定义的命令或用并具有可选参数定义的命令
\let
上使用。\DeclareRobustCommand
\newcommand
因此一个自然的问题是应该在这种情况下我们该怎么办?
例如,我如何重新定义\bibitem
以在其后添加另一个命令?这个:
\let\old@bibitem\bibitem
\def\bibitem{\old@bibitem\it}
不起作用,并且 \show\bibitem 会显示原因:
> \bibitem=macro:
->\@ifnextchar [\@lbibitem \@bibitem .
我该怎么做才能达到效果呢?
我宁愿不使用诸如这样的包,xpatch
因为我正在修改其他人将使用的类,并且我尝试使用尽可能少的包以最大限度地减少可能的冲突。
答案1
该命令\bibitem
有不参数,更不用说可选参数了。我在回答的引用部分中引用的命令是使用
\newcommand{<macro>}[<args>][<default>]{...}
没有其他以间接方式定义的,\@ifnextchar
或者\@ifstar
像\bibitem
或\section
。
如果您的目的是以斜体打印引用标签,那么\bibitem
独立于任何包(例如etoolbox
,xpatch
或letltxmacro
您加载的)进行修补都是错误的选择。
你能做什么?让我们看看:\bibitem
有你展示的定义,所以我们知道我们必须修补\@lbibitem
或\@bibitem
。
利用texdef
我们看到
> texdef -t latex -s @lbibitem
% latex.ltx, line 6228:
\def\@lbibitem[#1]#2{\item[\@biblabel{#1}\hfill]\if@filesw
{\let\protect\noexpand
\immediate
\write\@auxout{\string\bibcite{#2}{#1}}}\fi\ignorespaces}
> texdef -t latex -s @bibitem
% latex.ltx, line 6232:
\def\@bibitem#1{\item\if@filesw \immediate\write\@auxout
{\string\bibcite{#1}{\the\value{\@listctr}}}\fi\ignorespaces}
嗯。有两种情况:如果\bibitem
后面跟着[
,我们需要看看是如何\@biblabel
定义的,然后我们会看到
> texdef -t latex -s @biblabel
% latex.ltx, line 6278:
\def\@biblabel#1{[#1]}
所以我们只需要做
\def\@biblabel#1{[\textit{#1}]}
如果没有可选参数,我们需要看看环境enumerate
启动时的标准标签\begin{thebibliography}
是如何定义的。很好:
> texdef -t latex -s thebibliography
% article.cls, line 575:
\newenvironment{thebibliography}[1]
{\section*{\refname}%
\@mkboth{\MakeUppercase\refname}{\MakeUppercase\refname}%
\list{\@biblabel{\@arabic\c@enumiv}}%
{\settowidth\labelwidth{\@biblabel{#1}}%
\leftmargin\labelwidth
\advance\leftmargin\labelsep
\@openbib@code
\usecounter{enumiv}%
\let\p@enumiv\@empty
\renewcommand\theenumiv{\@arabic\c@enumiv}}%
\sloppy
\clubpenalty4000
\@clubpenalty \clubpenalty
\widowpenalty4000%
\sfcode`\.\@m}
{\def\@noitemerr
{\@latex@warning{Empty `thebibliography' environment}}%
\endlist}
嗯,这取决于类别;我们假设类别是article
。很好!标签仍使用打印\@biblabel
,因此上述技巧在两种情况下都适用。
所以你的任务只是添加
\def\@biblabel#1{[\textit{#1}]}
到您的个人样式文件;如果必须在文档序言中完成修补,请确保在\makeatletter
和之间添加行\makeatother
(请参阅\makeatletter 和 \makeatother 起什么作用?)。然而这可能取决于类别,但通常人们可以依赖这一事实来\@biblabel
改变它。
不,修补命令绝对不容易。