# Adding words centered above other words with TikZ v2 [closed]

EDIT: Please vote to close this question as "Unclear what you're asking". My problem and my understanding of it have developed in such a way that this question is now too messy. I have opened the new questions In TikZ, adjust the placement of a node above text and Adjust placement of commas and periods in TikZ txt style.

## ------------------------------------

This is a follow-up to the question I asked in Adding words centered above other words with TikZ. I've tried to implement Jason's suggestion, but I've found that it has spawned enough follow-up questions that it's best to simply address them in a separate question here.

(EDIT: It's now best to skip down to the edit at the bottom of this question.)

A MWE with output below:

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc}
\newlength{\Aheight}
\setlength{\Aheight}{\fontcharht\fontA}

\newcommand{\inline}[2]{%
\begin{tikzpicture}[baseline=(word.base), txt/.style={shape=rectangle, inner sep=0pt}]
\node[txt] (word) {#1};
\node[above] at (word.north) {\footnotesize{#2}};
\end{tikzpicture}%
}
\newcommand{\phraselabel}[2]{%
\begin{tikzpicture}[baseline=(word.base), txt/.style={shape=rectangle, inner sep=0pt}, text height = \Aheight, text depth = 0pt]
\node[txt] (word) {#1};
\node[above] at (word.north) (label) {\footnotesize{#2}};
\pgfkeysgetvalue{/pgf/inner xsep}{\myxsep}
\pgfresetboundingbox
\useasboundingbox ($(label.south west) + (\myxsep,0)$) rectangle (label.north east);
\end{tikzpicture}%
}

\begin{document}
\begin{enumerate}
\item \inline{gg}{xx} \inline{aa}{jj} \inline{tt}{xx} \inline{bb}{jj}.
\item \phraselabel{gg}{xx} \phraselabel{aa}{jj} \phraselabel{tt}{xx} \phraselabel{bb}{jj}.
\item gg aa tt bb.
\item \phraselabel{gg}{xxxxx} \phraselabel{aa}{jjjjj} \phraselabel{tt}{xxxxx} \phraselabel{bb}{jjjjj}.
\end{enumerate}
\end{document}


The new command \inline is Jason's suggestion, and the new command \phraselabel is my attempt to tweak it towards what I want.

First problem: In 1., we see that the label is not affected by descenders of the word below, something Jason did by setting baseline = (word.base) (xx is horizontally aligned with jj over the first two words). But 1. also shows that the labels are strongly affected by themselves having descenders (compare xx with jj over the first two words), and by the words below having ascenders (the xx over tt is lower than the jj over bb, since t has a shorter ascender than b).

I've fixed this problem in 2. by setting text depth = 0pt (cf. this answer) and text height to the height of the font's A character, which is normally the tallest text character a font has (cf. Wikipedia and this answer). But now I have a worry. Aren't I setting this up so that both the words below and the labels above have text boxes with the height of A? Clearly I have no need to set the height of the text boxes for the labels above to A. I only need to do this for the words below so that the labels above don't collide with words that have ascending characters like A. Is there a better way to do this? Also, I've used the height of A because it is the highest character I know of. But what if I want the labels even higher - how do I accomplish that? Presumably by tweaking the node[above] setting?

Second problem: In 1., the sentence is pushed away from the left margin. I've fixed this in 2. with code from this answer. It fixes that problem, but I think it gets entangled with the third problem.

Third problem: In 1., despite the code inner sep = 0pt, there's a lot of extra space between the words. This is improved in 2. because the extra space on the left side of the labels has been removed by changing the bounding box. Not only is there still too much space between the words, as seen when comparing with 3., but I am pretty sure that this is not the correct way to tweak the space between the words. If, for instance, I remove the extra space on the right side of the labels with \useasboundingbox ($(label.south west) + (\myxsep,0)$) rectangle ($(label.north east) - (\myxsep,0)$);, then the words are mushed together. How can I set the space here correctly? Note, however, that extra space between the words should emerge if the labels are so wide that they risk colliding with other lables (cf. 4.).

Fourth problem: In both 1. and 2., the final period . is, as a result of the problem just noted above, being pushed away from the last word. This is even clearer in 4. where the labels are wider. How can I make the label above the last word (and a label that would be above a word followed by a comma) not care about the final period? Note that it wouldn't be a proper solution to simply include the period into the word, as \phraselabel{bb.}{jj}, because the label jj would then be centered with respect to bb. and not bb. The alignment would therefore be off.

If this all means that there are simply too many problems with this approach, and that another approach altogether would be better, I'm open to suggestions. I think it's best to stick with TikZ, however, since I will include things like curly braces and arrows later.

## -----------------------------------------------------

EDIT

I've made some headway now, partly driven by suddenly understanding that I might understand better what's going on by adding boxes around the words and labels with draw.

MWE:

\documentclass{article}
\usepackage{tikz}
\newlength{\Aheight}
\setlength{\Aheight}{\fontcharht\fontA}

\newcommand{\phraselabel}[2]{%
\begin{tikzpicture}[baseline = (word.base), txt/.style = {shape = rectangle, inner sep = 0pt, text height = \Aheight, draw}, above/.style = {inner sep = 0pt, text depth = 0pt, draw}]
\node[txt] (word) {#1};
\node[above] at (word.north) (label) {\footnotesize{#2}};
\end{tikzpicture}%
}

\begin{document}
\begin{enumerate}
\item \phraselabel{gg}{xx} \phraselabel{aa}{jj} \phraselabel{tt}{xx} \phraselabel{bb}{jj}.
\item gg aa tt bb.
\item \phraselabel{gg}{xxxxx} \phraselabel{aa}{jjjjj} \phraselabel{tt}{xxxxx} \phraselabel{bb}{xxxxx}.
\end{enumerate}
\end{document}


The main fix here is that I've specified two separate styles txt/.style and above/.style, and specified them in appropriate ways (e.g. adding inner sep = 0pt to above/.style). The output is now this:

The boxes let me see that the interword spaces in 1. are now correct. It matches regular spaces. There are now two things I need to achieve:

1. How do I adjust the vertical placement of the nodes above the words?
2. The placement of a final period (cf. 4.) is not based on the word on the baseline, but on whichever element (baseline word or node above) is further into the margin. How can I make it only care about the baseline word?

## closed as unclear what you're asking by Sverre, user13907, Keks Dose, user31729, darthbithApr 10 '15 at 21:19

Please clarify your specific problem or add additional details to highlight exactly what you need. As it's currently written, it’s hard to tell exactly what you're asking. See the How to Ask page for help clarifying this question. If this question can be reworded to fit the rules in the help center, please edit the question.

• Why don't you just delete the question if you no longer have a use for it? – cfr Apr 10 '15 at 20:46
• @cfr I considered that, but the problems raised and their fixes might be useful for others who have the same problems. They might end up here by searching for the relevant words. Even though they're not problems to me anymore, they might be for future users. – Sverre Apr 10 '15 at 20:51
• Given all these constraints (and especially that you want to tag every word), it might be better to approach this a different way. See my new answer to your original question, which uses expex to handle all the labeling and then you can use tikz to add frills. – Jason Zentz Apr 10 '15 at 22:52