LaTeX可选参数

LaTeX可选参数,latex,optional-arguments,Latex,Optional Arguments,如何在LaTeX中创建带有可选参数的命令? 比如: \newcommand{\sec}[2][]{ \section*{#1 \ifsecondargument and #2 \fi} } } 那么,我可以这样称呼它 \sec{Hello} %Output: Hello \sec{Hello}{Hi} %Output: Hello and Hi 示例来自: \newcommand{\example}[2][YYY]{强制

如何在LaTeX中创建带有可选参数的命令? 比如:

\newcommand{\sec}[2][]{
    \section*{#1
        \ifsecondargument
            and #2
        \fi}
    }
}
那么,我可以这样称呼它

\sec{Hello}
%Output: Hello
\sec{Hello}{Hi}
%Output: Hello and Hi
示例来自:

\newcommand{\example}[2][YYY]{强制参数:#2;
可选参数:#1.}
这将\示例定义为具有两个参数的命令,
在{}中被称为#1和#2——到目前为止没有什么新的。
但通过将第二个可选参数添加到此\n命令
(该[YYY])新定义的
command\example是可选的,默认值为YYY。
因此\example的用法是:
\示例{BBB}
其中打印:
强制arg:BBB;可选参数:YYY。
或:
\示例[XXX]{AAA}
其中打印:
强制参数:AAA;可选参数:XXX。

创建“可选参数”的总体思路是,首先定义一个中间命令,该命令可提前扫描以检测令牌流中接下来出现的字符,然后插入相关宏以处理出现的参数(视情况而定)。使用泛型TeX编程可能会非常乏味(尽管并不困难)。LaTeX的
\@ifnextchar
对于这些事情非常有用

对于您的问题,最好的答案是使用新的
xparse
包。它是LaTeX3编程套件的一部分,包含用于定义具有任意可选参数的命令的广泛功能

在您的示例中,有一个
\sec
宏,该宏接受一个或两个大括号参数。这将通过使用
xparse
和以下各项来实现:

\documentclass{article} \usepackage{xparse} \begin{document} \DeclareDocumentCommand\sec{ m g }{% {#1% \IfNoValueF {#2} { and #2}% }% } (\sec{Hello}) (\sec{Hello}{Hi}) \end{document} \documentclass{article} \usepackage{xparse} \开始{document} \DeclareDocumentCommand\sec{m g}{% {#1% \IfNoValueF{2}{和{2}% }% } (\sec{Hello}) (\sec{Hello}{Hi}) \结束{document}
参数
{m g}
定义了
\sec
的参数
m
表示“强制参数”,而
g
表示“可选大括号参数”
\IfNoValue(T)(F)
可用于检查第二个参数是否确实存在。有关允许的其他类型的可选参数,请参阅文档。

您只需要以下内容:

\documentclass{article} \usepackage{xparse} \begin{document} \DeclareDocumentCommand\sec{ m g }{% {#1% \IfNoValueF {#2} { and #2}% }% } (\sec{Hello}) (\sec{Hello}{Hi}) \end{document}
\makeatletter
\def\sec#1{\def\tempa{1}\futurelet\next\sec@i}%保存第一个参数
\def\sec@i{\ifx\next\bgroup\expandafter\sec@ii\其他\以后扩展\sec@end\fi}%检查大括号
\def\sec@ii#1{\section*{\tempa\和#1}}%2个参数
\def\sec@end{\section*{\tempa}}%单个参数
\Maketother
\第{你好}
%输出:您好
\第{你好}{你好}
%输出:你好,你好

这是我的尝试,但它并不完全符合您的规格。没有完全测试,所以要小心

\newcount\seccount

\def\sec{%
    \seccount0%
    \let\go\secnext\go
}

\def\secnext#1{%
    \def\last{#1}%
    \futurelet\next\secparse
}

\def\secparse{%
    \ifx\next\bgroup
        \let\go\secparseii
    \else
        \let\go\seclast
    \fi
    \go
}

\def\secparseii#1{%
    \ifnum\seccount>0, \fi
    \advance\seccount1\relax
    \last
    \def\last{#1}%
    \futurelet\next\secparse
}

\def\seclast{\ifnum\seccount>0{} and \fi\last}%

\sec{a}{b}{c}{d}{e}
% outputs "a, b, c, d and e"

\sec{a}
% outputs "a"

\sec{a}{b}
% outputs "a and b"

所有这些都表明,在LaTeX中创建一个好的、灵活的(或禁止重载的)函数是很困难的!!!(那个TeX代码在我看来像希腊语)

好吧,再加上我最近的(尽管不是那么灵活)开发,下面是我最近在我的论文文档中使用的

\usepackage{ifthen}  % provides conditonals...
启动命令,默认情况下“可选”命令设置为空:

\newcommand {\figHoriz} [4] []  {
然后,我让宏设置一个临时变量,\temp{},这取决于可选参数是否为空。这可以扩展到任何传递的参数

\ifthenelse { \equal {#1} {} }  %if short caption not specified, use long caption (no slant)
    { \def\temp {\caption[#4]{\textsl{#4}}} }   % if #1 == blank
    { \def\temp {\caption[#1]{\textsl{#4}}} }   % else (not blank)
然后对这两种情况使用\temp{}变量运行宏。(这里,如果用户没有指定,它只是将短标题设置为与长标题相等)

在本例中,我只检查\newcommand{}提供的单个“可选”参数。如果你要设置它,比如说,3个“可选”参数,你仍然需要发送3个空白参数。。。例如

\MyCommand {first arg} {} {} {}

这很傻,我知道,但这就是我打算用乳胶做的——一旦我开始看TeX代码,它就没有那么感性了。。。不过,我确实喜欢罗伯逊先生的xparse方法,也许我会尝试一下…

我也遇到了类似的问题,当时我想创建一个命令,
\dx
,缩写为
\\mathrm{d}x
(即在积分的微分之前加上一个空格,并使“d”也竖直)。但我还想让它足够灵活,可以将积分变量作为可选参数包含在内。我把下面的代码放在序言中

\usepackage{ifthen}

\newcommand{\dx}[1][]{%
   \ifthenelse{ \equal{#1}{} }
      {\ensuremath{\;\mathrm{d}x}}
      {\ensuremath{\;\mathrm{d}#1}}
}
然后


gives

我想问题是关于如何确定是否给出了可选参数,而不是提供默认参数。虽然这是真的,但我在寻找提供默认参数的方法时发现了这个问题,所以这个答案对我来说是最有用的。威尔!它不起作用。输出:
(你好和)(你好和你好)
谢谢你的反馈,Alexey。我怀疑您使用的是旧版本的xparse;最近在这方面做了很多工作。TexLive2009刚刚发布:)我想TeX应该理解为命令后第一个“盒子”的适当数量。这个“盒子”是用大括号写的,或者是一个符号。例如,
x^2+1
x^{2+1}
所以我有个问题,您的命令是否测试大括号的存在?是否可以创建LaTeX命令
\sec
为命令
\sec{A}[b,c,d]
生成“A,b,c和d”,为
\sec{A}[b]创建“A和b”,为
\sec{A`}创建“A”?您有两个问题。1) 是的,我的命令测试是否存在大括号。2) 是的,可以为
\sec{A}[b,c,d]
\sec{A}[b]
\sec{A}
创建宏。相关问题:。我喜欢这种方法。更像“编程”,因此更容易阅读。干得好
\begin{document}
   $$\int x\dx$$
   $$\int t\dx[t]$$
\end{document}