(编辑:我原来的例子过于简单;这里有一个更准确的版本。)
我想遍历表示 PGF 键的字典式结构中的所有名称。我想将一些代码与所有这些键关联起来。以下是演示此问题的示例:
\documentclass{minimal}
\usepackage{pgfkeys}
\newcounter{traversed}
\newcommand{\traverse}[1]{
\pgfkeyscurrentkey{}/.begin overlay,
{
\pgfkeysalso{
\pgfkeyscurrentname/.cd,
.unknown/.code={\traverse{##1}},
#1
}
}
\pgfkeyscurrentkey{}/.end overlay,
}
\pgfkeys{
/handlers/.begin overlay/.code={%
\stepcounter{traversed}
\pgfkeysedef{\pgfkeyscurrentpath}{\arabic{traversed}}
},
/handlers/.end overlay/.code={
\pgfkeysedef{\pgfkeyscurrentpath/last}{\arabic{traversed}}
},
/traverse/.is family,
/traverse/.unknown/.code={\traverse{#1}},
}
\begin{document}
\pgfkeys{/traverse,a={b,c},d={e,f}}
% \pgfkeys{\pgfkeys{/traverse,a={b,c},d={e,f}}}
\end{document}
如果我运行这个文档,它的内容是
/traverse/a/.begin overlay,
/traverse/a/b/.begin overlay,
/traverse/a/b/.end overlay,
/traverse/a/c/.begin overlay,
/traverse/a/c/.end overlay,
/traverse/a/.end overlay,
/traverse/d/.begin overlay,
/traverse/d/e/.begin overlay,
/traverse/d/e/.end overlay,
/traverse/d/f/.begin overlay,
/traverse/d/f/.end overlay,
/traverse/d/.end overlay,
如果我\pgfkeys
直接调用此输出,则键将使用预期值进行定义。例如,
\pgfkeys{
/traverse/a/.begin overlay,
/traverse/a/b/.begin overlay,
/traverse/a/b/.end overlay,
/traverse/a/c/.begin overlay,
/traverse/a/c/.end overlay,
/traverse/a/.end overlay,
/traverse/d/.begin overlay,
/traverse/d/e/.begin overlay,
/traverse/d/e/.end overlay,
/traverse/d/f/.begin overlay,
/traverse/d/f/.end overlay,
/traverse/d/.end overlay,
}
\pgfkeys{/traverse/a}
在最终文档中生成 1。但是,如果我取消注释第一个代码片段中的注释行,TeX 会运行空间不足。我还尝试使用\edef
存储第一次调用的结果,\pgfkeys
然后再将此结果传递给第二次调用。但这会导致 TeX 进入无限循环。
关于如何运行第一次调用的结果有什么想法\pgfkeys
吗?
答案1
您在 周围创建了一个额外的组\pgfkeysalso
,因此设置键的效果仅限于该组内。如果您删除额外的组,错误就会消失,输出也会如您所愿。
\documentclass{article}
\usepackage{pgfkeys}
\pgfkeys{
/handlers/.traverse/.code={%
\pgfkeysalso{
\pgfkeyscurrentpath/.code={Some code}
}
traverse \pgfkeyscurrentpath{} \\
},
/traverse/.is family
}
\begin{document}
\pgfkeys{/traverse/1/.traverse}
\pgfkeys{/traverse/1}
\end{document}
但除特殊情况外,您不应使用\\
它来结束一行。此外,minimal
尽管名称如此,但它并不适合极简示例。