2009-11-28 83 views
88

如何创建与LaTeX的可选参数的命令? 喜欢的东西:LaTeX的可选参数

\newcommand{\sec}[2][]{ 
    \section*{#1 
     \ifsecondargument 
      and #2 
     \fi} 
    } 
} 

然后,我可以从guide这样称呼它

\sec{Hello} 
%Output: Hello 
\sec{Hello}{Hi} 
%Output: Hello and Hi 
+5

相关问题:[具有和不具有可选的参数不同的命令定义](http://tex.stackexchange.com/q/308/1347) 。 – 2011-07-17 12:56:34

回答

111

例子:

\newcommand{\example}[2][YYY]{Mandatory arg: #2; 
           Optional arg: #1.} 

This defines \example to be a command with two arguments, 
referred to as #1 and #2 in the {<definition>}--nothing new so far. 
But by adding a second optional argument to this \newcommand 
(the [YYY]) the first argument (#1) of the newly defined 
command \example is made optional with its default value being YYY. 

Thus the usage of \example is either: 

    \example{BBB} 
which prints: 
Mandatory arg: BBB; Optional arg: YYY. 
or: 
    \example[XXX]{AAA} 
which prints: 
Mandatory arg: AAA; Optional arg: XXX. 
+15

我认为这个问题是关于如何确定*是否给出了一个可选参数,而不是提供默认值。 – 2009-11-28 10:51:49

+28

虽然这是真的,但我在寻找提供默认参数的方式时发现了这个问题,所以这个答案对我来说是最有用的。 – 2013-01-08 22:07:27

18

背后打造 “可选参数” 的总体思路是先定义一个中间命令,它可以提前扫描以检测令牌流中接下来出现的字符,然后插入相关的宏以处理出现的参数作为适当的。使用通用的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} 

的参数{ m g }定义的\sec参数; m的意思是“强制性的说法”和g是“可选的支撑体系参数”。然后可以使用\IfNoValue(T)(F)来检查第二个参数是否确实存在。有关允许的其他类型的可选参数,请参阅文档。

+4

请问!这是行不通的。输出:'(你好和)(你好,你好)' – 2009-11-28 13:08:17

+0

感谢您的反馈,阿列克谢。我怀疑你使用的是旧版本的xparse;最近有很多工作要做。 TeX Live 2009刚刚发布:) – 2009-11-28 23:17:19

12

所有你需要的是这样的:

\makeatletter 
\def\sec#1{\def\tempa{#1}\futurelet\next\[email protected]}% Save first argument 
\def\[email protected]{\ifx\next\bgroup\expandafter\[email protected]\else\expandafter\[email protected]\fi}%Check brace 
\def\[email protected]#1{\section*{\tempa\ and #1}}%Two args 
\def\[email protected]{\section*{\tempa}}%Single args 
\makeatother 

\sec{Hello} 
%Output: Hello 
\sec{Hello}{Hi} 
%Output: Hello and Hi 
+0

我认为TeX理解为命令后第一个“盒子”的适当数量的参数。这个'盒子'是用花括号写的,或者它是一个符号。 IE浏览器。 'x^2 + 1'或'x^{2 + 1}' 所以我有问题,你的命令是否测试大括号的存在? 是否可以创建LaTeX命令'\ sec',生成: “A,b,c和d”用于命令'\ sec {A} [b,c,d]', “A和b” \ sec {A} [b]和 “A”代表'\ sec {A}'? – Crowley 2009-11-30 11:45:24

+0

你有两个问题。 1)是的,我的命令测试了大括号。 2)是的,可以为'\ sec {A} [b,c,d]'或'\ sec {A} [b]'或'\ sec {A}'创建宏。 – 2009-11-30 17:41:27

-1

这里是我的尝试,它不会按照你的规格完全相同,但。没有经过充分测试,所以要谨慎。

\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" 
17

以上所有的演出硬它可以使一个不错的,灵活的(或禁止超载)在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) 

然后我运行使用\临时{}变量的两种情况下的宏。 (在这里它只是设置短标题等于长标题,如果它没有被用户指定)。

\begin{figure}[!] 
    \begin{center} 
     \includegraphics[width=350 pt]{#3} 
     \temp %see above for caption etc. 
     \label{#2} 
    \end{center} 
\end{figure} 
} 

在这种情况下,我只检查\ newcommand {}提供的单个“可选”参数。如果你要为它设置3个“可选”参数,你仍然需要发送3个空白参数...例如。

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

这是非常愚蠢的,我知道,但是这是我们所据我要去乳胶 - 它只是不是无意义的,一旦我开始看TeX的代码...我不喜欢先生罗伯逊的xparse方法虽然,也许我会尝试...

+0

我喜欢这种方法。更“像编程”,因此更易于阅读。做得好! – 2016-01-29 15:51:44

1

我也有类似的问题,当我想创造一个命令,\dx,来简化\;\mathrm{d}x(即把一个额外的空间积分的微分前也有“d”直立)。但是,我还想让它足够灵活,以便将集成变量作为可选参数加入。我在序言中加入了以下代码。

\usepackage{ifthen} 

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

然后

\begin{document} 
    $$\int x\dx$$ 
    $$\int t\dx[t]$$ 
\end{document} 

\dx with optional argument给出