我不明白“...不符合其定义”的问题

我不明白“...不符合其定义”的问题

我设法从我的代码中提取了以下 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模块。]

相关内容