检测不到 \newcommand 中的参数

检测不到 \newcommand 中的参数

我想知道是否有办法创建一个命令,可以区分是否有参数。我不是指空参数,而是指根本没有参数。

以下是一个例子

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

相关内容