经过大量的反复试验后,我仍然无法解决以下问题:
简化版本:我想使用 \g@addto@macro 将代码添加到另一个将使用该宏的命令的宏中,我希望此代码能够起作用:
\newcommand{\foo}[1]{#1, }
\newcommand{\bar}[1]{
\g@addto@macro\foo{
##1#1
}
}
并产生这个输出:
\foo{A} -> A,
\bar{B}
\show\foo = #1, #1B
\foo{A} -> A, AB
\bar{C}
\show\foo = #1, #1B#1C
\foo{A} -> A, ABAC
我希望我想要的很清楚。在实际实现中,我想动态扩展类似 \switch 的结构。代码的问题是,在添加代码时,##
不会扩展为,而是扩展为 的第一个参数。这导致#
#1
\bar
\bar{B}
\show\foo = #1, ##1B
反过来,这不会产生所需的输出。如果可能的话,我想避免使用额外的软件包。
答案1
\g@addto@macro
使用令牌寄存器来停止#
您想要的解释。
你只是想要\def
。
\documentclass{article}
\begin{document}
\newcommand{\foo}[1]{#1, }
\def\zfoo#1\relax{\long\def\foo##1{#1}}
\newcommand{\baR}[1]{%
\expandafter\zfoo\foo{##1}##1#1\relax
}
\foo{A}
\show\foo
\baR{B}
\show\foo %= #1, #1B
\foo{A} %-> A, AB
\baR{C}
\show\foo% = #1, #1B#1C
\foo{A} %-> A, ABAC
\end{document}
产生
> \foo=\long macro:
#1->#1, .
l.13 \show\foo
?
> \foo=\long macro:
#1->#1, #1B.
l.17 \show\foo
%= #1, #1B
?
> \foo=\long macro:
#1->#1, #1B#1C.
l.22 \show\foo
% = #1, #1B#1C
?
答案2
不可以,您不能使用 将标记附加到带有参数的宏\g@addto@macro
。您也不能使用 来做到这\apptocmd
一点etoolbox
。
不过,您可以使用 来完成regexpatch
。
\documentclass{article}
\usepackage{regexpatch}
\newcommand{\foo}[1]{#1,\space}
\newcommand{\baz}[1]{%
\def\temp{#1}%
\regexpatchcmd{\foo}{ \Z }{ \cP\#1 \u{temp} }{}{}%
}
\begin{document}
\foo{A}
\baz{B}\foo{A}
\baz{C}\foo{A}
\end{document}
“搜索”正则表达式匹配替换文本的结尾;它被替换为\cP\#1
(这意味着#1
用正确的类别代码),然后是宏的扩展\temp
。因此我将\temp
其设置为参数\baz
。
不幸的是,当前版本regexpatch
无法修补替换文本以空格结尾的宏,所以在这个特殊情况下,我\space
在开始时使用了。
输出如下: