如何测试命令后面是否跟着参数?

如何测试命令后面是否跟着参数?

假设我有两个命令定义为

\def\witharg#1{something with #1}
\def\without{something without arg}

我想要定义一个新命令\mycmd,它的行为就像\witharg后面跟着一个参数(不一定用括号括起来),并且就像\without后面没有参数一样。事实上,后一种情况只有在后面跟着 token 时才为真\mycmd}为了让事情更清楚一点,我想要

{\mycmd\token\mycmd}

扩展为类似于

{\witharg{\token}\without}

我怎样才能实现这个目标?

请注意,实际上,尝试评估类似的操作{\witharg}会失败,因为 TeX 会抱怨说有一个多余的,即缺少的}参数。\witharg

答案1

每当你需要检查宏后面的内容时,通常要使用的原语是\futurelet(请参阅 TeX by Topic 以获得良好的参考)。在这种情况下,你可以编写类似

\def\mycmd{%
  \futurelet\mytoken\myargparse
}

它将\let以下标记转换为\mytoken,然后扩展\myargparse。定义\myargparse为取决于是什么\mytoken,就是这样:

\def\myargparse{%
  \ifx\mytoken\closingbracetoken
    \expandafter\without
  \else
    \expandafter\witharg
  \fi
}
\let\closingbracetoken=}

最后,检查它是否正常工作:

\def\witharg#1{something with #1}
\def\without{something without arg}
\def\token{TOK}
{\mycmd\token\mycmd}

答案2

xparse可以测试显式括号分隔的参数(或其他分隔符,请参阅文档):

\documentclass{article}
\usepackage{xparse}% http://www.ctan.org/pkg/xparse

\NewDocumentCommand\mycmd{g}{%
\IfValueTF{#1}{(something with #1)}{(something without arg)}%
}

\def\token{TOK}
\begin{document}

\mycmd{Hello}

\mycmd

{\mycmd\token\mycmd}

Blah, \mycmd{Hello}, blah, \mycmd, blah

\end{document}

编译输出

相关内容