命令 \@dblarg 在类中起什么作用?

命令 \@dblarg 在类中起什么作用?

在命令的定义中出现了 的声明\@dblarg,如下所示:\def\title{\@dblarg\CJ@title}。到底\@dblarg做什么?

答案1

它本质上检查后面的标记是否\CJ@title存在[,以便将相同的参数传递给主命令两次,如果[未找到。该命令\CJ@title必须定义为

\def\CJ@title[#1]#2{...}

这样,就可以调用如下方法

\title{xyz}

扩张将(连续)

\@dblarg\CJ@title{xyz}
...<some complex action>...
\CJ@title[{xyz}]{xyz}

并调用如下命令

\title[abc]{xyz}

扩张将(连续)

\@dblarg\CJ@title[abc]{xyz}
...<some complex action>...
\CJ@title[abc]{xyz}

我们可以...<some complex action>...通过查看的定义来理解\@dblarg

\long\def\@dblarg#1{\kernel@ifnextchar[{#1}{\@xdblarg{#1}}}
\long\def\@xdblarg#1#2{#1[{#2}]{#2}}

因此,\title{xyz}有一个(每行一个步骤,我省略了\kernel@ifnextchar与此无关的扩展)

\@dblarg\CJ@title{xyz}
\kernel@ifnextchar[{\CJ@title}{\@xdblarg{\CJ@title}}{xyz}
\@xdblarg{\CJ@title}{xyz}
\CJ@title[{xyz}]{xyz}

其中\title[abc]{xyz}一个

\@dblarg\CJ@title{xyz}
\kernel@ifnextchar[{\CJ@title}{\@xdblarg{\CJ@title}}[abc]{xyz}
\CJ@title[abc]{xyz}

第一种情况下有一对多余的括号,但根据 TeX 规则它将被删除;如果标题包含 ,则需要它]

如何做同样的事情xparse

通过xparse包,人们可以获得具有更清晰语法的相同功能(我假设这是在类或包文件中完成的)

\RequirePackage{xparse}

\NewDocumentCommand{\title}{om}{%
  \IfNoValueTF{#1}
    {\CJ@title{#2}{#2}}
    {\CJ@title{#1}{#2}}%
}
\newcommand{\CJ@title}[2]{...}

因此不需要任何限定的参数。

使用最新版本xparse可以做得更好:

\RequirePackage{xparse}

\NewDocumentCommand{\title}{O{#2}m}{%
  \CJ@title{#1}{#2}%
}
\newcommand{\CJ@title}[2]{...}

因为使用此代码,缺少的可选参数提供的值与强制参数相同。

答案2

这是允许其他函数/宏使用可选参数的简单方法。

例如,使用您的案例\def\title{\@dblarg\CJ@title},您可以使用

\title{some title}

没有可选参数,或者使用

\title[some optional title]{some title}

可选参数。这里的“简单”是指,如果你不指定可选组件(如前面的示例),则默认为

\title[some title]{some title}

从而将单参数响应转换为双参数。宏\CJ@title被适当地定义为管理两个参数,并且可以具有以下形式:

\def\CJ@title[#1]#2{%
  %...
}

这通常是具有可选参数的分段命令的情况:\section[<ToC entry>]{<body entry>}。如果您不指定可选参数,则仍会<body entry>进入目录。如何?\@dblarg

以下是其中包含的正式定义latex.ltx- 您会在里面找到它的用法\@startsection,仅作为示例:

\long\def\@dblarg#1{\kernel@ifnextchar[{#1}{\@xdblarg{#1}}}
\long\def\@xdblarg#1#2{#1[{#2}]{#2}}

相关内容