最近我发现了一段代码(来自ucharclasses
),使用了三个与扩展相关的宏\noexpand
、\unexpanded
和\expandafter
:
\def\do#1{\noexpand\setTransitionsFor{#1}{####1}{####2}}
\def\doclass#1{
\begingroup\edef\x{\endgroup
\noexpand\newcommand
\unexpanded\expandafter{\csname setTransitionsFor#1\endcsname}[2]%
{\csname #1Classes\endcsname}}\x}
\ClassGroups
我可以找到一些关于这些宏的参考资料,但我仍然不明白它们到底在做什么。我想知道为什么它们在上面的代码中是必要的,以及为什么我们需要像和中那样的四个升####1
号####2
。
答案1
\do
表演\noexpand
和##
\def\do#1{\noexpand\setTransitionsFor{#1}{####1}{####2}}
\edef\z{\do{abc}}
\show\z
由此可见
> \z=macro:
->\setTransitionsFor {abc}{##1}{##2}.
l.4 \show\z
因此,您会看到,在定义csname\z
时,它被阻止扩展,被替换为此处的参数,并被替换为\edef
\setTransitionsFor
\noexpand
#1
\do
abc
##
#
对于第二个宏,添加\show\x
然后使用 pdflatex 运行此片段
\def\doclass#1{
\begingroup\edef\x{\endgroup
\noexpand\newcommand
\unexpanded\expandafter{\csname setTransitionsFor#1\endcsname}[2]%
{\csname #1Classes\endcsname}}%
\show\x
\x}
\doclass{abc}
生产
> \x=macro:
->\endgroup \newcommand \setTransitionsForabc [2]{\abcClasses }.
\doclass ...csname #1Classes\endcsname }}\show \x
\x
l.9 \doclass{abc}
? x
因此\show
临时宏\x
将被执行并相当于
\newcommand \setTransitionsForabc [2]{\abcClasses }
abc
因此传递给的字符串\doclass
已用于构造命令名\setTransitionsForabc
和\abcClasses