\pgfkeysvalueof{<full key>} need three expansions
According to its definition, it takes three expansions for \pgfkeysvalueof{<full key>} to expand to the value held in <full key>.
% run `latexdef -p pgfkeys -s \pgfkeysvalueof` and you'll get
% pgfkeys.code.tex, line 172:
\def\pgfkeysvalueof#1{\csname pgfk@#1\endcsname}
- step one,
\pgfkeysvalueof expands to its replacement text, which is in the form of \csname ... \endcsname.
- step two,
\csname ... \endcsname expands to a control sequence that holds the value of <full key>. For /aaa, it's \pgfk@/aaa.
- step three, that control sequence expands to its replacement text. For
/aaa, the expansion result is empty.
The exact definition of \pgfkeysvalueof will change in the next release, see https://github.com/pgf-tikz/pgf/pull/1132, but the number of steps will remain the same.
Therefore
\expandafter\expandafter\expandafter\test
\expandafter\expandafter\expandafter{\pgfkeysvalueof{/aaa}}
works.
\pgfkeysValueOf that takes only two steps
In general,
- case 1: if the string to be tested is the replacement text of a macro, then OP's
\test works for this macro, like \test{\cmd};
- case 2: if the string to be tested is the (finite steps of) expansion of replace text of a macro, then in theory we can define a command
\cmdExpanded, based on \cmd, that only need two expansions. That means, \expandafter\test\expandafter{\cmdExpanded}}} works.
The \pgfkeysValueOf provided in example below belongs to case 2.
In addition, if expandability is not the key point, then pgfkeys's \pgfkeysgetvalue{<full key>}{<macro>} is another choice, for example
\pgfkeysgetvalue{/aaa}{\temp} % here \temp belongs to case 1
|\test{\temp}|
Example, with test cases to distinguish "blank value" from "non-blank value that expands to blank":
\documentclass{article}
\usepackage{tikz,etoolbox}
% OP's definiton
\newcommand{\test}[1]{%
\expandafter\ifblank\expandafter{#1}{blank}{#1}%
}
% egreg's answer
\ExplSyntaxOn
\NewExpandableDocumentCommand{\testExpl}{m}
{
\tl_if_blank:eTF { #1 } {blank} {#1}
}
\ExplSyntaxOff
% wipet's answer
\def\testExpanded#1{%
\expandafter\ifblank\expandafter{\expanded{#1}}{blank}{#1}}
% joseph's answer
\newcommand{\testRomannumeral}[1]{%
\expandafter\ifblank\expandafter{\romannumeral-`Q#1 }{blank}{#1}%
}
% my solution 1, expand three steps
\newcommand{\testThreeExps}[1]{%
\expandafter\expandafter\expandafter\test
\expandafter\expandafter\expandafter{#1}%
}
\begin{document}
\ttfamily
% three tests
\pgfkeys{
aaa/.initial={}, % blank: empty
bbb/.initial={{ }}, % blank: a space
ccc/.initial={\empty}, % non-blank: expand to empty
ddd/.initial={\space}, % non-blank: expand to a space
eee/.initial={eee}, % non-blank: expand to non-blank
}
\leavevmode\llap{Expected}%
\foreach \j in {aaa, bbb, ccc, ddd, eee} {%
% use \pgfkeysgetvalue, then one step expansion
\pgfkeysgetvalue{/\j}{\temp}%
\makebox[2cm]{|\test{\temp}|}%
}\bigskip
\foreach \i in {\test, \testExpl, \testExpanded, \testRomannumeral, \testThreeExps} {%
\leavevmode\llap{\detokenize\expandafter{\i}}%
\foreach \j in {aaa, bbb, ccc, ddd, eee} {%
\makebox[2cm]{|\i{\pgfkeysvalueof{/\j}}|}%
}
\par
}
% \pgfkeysValueOf{<full key>} takes one step to expansion to <full key>'s value
\newcommand{\pgfkeysValueOf}[1]{%
\expanded{\unexpanded
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter{\pgfkeysvalueof{#1}}}%
}
\leavevmode\hspace*{-4cm}%
\verb|\expandafter\test\expandafter{\pgfkeysValueOf{<full key>}}|\par%
\foreach \j in {aaa, bbb, ccc, ddd, eee} {%
\makebox[2cm]{|\expandafter\test\expandafter{\pgfkeysValueOf{/\j}}|}%
}
\end{document}

Note the test cases distinguish "blank key value" from "non-blank key value that expands to blank". Values of /aaa and /bbb are both blank, but values of /ccc and /ddd are neither blank, though they both expand to blank.
expl3, some of the Heiko Oberdiek bundle. – Joseph Wright May 17 '22 at 09:04