使用 pgfkeys 定义宏时发生名称冲突

使用 pgfkeys 定义宏时发生名称冲突

(请建议一个更好的标题!)

以下 LaTeX 文档定义了一个名为 的宏 /PrintStuff。此宏用于pgfkeys定义一个可选参数rowidstring。该宏\rowidstring@tables用于存储分配给该参数的值。

如果我将宏\rowidstring作为值传递给rowidstring 参数,则会收到以下错误。

! Use of \rowidstring doesn't match its definition.
\pgfkeys@code ... ->\edef \rowidstring @tables{#1}

\foobar例如,如果我使用,这个问题就会消失。

显然,TeX 对我使用相同的字符串\rowidstring 作为两个不同宏的名称的一部分感到不满,但除此之外,我不清楚问题是什么。

从技术上来说,这不是\rowidstring@tables两个\rowidstring不同的宏名吗?

在文档上运行跟踪会产生大量的输出,但我无法理解。

此外,在两个地方使用相同的字符串也很方便,就像我在这里做的那样。那么有没有一种解决方法可以让我做到这一点?

\documentclass[a4paper]{scrartcl}
\usepackage{pgf}

\pgfkeys
{
  /printstuff/.is family, /printstuff,
  default/.style =
  {
    rowidstring,
  },
  rowidstring/.estore in = \rowidstring@tables,
  rowidstring/.default = {},
}

\NewDocumentCommand{\PrintStuff}{O{}}
{
  \pgfkeys{/printstuff, default, #1}%
  \typeout{ROWIDSTRING is \rowidstring@tables}
}

\newcommand{\rowidstring}{id1,id2}
%\newcommand{\foobar}{id1,id2}

\begin{document}

\PrintStuff[rowidstring=\rowidstring]
%\PrintStuff[rowidstring=\foobar]

\end{document}

答案1

首先让我们来简化一下.estore in。你的密钥原则上与

\edef<macro>{<value>}

pgfkeys不检查是否<macro>真的是单个标记。 在您的例子中@是类别 12,因此您的rowidstring

\edef\rowidstring @tables{<value>}

如果您使用它,您定义一个\rowidstring具有参数模式的宏@tables(因此期望紧随其后的文字输入)。

每次调用时,default\edef\rowidstring @tables{}都会定义宏以期望输入@tables并扩展为空。当您在代码中使用它时,一切都很好,因为您使用的 后面\rowidstring通常会跟着@tablesin \PrintStuff(因为您最初想使用控制字\rowidstring@tables)。

现在,你打破了\PrintStuff[rowidstring=\rowidstring]你隐含地做的事情

\edef\rowidstring @tables{} % the effect of `default`
\edef\rowidstring @tables{\rowidstring}

第一个用\newcommand{\rowidstring}{id1,id2}宏覆盖了你的,期望后面跟着@tables。第二个然后使用这个宏,但它后面跟着}而不是@tables。TeX 尝试在 中扩展它\edef,但无法扩展并抛出错误

! Use of \rowidstring doesn't match its definition.

相关内容