如果宏嵌套超过两级,如何访问宏参数?
更详细地解释一下:在另一个命令中创建一个新命令(嵌套命令定义),可以实现类似的部分应用命令。例如,如果一个经常调用的命令有两个参数,并且其中一个参数的更改频率低于另一个参数,则这很有用:
\documentclass{minimal}
\begin{document}
\newcommand{\one}[1]{%
\newcommand{\two}[1]{#1, ##1}%
}
\one{a} % Partial application, nothing gets printed
\two{b} \quad \two{c}
\end{document}
不幸的是,如果涉及另一层嵌套,则此方法无效:
\documentclass{minimal}
\begin{document}
\newcommand{\one}[1]{%
\newcommand{\two}[1]{%
\newcommand{\three}[1]{#1, ##1, ###1}%
}
}
\one{a} % First partial application -> Error
\two{b} % Second partial application
\three{c}
\end{document}
错误发生在标记的行中,并显示以下消息:
[LaTeX] Line 8: Illegal parameter number in definition of \two.<to be read again> a
l.0 \one{c}
% First partial application -> Error
\one{a}
由于在上面的代码中用替换\one{1}
会导致输出1, b, b
,所以我认为这###1
被解释为##{#1}
。因此分别###1
扩展为##a
或##1
。第一个显然会失败,而第二个会编译但会导致意外结果。我xparse
也测试了 中的命令,问题似乎相同。
重新表述上面的问题:使用嵌套命令定义时,如何将###1
解释为 而{###1}
不是?为什么第一个例子中的 解释为而不是?##{#1}
##1
{##1}
#{#1}
我知道可以通过某种柯里化来避免第三级嵌套,如以下示例所示。
\documentclass{minimal}
\begin{document}
\newcommand{\one}[1]{%
\newcommand{\two}[1]{\helper{#1, ##1}}%
}
\newcommand{\helper}[1]{%
\newcommand{\three}[1]{%#1, ##1}%
}
\one{1} % First partial application
\two{b} % Second partial application by currying
\three{c}
\end{document}
对我来说,两次使用两级嵌套而不是一次使用三级嵌套似乎不太直观且更复杂,并且我想了解如何使用第三级嵌套。
答案1
#
在第二个嵌套级别中使用四个:
\documentclass{article}
\begin{document}
\newcommand{\one}[1]{%
\newcommand{\two}[1]{%
\newcommand{\three}[1]{#1, ##1, ####1}%
}
}
\one{a}
\two{b}
\three{c}
\end{document}
以下引自TeX 按主题分类给出解释(更多细节请参见11.5.5 宏参数字符):
当 TEX 的输入处理器扫描宏定义文本时,它会为任何出现宏参数字符后跟数字的情况插入一个参数标记。实际上,替换文本中的参数标记表示“在此处插入某某参数编号”。一行中的两个参数字符将被替换为一个参数字符。