该\newcommand
宏允许使用以下可选参数作为第一个参数#1
:
\newcommand{\mycommand}[3][defaultfor1]{blah blah blah}
是否可以有多个选项\newcommand
?
答案1
尝试使用 LaTeX 3 包xparse
。例如:
\documentclass{article}
\usepackage{xparse}
\NewDocumentCommand{\foocmd}{ O{default1} O{default2} m }{#1~#2~#3}
% ⤷ #1 ⤷ #2 ⤷ #3
\begin{document}
\foocmd{foo} \par
\foocmd[nondefault1]{foo} \par
\foocmd[nondefault2][notfoo2]{foo} \par
\end{document}
你可能会读文件了解更多信息。
答案2
您已经找到了其他方法的答案,因此这里仅介绍使用内核的基本方法。您需要手动定义宏,例如
\makeatletter
\def\mycommand{%
\@ifnextchar[%
{\mycommand@i}
{\mycommand@i[<default-for-1>]}%
}
\def\mycommand@i[#1]{%
\@ifnextchar[%
{\mycommand@ii{#1}}
{\mycommand@ii{#1}[<default-for-2>]}%
}
\def\mycommand@ii#1[#2]#3{%
% Do stuff
}
\makeatother
当然,这可以扩展到更复杂的情况。(在这里,我把是否创建函数留给你决定\long
。如果你希望它的一部分很长,那么所有的内部宏都应该很长。该xparse
方法允许它根据一些内部改组在参数之间变化。)
答案3
\usepackage{twoopt}
\newcommandtwoopt{\xyz}[3][Def1][Def2]{Something with #1, #2 and #3}
还有\renewcommandtwoopt
和\providecommandtwoopt
。
但是,那解析包(LaTeX3 包树的一部分,但也适用于 LaTeX2e)提供了\DeclareDocumentCommand
极大的灵活性,可以在每个位置以及 *-versions 中定义带有可选参数的命令。
历史回顾
TeX Live 中有一个newcommand.py
Python 脚本,附带可通过 访问的文档texdoc newcommand
。例如,要获取定义具有两个可选参数和一个强制参数的命令的代码,可以启动
python /usr/local/texlive/2011/texmf-dist/doc/latex/newcommand/newcommand.py
并在提示下% Prototype:
回答
MACRO twoopt OPT[#1={Def1}] OPT[#2={Def2}] #3
我们要定义的宏在哪里\twoopt
。脚本将构建一个定义宏的骨架:
\makeatletter
\newcommand{\twoopt}[1][Def1]{%
\@ifnextchar[{\twoopt@i[{#1}]}{\twoopt@i[{#1}][{Def2}]}%
}
\def\twoopt@i[#1][#2]#3{%
% Put your code here.
% You can refer to the arguments as #1 through #3.
}
\makeatother
注释行应该被实际的代码替换。
根据规范
MACRO finalopt #1 OPT[#2={default}]
定义一个带有强制参数和可选参数的宏:
\makeatletter
\newcommand{\finalopt}[1]{%
\@ifnextchar[{\finalopt@i{#1}}{\finalopt@i{#1}[{default}]}%
}
\def\finalopt@i#1[#2]{%
% Put your code here.
% You can refer to the arguments as #1 and #2.
}
\makeatother
答案4
使用两个或更多可选参数有一个缺点。如果用户想要更改第二个参数的默认值,则必须明确指定第一个参数的默认值。例如,\raisebox
应该设置可选的深度参数,但不应更改结果高度。这使得第一个可选参数变得繁琐:
\raisebox{-1ex}[\dimexpr\height-1ex\relax][0pt]{foobar}
另一种方法是使用一完全是可选参数,但支持键值接口。最好是:
\raisebox[depth=0pt]{foobar}
还可以轻松定义新键来支持新功能没有改变命令的签名(选项的数量和类型)。
有许多包支持定义和解析键(例如,keyval
和类似的包,,pgfkeys
...)。