我想知道是否有办法创建一个命令,可以区分是否有参数。我不是指空参数,而是指根本没有参数。
以下是一个例子
\newcommand{\mycommand}[1]{
\if \totallyempty
0
\elseif \empty
1
\else
%whatever
2
\fi
}
测试
\mycommand
0
\mycommand[]
1
\mycommand[2]
2
更新
抱歉,命令参数不需要用括号括起来{}
,正如许多人指出的那样,可选参数应该是。我主要担心[]
的是可能不指定参数,例如\mycommand
,,。\mycommand[]
\mycommand[2]
抱歉解释得不太正确。我修改了正文。谢谢。
解决方案
非常感谢提交的所有解决方案,它们都非常有创意且实用。
我不得不选择@egreg解决方案(https://tex.stackexchange.com/a/409770/105956) 非常容易实现且代码清晰。提及 @Phelype Oleinik 和 @David Carlisle 没有使用任何包。
非常感谢。诚挚的问候。
答案1
你可以,但你不应该。可选参数应该用 分隔[]
。
我希望命令名称足够清楚,能够表达我对此事的看法。
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\cs_new_eq:NN \IfBlankTF \tl_if_blank:nTF
\cs_new_eq:NN \IfEmptyTF \tl_if_empty:nTF
\ExplSyntaxOff
\NewDocumentCommand{\mybadcommand}{g}{%
\IfNoValueTF{#1}
{0}
{%
\IfEmptyTF{#1}% if you allow { } to represent case 1, use \IfBlankTF instead
{1}
{2}%
}%
}
\NewDocumentCommand{\mygoodcommand}{o}{%
\IfNoValueTF{#1}
{0}
{%
\IfEmptyTF{#1}% if you allow [ ] to represent case 1, use \IfBlankTF instead
{1}
{2}%
}%
}
\begin{document}
\mybadcommand
\mybadcommand{}
\mybadcommand{x}
\mygoodcommand
\mygoodcommand[]
\mygoodcommand[x]
\end{document}
答案2
xparse
提供g
参数规范:
{
一对 TeX 组标记(在标准 LaTeX 中, ... )中给出的可选参数,如果不存在则}
返回。-NoValue-
[
这违反了使用...作为可选参数的惯例]
。但是,用例是存在的。
\documentclass{article}
\usepackage{xparse}
\NewDocumentCommand{\mycommand}{ g }{%
\IfValueTF{#1}
{% https://tex.stackexchange.com/q/53068/5764
\if\relax\detokenize{#1}\relax
1%
\else
#1%
\fi}
{0}%
}
\begin{document}
\mycommand% 0
\mycommand{}% 1
\mycommand{1}% 1
\mycommand{2}% 2
\end{document}
答案3
您可以定义两个命令,一个没有参数,另一个带有空参数的条件,如下所示:
\documentclass{article}
\makeatletter
\newcommand{\mycommand}{%
\@ifnextchar[{\mycommand@something}{\mycommand@nothing}%
}
\newcommand{\mycommand@nothing}{%
0%
}
\newcommand{\mycommand@something}[1][]{%
\if\relax\detokenize{#1}\relax
1%
\else
#1%
\fi
}
\makeatother
\begin{document}
0\mycommand
1\mycommand[]
2\mycommand[2]
\end{document}
主命令是\mycommand
。如果下一个字符是 ,[
则执行\mycommand@something
,否则执行\mycommand@nothing
。
检查\mycommand@something
参数是否为空。如果为空,则条件为真,否则为假。
我无法让它与“curry 括号”一起工作,因为它们在 TeX 中具有特殊含义。我想暂时更改它们的 catcode 可能会起作用...
编辑:
正如 @egreg 指出的那样,使用很少的单词(两个标记:)
),人们可以使用\bgroup
来替代{
并欺骗 TeX 检查{
之后的\mycommand
。在这种情况下,\mycommand
可以完全按照需要使用:
\documentclass{article}
\makeatletter
\newcommand{\mycommand}{%
\@ifnextchar\bgroup{\mycommand@something}{\mycommand@nothing}%
}
\newcommand{\mycommand@nothing}{%
0%
}
\newcommand{\mycommand@something}[1]{%
\if\relax\detokenize{#1}\relax
1%
\else
#1%
\fi
}
\makeatother
\begin{document}
0\mycommand
1\mycommand{}
2\mycommand{2}
\end{document}
答案4
虽然从技术上来说可以使{}
分隔参数成为可选的,但您不应该这样做,因为它破坏了所有的 LaTeX 语法指南。{}
参数表示强制参数,[]
分隔参数是可选的。
\documentclass{article}
\makeatletter
\def\mycommand{\@ifnextchar[\my@command{yippee no argument here}}
\def\my@command[#1]{Here I deal with an argument (#1) \if\relax\detokenize{#1}\relax(which is empty)\fi}
\makeatother
\begin{document}
\mycommand
\mycommand[]
\mycommand[zz]
\end{document}