我如何定义一个新命令,使之接受带星号和不带星号的变体,并且还接受可选参数?
我尝试了以下操作:
\documentclass{minimal}
\makeatletter
\newcommand\MyCommand[1][1]{%
\@ifstar{%
The starred variant with parameter: #1%
}{%
The non-starred variant with parameter: #1%
}
}
\makeatother
\begin{document}
\MyCommand \\
\MyCommand* \\
\MyCommand[2] \\
\MyCommand*[2]
\end{document}
但这给出了:
带参数的无星号变体:1
带参数的星号变体:1
带参数的无星号变体:2
带参数的星号变体:1[2]
然而,人们可以这样写\MyCommand[2]*
来获得“带有参数的星号变体:2”,但不知何故,我希望上述版本能够起作用。
答案1
使用xparse
可选参数和带星号的变体非常容易:
\documentclass{article}
\usepackage{xparse}
\NewDocumentCommand\MyCommand
{
s % optional *
O{1} % first optional argument (default = 1)
}
{%
\IfBooleanTF{#1}
{The starred variant with parameter: #2}
{The non-starred variant with parameter: #2}
}
\begin{document}
\noindent
\MyCommand \\
\MyCommand* \\
\MyCommand[2]\\
\MyCommand*[2]
\end{document}
使用 LaTeX 会\newcommand
稍微复杂一些。\@ifstar
宏在展开并吸收其参数后会查看下一个标记,因此您需要先检查,*
然后再查找可选参数:
\documentclass{article}
\makeatletter
\newcommand\MyCommand
{%
\@ifstar
{\MyCommand@star}
{\MyCommand@nostar}%
}
\newcommand\MyCommand@star[1][1]{%
The starred variant with parameter: #1%
}
\newcommand\MyCommand@nostar[1][1]{%
The non-starred variant with parameter: #1%
}
\makeatother
\begin{document}
\noindent
\MyCommand \\
\MyCommand* \\
\MyCommand[2]\\
\MyCommand*[2]
\end{document}
两个版本均打印:
您的代码可以工作,但不如您所期望的那样。查找\MyCommand[1][1]
可选参数“while expand” \MyCommand
,然后为您提供:
\@ifstar{%
The starred variant with parameter: <optional argument or default>%
}{%
The non-starred variant with parameter: <optional argument or default>%
}
并且仅在那之后测试\@ifstar
将扩展以查找可选项*
并相应地选择文本,因此您定义的命令的实际语法是:
\MyCommand[optional argument]<optional star>
答案2
Make\MyCommand
不接受任何参数,只找出星号。然后从那里分叉。
\documentclass{minimal}
\makeatletter
\newcommand\MyCommand{%
\@ifstar{\mycommandstar}{\mycommandnostar}
}
\newcommand\mycommandstar[1][1]{The starred variant with parameter: #1}
\newcommand\mycommandnostar[1][1]{The non-starred variant with parameter: #1}
\makeatother
\begin{document}
\MyCommand \\
\MyCommand* \\
\MyCommand[2] \\
\MyCommand*[2]
\end{document}