我正在阅读以下帖子带有和不带有可选参数的不同命令定义关于如何实现带有和不带有可选参数的不同命令定义。此链接中提到的示例涵盖了一个可选参数的情况。遵循相同的指导原则,我一直尝试使用以下代码对两个可选参数执行相同的操作,但没有任何成功:
\makeatletter
\@ifundefined{myDummy}
{
\def\myDummy
{
\@ifnextchar[
{\@WithAtLeastParam}{\@WithoutParam}
}
\def\@WithoutParam#1{x_{#1}}
\def\@WithAtLeastParam[#1]
{
\@ifnextchar[
{\@WithTwoParam}{\@WithOneParam}
}
\def\@WithTwoParam#1[#2]#3{x_{#1\rightarrow #2,#3}}
\def\@WithOneParam#1#2{x_{#1\rightarrow #2}}
}
\makeatother
有人能告诉我我做错了什么吗?
答案1
您需要注释掉 后面的换行符\def\@WithAtLeastParam[#1]
,否则参数后面必须有一个空格,如果没有空格,TeX 将无法解析宏参数。这是不必要的,因为\def\myDummy
TeX 有控制序列后面空格的规则,但在每个\def
行以非控制序列结尾的行尾应该注释掉。我还注释了每个可能潜入宏的寄生空格(尽管这些并不重要,因为宏是在数学模式下使用的)。
还\@WithAtLeastParam
抓取第一个参数,这就是为什么你必须将抓取的参数转发给\@WithTwoParam
和\@WithOneParam
。
为了简单起见,我删除了\@ifundefined
测试,您可以再次添加它。
\documentclass[]{article}
\makeatletter
\def\myDummy%
{%
\@ifnextchar[
{\@WithAtLeastParam}
{\@WithoutParam}%
}
\def\@WithoutParam#1{x_{#1}}
\def\@WithAtLeastParam[#1]%
{%
\@ifnextchar[
{\@WithTwoParam{#1}}
{\@WithOneParam{#1}}%
}
\def\@WithTwoParam#1[#2]#3%
{%
x_{#1\rightarrow #2,#3}%
}
\def\@WithOneParam#1#2%
{%
x_{#1\rightarrow #2}%
}
\makeatother
\begin{document}
$\myDummy{1} \myDummy[1]{2} \myDummy[1][2]{3}$
\end{document}
行为相同,但使用以下方式实现xparse
:
\documentclass[]{article}
\usepackage{xparse}
\NewDocumentCommand \myDummy { o o m }
{%
x_{\IfValueT{#1}{#1\rightarrow}\IfValueT{#2}{#2,}#3}%
}
\begin{document}
$\myDummy{1} \myDummy[1]{2} \myDummy[1][2]{3}$
\end{document}