3

If I wish to add a pin to a node in TiKZ, I can do so like this:

\documentclass[tikz,border=5pt]{standalone}

\begin{document}

  \begin{tikzpicture}
    \node [draw, thick, circle, minimum width=10pt, pin=-90:A Circle] {};
  \end{tikzpicture}

\end{document}

pin

Now suppose I wish to draw a number of circles. I might define a custom style but suppose that 'circle' is actually a place-holder for some more complex bit of code. In that case, I might define a pic:

\documentclass[tikz,border=5pt]{standalone}

\begin{document}

  \tikzset{
    my circle/.pic={
      \node [draw, thick, circle, minimum width=10pt] {};
    },
  }

  \begin{tikzpicture}
    \pic {my circle};
  \end{tikzpicture}

\end{document}

If I wish to include text inside my circles, I can use the pic text facility to do this:

\documentclass[tikz,border=5pt]{standalone}

\begin{document}

  \tikzset{
    my circle/.pic={
      \node [draw, thick, circle, minimum width=10pt] {\tikzpictext};
    },
  }

  \begin{tikzpicture}
    \pic [pic text=A Circle] {my circle};
    \pic [pic text=Another] at (20mm,0) {my circle};
  \end{tikzpicture}

\end{document}

pic texts

Or, I could use the pic text to create pins:

\documentclass[tikz,border=5pt]{standalone}

\begin{document}

  \tikzset{
    my circle/.pic={
      \node [draw, thick, circle, minimum width=10pt, pin=-90:\tikzpictext] {};
    },
  }

  \begin{tikzpicture}
    \pic [pic text=A Circle] {my circle};
    \pic [pic text=Another] at (20mm,0) {my circle};
  \end{tikzpicture}

\end{document}

pic text pins

Now suppose that some of my circles need pins and others do not:

\documentclass[tikz,border=5pt]{standalone}

\begin{document}

  \tikzset{
    my circle/.pic={
      \node [draw, thick, circle, minimum width=10pt, pin=-90:\tikzpictext] {};
    },
  }

  \begin{tikzpicture}
    \pic [pic text=A Circle] {my circle};
    \pic  at (20mm,0) {my circle};
  \end{tikzpicture}

\end{document}

pic text pins and pic text empty pins

How can I test whether the pin text is empty or not within the pic so that I can execute the pin part of the code conditionally? I'm assuming there is a fairly easy way to do this but I just couldn't find it. Although I solved my immediate problem by bruite force, I'd like a more elegant solution.

Things I tried: the \def\tempa{} \def\tempb ... \ifx\tempa\tempb ... trick; the same trick with various other kinds of def (\edef, \xdef); various things from etoolbox more-or-less at random; trying to figure out a workaround using .try and an independent labelling system; searching the TiKZ manual; searching this site; etc. Since nothing came anywhere near working, I will not give a blow-by-blow account. Most of my attempts failed to compile. I did get some to compile, but they were insensitive to whether or not pic text had been specified so the code, while apparently mostly harmless, was also evidently useless.

egreg's tests

This was the thread which seemed to come closest to what I wanted, albeit it not terribly close. So I tried the tests suggested there. For example, here is my attempt to apply the no-printed-output test (which I took to be the most promising):

 \tikzset{
    my circle/.pic={
      \setbox0=\hbox{\tikzpictext\unskip}\ifdim\wd0=0pt
        \node [draw, thick, circle, minimum width=10pt] {};%
      \else
        \node [draw, thick, circle, minimum width=10pt, pin=-90:\tikzpictext] {};%
      \fi
    },
  }

This compiles, which is good, but it treats all cases as empty, which is less good.

The \unskip, \hfuzz and \detokenize tests also compile but these treat all cases as non-empty (which is maybe not surprising since pic text has a default value, albeit an empty one):

  \tikzset{
    my circle/.pic={
      \if\relax\detokenize{\tikzpictext}\relax
        \node [draw, thick, circle, minimum width=10pt] {};%
      \else
        \node [draw, thick, circle, minimum width=10pt, pin=-90:\tikzpictext] {};%
      \fi
    },
  }

What is the right way to implement this test?

5

I searched through the pgf souce for \tikzpictext and found the following solution (more or less):

\documentclass[tikz,border=5pt]{standalone}
\begin{document}

\tikzset{my circle/.pic={
  \ifx\tikzpictext\relax
      \node [draw, thick, circle, minimum width=10pt] {};%
    \else
      \node [draw, thick, circle, minimum width=10pt, pin=-90:\tikzpictext] {};%
    \fi
  };
}

\begin{tikzpicture}
    \pic [pic text=A Circle] {my circle};
    \pic  at (20mm,0) {my circle};
\end{tikzpicture}

\end{document}

tikzpictest

  • Thank you! Not only does this work for the MWE, it also works more or less out-of-the-box for my actual code ;). – cfr Oct 15 '14 at 0:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.