在宏调用中重新定义宏时,出现 \reserved@a' 错误定义中的非法参数编号

在宏调用中重新定义宏时,出现 \reserved@a' 错误定义中的非法参数编号

以下示例在简化过程中已基本脱离了其原始上下文。

如果使用 编译此 LaTeX 文件pdflatex parameternum.tex,则可得到

! Illegal parameter number in definition of \reserved@a.

该文件的结构长期以来一直保持不变。但是,我最近才添加了\IfFileExists\PackageError 的使用\foo,这让它变得很庞大。如果只是使用

\NewDocumentCommand{\foo}{m +m}
{
  #2
}

没有错误。同样,如果漏掉了

\renewcommand{\nextnuml}[1]{\refstepcounter{tabenum}\thetabenum.\label{\theletternum:#1}}

从对 的调用中的第二个参数开始\foo,错误消失。这两个更改有所不同,但它们都涉及参数字符。

或者,保留该行,但将参数字符从 # 加倍为 ## 也可以消除错误。即

\renewcommand{\nextnuml}[1]{\refstepcounter{tabenum}\thetabenum.\label{\theletternum:##1}}

这看起来类似于在另一个宏的定义中定义一个宏需要将参数字符加倍的情况,并且错误也类似。但据我所知,这是在宏调用中(重新)定义宏,所以不是一回事。

正如前面所说,将参数字符加倍可以解决错误,但我当然想知道这里发生了什么。

运行跟踪并没有给我带来启发,尽管它确实产生了

<argument> ...etabenum .\label {\theletternum :##1
                                                  }} Text
\reserved@a #1#2->#1

文件如下。

% 12pt default for scrlttr2
\documentclass{scrlttr2}
\newcommand{\nextnuml}[1]{\refstepcounter{tabenum}\thetabenum.\label{#1}}

% \NewDocumentCommand{\foo}{m +m}
% {
%   #2
% }

\NewDocumentCommand{\foo}{m +m}
{
 \IfFileExists{./#1}{
   #2
 }{\PackageError{foo}{CONFIG FILE '#1' DOES NOT EXIST - NOT CREATING FORMLETTER}{Check that the config filename  (first argument) has been correctly passed to \formletter}}
}

% Parameters for document commands
\newcommand{\addressesconfigfilename}{formletterbug.addresses.yaml}

\begin{filecontents}[overwrite,noheader]{\addressesconfigfilename}
foo
\end{filecontents}

\begin{document}
\newcounter{letternum}
\foo{\addressesconfigfilename}
{
  \stepcounter{letternum}
  \renewcommand{\nextnuml}[1]{\refstepcounter{tabenum}\thetabenum.\label{\theletternum:#1}}
  Text
}
\end{document}

PS. 当我发布这篇文章的时候,\IfFileExists 后面的“\reserved@a 定义中的参数编号非法”出现了类似的问题。因为这也涉及到\IfFileExists它可能相关。虽然我不明白 Phelype 的回答。

\IfFileExists 的工作方式与“通常”的条件不同:它将真和假分支存储在宏中,并在稍后使用它们。

请提供更多详细信息。这是否相当于在另一个宏中定义一个宏?如果不是,为什么需要加倍?

答案1

您正在路过

\stepcounter{letternum}
  \renewcommand{\nextnuml}[1]{\refstepcounter{tabenum}\thetabenum.\label{\theletternum:#1}}
  Text

作为参数放入\IfFileExists并如另一个问题所述,然后它会窒息#1

您可以改用间接寻址:

\makeatletter
\NewDocumentCommand{\foo}{m +m}
{
 \IfFileExists{./#1}
  {\@firstoftwo}
  {\@secondoftwo}
  {#2}
  {\PackageError{foo}{CONFIG FILE '#1' DOES NOT EXIST - NOT CREATING FORMLETTER}{Check that the config filename  (first argument) has been correctly passed to \formletter}}
}

或者使用 L3 命令:

\ExplSyntaxOn
\NewDocumentCommand{\foo}{m +m}
{
 \file_if_exist:nTF
  {./#1}
  {#2}
  {\PackageError{foo}{CONFIG~FILE~'#1'~DOES~NOT~EXIST}{}}
}
\ExplSyntaxOff

相关内容