Although I clearly saw Alan's original answer, I have no memory of it and so when seeing this immediately starting thinking about how I would get some text automatically into a node.
There are several "hooks" in the construction of a node which can be used. Although these hooks are intended for certain purposes, they can be subverted for others, and some aren't really intended for anything but are just "general hooks".
The key macro in the TikZ code is \tikz@do@fig
(reminds me of the card game Go Fish!). Looking through this macro, we find the following hooks, together with some other important stuff:
- The first thing that happens in that a box is started, called
\pgfnodeparttextbox
. This is what will be put inside the node as its "text" (and used for size computations).
- The first "hook" is:
\tikzset{every text node part/.try}
. So anything stored in that key gets evaluated. This can include arbitrary code. However, adding text at this point does nothing as we are still in "picture mode".
- The next important thing is that we get out of "picture mode". Now things can start to have an effect.
- At this point,
\tikz@textfont
is executed. This contains whatever was saved by the font
key. Literally. This is the secret to Alan's method.
- Now it tests to see if the text was given a width, and if so starts a minipage (and a group).
- Next hook is
\tikz@atbegin@node
. This is a general purpose hook that can contain anything. As we're out of the picture mode, any text here is visible so this can be used to insert text. This is used to great effect in keys like matrix of math nodes
to insert the magic $
at the start of the node. However ...
- Now we set the colour. This means that all the previous hooks were enacted before the colour was set.
- At this point,
\tikz@do@fig
is almost done. The last bits are to set up some stuff for after the node text is processed.
- The node text is now read.
- After the node text is read, control passes over to
\tikz@fig@collectresetcolor
. This does something with resetting colours, but only if explicitly asked. I'm not at all clear as to the effect that this has.
- Control now passes to
\tikz@fig@boxdone
.
- The first thing that happens here is
\tikz@atend@node
is executed (this is used by matrix of math nodes
to insert the final $
).
- Next, we tear down all of the stuff that
\tikz@do@fig
set up with no obvious hooks (one could play with \aftergroup
and similar hacks, but only with Great Care).
So, we have three hooks provided by the keys font
, execute at begin node
, and execute at end node
. Each has a drawback in that each is separated from the real text by one or more actions:
font
occurs before any text width
is taken into account, and before the text=colour
is enacted.
execute at begin node
is before text=colour
is enacted.
execute at end node
is after whatever the \reset@color
is doing.
One other fact is important to note before putting all of this theory into practice. That is the question as to what colour is in effect at the start of all these shenanigans. This is the fill colour. This is quite important to note because it explains why Alan's code is seeming to fail in your example. It isn't. The text is there. It's just that it is rendered with the same colour as the fill. This suggests a simple addition to Alan's solution: set the colour explicitly.
Now, in fact, I'd recommend using execute at begin node
instead of font
. This is because font=X
sets the hook to X
, overriding anything already set. Whereas execute at begin node=X
appends X
to the list of things to be "executed". This makes it easier to manipulate in stages.
Here's some experimental code:
\documentclass{article}
%\url{http://tex.stackexchange.com/q/48918/86}
\usepackage{tikz}
\makeatletter
\def\usetextcolour{%
\ifx\tikz@textcolor\pgfutil@empty%
\else%
\pgfutil@colorlet{.}{\tikz@textcolor}%
\fi%
\pgfsetcolor{.}%
}
\makeatother
\tikzset{
every node/.style={
draw=orange,
fill=blue,
text=red
},
auto text colour/.style={
execute at begin node=\usetextcolour
},
method 1/.style={
every text node part/.style={add text}
},
add text/.code={first method},
method 2/.style={
font={\usetextcolour second method}
},
method 3/.style={
auto text colour,
execute at begin node={second method}
},
method 4/.style={
execute at end node={third method}
},
}
\begin{document}
\begin{tikzpicture}
\foreach \k in {1,...,4} {
\node[method \k] at (0,-\k) {lorem};
}
\end{tikzpicture}
\end{document}
The "first method" tries to use the every text node part/.try
hook but fails as that's too early. The other methods are the other hooks. An interesting experiment to try (to verify what I said about colours) is to set fill opacity=0,text opacity=1
and to remove the references to \usetextcolour
. This shows that the text added by the second and third methods is in the fill colour, as claimed.
Here's the results with the above code:
I think that of these methods, I'd go for the execute at end node
hook. Whilst that \reset@color
stuff worries me a bit, it doesn't worry me all that much so it seems the cleanest hook to get stuff into the node contents automatically.
font={}
was not designed to place text in a node.align=right,font={$x+2$\\very bad idea }