我正在尝试定义我的pgfkeys
键树的子树,以便任何键、在该子树下的任何路径上都可以分配,而无需事先定义该键。
换句话说,我希望下面的任何路径/mykeys/
都可以分配而无需先前的定义,例如:
\pgfkeys{/mykeys/key=hello} % ok
\pgfkeys{/mykeys/nested/key=hello} % ok
\pgfkeys{/mykeys/any/arbitrarily/nested/key=hello} % still ok
最初的想法是安装一个.unknown
处理程序,用给定的值默默地初始化键并继续。然而,这种方法似乎只适用于树的第一层,IE对于上述示例的第一行。我还尝试使用.unknown
处理程序在未知密钥本身内安装.unknown
处理程序,但当密钥用作路径的一部分时,处理程序似乎不会被调用。
需要明确的是:我事先不知道将使用的关键路径:我需要它适用于内部的任何任意路径/mykeys
。
我尝试的代码如下:
\documentclass{article}
\usepackage{pgfkeys}
\newcommand\unknown[1]{%
\def\@key{\pgfkeyscurrentpath/\pgfkeyscurrentname}%
\pgfkeyssetvalue{\@key}{#1}%
\pgfkeys{\@key/.unknown/.code = {\unknown{#1}}}
}
\pgfkeys{
/mykeys/.unknown/.code = {\unknown{#1}}
}
\begin{document}
\section{Hello}
\pgfkeys{/mykeys/key=hello}
Value: \pgfkeysvalueof{/mykeys/key}
\pgfkeys{/mykeys/nested/key=hello}
Value: \pgfkeysvalueof{/mykeys/nested/key}
\end{document}
如您所见,第一次调用有效\pgfkeys
并\pgfkeysvalueof
返回正确的值,而第二次调用则没有。
我怎样才能达到预期的效果?
答案1
我很惊讶,因为我认为将您的密钥定义为:
\pgfkeys{/mykeys/.is family, /mykeys,
.unknown/.code = {
\pgfkeyssetvalue{\pgfkeyscurrentpath/\pgfkeyscurrentname}{#1}
}
}
会执行您想要的操作,但未知处理程序不会递归应用。似乎一种解决方法是覆盖通用.unknown
处理程序:
\documentclass{article}
\usepackage{pgfkeys}
\pgfkeys{/mykeys/.is family, /mykeys}
\pgfkeys{/handlers/.unknown/.code = {
\pgfkeyssetvalue{\pgfkeyscurrentpath/\pgfkeyscurrentname}{#1}
},
}
\begin{document}
\section{Hello}
\pgfkeys{/mykeys/key=hello}
Value: \pgfkeysvalueof{/mykeys/key}
\pgfkeys{/mykeys/nested/key=hello}
Value: \pgfkeysvalueof{/mykeys/nested/key}
\end{document}
这会产生想要的输出:
当然,现在每一个未知密钥将以这种方式设置,这可能会产生不良的副作用
答案2
我也一直在寻找解决同一问题的方法,但没有成功。
这似乎有效(没有经过非常彻底的测试,如果有人有更好的解决方案,我很乐意看到它)
\usepackage{xstring}
\pgfkeys{/handlers/.unknown/.code=
{%
\IfBeginWith{\pgfkeyscurrentkey}{/myprefix}{%
\pgfkeyssetvalue{\pgfkeyscurrentpath/\pgfkeyscurrentname}{#1}%
}{%
{Unknown key ‘\pgfkeyscurrentkey’.}%
}%
}%
}%