LaTeX可选参数


Answers:


176

指南中的示例:

\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.

21
我认为问题在于如何确定是否提供了可选参数,而不提供默认值。
Konrad Rudolph,2009年

43
尽管是真的,但我在寻找一种提供默认参数的方法时发现了这个问题,因此此答案对我来说是最有用的。
Tanner Swett

26

创建“可选参数”背后的总体思路是,首先定义一个中间命令,该命令向前扫描以检测令牌流中接下来要出现的字符,然后插入相关的宏以适当地处理即将出现的参数。使用通用TeX编程,这可能非常繁琐(尽管并不困难)。LaTeX \@ifnextchar对于此类事情非常有用。

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

在您的示例中,您有一个\sec接受一个或两个括号参数的宏。这可以通过xparse以下方式实现:

\ documentclass {article}
\ usepackage {xparse}
\ begin {document}
\ DeclareDocumentCommand \ sec {mg} {%
    {#1%
        \ IfNoValueF {#2} {和#2}%
    }%
}
(\ sec {Hello})
(\ sec {Hello} {Hi})
\ end {document}

参数{ m g }定义了\sec; 的参数;m表示“强制性参数”,并且g是“可选的括号”。\IfNoValue(T)(F)然后可以用来检查第二个参数是否确实存在。有关允许的其他类型的可选参数,请参见文档。


4
将!这是行不通的。输出:(Hello and ) (Hello and Hi)
Alexey Malistov

感谢您的反馈,Alexey。我怀疑您使用的是旧版本的xparse;最近有很多工作要做。TeX Live 2009刚刚发布了:)
Will Robertson

24

以上所有这些都表明,在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 {}变量运行宏。(如果用户未指定,这里只是将短标题设置为等于长标题)。

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

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

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

我知道这是很愚蠢的,但是这与我要使用LaTeX差不多-一旦我开始查看TeX代码就不那么明智了……我确实喜欢罗伯逊先生的xparse方法,也许我会尝试...


我喜欢这种方法。更像“编程式”,因​​此更易于阅读。做得好!
love.by.Jesus,2016年

11

您只需要以下内容:

\makeatletter
\def\sec#1{\def\tempa{#1}\futurelet\next\sec@i}% Save first argument
\def\sec@i{\ifx\next\bgroup\expandafter\sec@ii\else\expandafter\sec@end\fi}%Check brace
\def\sec@ii#1{\section*{\tempa\ and #1}}%Two args
\def\sec@end{\section*{\tempa}}%Single args
\makeatother

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

我以为TeX可以将命令后第一个“框”的适当计数理解为参数。这个“盒子”用大括号写出来,或者是一个符号。就是 x^2+1x^{2+1} 所以我有疑问,您的命令是否测试了括号的存在?是否可以创建LaTeX命令以\sec生成:命令使用“ A,b,c和d \sec{A}[b,c,d]”,\sec{A}[b] and "A" for \ sec {A}`使用“ A和b” ?
克劳利2009年

你有两个问题。1)是的,我的命令测试了括号的存在。2)是的,它可以创建宏\sec{A}[b,c,d]\sec{A}[b]\sec{A}
2009年

6

当我想创建一个\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提供可选参数


-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"
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.