我最近\@testopt
发现问题。我尝试了解使用此宏的目的,但在我的调查中,我发现了其他宏,例如\@protected@testopt
,甚至是新的软件包,例如exp-testopt
。实际上,我只使用 TeX 和 LaTeX2e 进行开发,您觉得这个宏怎么样?
最可靠的方法是什么?
答案1
存在的原因至少有几个\@testopt
。
如果你看一下的定义\@testopt
,你会发现它是
> \@testopt=\long macro:
#1#2->\kernel@ifnextchar [{#1}{#1[{#2}]}.
这使用\kernel@ifnextchar
而不是\@ifnextchar
:后者可能会被例如 AMS 数学材料重新定义,而 是\kernel@ifnextchar
“冻结的”,永远不应该被重新定义。因此\@testopt
将始终显示相同的行为,搜索[
和跳过空格。从这个意义上讲,使用它而不是自己编写测试可以提高可靠性。
这里的另一个因素是 token 的使用。\@testopt
是一个 token,而手动进行测试需要四个 token(\kernel@ifnextchar
和[
对[...]
)。当 LaTeX2e 发布时,token 使用的减少非常重要:内核中有很多地方进行了这样的改动以减小大小。当然,今天这并不重要。
答案2
我认为直接使用没有任何优势\@testopt
。你提到的问题有
\def\collecttikzpicture{\@testopt\@collecttikzpicture{}}
\def\@collecttikzpicture[#1]{%
\global\setbox\tempbox=\hbox\bgroup\begin{tikzpicture}[#1]%
}
功能上等同于
\newcommand\collecttikzpicture[1][]{%
\global\setbox\tempbox=\hbox\bgroup\begin{tikzpicture}[#1]%
}
并且具有健壮的优点,即在移动参数中使用时,它最终会扩展为自身,这是不是前一个定义的情况。
根据后一种定义,扩展\collecttikzpicture
为
\@protected@testopt \collecttikzpicture \\collecttikzpicture {}
其中第三个标记是名称中带有反斜杠的特殊控制序列,其作用与上一个定义相同\@collecttikzpicture
。因此,您甚至不必担心为实际操作定义辅助控制序列,因为\newcommand
会自动处理该问题。当\@protected@testopt
展开时,它使用\@testopt
,所以\kernel@ifnextchar
(而不是\@ifnextchar
)。
定义具有强制参数的命令\@testopt
非常简单:
\def\foo{\@testopt\@foo{DEFAULT}}
\def\@foo[#1]#2#3{Something with #1, #2, #3}
\foo{X}{Y}
让我们看看为什么在和的扩展之后\foo[A]{X}{Y}
。这是第一个:
\foo{X}{Y}
\@testopt\@foo{DEFAULT}{X}{Y}
\kernel@ifnextchar [{\@foo}{\@foo[{DEFAULT}]}{X}{Y}
\@foo[{DEFAULT}]{X}{Y}
Something with DEFAULT, X, Y
这是第二个:
\foo[A]{X}{Y}
\@testopt\@foo{DEFAULT}[A]{X}{Y}
\kernel@ifnextchar [{\@foo}{\@foo[{DEFAULT}]}[A]{X}{Y}
\@foo[A]{X}{Y}
Something with A, X, Y
但是当然,
\newcommand{\foo}[3][1]{Something with #1, #2 and #3}
更容易和强壮的。
答案3
它可能也与此相关,它\@testopt
来自 LaTeX2.09,所以最初所有使用可选参数的 LaTeX 命令都是使用它明确定义的。
和朋友的语法扩展\newcommand
允许使用可选参数声明命令,这是较新的 (latex2e) 添加。它们\@testopt
在内部使用,但正如 @Joseph 所说,使用更高级别的形式可以节省一些标记并增加稳健性。