I was bugged by the same problem for quite a while... and I think I have finally found a solution that's usable in everyday life ;-)
I defined a new (generic) anchor top base
, which does the job in non-complicated cases.
\documentclass{article}
\usepackage{tikz}
\makeatletter
\pgfdeclaregenericanchor{top base}{%
\csname pgf@anchor@#1@north\endcsname
\pgf@anchor@generic@top@base@main
}
\pgfdeclaregenericanchor{top base west}{%
\csname pgf@anchor@#1@north west\endcsname
\pgf@anchor@generic@top@base@main
}
\pgfdeclaregenericanchor{top base east}{%
\csname pgf@anchor@#1@north east\endcsname
\pgf@anchor@generic@top@base@main
}
\def\pgf@anchor@generic@top@base@main{%
{%
\pgfmathsetlength\pgf@ya{\pgfkeysvalueof{/pgf/outer ysep}}%
\advance\pgf@y-\pgf@ya
\pgfmathsetlength\pgf@ya{\pgfkeysvalueof{/pgf/inner ysep}}%
\advance\pgf@y-\pgf@ya
\pgf@ya=0pt
\pgfutil@loop
\ifdim\pgf@y>\baselineskip
\advance\pgf@y-\baselineskip
\advance\pgf@ya\baselineskip
\pgfutil@repeat
\global\pgf@y=\pgf@ya
}%
}
\makeatother
\begin{document}
The following node
\begin{tikzpicture}
[align=center,baseline=(a.base)]
\node(a){sticks\\up};
\end{tikzpicture}
while the next one
\begin{tikzpicture}
[align=center,baseline=(a.top base)]
\node(a){sticks\\down};
\end{tikzpicture}
\end{document}
The anchor (actually, the three anchors, because I also defined the east and the west version) is then of course usable also in within a tikzpicture
. An example follows.
\begin{tikzpicture}[align=center,every node/.style={draw,outer sep=2pt}]
\node(a){first node\\with\\some text};
\node[anchor=top base west,at=(a.top base east)] (b)
{this node\\is anchored\\at top base\\and positioned\\at top
base\\of the node\\on its left};
\node[anchor=base west,at=(b.top base east)](c)
{this node\\is anchored\\at base\\and positioned\\at top
base\\of the node\\on the left};
\node[anchor=top base west,at=(c.base east)](d)
{anchored\\at base\\positioned\\at top
base\\of the left node};
\end{tikzpicture}
How does it work? It first deduces the height (without depth) of the original box where the node text was typeset. Then it estimates the number of newlines by counting how many \baselineskip
s fit in the height, and sets the top base
anchor that much to the north.
The problems: two. First, the procedure fails if a font larger than \baselineskip
was used in the box --- ok, I can live with that. Second, much more problematically, it only works for some shapes (rectangle, ellipse, and some others). For other shapes it is impossible to deduce the height of the original box; the information is of course there when saved anchors are computed, but then it gets lost... more precisely, it cannot be recovered from saved anchors and dimensions. I'm thinking the only way to hack this is to define a new shape (say circle'
), inheriting everything from circle
and adding additional saved dimensions/anchors.
I hope this helps, although it is not as generic as the name suggests :-)
\documentclass
and the appropriate packages so that those trying to help don't have to recreate it.baseline
key.