# tikz nodes for subformulae (nested in nodes)

One of the features I really valued in pstricks (I have long changed to tikz and this is the only feature I am missing) is that I could just designate any fragment as a node and then connect that to other nodes I had lying around.

Here is a specific example I came up while converting legacy code for my lecture.

\begin{tikzpicture}[yscale=1.5]
\node (love) at (2,0) {$\text{love}$};
\node (aform) at (0,1) {$\forall{X}\text{man}(X)\rightarrow\Box$};
\node (eform) at (4,1){$\exists{X}\text{woman}(X)\wedge\Box$};
\node (top) at (2,2) {$\Box$};
\draw[dashed,->] (top) --node[left] {1} (aform);
\draw[dashed,->] (top) --node[right] {2} (eform);
\draw[dashed,->] (aform.east) --node[left] {3} (love);
\draw[dashed,->] (eform.east) --node[rightl] {4} (love);
\end{tikzpicture}


But I am cheating in the last two lines of the picture. What I really want to do is to link the boxes in the nodes aform and eform to the node love. In pstricks I would just have used the \rnode macro and done something like

\node (aform) at (0,1) {$\forall{X}\text{man}(X)\rightarrow\rnode{abox}{\Box}$};
\node (eform) at (4,1){$\exists{X}\text{woman}(X)\wedge\rnode{ebox}{\Box}$};


and used the node labels simply with (now pure tikz again)

\draw[dashed,->] (abox) --node[left] {3} (love);
\draw[dashed,->] (ebox) --node[rightl] {4} (love);


I have tried various things, e.g. using \tizk[remember picture]\node (abox) {\Box}; but nothing I came up with worked. I would be grateful to learn how to do this.

-
While code snippets are useful in explanations, it is always best to compose a fully compilable MWE that illustrates the problem including the \documentclass and the appropriate packages so that those trying to help don't have to recreate it. While solving problems is fun, setting them up is not. Then those trying to help can simply cut and paste your MWE and get started on solving problem. – Peter Grill Nov 23 '12 at 9:16
that makes sense, I apologize for the omission and will do better in the future. – Michael Kohlhase Nov 28 '12 at 16:32

It's the lucky case where you can use labels since the boxes are at the end but otherwise you have to chop the text into different nodes (or use more labels).

\documentclass{standalone}
\usepackage{tikz,amsmath,amssymb}
\begin{document}
\begin{tikzpicture}[yscale=1.5,label distance=-0.3em]
\node (love) at (2,0) {$\text{love}$};
\node[label={[name=aformlabel,anchor=base]0:$\Box$}] (aform) at (0,1) {$\forall{X}\text{man}(X)\rightarrow$};
\node[label={[name=eformlabel,anchor=base]0:$\Box$}] (eform) at (4,1){$\exists{X}\text{woman}(X)\wedge$};
\node (top) at (2,2) {$\Box$};
\draw[dashed,->] (top) --node[left] {1} (aformlabel);
\draw[dashed,->] (top) --node[right] {2} (eformlabel);
\draw[dashed,->] (aformlabel) -- node[left] {3} (love);
\draw[dashed,->] (eformlabel) -- node[right] {4} (love);
\end{tikzpicture}
\end{document}


-

Update tikzmark is now available on CTAN and contains this \subnode command.

The latest version of the tikzmark package (currently available in beta form from the TeX-SX Launchpad page - download tikzmark.dtx and run tex tikzmark.dtx to create the necessary files) has a \subnode command which ought to do what you want. The syntax is \subnode{<name>}{<content>}. What it does in effect is to create a tight-fitting rectangular node around the content with name name. How it does this is not so important except that you need to use the remember picture key on the picture in order to refer to this pseudo-node and it takes two runs to settle down. If you want to have a usual node, or a different shape, then use the fit library to put one around it, as in \node[ellipse,fit=(othernode)] {};. The fact that the pseudo-node is tight-fitting means that this will be the same size as it would have been had it been created in normal circumstances.

This is experimental code, so please let me have any feedback on its usefulness or unexpected behaviour.

\documentclass{article}
%\url{http://tex.stackexchange.com/q/83911/86}
\usepackage{amsmath}
\usepackage{amssymb}
\usepackage{tikz}
\usetikzlibrary{tikzmark,fit}

\begin{document}

\begin{tikzpicture}[remember picture]
\node (a) {this \subnode{b}{is} in a box};
\node at (0,-.5) (d) {this is in a box};
\node at (1,1) (c) {c};
\draw[->] (c) -- (b);
\node[fit=(b),draw,inner sep=0pt] {};
\draw[->] (a.north) to[bend right] (b.north);
\end{tikzpicture}

\begin{tikzpicture}[yscale=1.5,remember picture]
\node (love) at (2,0) {$\text{love}$};
\node (aform) at (0,1) {$\forall{X}\text{man}(X)\rightarrow\subnode{mbi}{$\Box$}$};
\node (eform) at (4,1){$\exists{X}\text{woman}(X)\wedge\subnode{wbi}{$\Box$}$};
\node (top) at (2,2) {$\Box$};
\node[fit=(mbi)] (mb) {};
\node[fit=(wbi)] (wb) {};
\draw[dashed,->] (top) --node[auto,swap] {1} (aform);
\draw[dashed,->] (top) --node[auto] {2} (eform);
\draw[dashed,->] (mb) --node[auto,swap] {3} (love);
\draw[dashed,->] (wb.240) --node[auto] {4} (love);
\end{tikzpicture}

\tikz[remember picture,overlay] \draw[->] (0,0) to[bend left] (b);

\end{document}


The above produces the following for your diagram (commenting out the other parts):

-
Excellent, this was exactly what I was looking for. In fact I had been hoping that someone point me to this. It solves my problem completely, and makes me even happier with tikz than I had been before. Thanks a lot. One question though, you only introduced the nodes mb and wb for the bit of space they put around the boxes? Or are they for didactic reasons only. I would have expected to get the "space effect" with a outer sep, but that does not seem to work. – Michael Kohlhase Nov 28 '12 at 16:31
Yes, those are for "space effect". I decided in the implementation to keep the subnode tight around its text box. That makes it more flexible with fitting odd shaped nodes around it afterwards. But then if one wants to use it as an ordinary rectangular node, one needs to add the space back in. Maybe I should make it so that one can pass options to the subnode creation to be able to (in effect) combine those steps - it's very much early days on this. – Loop Space Nov 28 '12 at 17:19
Just to say that I've now implemented my thoughts in the above comment. The nodes mb and wb can be subsumed into the \subnode command. It might take a few iterations for the code to settle down so I'll wait before editing my post above until it has. – Loop Space Dec 11 '12 at 17:12