我正在尝试编写一个只接受一个可选参数的函数。如何使用 来实现\newcommand
?
这是我的尝试:
\newcommand{\s}[1]{%
\ifthenelse{\equal{#1}{}}{S(\Theta)}{S^{#1}(\Theta)}%
}
但是当我没有指定参数时它就会失败。
编辑:\newcommand{\s}[1][]
不起作用,因为输出不符合预期:
\s{2} -> S(Theta)2
答案1
编辑:
在您的编辑中您说:
编辑:
\newcommand{\s}[1][]
不起作用,因为输出不符合预期:\s{2} -> S(Theta)2
所以你对命令的定义\s
是错误的。我建议你使用这个定义\s
:
\documentclass{article}
\usepackage{xparse}
\NewDocumentCommand{\s}{o}{%
S(\Theta)\IfValueT{#1}{^{#1}}%
}
\begin{document}
$\s$
$\s[2]$
\end{document}
使用xparse
来定义命令,并且正如 egreg 在评论中所建议的那样,使用\IfValueT
来检查可选参数的存在并写下上标。
但您必须调用\s[2]
。定义用括号分隔的可选参数并不是一个好主意。
我之前的回答:
您必须添加一个默认值来告诉 LaTeX 该参数是可选的,如下所示:
% ↓ default value to the optional argument
\newcommand{\s}[1][]{...}
或者您可以使用xparse
来更好地控制参数:
\documentclass{article}
\usepackage{xparse}
\usepackage{ifthen}
% "usual" way
\newcommand{\s}[1][]{%
\ifthenelse{\equal{#1}{}}{S(\Theta)}{S^{#1}(\Theta)}%
}
% Exactly the same as above. The O{} tells xparse that the first argument
% is optional and the default value is empty
\NewDocumentCommand{\xxs}{O{}}{%
\ifthenelse{\equal{#1}{}}{S(\Theta)}{S^{#1}(\Theta)}%
}
% This one also tells xparse that the first argument is optional, but
% the presence of the optional argument can be tested with \IfNoValueTF
\NewDocumentCommand{\xs}{o}{%
\IfNoValueTF{#1}%
{S(\Theta)}%
{S^{#1}(\Theta)}%
}
\begin{document}
$\s$
$\s[a]$
$\xxs$
$\xxs[a]$
$\xs$
$\xs[a]$
\end{document}
答案2
另一种方法是使用\@ifnextchar
:
\documentclass{article}
\begin{document}
\makeatletter
\newcommand\@s{S(\theta)}
\newcommand\s@opt[1]{S^{#1}(\theta)}
\newcommand\s{\@ifnextchar\bgroup\s@opt\@s}
\makeatother
\[ \s\s{2} \]
\end{document}
这里发生的事情是,当您执行时\s
,然后\@ifnextchar
检查下一个字符。
如果它是一个左括号(或任何\bgroup
),那么它就执行\s@opt
,如果不是,它就执行\@s
。\s@opt
需要一个参数,但是\@s
没有。
也就是说:如果下一个字符是\bgroup
(左括号*),则 LaTeX 将用 替换\s
,\s@opt
否则用 替换\@s
。
低于此点的风险由您自行承担。
我们进入兔子洞:
你甚至可以在这里做更多奇特的事情,例如 make \s^{2}
-> S^{2}(\theta)
like so**:
\documentclass{article}
\begin{document}
\makeatletter
\newcommand\@s{S(\theta)}
\def\s@pow^#1{S^{#1}(\theta)}
\newcommand\s{\@ifnextchar^\s@pow\@s}
\makeatother
\[ \s \] %<- prints S(\theta)
\[ \s^{2} \] %<- prints S^2(\theta)
\end{document}
或者你可以做一个可选的平方,比如\s{\theta}^{2}
-> S^{2}(\theta)
while \s{\theta}
-> S(\theta)
:
\documentclass{article}
\begin{document}
\makeatletter
\def\s#1{\def\res@a{#1}\@ifnextchar^\s@pow\@s}
\def\@s{S(\res@a)}
\def\s@pow^#1{S^{#1}(\res@a)}
\makeatother
\[ \s{\theta} \] %<- S(\theta)
\[ \s{\theta}^{2} \]%<- S^{2}(\theta)
\end{document}
*:除非另有定义,但通常情况并非如此。
**:出于某些原因,可能不建议这样做。我不知道这些原因,但我感觉我在做一些黑客行为?