-
Notifications
You must be signed in to change notification settings - Fork 113
Description
Brief outline of the bug
With /handler config=full or existing, an assignment like key/.style={stuff} should only set the style if key exists in the current path or somewhere in the search paths set with .search also. However, when one or more paths are passed to .search also, and key does not exist in the current path, key/.style={stuff} will always be executed it in the first search path, regardless of whether it exists there or not. It will never fail, like it should when the key on which the handler is called does not exist.
In the example below, the first case (with color=green) appears to work. The style every foo is set in /main path, because the style did not exist in /second path. However, in the second example you can see it fail: every foo is set in /third path although it did not exist there before, despite the handler config.
Cause of the bug
If you look at the log file, you can see the cause of the issue (thanks to the patched commands):
.search alsoexecutes\pgfqkeys{/third path}{every foo/.style/.try/.expand once=value}(defined in\pgfkeys@searchalso@appendentry).\pgfkeys@add@path@as@neededprepends/third pathand sets\ifpgfkeysaddeddefaultpath=\iftrue(in\pgfkeys@addpath).\pgfkeys@ifexecutehandler@handlefullorexistingexecutes.expand oncebecause it exempt from/handler config..expand onceexecutes\pgfkeysalso{/third path/every foo/.style/.try=value}.\pgfkeysalsocalls\pgfkeys@add@path@as@needed, which sees an absolute path and sets\ifpgfkeysaddeddefaultpath=\iffalse(in\pgfkeys@nevermind)..trycalls\pgfkeys@ifexecutehandler@handlefullorexistingwith\pgfkeyscurrentpath=/third path/every foo/.style, which succeeds because\ifpgfkeysaddeddefaultpathis false.
Log file excerpt:
[...]
pgfkeys@addpath: every foo/.style
pgfkeys@addpath: every foo/.style/.try/.expand once
pgfkeysalso: /third path/every foo/.style/.try={color=blue}
pgfkeys@nevermind: /third path/every foo/.style/.try
/third path/every foo/.style={color=blue}
pgfkeys@nevermind: /third path/every foo/.code
[...]
Minimal working example (MWE)
\documentclass{article}
\usepackage{pgfkeys}
\pgfkeys{
/main path/foo/.code={\{\pgfkeysalso{/main path/every foo} foo\}},
/main path/every foo/.style={color=red}, % It even works if this is commented out
/main path/color/.code=color\{#1\},
/handler config=full or existing,
}
\usepackage{etoolbox}
\makeatletter
\pretocmd\pgfkeys@nevermind{
\immediate\write16{pgfkeys@nevermind: \detokenize{#1}}
}{}{}
\pretocmd\pgfkeys@addpath{
\immediate\write16{pgfkeys@addpath: \detokenize{#1}}
}{}{}
\pretocmd\pgfkeysalso{
\immediate\write16{pgfkeysalso: \expandafter\expandafter\expandafter\detokenize\expandafter\expandafter\expandafter{#1}}
}{}{}
\pgfkeys{/handlers/.style/.code=\immediate\write16{\pgfkeyscurrentpath/.style={#1}}\pgfkeys{\pgfkeyscurrentpath/.code=\pgfkeysalso{#1}}}
\makeatother
\begin{document}
\pgfkeys{
/second path/.cd,
/second path/.search also={/main path},
every foo/.style={color=green}, % no 'every foo' in /second path
foo
}
This worked, foo is green, not red
\pgfkeys{
/second path/.cd,
/second path/.search also={/third path, /main path},
every foo/.style={color=blue},
foo
}
This failed, foo is still green, not blue
\end{document}