# Detecting if inside a tikzpicture node

I would like to detect if a macro is executed inside a tikzpicture or more specific inside a node of a picture. In my MWE I used \ifpgfpicture which does not do the job because it considers the node content as 'outside' the picture. I would like to see 'INSIDE' as node text.

I am not looking for any additions to the tikzpicture environment like some every picture tricks to remember that we are inside the environment. Is there any already existing state macro/variable of pgf/tikz which can be questioned for this purpose?

\documentclass{article}
\usepackage{tikz}

\newcommand{\testinpic}{%
\ifpgfpicture INSIDE \else OUTSIDE\fi%
}

\begin{document}

\testinpic

\begin{tikzpicture}
\fill[blue!10!white] (-4,-1) rectangle (4,1);
\node {\testinpic};
\end{tikzpicture}

\end{document}


• I think the answer is no but not 100% sure. The text is put into an hbox or minipage environment before placed in the node shape. So you need to patch the node placement code to insert a hook. Otherwise it will never be inside since everything is expanded before the placement. – percusse Jun 27 '13 at 8:58
• I'm with percusse on this. Looking at the code, then TikZ goes to a lot of trouble to ensure that what happens inside a node is pretty similar to what happens in ordinary text. So I think I would go for a new conditional and add it to every tikzpicture via the execute at begin picture style. I think that would be more reliable than trying to hook into something in the node structure. – Loop Space Jun 27 '13 at 9:11
• Related Question: Detecting if inside a tikzpicture – Peter Grill Nov 7 '18 at 23:30

You can do

\documentclass{article}
\usepackage{tikz}

\makeatletter
\newcommand{\testinpic}{%
\ifx\pgfpictureid\@undefined OUTSIDE \else INSIDE\fi%
}
\makeatother

\begin{document}

\testinpic

\begin{tikzpicture}
\fill[blue!10!white] (-4,-1) rectangle (4,1);
\node {\testinpic};
\end{tikzpicture}

\end{document}

• I fear I have to expect nested environments. Therefore, this solution would not help. – Thomas F. Sturm Jun 27 '13 at 11:40
• @ThomasF.Sturm try now:-) – David Carlisle Jun 27 '13 at 11:55
• @DavidCarlisle Yes, that's it! :-) I've just checked it with my application and it does what it should do. Thank you! – Thomas F. Sturm Jun 27 '13 at 12:37

With some possibly unwise hacking like this maybe? With multiple nesting it would get confusing.

\documentclass{standalone}
\usepackage{tikz}

\makeatletter
\newif\iftikzinsidepicture
\newif\iftikzinsidenode
\def\tikz@picture[#1]{%
\pgfpicture%
\tikzinsidepicturetrue%
\let\tikz@atbegin@picture=\pgfutil@empty%
\let\tikz@atend@picture=\pgfutil@empty%
\let\tikz@transform=\relax%
\def\tikz@time{.5}%
\tikz@installcommands\scope[every picture,#1]%
\expandafter\tikz@atbegin@picture%
\tikz@lib@scope@check%
}

\let\tikz@do@fig@main@orig=\tikz@fig@main
\def\tikz@fig@main{%
\tikzinsidepicturefalse%
\tikzinsidenodetrue%
\tikz@do@fig@main@orig%
}
\makeatother

\def\test{{\footnotesize
\iftikzinsidenode
INSIDE-NODE
\iftikzinsidepicture
INSIDE-NODE-PICTURE
\else
OUTSIDE-NODE-PICTURE
\fi
\else%
\iftikzinsidepicture
INSIDE-PICTURE
OUTSIDE-NODE
\else
OUTSIDE-PICTURE
\fi
\fi}}

\begin{document}

\begin{tabular}{l}

\test \\

\begin{tikzpicture}

\fill[blue!20] (-4,-1) rectangle (4,1);
\pgftext{\test}

\node [fill=red!20] at (0,-0.5){\test};

\node [fill=white] at (0,0.5){ \tikz{\pgftext{\test}} };

\end{tikzpicture}

\end{tabular}
\end{document}


• This is not the answer I hoped for, since it is hacking the tikz code. That's too risky for the application I have in mind, but nevertheless I think it could be very interesting for other applications. – Thomas F. Sturm Jun 27 '13 at 11:34