LaTeX可选参数
如何在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]{强制
\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}