Closed schtandard closed 3 years ago
Hi @schtandard. When you write
\pgfkeys{/main path/.cd,/main path/option=value}
you are actually creating a key with full path /main path/main path/option=value
because of the first /main path/.cd
. If you instead use
\pgfkeys{/main path/.cd,bla=value}
then the handler should work. This is also mixed up with the fact that you can directly set a key with a value regardless of its existence. Hence you have to invoke the right key family for the search.
No, when \tracingall
the log shows that the key /main path/option
is being set. Unfortuantely I don't know how to fix it yet. The code is a real mess.
Ah I missed the initial /
. But setting value behavior change means breaking a lot of code so I don't think you have too many options.
This problem was introduced by https://github.com/pgf-tikz/pgf/commit/96e02db761b56e7ceb2d827a93b9100cbafd1855#diff-066476085e65c7869b9a0620c8c56f1a in 2013, using the code from patch #19 on sourceforge. That patch aimed to allow unbalanced \if
in key values.
The key is the following change made by that commit, in definition of \pgfkeys@searchalso@prepare@unknown@handler
,
+ \toks1={\def\pgfutilnext{\pgfkeysvalueof{/handlers/.unknown/.@cmd}##1\pgfeov}\pgfutilnext}%
- \toks1={\pgfkeysalso{/handlers/.unknown/.@cmd/.expand once=\pgfkeys@searchalso@temp@value}}%
#1
of \pgfkeys@searchalso@prepare@unknown@handler
is stored in \pgfkeys@searchalso@temp@value
. \pgfkeysalso{/handlers/.unknown/.@cmd/.expand once=\pgfkeys@searchalso@temp@value}
is used when unknown full key is encountered. But that code actually redefines /handlers/.unknown/.@cmd
. This leads to the nothing-happened problem. Removing /.@cmd
solves the problem.\pgfkeysalso{/handlers/.unknown/.expand once=\pgfkeys@searchalso@temp@value}
.
\pgfkeysalso
parses its key-list argument and updates all current-key macros, for example \pgfkeyscurrentkeyRAW
. This updating makes \pgfkeys{/main path/.cd,/main path/option=value}
produce text Found unknown option /handlers/.unknown=value!
, while the expected output is Found unknown option /main path/option=value!
.\toks1
is used in \noexpand\else\the\toks1 \noexpand\fi
, I use some tricks to expand the trailing \fi
first. See the following full example.Full example
\documentclass{article}
\usepackage{pgfkeys}
\usepackage{xpatch}
\makeatletter
\xpatchcmd\pgfkeys@searchalso@prepare@unknown@handler
{\toks1={\pgfkeysalso{/handlers/.unknown/.@cmd/.expand once=\pgfkeys@searchalso@temp@value}}}
{%
\toks1={%
\pgfkeysgetvalue{/handlers/.unknown/.@cmd}{\pgfkeys@code}%
% trick:
% to allow unbalanced \if values (stored in \pgfkeys@searchalso@temp@value),
% expand the \fi right after "\the\toks1 " first, see below
\expandafter\expandafter\expandafter\pgfkeys@code\expandafter\pgfkeys@searchalso@temp@value\expandafter\pgfeov
}%
}
{}{\fail}
\makeatother
\begin{document}
\parindent=0pt
\subsection*{Test issue \#671, \texttt{.search also} with unknown full key}
% define a key:
\pgfkeys{/secondary path/option/.code={Invoking /secondary path/option with ‘#1’}}
% set up a search path:
\pgfkeys{/main path/.search also={/secondary path}}
% try searching for ‘option=value’ in ’/main path’:
% -> this finds ‘/secondary path/option’!
\pgfkeys{/main path/.cd, option=value}
% negative example:
% try searching for fully qualified key /main path/option.
% This won’t be handled by .search also.
\pgfkeys{/handlers/.unknown/.code={Found unknown option \pgfkeyscurrentkeyRAW={#1}!}}%
\pgfkeys{/main path/.cd, /main path/option=value}
\subsection*{Test patch \#19, unbalanced \texttt{\char`\\if} values}
% example is from https://sourceforge.net/p/pgf/patches/19/
\pgfkeys{
rules/.cd,
define rule/.code={DEFINING RULE: \detokenize{#1}\par},
special/.search also=/rules,
% We get an error if the following line is uncommented.
special/.cd,
define rule={\ifnum\answer=42\relax}, % `mild' error: "(\end occurred when \ifx on line 12 was incomplete)"
define rule={\fi}, % fatal
}
\end{document}
The following example can be found on page 969 of the manual:
The last
\pgfkeys
call should trigger/handlers/.unknown
. Instead, nothing happens, there isn't even an error. Apparently, when all the elements in the/.search also
path list have been checked, the key is just thrown away.