samcarter
Background: I'm trying to make the piece pic from the jigsaw package compatible with the pic text and pic text options.

Adding the text itself works fine, I'm just running into a problem when trying to pass options to the text.

Below is the approach I tried. It works fine for options like draw, but for other options, like text=blue, I get the following error about the option being


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


I assume the = is causing the problem? Is there a workaround?


\documentclass{article}
\usepackage{tikz}

\tikzset{
pics/test/.style n args={4}{
code = {
\path[pic actions] (0,0) rectangle (1,1);
\node[
%        /tikz/text=blue % works
\tikzpictextoptions
] at (0.5,0.5) {\tikzpictext};
}
}
}

\begin{document}

\begin{tikzpicture}
\path pic[
pic text = {text},
%pic text options={draw}, % works
pic text options={text=blue}
]{test={1}{-1}{0}{0}};
\end{tikzpicture}

\end{document}



Skillmon
Your problem is the way Ti*k*Z parses the options and builds the error messages afterwards, which can lead to quite confusing results.

In your example pgfkeys will see the following key list: \tikzpictextoptions. It'll split that on the comma (none there), so the first and only element will be \tikzpictextoptions. Then it'll try to split at the equals sign (none there), so the key name/path will be \tikzpictextoptions. It'll check whether such a key is defined using \ifcsname in which the \tikzpictextoptions will get expanded, now pgfkeys will check whether a key with the name text=blue in the current default path exists (it doesn't). Next it'll throw an error, and inside that error the parsed key name will again be fully expanded, leading to the message about an undefined key named text=blue in the current default path /tikz/.

**I therefore postulate the following rule of thumb:**

If a message of pgfkeys about an unknown key contains an equals sign, the problem is expansion, and you should've expanded your key-list earlier.

The following works:


\documentclass{article}
\usepackage{tikz}

\tikzset{
pics/test/.style n args={4}{
code = {
\path[pic actions] (0,0) rectangle (1,1);
\expandafter\node\expandafter[\expandafter{\tikzpictextoptions}]
at (0.5,0.5) {\tikzpictext};
}
}
}

\begin{document}

\begin{tikzpicture}
\path pic[
pic text = {text},
%pic text options={draw}, % works
pic text options={text=blue}
]{test={1}{-1}{0}{0}};
\end{tikzpicture}

\end{document}

Qrr
The other answers already tell you why it doesn't work (the whole content of \tikzpictextoptions will be tested to be the key name because the parser is dumb), they all fallback to low-level expansion control (which isn't wrong but can be annoying in more complex cases).

However, PGFKeys and TikZ already come with tools to handle this.

They are

* the .expand once handler and
* the style style.

The latter is very simple, it's defined as


\tikzset{style/.style={#1}}


meaning it just applies the styles that are given to it, which is pretty pointless *unless* you have to do something with #1.

In this case you want to expand #1, i.e. \pictextoptions, before the actual PGFKeys parser sees it.

## Code

\documentclass{article}
\usepackage{tikz}
\tikzset{
pics/test/.style n args={4}{
code = {
\path[pic actions] (0,0) rectangle (1,1);
\node[style/.expand once=\tikzpictextoptions] at (0.5,0.5) {\tikzpictext};
}
}
}
\begin{document}
\begin{tikzpicture}
\path pic[
pic text = {text},
pic text options={text=blue}
]{test={1}{-1}{0}{0}};
\end{tikzpicture}
\end{document}

frougon
I haven't investigated what precisely happens, but it works if you manually expand \tikzpictextoptions so that \node sees text=blue as opposed to \tikzpictextoptions inside its optional argument:

\documentclass{article}
\usepackage{tikz}

\tikzset{
pics/test/.style n args={4}{
code = {
\path[pic actions] (0,0) rectangle (1,1);
\expanded{%
\noexpand\node[{%
\unexpanded\expandafter{\tikzpictextoptions}}]}
at (0.5,0.5) {\tikzpictext};
}
}
}

\begin{document}

\begin{tikzpicture}
\path pic[
pic text={text},
pic text options={text=blue},
]{test={1}{-1}{0}{0}};
\end{tikzpicture}

\end{document}


![image.png](/image?hash=9a83f01801d16a87658493856f0ba24b1eda8ca6e4082d2e53cea38d564f3b5b)

This is an improved version of my original answer thanks to [Skillmon's comment](https://topanswers.xyz/transcript?room=3386&id=153281#c153281) and more careful reading of his code:

- because current engines have the \expanded primitive, the revised code can use


\expanded{%
\noexpand\node[{%
\unexpanded\expandafter{\tikzpictextoptions}}]}
at (0.5,0.5) {\tikzpictext};


\begingroup
\edef\tmp{\endgroup
\noexpand\node[{%
\unexpanded\expandafter{\tikzpictextoptions}}]}%
\tmp


- the outer curly braces in the resulting \node[{...}] make the construct safe in case \tikzpictextoptions contains square brackets (they will be automatically stripped by TeX when it grabs the optional argument of \node).

Note: this is essentially the same as what Skillmon [did](https://topanswers.xyz/tex?q=3340#a3413). I had initially not seen his answer because my network connection was down for a few hours and the page didn't automatically refresh when the connection went back up.

Enter question or answer id or url (and optionally further answer ids/urls from the same question) from

Separate each id/url with a space. No need to list your own answers; they will be imported automatically.