基于早期版本如何向宏中添加单个花括号?,我尝试了以下方法,将内部命令逐个添加到某些外部命令中。(我这样做的原因是我不知道何时到达最后一个元素,序列的每一步都必须是有效的代码。)但是,虽然第一次替换有效,但第二次替换无效,而且我并没有真正看到区别:
\documentclass{article}
\usepackage{regexpatch}
\newcommand{\addinnertoouter}[1]{
\regexpatchcmd{\test}
{ \c{outer} \{ (.*) \} \Z}
{ \c{outer} \cB\{ \1 \c{inner} \cB\{ #1 \cE\} \cE\} }
{}{error}
}
\begin{document}
\ttfamily
\def\test{\outer{\inner{abc}}}
\meaning\test
\addinnertoouter{def}
\meaning\test
\addinnertoouter{ghi}
\meaning\test
\end{document}
答案1
直接使用l3regex
就可以\regexpatchcmd
了:
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand \addinnertoouter { m }
{
\regex_replace_once:nnNTF
{ \c{outercmd} \{ (.*) \} \Z}
{ \c{outercmd} \cB\{ \1 \c{inner} \cB\{ #1 \cE\} \cE\} }
\test
{ }
{ error }
}
\ExplSyntaxOff
\begin{document}
\ttfamily
\def\test{\outercmd{\inner{abc}}}
\meaning\test
\addinnertoouter{def}
\meaning\test
\addinnertoouter{ghi}
\meaning\test
\end{document}
(\outer
是一种(非常特殊的) TeX 原语,因此最好使用其他东西。)
问题是,它l3regex
显然使添加的def
标记 catcode 为 12(在我看来是个错误;我会召唤一个向导来检查),当\regexpatchcmd
尝试重新标记它们时,它们会变成 catcode 11,并且\regexpatchcmd
认为(正确地)该宏无法修补。如果您不介意插入的标记是 catcode 12(在这种情况下可能无关紧要),那么\regex_replace_once:nnNTF
它将满足您的需求。
请注意,你的参数\addinnertoouter
仍然是一个正则表达式,因此如果你这样做,\addinnertoouter{\textit{jkl}}
输出将不是你所期望的。你可以使用的\u
功能l3regex
来添加任意的标记列表(无需更改 catcode,因此它也适用于\regexpatchcmd
):
\documentclass{article}
\usepackage{regexpatch}
\ExplSyntaxOn
\tl_new:N \l_bers_tmpa_tl
\NewDocumentCommand \addinnertoouter { m }
{
\tl_set:Nn \l_bers_tmpa_tl {#1}
\regexpatchcmd
\test
{ \c{outercmd} \{ (.*) \} \Z}
{ \c{outercmd} \cB\{ \1 \c{inner} \cB\{ \u{l_bers_tmpa_tl} \cE\} \cE\} }
{ }
{ error }
}
\ExplSyntaxOff
\begin{document}
\ttfamily
\def\test{\outercmd{\inner{abc}}}
\meaning\test
\addinnertoouter{def}
\meaning\test
\addinnertoouter{ghi}
\meaning\test
\addinnertoouter{\textit{jkl}}
\meaning\test
\end{document}
答案2
菲利佩·奥莱尼克已经描述过catcode 的问题发生了变化\regexpatchcmd
,所以我在这里跳过解释部分... 也可以通过替换以下行来修复此问题
{ \c{outer} \cB\{ \1 \c{inner} \cB\{ #1 \cE\} \cE\} }
经过
{ \c{outer} \cB\{ \1 \c{inner} \cB\{ \cL(#1) \cE\} \cE\} }
在您的原始代码中,正确给出
答案3
您可以使用以下\u
功能l3regex
:
\documentclass{article}
\usepackage{regexpatch}
\newcommand{\addinnertoouter}[1]{%
\def\berstemp{#1}%
\regexpatchcmd{\test}
{ \c{outer} \{ (.*) \} \Z}
{ \c{outer} \cB\{ \1 \c{inner} \cB\{ \u{berstemp} \cE\} \cE\} }
{}{error}
}
\begin{document}
\ttfamily
\def\test{\outer{\inner{abc}}}
\meaning\test
\addinnertoouter{def}
\meaning\test
\addinnertoouter{ghi}
\meaning\test
\end{document}