所以我想创建一个命令,当像这样调用时\setcol{A}{n}
应该产生,我也想产生而不是。{A}^{[n]}
\setcol{\setcol{A}{n}}{m}
{A}^{[n][m]}
{A^{[n]}}^{[m]}
但是,这就是块\setcol
在宏内部评估时简单地重新定义的内容\setcol
,我想\setcol{(\setcol{A}{n} + B)}{m}
评估为{({A}^{[n]}+B)}^{[m]}
。
因此,基本上我需要检查参数是否\setcol
是裸调用\setcol
,并在这种情况下执行不同的操作。我该怎么做?我觉得必须进行某种检查,\ifx
但我对此有点模糊。
答案1
您可以通过测试参数是否恰好包含 3 个括号组或标记来实现此目的,如果是,则测试这些标记中的第一个是否为\setcol
。如果是,则输出特殊情况,否则使用正常输出。
下面使用expl3
来实现这一点(因为它已经包含了我们进行这些测试所需的一切)。
\documentclass[]{article}
\ExplSyntaxOn
\NewDocumentCommand \setcol {m m}
{
\bool_lazy_and:nnTF
{ \int_compare_p:nNn { \tl_count:n {#1} } = 3 }
{ \tl_if_head_eq_meaning_p:nN {#1} \setcol }
{
\pgerdes_setcol_special:nnnn #1 {#2}
}
{
\pgerdes_setcol_normal:nn {#1} {#2}
}
}
\cs_new:Npn \pgerdes_setcol_special:nnnn #1 #2 #3 #4
{
{#2} \sp { [#3] [#4] }
}
\cs_new:Npn \pgerdes_setcol_normal:nn #1 #2
{
{#1} \sp { [#2] }
}
\ExplSyntaxOff
\begin{document}
$\setcol{A}{n}$
$\setcol{\setcol{A}{n}}{m}$
$\setcol{(\setcol{A}{n} + B)}{m}$
\end{document}
既然您已经有了使用的想法\ifx
,那么这里是我在没有它的情况下如何做的expl3
(因此这可能更具教育意义),想法保持不变,测试它是否是 3 个标记并且第一个是\setcol
。
\documentclass[]{article}
\makeatletter
\newcommand\setcol[1]
{%
\setcol@ifthree{#1}
{%
\setcol@special#1{#1}%
}
{%
\setcol@normal{#1}%
}%
}
\newcommand\setcol@ifthree[1]
{%
\ifnum\numexpr\setcol@count#1\setcol@stop=3
\expandafter\@firstoftwo
\else
\expandafter\@secondoftwo
\fi
}
\newcommand\setcol@count[1]
{%
\ifx\setcol@stop#1%
\else
\expandafter+\expandafter1\expandafter\setcol@count
\fi
}
\newcommand\setcol@special[5]
{%
\ifx\setcol#1%
{#2}^{[#3][#5]}%
\else
{#4}^{[#5]}%
\fi
}
\newcommand\setcol@normal[2]
{%
{#1}^{[#2]}%
}
\newcommand*\setcol@stop{\setcol@stop}
\makeatother
\begin{document}
$\setcol{A}{n}$
$\setcol{\setcol{A}{n}}{m}$
$\setcol{(\setcol{A}{n} + B)}{m}$
\end{document}
(输出如上)