Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

This is a followup question to Expandable nested boxes with TikZ.

When using the \tikz command inside the tikzpicture environment, the positioning of the contents is altered.

Here are the two examples:

enter image description here

And the code responsible:

\documentclass{article}

\usepackage{tikz}
\usetikzlibrary{backgrounds,shapes.multipart}

\begin{document}

Here we have a
\begin{tikzpicture}[show background rectangle]
  \node[draw, rectangle split, rectangle split parts=2] at (0,0)
    { foo%
      \nodepart{two}
        bar
    };
\end{tikzpicture} picture.

Here we have a
\begin{tikzpicture}[show background rectangle]
  \tikz{
    \node[draw, rectangle split, rectangle split parts=2] at (0,0)
      { foo%
        \nodepart{two}
          bar
      };
  }
\end{tikzpicture}
picture.

\end{document}

The lower left corner of the node in the second example is just right in the middle of the picture, so there must be a very good reason it is there. :-) Which one?

share|improve this question
add comment

2 Answers

up vote 6 down vote accepted

You can't use \tikz inside a tikzpicture environment like this. I have no idea what you are trying to do or what makes you think you can do this.

The \tikz command is the short version of the tikzpicture environment. Having it direct inside a tikzpicture environment makes as much sense as using a tikzpicture environment inside a tikzpicture environment!

So you second picture is basically:

\begin{tikzpicture}[show background rectangle]
\begin{tikzpicture}
    \node[draw, rectangle split, rectangle split parts=2] at (0,0)
      { foo%
        \nodepart{two}
          bar
      };
\end{tikzpicture}
\end{tikzpicture}

Still wondering why this doesn't get you good results?

The only surprise here is that both doesn't raise an error message! (This should be sent as bug report to the developers.)

You can't safely use arbitrary normal typesetting commands inside a tikzpicture. It's whole content is placed into a dummy TeX box which is later discarded while the drawing commands add their material into a second box which is typeset afterwards. Try adding some text without anything else into the picture. TikZ will just ignore it. You can however safely use \tikz or tikzpicture inside the content of a node. TikZ takes care to interrupt the current picture while processing the node content.

I could now speculate why you get exactly the output you get, but this would matter much. Apparently the size/bounding box survives but the placement is of.


If you want to be able to use drawing code inside and outside a node you can see if you are currently inside a tikzpicture by testing of e.g. \path has its normal TikZ definition. Note that TikZ reverts its own commands to the previous definition when typesetting the contents of nodes.

\documentclass{article}

\usepackage{tikz}
\usetikzlibrary{backgrounds,shapes.multipart}

\makeatletter
% Ensures processing of content inside a `tikzpicture` (using the short version `\tikz`)
\newcommand{\ensuretikz}{%
  \ifx\path\tikz@command@path
    \expandafter\@firstofone
  \else
    \expandafter\tikz
  \fi
}
\makeatother

\begin{document}

Here we have a
\begin{tikzpicture}[show background rectangle]
  \node {
  \ensuretikz{%
  \node[draw, rectangle split, rectangle split parts=2] at (0,0)
    { foo%
      \nodepart{two}
        bar
    };
 }
 };
\end{tikzpicture} picture.

Here we have a
\begin{tikzpicture}[show background rectangle]
  \ensuretikz{
    \node[draw, rectangle split, rectangle split parts=2] at (0,0)
      { foo%
        \nodepart{two}
          bar
      };
  }
\end{tikzpicture}
picture.

\end{document}
share|improve this answer
    
Is there a way to define a new command which draws a node (say rectangle) and add the \tikz command if it is called inside the content of another node? –  Nickolay Kolev May 20 '11 at 9:48
    
@Nickolay: I updated my answer to include a possible solution. You should have stated this in the question from the beginning so that people know what you are trying to achieve. –  Martin Scharrer May 20 '11 at 10:22
    
I know that it sounds odd to have a \tikz command inside a tikzpicture environment but, under some circumstances it can be helpful and I really liked this when I noticed that it could be done. I don't see this as a bug, but as a feature. –  Gonzalo Medina May 20 '11 at 18:36
    
@Gonzalo: It doesn't seem to work reliable. I would use a scope or \node {\tikz{...}}; instead. –  Martin Scharrer May 20 '11 at 18:38
    
ah, yes... I meant using \tikz as the argument of \node (as I suggested in some other answer here); I didn't read carefully this question, so I initially didn't realize that Nickolay was using \tikz "directly" inside \tikzpicture, which, in fact, doesn't seem the right thing to do. Sorry for the misunderstanding. –  Gonzalo Medina May 20 '11 at 18:53
show 1 more comment

I find this question before asking this one

I don't understand why a tikzpicture inside a tikzpicture is a wrong thing, I understand that it's perhaps strange or very strange but there are some examples of linked environments.

I realize with the pgfornament package that it's possible but we need to be careful. Till Tantau thought about this with \tikzifinpicture (see the question how to check ... Ok it's perhaps a wrong idea but it works despite the Tantau'comment

% TT: This is a wrong test! Who uses this?...

Now the problem is simple : You are inside a tikz's picture and you create a new picture (tikz or not tikz). This picture is placed at the current point, here the center of the rectangle, and by default the picture is placed with the south west anchor like in this case :

enter image description here

    \documentclass{article}    
    \usepackage{tikz}
    \usetikzlibrary{backgrounds,shapes.multipart}
    \begin{document}

Here we have \tikz{%
    \node[draw, rectangle split, rectangle split parts=2]  at (0,0)
      { foo%
        \nodepart{two}
          bar
      }; 
        } and  \tikz[baseline=(current bounding box.center)]{
    \node[anchor=west,draw, rectangle split, rectangle split parts=2]  at (0,0)
      { foo%
        \nodepart{two}
          bar
      }; 
        } picture.  

    \end{document}

In your case you need to do the same thing :

enter image description here

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{backgrounds,shapes.multipart}

\begin{document}

Here we have a   
\begin{tikzpicture}[show background rectangle]
    \tikz[baseline=(x.center)]{
    \node[anchor=west,draw, rectangle split, rectangle split parts=2] (x) at (0,0)
      { foo%
        \nodepart{two}
          bar
      };
  }% 
\end{tikzpicture}
picture.  

\end{document} 
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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