Font change commands are (now) robust, so if you use \protected@edef
instead of plain \edef
, then LaTeX's protection mechanism will kick in and prevent the expanson of \small
. However this will only work if the key contains robust or expandable commands (which is most often not the case).
A more robust way of doing this exploits the implementation details of \pgfkeysvalueof
, which is just \csname pgfk@<full path to key>\endcsname
(after one expansion). The \csname
expands whatever is in the path and makes a control sequence (after a second expansion), then one more expansion (third) yields the contents of the key, so you can use:
\def\unexpandedvalueof#1{%
\unexpanded
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter{\pgfkeysvalueof{#1}}}
to expand \pgfkeysvalueof
exactly 3 times and leave the result inside \unexpanded
, so it doesn't expand further in \edef
.
Note that, since \pgfkeysvalueof
uses directly \csname
, in case the key didn't exist previously, TeX will leave \relax
after the expansion and the emptiness test will result false. If you want it to return true for an undefined key, then you need to check for the \relax
before expanding the actual control sequence that stores the key:
\def\unexpandedvalueof#1{%
\unexpanded\expandafter\expandafter
\expandafter\rmano@valueof@chk\pgfkeysvalueof{#1}}
\def\rmano@valueof@chk#1{%
\ifx\relax#1%
\expandafter\pgfutil@firstoftwo
\else
\expandafter\pgfutil@secondoftwo
\fi
{{}}%
{\expandafter{#1}}}
Here's a compilable example:
\documentclass[]{article}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{tikz}
\usepackage{unravel}
\makeatletter
\newcount\cnt\cnt=0\relax
\tikzset{dir/.is family}
\tikzset{dir/t0/.initial={}}
\begin{document}
\tikzset{dir/t0={\small SMALL}}
Key \the\cnt is: \pgfkeysvalueof{/tikz/dir/t\the\cnt}
\makeatletter
\newcommand\unexpandedvalueof[1]{%
\unexpanded\expandafter\expandafter
\expandafter\rmano@valueof@chk\pgfkeysvalueof{#1}}
\def\rmano@valueof@chk#1{%
\ifx\relax#1%
\expandafter\pgfutil@firstoftwo
\else
\expandafter\pgfutil@secondoftwo
\fi
{{}}% #1 is \relax, so consider empty
{\expandafter{#1}}}% otherwise, leave the key after one more expansion
\makeatletter
\edef\mykey{x\unexpandedvalueof{/tikz/dir/t\the\cnt}}
\edef\plainx{x}
\ifx\plainx\mykey
key t\the\cnt{} is empty
\else
key t\the\cnt{} is not empty
\fi
\edef\mykey{x\unexpandedvalueof{/tikz/dir/tBOO}}
\edef\plainx{x}
\ifx\plainx\mykey
key t\the\cnt{} is empty
\else
key t\the\cnt{} is not empty
\fi
\end{document}
ConTeXt renames the \unexpanded
primitive, so you need to use \normalunexpanded
instead. You can use this code to define a generic \pgfutil@unexpanded
:
\ifcsname normalunexpanded\endcsname
\let\pgfutil@unexpanded\normalunexpanded
\else
\let\pgfutil@unexpanded\unexpanded
\fi
\protected@edef
instead of\edef
should work...\protected@edef
available in ConTeXt?tikz
to only usepgfkeys
is a bit inefficient.circuitikz
...