Nested pics in TikZ 3.0

TiKz 3.0 introduce pics and I like them, but it seems that they are not as powerfull as I wish. For example I'm not able to use nested pics like this :

\tikzset{
one/.pic = {\draw[pic actions] (0,0) -- (1,1);},
two/.pic = {\path pic[pic actions]{one};}
}
\begin{tikzpicture}
\path pic[ultra thick, red]{one};
\path pic[thin]{two};
\end{tikzpicture}


Is this a bug, or is this simply how pics works?

There is no error message. Simply (Xe/PDF)LaTeX don't finish the job.

EDIT : Following Mark Wibrow's comment if we delete pic actions from pic{two} it works:

\tikzset{
one/.pic = {\draw[pic actions] (0,0) -- (1,1);},
two/.pic = {\path pic{one};}
}
\begin{tikzpicture}
\path pic[ultra thick, red]{one};
\path pic[thin, blue]{two};
\end{tikzpicture}


So the problem seems to be inside pic actions.

• tikzpictures can't be nested, (TikZ) matrix can't be nested, (TikZ) pics can't be nested... – Paul Gaborit Dec 5 '14 at 16:40
• You can put tikzpictures inside a node, and so make nastings. So in some sens you can ;) And why there is no error if it is by design ? – Kpym Dec 5 '14 at 17:05
• You could try two/.pic={\pic {one};} – Mark Wibrow Dec 5 '14 at 17:23
• @Kpym TikZ (in its current version) is not designed to allow tikzpictures into a node. Sometimes it works, but this is not guaranteed. It's the same for matrices (explicitly forbidden). For pics, I could be wrong. – Paul Gaborit Dec 5 '14 at 23:13
• @Kpym In fact, nested pics are allowed but there is always some bugs. – Paul Gaborit Dec 5 '14 at 23:26

I give here my partial knowledge of the problem.

Disclaimer

I'm not a texpert, and most of the thing that I write here are guesses.

Prerequisite

Some styles are inherited from the scope to the path and other are not. Some styles are inherited from the path to nodes and pics and other are not.

I don't know what is the precise rule, but I suppose that the only styles that are not inherited are the "actions" (as we can reed in the documentation about pic actions : "actions" are drawing, filling, shading, and clipping or any combination thereof).

How styling pics works

I don't know how exactly styling pics works, but my investigation (not of the code, because as I said I'm not an texpert) leads me to the following algorithm :

\tikzset{picname/.pic={the pic code}}
\pic[some style]{picname};


is transformed to something like

\begin{scope}[coordinate transform, every pic, some style]
the pic code
\end{scope}


This is oversimplified version because there is foreground code and background code and so on ...

So pic actions is useful when we want to inherit some action, let say fill from 'some style' to a path that is inside 'the pic code'. And this is well documented in the doc.

The problem with 'pic actions'

The problem with pic actions is that when we investigate it with something like

\pgfkeysgetvalue{/tikz/pic actions/.@cmd}{\temp};
\wlog{\meaning\temp}


the result is

\long macro:#1\pgfeov ->\tikz@addmode {\tikz@picmode }


which is not what we observe for some "ordinary" style, like :

\long macro:#1\pgfeov ->\pgfkeysalso {fill}


So probably here is the key why using pic actions in nested pics fails.

I think that pic actions must be used only for simple inheritance. But still there is a bug in pic actions, because when you use it in nested pics latex freeze without throwing an error.

When we need more complexe inheritance, we need to use some styling as shown below.

How to overcome 'pic actions'

Here is an example of how we can create complexe picture with complexe style and realy complex nesting (it works in a fashion similar to @cfr answer).

\tikzset {
every cherry fruit/.style = {fill,red},
cherry fruit/.style={every cherry fruit/.append style={#1}},
every cherry stem/.style = {brown, ultra thick},
cherry stem/.style={every cherry stem/.append style={#1}},
every cherry leaf/.style = {fill, green},
cherry leaf/.style={every cherry leaf/.append style={#1}},
cherry/.pic = {
\draw[every cherry fruit] (0,0) {[rounded corners=1cm] -- (1,1) -- (2,-1) -- (0,-3) -- (-2,-1) -- (-1,1)} -- cycle;
\draw[bend left, every cherry stem] (0,0) to coordinate[pos=.7] (A) (1,2);
\draw[bend left, every cherry leaf] (A) to +(-1.5,1) to cycle;
},
every cherry one/.style={},
cherry one/.style={every cherry one/.append style={#1}},
every cherry two/.style={},
cherry two/.style={every cherry two/.append style={#1}},
two cherries/.pic = {
\pic[every cherry one]{cherry};
\pic[xshift=5cm, every cherry two]{cherry};
}
}
\begin{tikzpicture}
\pic[cherry fruit=yellow]{cherry};
\pic[xshift=5cm]{cherry};
\pic[yshift=-5cm, cherry fruit={fill=none, draw, ultra thick}, cherry one={cherry fruit=yellow}]{two cherries};
\end{tikzpicture}


You could pass the options you want as an argument to two:

\documentclass[tikz, border=5pt]{standalone}
\tikzset{
one/.pic = {\path[pic actions] (0,0) -- (1,1);},
two/.pic = {\path pic[#1]{one};}
}

\begin{document}

\begin{tikzpicture}
\path pic[ultra thick, red, draw]{one};
\path pic{two={thin, blue, draw}};
\end{tikzpicture}

\end{document}


Since I'm not sure just how you're using this, I'm not sure whether this is an option you've rejected, an option which you've not rejected yet but will have to reject now, or an option which might be of use.

• thanks for your answer, but it doesn't respond to my question 'Is this a bug, or is this simply how pics works?'. I know that I can do what you propose, but doing this pic{two} is not used like standard pic. I'm more and more convinced that this is a bug. I can't see a reason to not be able to pass pic actions style to the subpic. – Kpym Dec 6 '14 at 7:11
• @Kpym I was really responding to your comment about the problem of one being drawn but not the other. – cfr Dec 6 '14 at 15:30
• ok. And I was responding to Mark Wibrow when he said 'In fact it seems to make not much sense to say \path pic [pic actions] {...}.' ;) – Kpym Dec 6 '14 at 15:55