编辑:关于悬赏,我对下面的问题很满意,这个悬赏就是针对这个问题的。我认为我找不到更好的了
我搜索了一些有关 LaTeX 中可选参数的用法,但有些事情对我来说还不是很清楚。
什么时候
我的问题不是针对命令或包,而是针对两者。
有时我们需要为包或命令指定一个或多个可选参数。我们可以找到如下命令:
\Foo[OptArg1,OptArg2]{Arg1}{Arg2}
和类似:
\Foo[OptArg1][OptArg2]{Arg1}{Arg2}
对于第一个,我看到一个系列有两个可选参数,以逗号分隔。对于第二个,我看到两个系列,每个系列都有一个可选参数。
我认为这两种方式有些不同,但并不完全明白我的命令何时必须使用第一种方式,何时必须使用第二种方式。
例如,假设我们需要一个命令,该命令将使用第一个可选参数将第一个非可选参数拆分成几部分。那么我更喜欢第二种方法,因为在第一种方法中,我的逗号作为分隔符不会被理解(它已经是一个分隔符)。但我仍然可以使用如下命令:
\Foo[separator={,},OptArg2]{Arg1}{Arg2}
做同样的事情。
当然,如果我想用 \Foo[separator={//}][OptArg2//OptArg3] 来分隔第二个系列的可选参数,这将是唯一的(或至少是更好的)选择,因为我必须在读取第二个系列参数之前定义分隔符。
如何
此外,有时如果给出了两个系列,命令必须表现不同,如果给出了一个系列,则表现不同。例如,在我上面的例子中,如果没有给出第一个参数,则逗号将用于分隔第二个系列的可选参数。但如果给出了,则它将被用作分隔符,并且命令在读取参数时将表现不同。
在这种情况下,我认为 \def 是比 newcommand 更通用的编写命令的选项,因为我们在读取参数时有更多选择。(\newcommand 会在读取第一个参数之前破坏第二个参数或类似的东西。还请考虑在第二个系列参数中包含“]”...)
我的问题是:
- 什么时候(标准 LaTeX)我必须使用第一种方式,什么时候必须使用第二种方式?
- 在一般情况下,例如在我们尚不知道参数数量的情况下,或者在上述使用分隔符或我已经描述过的 ']' 的情况下, \def 是否是定义我们的命令的唯一或更好的方法?
PS:在第二个问题中,考虑一下我希望我的命令允许我通过读取下一个字符来处理很多情况。(例如,我想逐个读取命令后的字符,并且只有当我找到两个普通参数或命令 \stop 等时才停止。不要求提供此代码,只是询问 \newcommand 是否可以做到这一点 - 并且这是一个不错的选择 - 或者 \def 是否是唯一的选择)
答案1
你的问题混淆了两个不同的东西。LaTex2e 中有可选参数,[]
而中有强制参数,{}
所以
\Foo[OptArg1,OptArg2]{Arg1}{Arg2}
有一个可选参数和两个强制参数。
\Foo[OptArg1][OptArg2]{Arg1}{Arg2}
有两个可选参数和两个强制参数。
第二个问题是逗号分隔列表,这可能根本不是语法的一部分,只是逗号被视为一个字符,例如在
\newcommand\Foo[3][]{(#1)-(#2)(#3)}
那么#1
将是OptArg1,OptArg2
, #2
将是Arg1
和#3
将是Arg2
,结果将是排版
(最佳参数 1,最佳参数 2)-(参数 1)-(参数 2)
逗号没有特殊的规则。
当然,命令可以对参数做任何它想做的事情,这可能包括对逗号进行迭代。Latex 格式中有这样的工具(\@for
)或者几个包提供了宏来解析逗号分隔的列表。然而,这与可选的参数检测无关。在(合法)语法示例中
\usepackage[foo,bar]{array,longtable}[2015/01/01 packages by you, me and someone]
有两个可选参数和一个强制参数,第一个可选参数和强制参数稍后在处理时以\usepackage
逗号分隔。第二个可选参数不是以逗号分隔,而是以空格分隔,/
以便从参数开头提取日期。
至于定义,如果开始时只有一个可选参数,则可以使用\newcommand
如果有两个或更多,您也可以使用\newcommand
,但需要分阶段定义宏,但使用 xparse
或类似的包可能更容易,以允许更简单的规范并自动处理定义所需的内部宏。但是,最好不要有太多连续的可选参数,就像您有
\Foo[OptArg1][OptArg2]{Arg1}{Arg2}
如果你需要指定,那么 thenOptArg1
并不是可选的OptArg2
。语法如下
\Foo[opt1=a,opt2=b]{Arg1}
允许每个选项被单独省略。但这种 key=value 解析可以应用于任何标记字符串,无论它是强制参数还是可选参数。例如,graphicx
使用keyval
包来解析其可选参数中的,
and=
\includegraphics[width=10pt,height=8pt]{image}
并hyperref
使用相同的解析来解析强制参数中的相同语法
\hypersetup{colorlinks=false,plainpages=true}