# How to detect if option provided via \tikzset

I would like to be able to detect if a particular option has been provided via a \tikzset and issue a message based on that.

The MWE yields:

But once the conditional works (just a comment for now) it should yield:

## Notes:

• Even though I don't think that this case introduces any additional complexity, I am not concerned about the case where a \tikzset uses a style defined by another \tikzset.

## Code:

\documentclass{article}
\usepackage{tikz}

\tikzset{Hollow/.style={red}}
\tikzset{Solid/.style={green}}

\newcommand{\TikzPicture}{%
\begin{tikzpicture}
\draw [ultra thick, blue, ->, My Options] (0,0) -- (1,0)
% If option Hollow is specified
node [right] {Error: Option Hollow specified.}
;
\end{tikzpicture}%
}%

\begin{document}

\tikzset{My Options/.style={Hollow}}
\TikzPicture

\tikzset{My Options/.style={}}
\TikzPicture
\end{document}

• Hollow is defined as a style so it's a combination of certain key=value pairs, it doesn't set a distinctive switch per se when called. If it's a distinct option you can /.try it at the first instance then it's gonna stay there. – percusse Mar 5 '13 at 23:09
• @percusse: Never heard of /.try, will have to look that up.. – Peter Grill Mar 5 '13 at 23:31

Edit: Via the .forward to handler (only available with the CVS version of PGF) , you can attach a boolean to your Hollow style when you want to test if it is specified:

\documentclass{article}
\usepackage{tikz}
\usepackage{etoolbox}

\newbool{Hollow}

\tikzset{
Hollow is used/.code=\booltrue{Hollow},
Test Hollow/.code={\tikzset{Hollow/.forward to=/tikz/Hollow is used}},
Hollow/.style={red},
Solid/.style={green},
}

\newcommand{\TikzPicture}{%
\begin{tikzpicture}
\draw [Test Hollow,ultra thick, blue, ->, My Options] (0,0) -- (1,0)
\ifbool{Hollow}{
node [right] {Error: Option Hollow specified.}
}{
node [right] {Ok: Option Hollow is not specified.}
}
;
\end{tikzpicture}%
}%

\begin{document}

\tikzset{My Options/.style={Hollow}}
\TikzPicture

\tikzset{My Options/.style={}}
\TikzPicture

\tikzset{Hollow/.style={violet,dotted}}

\tikzset{My Options/.style={Hollow}}
\TikzPicture

\end{document}


First solution (with version 2.10 of PGF):

\documentclass{article}
\usepackage{tikz}
\usepackage{etoolbox}

\newbool{Hollow}

\tikzset{
Hollow/.code={
\booltrue{Hollow}
\pgfkeysalso{red}
},
Solid/.style={green},
}

\newcommand{\TikzPicture}{%
\begin{tikzpicture}
\draw [ultra thick, blue, ->, My Options] (0,0) -- (1,0)
\ifbool{Hollow}{node [right] {Error: Option Hollow specified.}}{}
;
\end{tikzpicture}%
}%

\begin{document}

\tikzset{My Options/.style={Hollow}}
\TikzPicture

\tikzset{My Options/.style={}}
\TikzPicture

\end{document}

• @Qrrbrbirlbel Thanks for your comment. I pushed your idea a little further... – Paul Gaborit Mar 6 '13 at 0:05
• You don't need etoolbox for booleans. You can add an /.is if to hollow and it would be set in a similar fashion. – percusse Mar 6 '13 at 0:11
• @PaulGaborit Yes! Though, the /.forward to handler is only available with the CVS version of PGF, isn’t it? – Qrrbrbirlbel Mar 6 '13 at 0:13
• @Qrrbrbirlbel Oops! You are right! I always forget to check whether what I propose is already available in version 2.10 of PGF. – Paul Gaborit Mar 6 '13 at 0:18
• @PaulGaborit Well, the definition of .forward to is four lines of code long. I think one could insert that in their source. – Qrrbrbirlbel Mar 6 '13 at 0:27

This approach re-defined the .style handler by appending (in this case)

\expandafter\let\csname ifqrr@trace@pgfk@/tikz/Hollow\endcsname\iftrue


to it. Now, /tikz/Hollow is stored in the macro \pgfkeyscurrentpath, so we need to expand it once, because, of course, \pgfkeyscurrentpath will be different when the style is called.

This is the reason I used .ecode instead of .code for the redefinition of the .style handler:

\pgfkeys{
/handlers/.style/.code=
\pgfkeys{
\pgfkeyscurrentpath/.ecode=
\noexpand\expandafter\noexpand\let\noexpand
\csname ifqrr@trace@pgfk@\pgfkeyscurrentpath\noexpand\endcsname\noexpand\iftrue
\noexpand\pgfkeysalso{\unexpanded{#1}}%
}
}


This has the following consequences:

• Currently, it only works with .style, not with .estyle, .style args, .estyle args, .style 2 args or .style n args. It also does not work with the handler .append style (which is often used) with a previous undefined style, i.e. .append style without a previous .style.
• It does not work with previous defined styles.

I also have defined a two-argument expecting .if handler that tests if the key is given, but sadly, it cannot be used inside a path. Therefore I have defined a very simple \iftikzstyle macro that only works for keys in the /tikz/ path but it can be used inside a path.

### Further Improvements

• Re-defining all other style handlers (its just expansion ;))
• We need to go deeper:

It would be better to add the \let sequence where the styles are called if one specifies it (for example with \tikzset or in the optional arguments of a \draw). This could make existing/pre-defined styles also available for /.if and \iftikzstyle.

## Code

\documentclass{article}
\usepackage{tikz}

\pgfkeys{/handlers/.style/.code=\pgfkeys{\pgfkeyscurrentpath/.ecode=\noexpand\expandafter\noexpand\let\noexpand\csname ifqrr@trace@pgfk@\pgfkeyscurrentpath\noexpand\endcsname\noexpand\iftrue\noexpand\pgfkeysalso{\unexpanded{#1}}}}
\pgfkeys{
/handlers/.if/.code 2 args={% works not in the middle of a path
\expandafter\ifx\csname ifqrr@trace@pgfk@\pgfkeyscurrentpath\endcsname\iftrue#1\else#2\fi}}

\makeatletter
\newcommand*{\iftikzstyle}[1]{% only for /tikz/ styles
\expandafter\ifx\csname ifqrr@trace@pgfk@/tikz/#1\endcsname\iftrue
\expandafter\@firstoftwo
\else
\expandafter\@secondoftwo
\fi
}
\makeatother

\tikzset{Hollow/.style={red}}
\tikzset{Solid/.style={green}}

\newcommand{\TikzPicture}{%
\begin{tikzpicture}
\draw [ultra thick, blue, ->, My Options] (0,0) -- (1,0)
\iftikzstyle{Hollow}{node[right] {Error: Option Hollow specified.}}{node[opacity=.5,right] {Option Hollow not specified}}
;
\end{tikzpicture}%
}%

\begin{document}
\tikzset{My Options/.style={Hollow}}
\TikzPicture

\tikzset{My Options/.style={}}
\TikzPicture

\tikzset{Hollow/.if={Hollow is specified.}{Hollow is not specified.}}

\tikzset{Hollow}
\tikzset{Hollow/.if={Hollow is specified.}{Hollow is not specified.}}
\end{document}