# A condition in \tikzset

I would like to set a drawing option to decorate lines with a circle of a color of my choice, with "none" meaning no circle. I am hoping for something like this:

\documentclass{amsart}
\usepackage{tikz}
\usetikzlibrary{positioning, decorations.markings}
\tikzset{-o-/.style n args={1}{
append after command={\pgfextra{\let\mainnode=\tikzlastnode}% Borrowed this line, but I don't understand it.
\def\argone{#1} \def\argtwo{none}
\ifx\argone\argtwo
\else
decoration={markings, mark=at position 0.5 with {draw[black, fill=#1] circle[radius=2pt];}}, postaction={decorate}
\fi
}}}

\newcommand*{\mytriangle}[1]{
\begin{tikzpicture}
\draw[-o-={#1}] (0,0)--(0,1);
\draw[-o-={#1}] (0,0)--(1,0);
\draw[-o-={#1}] (1,0)--(0,1);
\end{tikzpicture}}

\begin{document}
\mytriangle{white}, \mytriangle{none}.
\end{document}


I tried to borrow

append after command={\pgfextra{...} ...}


from this question, since otherwise ifx conditional does not work inside of \tikzset, but now my code does not make the desired decorations.

• Why don't you set your test within \mytriangle instead of \tikzset? – NBur Jan 11 at 7:51
• I want to use it in a large number of tikz pictures. – Adam Jan 11 at 7:59

You can use a .code type and invoke \pgfkeysalso inside the code instead of evaluating the conditional inside a .style. Internally a .style is just that, \tikzset{foo/.style={bar}} does the same as \tikzset{foo/.code=\pgfkeysalso{bar}}, but in .code you can evaluate arbitrary code, and not only call \pgfkeysalso.

Note that you don't need append after command for this (you're using the decorations.markings library for the placement of the code).

I borrowed \str_if_eq:nnF from expl3 for this (your \def\argone{#1}\def\argtwo{none}\ifx test could work, too, but might have unwanted side effects of redefining the two macros \argone and \argtwo, you'd have to put a group around that test for it to be safe).

\documentclass{amsart}

\ExplSyntaxOn
\cs_new_eq:NN \ifstreqF \str_if_eq:nnF
\ExplSyntaxOff

\usepackage{tikz}
\usetikzlibrary{positioning, decorations.markings}
\tikzset
{
-o-/.code=%
{%
\ifstreqF{#1}{none}
{%
\pgfkeysalso
{
decoration=%
{%
markings,
mark=at position 0.5 with {\draw[black, fill={#1}]
},
postaction={decorate}
}
}
}
}

\newcommand*{\mytriangle}[1]{
\begin{tikzpicture}
\draw[-o-={#1}] (0,0)--(0,1);
\draw[-o-={#1}] (0,0)--(1,0);
\draw[-o-={#1}] (1,0)--(0,1);
\end{tikzpicture}}

\begin{document}
\mytriangle{white}, \mytriangle{none}.
\end{document}


Side note on your test: The following would be a working and safe variant of it:

\begingroup
\def\argone{#1}%
\def\argtwo{none}%
\expandafter
\endgroup
\ifx\argone\argtwo
<true>
\else
<false>
\fi


The \begingroup ...\endgroup keeps the definitions of \argone and \argtwo local, and thanks to \expandafter the \ifx is evaluated before the definitions of \argone and \argtwo are restored by the end of the group.

• Thanks, that works great! As it was a minimal example, now I am trying to add the position of the circle as the second argument, so that I can use \draw[-o-={white}{0.5}] .... I tried \tikzset{-o-/.code with n args={2}{\ifstreqF{#1}{none {\pgfkeysalso{decoration={markings, mark=at position #2 with {\draw[black, fill={#1}] circle[radius=2pt];}},postaction={decorate}} but it doesn't work... – Adam Jan 11 at 21:19
• @Adam because the correct name is .code n args without the with, also, for 2 args, consider using .code 2 args instead. – Skillmon Jan 11 at 21:23
• Of course. Thanks! – Adam Jan 11 at 21:24
• @Adam but first take a look at the documentation of .code 2 args, it differs from .code n args={2}{...}, which you could take advantage of, if you so wanted. – Skillmon Jan 11 at 21:26