# Expanding macro defined by \csdef to define a style via \tikzset

I need to store tikz option in a \csdef{}:

\csdef{My Node Option}{draw=red, thick, fill=yellow}


How do I use this definition to define a style via \tikzset? I attempted to use .expand once as per How do I define tikz styles with a xkeyval command?:

\tikzset{Node Options/.style/.expand once=\csuse{My Node Option}}


but that leads to a

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

The desired result is to modify only the \tikzset in the MWE and obtain:

## Notes:

• As egreg commented, spaces in names of commands should be avoided. However, in my actual use case, the command names defined by the csdef{} are named after file names with paths which include spaces, slashes, numbers, periods.

Code:

\documentclass{article}

\usepackage{tikz}
\usepackage{etoolbox}

\begin{document}

\csdef{My Node Option}{draw=red, thick, fill=yellow}

\noindent
\begin{tikzpicture}
\tikzset{Node Options/.style/.expand once=\csuse{My Node Option}}%% ????

\node [Node Options] at (0,0) {Node Text};
\end{tikzpicture}%
\end{document}

• You'd need /.expand thrice, which doesn't exist. But /.expand twice=\csname My Node Option\endcsname works. I know that spaces in names of commands and options is bad. ;-) – egreg Oct 30 '18 at 0:03

You can use expanded instead of expand once in your MWE:

\tikzset{Node Options/.style/.expanded=\csuse{My Node Option}}%% ????

• +1 It's better to give a complete minimal working example as an answer to show that your solution works, but I agree that this does work and hence that this is probably the preferred tikz solution. – Andrew Oct 29 '18 at 23:34

\csuse{...} is not quite the same as \csname...\endcsname:

% etoolbox.sty, line 883:
\newcommand*{\csuse}[1]{%
\ifcsname#1\endcsname
\csname#1\expandafter\endcsname
\fi}


If you expand once in your context you get

\ifcsname My Node Option\endcsname\csname My Node Option\endcsname\fi


A further expansion step will remove the conditional, leaving

\csname My Node Option\endcsname\fi


which requires two expansion steps in order to deliver

draw=red, thick, fill=yellow\fi


but then the \fi kicks in, because it is shuffled around at the wrong place.

You can do

\tikzset{Node Options/.style/.expand twice=\csname My Node Option\endcsname}


that avoids the problem of the dangling \if.

However, the best strategy, in my opinion, is to use styles all around:

\documentclass{article}

\usepackage{tikz}

\begin{document}

\tikzset{My Node Option/.style={draw=red, thick, fill=yellow}}

\begin{tikzpicture}
\tikzset{Node Options/.style=My Node Option}

\node [Node Options] at (0,0) {Node Text};
\end{tikzpicture}

\end{document}


You can use the \begingroup\edef\x{\endgroup <stuff to expand>}\x expansion trick:

\documentclass{article}

\usepackage{tikz}
\usepackage{etoolbox}

\begin{document}

\csdef{My Node Option}{draw=red, thick, fill=yellow}

\noindent
\begin{tikzpicture}
\begingroup\edef\x{\endgroup
\noexpand\tikzset{Node Options/.style={\csuse{My Node Option}}}}%
\x

\node [Node Options] at (0,0) {Node Text};
\end{tikzpicture}%

\end{document}


Note the additional braces around the \csuse.