9

I would like to send a serie of tikz keys to a tikz path with the pgfkeys interface. I succeeded with the following code but is there a simpler way to do that ? Can I do the same thing with something like \draw[\prop] ... ? Actually I would like to avoid the scope environment.

\documentclass[a4paper]{article}

\usepackage{tikz}

\pgfkeys{
    /test/pgfkeys/.cd,
    nom/.store in = \nom,
    prenom/.store in = \prenom,
    prop/.store in = \prop
    %prop/.code = \tikzset{#1}
}

\newcommand{\qui}[1][]{
    \pgfkeys{/test/pgfkeys/.cd,#1}
    I am \prenom{} \nom{} !

    \begin{tikzpicture}
        \begin{scope}
            \tikzset{\prop}
            \draw (0,0) -- (1,0);
        \end{scope}
    \end{tikzpicture}
}

\begin{document}
\qui[prenom = toto, nom = titi, prop = {very thick, color = red!80, -stealth}]
\end{document}

EDIT :

New code using Andrew Stacey answer. This code works now :

\documentclass[a4paper]{article}

\usepackage{tikz}

\pgfkeys{
    /tikz/.cd,
    execute style/.style = {#1},
    execute macro/.style = {execute style/.expand once=#1},
    /test/pgf/.cd,
    nom/.store in = \nom,
    prenom/.store in = \prenom,
    prop/.store in = \prop
}

\newcommand{\qui}[1][]{
    \pgfkeys{/test/pgf/.cd,#1}
    I am \prenom{} \nom{} !

    \begin{tikzpicture}
        \draw[execute macro = \prop] (0,0) -- (1,0);
    \end{tikzpicture}
}

\begin{document}
\qui[prenom = toto, nom = titi, prop = {very thick, color = red!80, -stealth}]
\end{document}

Here is the output :

enter image description here

Ger
  • 2,720
  • You can replace everything from \begin{tikzpicture} to end{tikzpicture} with \tikz \draw \expandafter[\prop] (0,0) -- (1,0);. Does that do what you want? – Jake Dec 05 '12 at 16:25

3 Answers3

10

I have this in my code for recent answers but I can't find the answer that it relates to (usually I save the URL in the code but I sometimes forget, and my searching hasn't turned it up). The problem is that the \prop doesn't get expanded until after the list of keys has been split up. The solution is to refeed it into the pgfkey machine so that it goes through the splitting process once more time.

\documentclass{article}
%\url{http://tex.stackexchange.com/q/85637/86}
\usepackage{tikz}

\tikzset{
  execute style/.style={#1},
  execute macro/.style={execute style/.expand once=#1},
}

\begin{document}
\begin{tikzpicture}
\foreach \x/\y/\properties in {
  1/0/{color=blue,double=red},
  0/0/,
  0/1/{dotted,green}
} {
  \draw [execute macro=\properties] (\x,\y) -- ++(1,0);
}
\end{tikzpicture}
\end{document}

This actually has the same effect as Jake's comment with \expandafter but is a bit more flexible as it can be used anywhere in the list of keys.

Here's the code from the question using this method:

\documentclass[a4paper]{article}
%\url{http://tex.stackexchange.com/q/85637/86}
\usepackage{tikz}

\tikzset{
    execute style/.style = {#1},
    execute macro/.style = {execute style/.expand once=#1},
    /test/pgf/.cd,
    nom/.store in = \nom,
    prenom/.store in = \prenom,
    prop/.store in = \prop
}

\newcommand{\qui}[1][]{
    \tikzset{/test/pgf/.cd,#1}
    I am \prenom{} \nom{} !

    \begin{tikzpicture}
        \draw[execute macro=\prop] (0,0) -- (1,0);
    \end{tikzpicture}
}

\begin{document}
\qui[prenom = toto, nom = titi, prop = {very thick, color = red!80,
-stealth}]
\end{document}

(I changed \pgfkeys to \tikzset since \draw assumes everything to be in the /tikz path so it seemed easier to start there.)

The important point is that when the macro, \prop, is used in a style then it is not used "bare" but is the argument to the execute macro key. This is the key that says "expand this macro once and then reinsert it into the stream" (well, actually execute macro does the expansion and execute style the reinsertion).

Andrew Stacey
  • 153,724
  • 43
  • 389
  • 751
  • David Carlisle found the original of this. It is http://tex.stackexchange.com/a/64237/86 (it was further back that the timestamps of my file suggested). – Andrew Stacey Dec 05 '12 at 17:22
  • I edit my first post. I tried to follow your example but I do not succeed. Where am I wrong ? Do .style handlers act in a same way as .code handlers ? – Ger Dec 06 '12 at 07:26
  • @Ger I've added an example based on your code. – Andrew Stacey Dec 06 '12 at 07:58
  • Ok, now it works without error message but the key I give to the path have not got any effects. I update my source code in the question. – Ger Dec 06 '12 at 08:23
  • @Jake True, but I was trying to cut down on extra handlers at call time as I think they're harder to remember (and less intuitive). – Andrew Stacey Dec 06 '12 at 08:33
  • @Ger Sorry! I mis-copied my own code. It should have been execute macro/.style not execute macro/.code. – Andrew Stacey Dec 06 '12 at 08:36
  • @AndrewStacey: Makes sense – Jake Dec 06 '12 at 08:37
  • @AndrewStacey Thanks a lot for your help, it works ! About the fact you change \pgfkeys to \tikzset and about path in general. What is the best way to code ? As you can see I do not put my new keys at the origin I add /test/pgf/ is it useless ? Is it recommended ? If I use \tikzset does it mean that I add new keys to the whole tikz keys ? – Ger Dec 06 '12 at 09:07
  • And a last comment/question. Are the key execute macro and execute style general keys that I can define one time and use elsewhere in a package file for example ? – Ger Dec 06 '12 at 09:12
  • The best way to think of tikzset and pgfkeys is with directories in a file system. So pgfkeys starts at the root whilst tikzset starts in the /tikz/ subdirectory. So when you specify an absolute path it doesn't matter where you start, thus your /test/pgf/ works whichever you use. The reason for using tikzset for the expand ... keys is that they are used in the \draw[...] command which starts in the /tikz directory by default so since they will be used there it makes sense to define them there. – Andrew Stacey Dec 06 '12 at 09:25
  • 1
    And to your last comment/question: yes, you can. You can define them in your preamble or in a separate .sty file and use them wherever afterwards. Note that keys respect grouping so defining one inside a group does not mean that it will work outside. – Andrew Stacey Dec 06 '12 at 09:26
6

Whereas Andrew Stacey answers the question about expansion, I want to give an option that actually uses TikZ styles!

There is no need for the scope environment.

Code

\documentclass[a4paper]{article}

\usepackage{tikz}

\pgfkeys{
    /test/pgfkeys/.cd,
    nom/.store in = \nom,
    prenom/.store in = \prenom,
    prop/.style = {prop style/.estyle={#1}},
}

\newcommand{\qui}[1][]{
    \pgfkeys{/test/pgfkeys/.cd,#1}
    I am \prenom{} \nom{} !

    \begin{tikzpicture}
         \draw[/test/pgfkeys/prop style] (0,0) -- (1,0);
    \end{tikzpicture}
}

\begin{document}
\qui[prenom = toto, nom = titi, prop = {very thick, color = red!80, -stealth}]
\end{document}
Qrrbrbirlbel
  • 119,821
3

Another "flexible" solution is to use loops package.

\documentclass{article}
\usepackage{tikz}
\usepackage{loops}

\begin{document}
\begin{tikzpicture}
\foreachfox [arg=#1/#2/#3]{
  1/0/{color=blue,double=red},
  0/0/,
  0/1/{dotted,green}
}{
  \draw[#3] (#1,#2) -- ++(1,0);
}
\end{tikzpicture}
\end{document}
Ahmed Musa
  • 11,742
  • You're basing this on the code from my answer which wasn't really taken from the original question so I don't think it quite addresses the point of this question. However, I think it would be a great answer at the question I link to in the comment to my answer. – Andrew Stacey Dec 05 '12 at 20:48
  • 1
    Progress means every leg standing on the shoulders of giants, looking skywards. – Ahmed Musa Dec 06 '12 at 00:44