我设法从我的代码中提取了以下 MnWE,它显示了我遇到的问题:
示例 1
\begin{document}
\newcommand{\createDATA}[1]{
\xdef\DATA{}
\newcommand{\test}[2][]{
\xdef\DATA{\DATA args=##1 , ##2 }
}
\test[x]{\macom[x]{blabla}}
}
\newcommand{\macom}[2][q]{AAA}
\createDATA
\DATA
\end{document}
编译时出现错误 :! Use of \\test doesn't match its definition.
我无法理解。另一方面,请注意,如果在 I 的定义中用没有可选参数的命令 \createDATA
替换,则它会起作用:\macom
示例 2
\begin{document}
\newcommand{\createDATA}[1]{
\xdef\DATA{}
\newcommand{\test}[2][]{
\xdef\DATA{\DATA args=##1 , ##2 }
}
\test[x]{\macomm{blabla}}
}
\newcommand{\macomm}[1]{BBB}
\createDATA
\DATA
\end{document}
对我来说这很神秘...
答案1
您正在尝试\edef
( \xdef
= \global\edef
) 宏\macom
。但是,由于是\macom
带有可选参数的命令,因此无法安全地执行此操作。您需要不执行\edef
,而是使用 LaTeX 保护机制:
\documentclass{article}
\begin{document}
\makeatletter
\newcommand{\createDATA}[1]{%
\xdef\DATA{}%
\newcommand{\test}[2][]{%
\protected@xdef\DATA{\DATA args=##1 , ##2 }%
}%
\test[x]{\macom[x]{blabla}}%
}
\makeatother
\newcommand{\macom}[2][q]{AAA}
\createDATA
\DATA
\end{document}
或者\macrom
使用 e-TeX 扩展使引擎更加强大,例如
\documentclass{article}
\usepackage{etoolbox}
\begin{document}
\newcommand{\createDATA}[1]{%
\xdef\DATA{}%
\newcommand{\test}[2][]{%
\xdef\DATA{\DATA args=##1 , ##2 }%
}%
\test[x]{\macom[x]{blabla}}%
}
\newrobustcmd{\macom}[2][q]{AAA}
\createDATA
\DATA
\end{document}
(顺便说一句,你的命令中有很多多余的空格:我已添加%
以删除行尾并处理这些问题。)
有关坚固、受保护和“脆弱”的含义的更多信息,请参阅脆弱命令和坚固命令之间有什么区别?
不能使用带有可选参数的命令的原因\edef
是,这些参数是使用 TeX 原语获取的\futurelet
。这会执行分配,而分配是不可扩展的。另一方面,获取强制参数不需要任何技巧,因此它是可扩展的。
[这比这更复杂一些,因为有多种可扩展测试可选参数的方法。这些方法比不可扩展的方法更具限制性,因此 LaTeX2e 内核采用了全面但不可扩展的方法。有关可扩展和不可扩展可选参数抓取的预构建方法,以及自动强大的功能和许多额外的巧妙之处,请参阅 LaTeX3xparse
模块。]