在理想世界中乳胶化此文档
\documentclass{article}
\usepackage{tikz}
\begin{document}
\pgfkeys{/a/.code=(a)}
\pgfkeys{/a}
\def\b{\pgfkeys{/a}}
\b
\edef\c{\pgfkeys{/a}}
\c
\end{document}
将创建一个包含“(a)(a)(a)”的文档...但在现实世界中,行“\edef\c{\pgfkeys{/a}}”会使 PGF 陷入循环,如果我用 Cc 中断 pdflatex 或 lualatex,我会收到以下消息:
! Interruption.
\pgfkeys@parse ...uturelet \pgfkeys@possiblerelax
\pgfkeys@parse@main
l.33 \edef\c{\pgfkeys{/a}
}
?
推荐的解决方法是什么?
注意:这是另一个问题的最小版本:如何将 \pgfkeys 的结果发送给 Lua?
答案1
\pgfkeys
不可扩展。没有办法让你\edef
工作。
expkv 包提供了可扩展的键值命令。有了它,您的示例就可以运行:
\documentclass{article}
\usepackage{expkv}
\begin{document}
\ekvdefNoVal{fam}{a}{(a)}
\ekvset{fam}{a}
\def\b{\ekvset{fam}{a}}
\b
\edef\c{\ekvset{fam}{a}}
\c
\end{document}
但请注意,这很大程度上取决于您按键的实际操作。如果您的代码执行的操作比打印更复杂,(a)
如果您没有妥善保护它,它可能会再次崩溃。
答案2
正如我所解释的别的地方宏\pgfkeys
及其派生函数的作用远不止调用.code
您所定义的函数。
当 PGFkeys 完成键值对的解析时,您将必须使用它实际调用的内部宏:
\edef\c{\pgfkeysvalueof{/a/.@cmd}\pgfeov}
(每个键在内部被定义为由分隔的.code
宏,这是一种调用的奇特方式。)\pgfk@/full/path to/key/.@cmd
\pgfeov
\pgfkeysvalueof
\csname pgfk@#1
如果你需要经常使用它,你可能需要定义自己的宏\pgfkeyscall
:
\newcommand\pgfkeyscall[2]{\pgfkeysvalueof{#1/.@cmd}#2\pgfeov}
然后你可以使用它作为
\edef\c{\pgfkeyscall{/a}{}}
不过,在这个简单的/b
不做任何事情的情况下,您可能只想使用一个值键,它只存储内容,也可以通过使用完全扩展\pgfkeysvalueof{/b}
(它应该能够在不进行定义的情况下转发到 Lua)。
\pgfkeys{/b/.initial=(b)}
\edef\c{\pgfkeysvalueof{/b}}
\c
% or
\pgfkeysgetvalue{/b}\c % no edef
\c
代码
\documentclass{article}
\usepackage{pgfkeys}
\newcommand\pgfkeyscall[2]{\pgfkeysvalueof{#1/.@cmd}#2\pgfeov}
\pgfkeys{
/a/.code=(a),
/b/.initial=(b)}
\begin{document}
\pgfkeys{/a,/b}
\edef\c{\pgfkeyscall{/a}{}}%
\c
\pgfkeysgetvalue{/b}\c
\c
\end{document}
输出
(一)(二)
(一)(二)
答案3
以下答案是错误的,请参阅这个问题和答案为什么以及如何。
原答案在这里:
我假设您要做的就是将其设置\c
为与 的扩展具有相同的值\pgfkeys{/a}
,但这样做\edef
会导致无限循环(比我更有经验的人可能会告诉您原因)。
以下作品(空格可能不太正确,你可以根据需要调整和摆弄)
\documentclass{article}
\usepackage{tikz}
\begin{document}
\pgfkeys{/a/.code=(a)}
\pgfkeys{/a}
\def\b{\pgfkeys{/a}}
\b
\expandafter\def\c{\pgfkeys{/a}}
\c
\end{document}
结果是(a) (a) (a)
(我的 PDF 似乎第一个和第二个之间的空间比第二个和第三个之间的空间更大,这就是为什么您可能需要在某个地方进行调整。我不知道在哪里。%
适当地在行尾撒点东西可能会解决这个问题。)