Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

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:

enter image description here

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

enter image description here

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}
share|improve this question
    
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

2 Answers 2

up vote 11 down vote accepted

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}

enter image description here

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}
share|improve this answer
    
@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}

Output

enter image description here

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.