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 write a command which allows the user to change tikz styles. My code goes like this:

\documentclass{article}
\usepackage{tikz,xkeyval}

\makeatletter
\def\DEFstyle{}
\define@key{styles}{styleA}{\def\DEFstyle{#1}}
\newcommand{\setstyles}[1]{%
  \setkeys{styles}{styleA={}} 
  \setkeys{styles}{#1}
  \tikzstyle{TIKZSTYLE}=[\DEFstyle]
}
\makeatother

\begin{document}
\setstyles{styleA={top color=green,bottom color=red}}
\end{document}

However, I always get an error message:

! Package pgfkeys Error: I do not know the key '/tikz/top color=green,bottom color=red' and I am going to ignore it. Perhaps you misspelled it.

But the content of \DEFstyle is definitely top color=green,bottom color=red and when I directly write \tikzstyle{TIKZSTYLE}=[top color=green,bottom color=red] then everything works fine. Where does the bug hide?

share|improve this question
    
Welcome to TeX.SX. –  Claudio Fiandrino Mar 5 '13 at 18:28
    
The exact option is not important as long as it works. \tikzset{TIKZSTYLE/.style/.expand once=\DEFstyle} seems to work! Thanks a lot! May you consider to explain your solution? Otherwise I can answer this question myself. Also: thanks for the link. –  Andreas Milford Mar 5 '13 at 18:42
    
I cant answer my own question yet due to stackexchange spam limits. –  Andreas Milford Mar 5 '13 at 19:04
add comment

2 Answers

First of all,

\tikzstyle{<key>}=[<value>]

is the same as

\tikzset{<key>/.style={<value>}}

From this point I will only use the \tikzset syntax (→ Should \tikzset or \tikzstyle be used to define TikZ styles?). But you would've had the same problem with \tikzset.

The assignment is not a problem, the style TIKZStyle contains simply your argment to styleA. But when TikZ executes this style (say when \draw[TIKZSTYLE]) it sees firstly \DEFstyle and its definition and tries it as a key, but a key named top color=green,bottom color=red (for TikZ this is just one “string” at this moment) does not exist.

Even top color=green won’t work because, again, TikZ does not see the = hidden in \DEFstyle.
The only thing that would work is is a style without a parameter, say

\setstyles{styleA={rounded corners}}%
\tikz \draw[TIKZSTYLE] (0,0) rectangle (1em,2ex);

which results in rounded rectangle. But even that is not safe enough:

\setstyles{styleA={rounded corners}}%
\def\DEFstyle{fill}%
\tikz \draw[TIKZSTYLE] (0,0) rectangle (1em,2ex);

(But then again, throw some @ in the \DEFstyle macro’s name …).

These are the reasons we need to expand \DEFstyle before assigning it to the TIKZSTYLE style:

\tikzset{TIKZSTYLE/.style/.expand once=\DEFstyle}%

In your definition of the \setstyles macro are some spurious spaces:


I do not know much about your project, but as a reminder, you can do this all with PGF keys. See the second Code block.

Code

\documentclass[tikz]{standalone}
\usepackage{xkeyval}

\makeatletter
\def\DEFstyle{}
\define@key{styles}{styleA}{\def\DEFstyle{#1}}
\newcommand{\setstyles}[1]{%
  \setkeys{styles}{styleA={}}%
  \setkeys{styles}{#1}%
  \tikzset{TIKZSTYLE/.style/.expand once=\DEFstyle}%
}
\makeatother

\begin{document}
\setstyles{styleA={top color=green,bottom color=red}}
\tikz \draw[TIKZSTYLE] (0,0) rectangle (1em,2ex);
\end{document}

Code (sans-xkeyval)

\documentclass[tikz]{standalone}

\pgfkeys{
    /no xkeyval/styleA/.style={
        /tikz/TIKZSTYLE/.style={#1}
    }
}
\newcommand*{\setstyles}[1]{%
    \pgfqkeys{/no xkeyval}{#1}%
}
\begin{document}%
\setstyles{styleA={top color=green,bottom color=red}}%
\tikz \draw[TIKZSTYLE] (0,0) rectangle (1em,2ex);
\end{document}
share|improve this answer
add comment

One use of xkeyval package might be to preset some keys, so that their preset values can be used when no user value is provided for them.

\documentclass{article}
\usepackage{tikz,xkeyval}

\makeatletter
\define@key{styles}{color set}{\def\rectstyle{#1}}
\define@key{styles}{rect size}{\def\rectsize{#1}}
\presetkeys{styles}{color set={top color=white,bottom color=gray},rect size={5em,5em}}{}
\newcommand*{\setstyles}[1][]{%
  \setkeys{styles}{#1}%
  \edef\tempa{\unexpanded{\tikz\draw}[\rectstyle](0,0)rectangle(\rectsize)}\tempa;
}
\makeatother

\begin{document}
\begin{tikzpicture}
\setstyles
\hspace{1cm}
\setstyles[color set={top color=green,bottom color=red},rect size={5ex,6ex}]
\hspace{1cm}
\setstyles[rect size={10ex,8ex}]
\end{tikzpicture}
\end{document}

enter image description here

share|improve this answer
add comment

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.