# Multiple TikZ keys with foreach

Playing around with pgffor, I'm trying to slightly modify an example from the TikZ/pgf manual:

\path \foreach \x/\content/\style in {%
0/a/draw,
1/b/{draw,red},
2/c/{circle,blue},
3/d/draw%
} {
node[\style] at (\x,0) {\content}
} ;


Unfortunately, this does not work for nodes with multiple \style options set. TikZ complains with

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


Now, this works perfectly, when I use a comma separated list for some other variable (e.g. \content). So now, my question is: how can I split \style while executing the loop? Obviosly, pgf tries to find one key named draw,red, when it should be looking for two keys instead, namely draw and red.

Is there some clever LaTeX macro that correctly expands the loop variable or tells pgf to expect multiple keys?

-
Not an answer to your question, but you can define a new name for your comma-separated styles. For example red drawing/.style={red, draw} and use this style in your loop. –  JLDiaz Jul 20 '12 at 21:22
Is there a certain reason why you don't like to set up a style an use this? You may say \tikzset{somekey/.style={draw, red}} and insert somekey instead of the comma-list. –  bloodworks Jul 20 '12 at 21:25
@JLDiaz, bloodworks: Yep, I used that as a workaround after writing this question, but it is just too unflexible, if you have a lot of different combination of styles (some of which you will only use once) –  knittl Jul 20 '12 at 21:29
Related: tex.stackexchange.com/q/29048/86 as this is about expansion of macros in keys. –  Loop Space Jul 20 '12 at 21:46
And I'm sure we've had similar questions but my searching skills are severely depleted. –  Loop Space Jul 20 '12 at 21:50

Here's another version, not all that different from the previously supplied but combines them in a slightly different way. In effect, it is a bit like defining a dynamic style alias that expands to the given list of options. When a style like red drawing/.style={draw,red} is defined, then calling red drawing executes \tikzset{draw,red} (sort of, actually it's pgfkeys). So we simulate this by defining a key that executes \tikzset on whatever it is passed. So apply style={do,something,and,something,else} will execute \tikzset{do,something,and,something,else}. On its own, this isn't all that useful. But when combined with the /.expand once key handler we can pass it a macro, get that macro expanded once, and then execute the style it contains.

\documentclass{article}
\usepackage{tikz}
\tikzset{%
apply style/.code={%
\tikzset{#1}%
}
}
\begin{document}

\begin{tikzpicture}
\path \foreach \x/\content/\style in {%
0/a/draw,
1/b/{draw,red},
2/c/{circle,draw=blue},
3/d/draw%
} {
node[apply style/.expand once=\style] at (\x,0) {\content}
} ;
\end{tikzpicture}
\end{document}

-
I really like this solution. It's the least overhead and leaves the loop almost un-modified :) –  knittl Jul 22 '12 at 7:52
I've tried almost the same apply style=\style option with ecode and I don't understand why \tikzset{apply style/.ecode={\noexpand\tikzset\noexpand{#1}}} refuses to work. –  percusse Jul 22 '12 at 13:56
Ah scratch that. Now I have it with regular /.code and \expandafter's which is still lengthy than your solution. –  percusse Jul 22 '12 at 13:58
@percusse: .ecode is effective at key definition time, not when the key is called. Even .estyle won't help you in that case. –  Ahmed Musa Jul 22 '12 at 15:00

Use indirect styles numbered (perhaps more verbose but flexible):

\documentclass[tikz]{standalone}
\begin{document}
\begin{tikzpicture}
\tikzset{
s0/.style={draw},
s1/.style={draw,red},
s2/.style={circle,draw=blue},
s3/.style={draw},
}
\foreach \x/\content in {%
0/a,
1/b,
2/c,
3/d%
} {
\node[s\x] at (\x,0) {\content};
};
\end{tikzpicture}
\end{document}


-

Personally I always use the next method and in a lot of cases I use \protected@edef with LaTeX. With the next method you can use \path node ... node ... ;.

\documentclass{standalone}
\usepackage{tikz}
% \makeatletter\let\protectededef\protected@edef   not useful here but It' sometimes
% interesting
\begin{document}
\begin{tikzpicture}
\path
\foreach \x/\content/\style in {0/a/draw,
1/b/{draw,red},
2/c/{draw,circle,blue},
3/d/draw}{
\pgfextra{\edef\tmp{   % or \pgfextra{\protectededef\tmp{
node[\style] at (\x,0) {\content}}}
\tmp
};
\end{tikzpicture}
\end{document}


-
I think this would also work with only \edef (without protection). –  percusse Jul 21 '12 at 9:43
@percusse Yes you are right! in a lot of cases, I need \protected@edef so it's always my first attempt. –  Alain Matthes Jul 21 '12 at 11:00

You can stick with your method. With a slight modification, it works.

\documentclass{standalone}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
\foreach \x/\content/\style in {%
0/a/draw,
1/b/{draw=red},
2/c/{circle,draw=blue},
3/d/draw
}{
\edef\x{\noexpand\node[\style] at (\x,0) {\content}}\x;
}
\end{tikzpicture}
\end{document}


And PolGab's solution is:

\documentclass[tikz]{standalone}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}[0/.style=draw,1/.style={draw=red},
2/.style={circle,draw=blue},3/.style=draw]
\foreach \x/\content in {0/a, 1/b, 2/c, 3/d}{
\node[\x] at (\x,0) {\content};
}
\end{tikzpicture}
\end{document}


EDIT (2012/07/22)

Expanding on Andrew Stacey's solution, here is another one. Using + to list the keys eliminates the need for braces. The code can be generalized to take any symbol in place of +.

\documentclass{article}
\usepackage{tikz}
\makeatletter
\def\replaceplus#1{\xreplaceplus#1+\@nil}
\def\xreplaceplus#1+#2\@nil{%
\ifcat$\detokenize{#2}$\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
{\unexpanded{#1}}{\xreplaceplus#1,#2\@nil}%
}
\newcommand*\tikzexpanded[2]{%
\begingroup
\def\reserved@a##1#1##2##3\@nil{%
\ifx\@nnil##2\def\x{#2}\else\edef\x{##2{#2}}\fi
}%
\reserved@a
xx{\@iden}x0{\unexpanded}x1{\unexpanded\expandafter}%
x2{\unexpanded\expandafter\expandafter\expandafter}#1{\@nnil}\@nil
\edef\x{\expandafter\replaceplus\expandafter{\x}}%
\edef\x{\endgroup\noexpand\tikzset{\unexpanded\expandafter{\x}}}\x
}
\tikzset{%
use style/.code={\tikzset{#1}},
use style expanded/.code={\tikzexpanded{xx}{#1}},
use style expand once/.code={\tikzexpanded{x1}{#1}},
use style expand twice/.code={\tikzexpanded{x2}{#1}}
}
\makeatother
\begin{document}
\begin{tikzpicture}
\path \foreach \x/\content/\style in{%
0/a/draw,
1/b/draw + red,
2/c/circle + draw=blue,
3/d/draw
}{
node[use style expand once=\style] at (\x,0) {\content}
};
\end{tikzpicture}
\end{document}

-
Can I use the same for a \path node ... node ... node command? –  knittl Jul 21 '12 at 8:34
@knittl with my method you can use  \path node .. node .. ; –  Alain Matthes Jul 21 '12 at 11:03