
(Isto é inspirado emProblema entre chaves, caminhos com duas macros e pgfkeys)
O seguinte código
\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}
produz erro
Erro do pacote pgfkeys: não conheço a chave '
/foo/fill
', para a qual você passou 'vermelho', e vou ignorá-la. Talvez você tenha escrito errado.
Isto não é surpreendente, porque não há nada abaixo /foo
.
O seguinte código
\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}
produz uma imagem com sucesso
Isso também não é surpreendente, porque /foo
tenta pesquisar fill
em /bar
e /tikz
e descobre que /tikz/fill
está definido.
O seguinte código
\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}
surpreendentemente, não produz nenhum erro, mas uma imagem ingénua.
Parece que /foo
pede /bar
para encontrar fill
abaixo /tikz
e eles obtiveram sucesso (portanto, nenhum erro). Mas, por alguma razão, o estilo não foi aplicado.
Por que isso está acontecendo? Posso de alguma forma fazer um destes acontecer:
- levantar um erro; ou
- aplique o estilo com sucesso; ou melhor ainda
- aplicar o estilo com sucesso e gerar um aviso?
Responder1
Se estou vendo isso corretamente, a verificação \ifpgfkeysaddeddefaultpath
executada no início do .unknown
código configurado por .search also
é alternada como falsa quando /foo/.unknown
as tentativas
\pgfqkeys{/bar}{fill=red}
o que faz com que você /bar/.unknown
não tente mais nada.
(Basicamente, essa é a diferença entre /bar/.cd, fill=red
e /bar/fill=red
onde o último é considerado correto e gera um erro proposital, apesar de uma .search also
alternativa.)
Não tenho paciência para ver por que isso acontece e onde isso acontece e se isso é mesmo um bug ou intencional, mas parece mais fácil configurar um .unknown
manipulador personalizado…
Depende apenas de como você deseja lidar com algumas coisas.
Como /tikz/.unknown
não faz a \ifpgfkeysaddeddefaultpath
verificação, não diferencia entre /tikz/.cd, <key>=<value>
e /tikz/<key>=<value>
. (Internamente, em vez de .cd
, muitas vezes o mais rápido \pgfqkeys{/tikz}{<key>=<value>}
é usado, mas é basicamente o mesmo.)
Porém, às vezes a <key>
é um estilo e então depende de qual caminho os executamos. Fazendo
\pgfkeys{/abc/.cd, /tikz/thick}
levará a um erro sobre uma chave desconhecida, /abc/line width
já que ainda estamos no /abc
caminho (bem, a menos que /abc/line width
seja definido, é claro, que será usado).
Isso me leva a um .unknown
manipulador que está muito próximo doexemplo do manual.
Infelizmente, /tikz/.unknown
não é definido \pgfkeyssuccesstrue
quando encontra uma cor, uma especificação de seta ou um nome de forma, o que torna difícil descobrir se /tikz/<key>
foi realmente bem-sucedido, o que significa que o mantenedor /foo
não pode gerar uma mensagem de erro adequada sem redefinir /tikz/.unknown
ou fazer o mesmo discurso em si.
Código
\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}