I'm looking to draw labeled arrows linking normal math text fragments like this with TikZ:
Asked
Active
Viewed 1,725 times
1 Answers
11
A solution in TikZ, which sets the components of the math expression as series of nodes. Then the annotation labels are placed as nodes. Finally the arrows are drawn between the nodes.
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{arrows.meta}
\usepackage{bookman}
\begin{document}
% \[
% \lambda x.\,(\lambda x.\, x\,y)\,
% (x\,(\lambda x.\,\lambda y.\,y\,z\,x))
% \]
\[
\begin{tikzpicture}[
inner sep=0pt,
outer sep=0pt,
baseline=(lx_1.base),
]
\path[every node/.append style={anchor=base west}]
(0, 0)
\foreach \name/\code in {
lx_1/\lambda x,
tmp/.\,(,
lx_2/\lambda x,
tmp/.\,,
x_1/x,
tmp/\,,
y_1/y,
tmp/)\,(,
x_2/x,
tmp/\,(,
lx_3/\lambda x,
tmp/.\,,
ly_1/\lambda y,
tmp/.\,,
y_2/y,
tmp/\,,
z_1/z,
tmp/\,,
x_3/x,
tmp/))%
} {
node (\name) {$\code$}
(\name.base east)
}
;
\path[
every node/.append style={
anchor=base,
font=\slshape\scriptsize,
},
]
% Annotation: frei
(y_1.base) -- node[above=1.2\baselineskip] (frei) {frei} (z_1)
% 4 annotations: gebunden
(lx_1.base) -- node[below=3\baselineskip] (geb_1) {gebunden} (x_2)
(lx_2.base) -- node[below=1.4\baselineskip] (geb_2) {gebunden} (x_1)
(lx_3.base) -- node[below=3\baselineskip] (geb_3) {gebunden} (x_3)
(ly_1.base) -- node[below=1.4\baselineskip] (geb_4) {gebunden} (y_2)
;
\begin{scope}[
>={Stealth[length=5pt]},
thick,
rounded corners=2pt,
shorten <=.3em,
shorten >=.3em,
]
\draw[->] (frei) -| (y_1);
\draw[->] (frei) -| (z_1);
\def\GebArrow#1#2#3{
\draw[->]
(#2.north) ++(0, .3em) coordinate (tmp)
(#1) |- (tmp) -| (#3)
;%
}
\GebArrow{x_2}{geb_1}{lx_1}
\GebArrow{x_1}{geb_2}{lx_2}
\GebArrow{x_3}{geb_3}{lx_3}
\GebArrow{y_2}{geb_4}{ly_1}
\end{scope}
\end{tikzpicture}
\]
\end{document}
Heiko Oberdiek
- 271,626


arrows.metaprovides more arrow tips and customisation. – cfr Sep 08 '16 at 21:06