(这是受到启发键、具有两个宏的路径和 pgfkeys 之间的问题)
下面的代码
\documentclass[tikz]{standalone}
\begin{document}
\pgfkeys{
%/foo/.search also={/bar,/tikz},
%/foo/.search also={/bar},
/bar/.search also={/tikz}
}
\tikz\draw[/foo/.cd,fill=red]circle(1);
\end{document}
产生错误
程序包 pgfkeys 错误:我不知道
/foo/fill
您传递了“red”的键“ ”,我将忽略它。也许您拼错了。
这并不奇怪,因为 下面什么都没有/foo
。
下面的代码
\documentclass[tikz]{standalone}
\begin{document}
\pgfkeys{
/foo/.search also={/bar,/tikz},
%/foo/.search also={/bar},
/bar/.search also={/tikz}
}
\tikz\draw[/foo/.cd,fill=red]circle(1);
\end{document}
成功生成图片
这也不足为奇,因为/foo
尝试fill
在/bar
和下搜索/tikz
,会发现已/tikz/fill
定义。
下面的代码
\documentclass[tikz]{standalone}
\begin{document}
\pgfkeys{
%/foo/.search also={/bar,/tikz},
/foo/.search also={/bar},
/bar/.search also={/tikz}
}
\tikz\draw[/foo/.cd,fill=red]circle(1);
\end{document}
令人惊讶的是,它没有产生任何错误,而只产生了一幅幼稚的图像。
似乎/foo
要求在 下/bar
查找,并且成功(因此没有错误)。但由于某种原因,样式未能应用。fill
/tikz
为什么会发生这种情况?我能以某种方式实现以下其中之一吗:
- 引发错误;或
- 成功运用风格;甚至更好
- 成功应用样式并发出警告?
答案1
如果我没看错的话,在代码开始\ifpgfkeysaddeddefaultpath
时执行的检查在尝试时被切换为 false.unknown
.search also
/foo/.unknown
\pgfqkeys{/bar}{fill=red}
这使得他们/bar/.unknown
不再尝试其他任何事情。
/bar/.cd, fill=red
(基本上,这就是和之间的不同之处/bar/fill=red
,后者被认为是正确的,但尽管有其他选择,却故意引发错误.search also
。)
我没有耐心去研究为什么会发生这种情况、在哪里发生以及这是否是一个错误或故意为之,但设置自定义.unknown
处理程序似乎更容易……
这只是取决于你想如何处理某些事情。
由于/tikz/.unknown
不进行\ifpgfkeysaddeddefaultpath
检查,因此它不区分/tikz/.cd, <key>=<value>
和。(在内部,通常使用更快的/tikz/<key>=<value>
而不是,但这基本上是相同的。).cd
\pgfqkeys{/tikz}{<key>=<value>}
然而,有时 a<key>
是一种风格,然后它取决于我们执行它们的路径。做
\pgfkeys{/abc/.cd, /tikz/thick}
将导致有关未知密钥的错误,/abc/line width
因为我们仍然在/abc
路径中(当然,除非/abc/line width
定义了,否则将会使用)。
这让我想到了一个.unknown
非常接近手册示例。
不幸的是,当它找到颜色、箭头规范或形状名称时,它/tikz/.unknown
没有设置,这使得很难确定是否真的成功,这意味着维护者无法在不重新定义或执行相同操作的情况下引发正确的错误消息。\pgfkeyssuccesstrue
/tikz/<key>
/foo
/tikz/.unknown
代码
\documentclass[tikz]{standalone}
\begin{document}
\pgfkeys{
/bar/.search also=/tikz, % this can stay, I guess
/foo/.unknown/.code=
\ifpgfkeysaddeddefaultpath
\let\unknownname\pgfkeyscurrentname
\pgfkeysalso{
/bar/\unknownname/.try={#1}, % only try /tikz if /bar failed
/tikz/\unknownname/.lastretry={#1}}%
% Ugh! /tikz/.unknown doesn't set \pgfkeyssuccesstrue
% after it handles a color, an arrow specification or a shape's name
% then this will be annoying:
\unless\ifpgfkeyssuccess
\errmessage{Well, I couldn't find /foo/\unknownname={#1},
/bar/\unknownname={#1} and /tikz/\unknownname={#1}.
I don't know what you want from me.}%
\fi
\else % someone tried to do /foo/<unknown key>, let's fail:
\errmessage{myPackage: /foo/\pgfkeyscurrentname\space is an unknown key.}%
\fi
}
\tikz[radius=1]{
\draw[/bar/.cd, fill=red] circle[];
\draw[/bar/fill=red] (right:1) circle[];% will always fail
\draw[/foo/.cd, fill=red] (right:2) circle[];
\draw[/foo/fill=red] (right:3) circle[];% will always fail
}
\tikz{
\draw[/bar/.cd, inner xsep=0+0] node {\pgfkeysvalueof{/pgf/inner xsep}};
\draw[/foo/.cd, ->] (right:1) -- +(right:.5); % Ugh!
\draw[/foo/.cd, red!50] (right:2) -- +(right:.5); % Ugh!
\draw[/foo/.cd, circle] (right:3.5) node[draw]{}; % Ugh!
\draw[/foo/.cd, thick] (right:4) -- +(right:.5);% finds /tikz/thick but then
% has to try /foo/line width
% and then /bar/line width and
% then finally /tikz/line width
}
\pgfkeys{/tikz/.cd, abc}% → unknown /tikz/abc
\pgfkeys{/bar/.cd, abc} % → unknown /tikz/abc
\pgfkeys{/foo/.cd, abc} % → unknown /foo/abc, /bar/abc, /tikz/abc
\end{document}