# How to anchor labels in tikz for baseline alignment

LaTeX handles subscripts and superscripts nicely, automatically correcting for various sizing and placement issues. I am trying to build a function that works like subscripts and superscripts, but the smaller sized items are placed directly above/below/left/right of the main symbol, rather than upright/downright/upleft/downleft.

If such a command already exists, or you have suggestions for how to build one, I'd certainly appreciate a pointer or ideas.

In the meantime, I have tried many things (for instance \array gymnastics), all of which have problems. At present I am considering a TikZ-based method, as follows.

\newcommand{\putaround}[5]{
\begin{tikzpicture}[inner sep=0ex]
\node [label={[label distance=.1ex]below:$\scriptscriptstyle #2$},
label={[label distance=-.15ex]left:$\scriptscriptstyle #3$},
label={[label distance=.1ex]above:$\scriptscriptstyle #4$},
label={[label distance=-.15ex]right:$\scriptscriptstyle #5$}]
{$#1$}; %[minimum height=1ex,minimum width=1ex] {$\mathfrak A$};
\end{tikzpicture}
}

$\putaround{\mathrm H}{n}{m}{p}{q}$


The first of many issues with this is that the baselines of the left and right entries are off (a situation made especially vivid if you replace the m by an m'). I tried to adjust the label anchoring by adding anchor=mid various places to no avail.

My question then is, is there a way to anchor labels in a way that will correct this baseline/alignment issue?

-

I tried to adjust the label anchoring by adding "anchor=mid" various places to no avail.

I encountered a similar lack of avail in answering How can I force TikZ pin angle? Using the same Extreme Hack that I used that, I got something that works. The key details are:

1. (not really related) use anchor=base on the main node and baseline=0pt on the tikzpicture.
2. For the side labels don't use automatic positioning (as in label=above:X). Use label position and set the label anchor.
3. But to set the label anchor, you need a hack because the automatic positioning will override your explicit choice.

Code:

\documentclass{article}
%\url{http://tex.stackexchange.com/q/97201/86}
\usepackage{tikz}

\makeatletter
\tikzset{reset label anchor/.code={%
\let\tikz@auto@anchor=\pgfutil@empty
\def\tikz@anchor{#1}
},
reset label anchor/.default=center
}
\makeatother

\newcommand{\putaround}[5]{
\begin{tikzpicture}[inner sep=0ex,baseline=0pt]
\node [anchor=base,label={[label
distance=.1ex]below:$\scriptscriptstyle #2$},
label={[label distance=-.15ex,label position=mid west,reset label
anchor=base east]:$\scriptscriptstyle #3$},
label={[label distance=.1ex]above:$\scriptscriptstyle #4$},
label={[label distance=-.15ex,label position=mid east,reset label
anchor=base west]:$\scriptscriptstyle #5$}]
{$#1$}; %[minimum height=1ex,minimum width=1ex] {$\mathfrak A$};
\end{tikzpicture}
}

\begin{document}

$\putaround{\mathrm H}{n}{m'}{p}{q} \mathrm{H}$

\end{document}


Result:

-
I'm wondering if \smashing and positioning on the border shape would be a better way for this. If we can measure the height of the side arguments beforehand, we can shift down half the height and place it on the east and west anchors. And since they are smashed it should not cause any text descending problem. –  percusse Feb 7 '13 at 16:15
The picture above looks great. When I compile the code, though, I get the error message "Missing number, treated as zero" at the \putaround command. –  Chris Feb 8 '13 at 23:01
I managed to avoid that error message on my system by changing the line for label #3 to "label={[label distance=-.15ex,reset label anchor=base east]mid west:$\scriptscriptstyle #3$}," and similarly adjusting the line for label #5. –  Chris Feb 27 '13 at 22:38

You can just set text depth=0pt for the left and right elements to make TikZ ignore the descenders, and text height=0.5ex to ignore the ascenders (thanks Andrew!):

\documentclass{article}
\usepackage{tikz}

\begin{document}
\newcommand{\putaround}[5]{
\begin{tikzpicture}[inner sep=0ex]
\node [label={[label distance=.1ex]below:$\scriptscriptstyle #2$},
label={[label distance=-.15ex, text depth=0pt, text height=0.5ex]left:$\scriptscriptstyle #3$},
label={[label distance=.1ex]above:$\scriptscriptstyle #4$},
label={[label distance=-.15ex, text depth=0pt, text height=0.5ex]right:$\scriptscriptstyle #5$}]
{$#1$};
\end{tikzpicture}
}

$\putaround{\mathrm H}{n}{m'}{p}{q}$
\end{document}

-
And the ascenders? Stick in \int for one of the side labels to see what I mean. You might want to add text height=0pt as well. –  Loop Space Feb 7 '13 at 15:21
@AndrewStacey: You're right, thanks! –  Jake Feb 7 '13 at 15:25
This works very nicely so long as the left and right labels are lower case letters, but because the text height adjustment is fixed, the side labels are no longer well placed if say 'm' and 'q' are replaced by '.' or some other symbol that is shorter or taller than x. –  Chris Feb 8 '13 at 23:32