# Create dependency graphs between characters

I was asked in thread 139691 to open a new question - so here we go:

I need to create dependency graphs between characters in LaTex.

As the output shall be processed via "pdflatex" later on, I opted for "TikZ" being said to be compatible with "pdflatex". As "TikZ" itself seems to be to "a science unto itself", I tried out "TikZ-dependency" like depicted in thread 139691.

Nevertheless, I was unable to achieve with "TikZ-dependency" what I want (cf. example drawn in Freeoffice below).

Additionally, one has to bear in mind that there might be more complex examples than the one shown, where alliterations resp. assonances intersect, so that a second row of annotation boxes "Alliteration" resp. "Assonance" with arrows pointing to characters would be needed (like in the examples shown in the package documentation of "tikz-dependency"). However the arrows of the second row's annotations should of course not cross the first row of annotation boxes in front, but in the background behind.

I would be glad if anyone could give me a manageable solution to this challenge. Manageable is meant in terms of simple applicability to a large number of examples.

• Welcome! Please post the code which you tried so that we have something to work from rather than starting from scratch.
– cfr
Oct 18, 2015 at 15:52
• Why not just create the images in Freeoffice and use \includegraphics to include them in your document? If that's how you want them to look, why not use the obvious solution?
– cfr
Oct 18, 2015 at 16:01
• Here's the code I tried:
– Oli
Oct 18, 2015 at 16:17
• Ooops - I will try it in an answer...
– Oli
Oct 18, 2015 at 16:17
• @cfr: In principle a good idea to draw the images in Freeoffice and insert them as such in Tex. However, to draw such an image in Freeoffice is a lot of fumbling around and time consuming, hence unsuitable for numerous examples. I did it only to provide an example what I'm looking for here in forum. Moreover, the font used in Freeoffice will differ from the one in Tex.
– Oli
Oct 18, 2015 at 16:36

Here's one possibility; more than one level can be used:

\documentclass{article}
\usepackage{xparse}
\usepackage{tikz}
\usetikzlibrary{calc}

\newcommand\TMark[2]{\tikz[remember picture,baseline=(#1.base)]\node[inner sep=0pt,outer sep=0pt] (#1) {#2};}

\tikzset{
common/.style={
draw,
rounded corners,
minimum height=20pt,
fill=white
}
}

\newcounter{alltmp}
\newcounter{asstmp}

\def\shiftSign{+}

\NewDocumentCommand\Allit{O{2.5\baselineskip}O{black}mm}{%
\stepcounter{alltmp}%
\foreach \Value [count=\xi] in {#4} {};
\node[common]
at ([yshift=#1]{ $(all#31)!0.5!(all#3\xi)$ }|-all#31.base)
(alli-\thealltmp) {Alliteration};
\foreach \Value [count=\j] in {#4}
{
\path[draw,->,#2]
let
\p1=(alli-\thealltmp),
\p2=(\Value.north)
in
node
{\ifdim\x1>\x2\relax
\gdef\ShiftSign{-}%
\gdef\Angle{210}%
\gdef\Xshift{0em}%
\gdef\Mult{30}%
\else
\gdef\ShiftSign{+}%
\gdef\Angle{300}%
\gdef\Xshift{0em}%
\gdef\Mult{0}%
\fi
}
(alli-\thealltmp.\Angle-\ShiftSign\j*\Mult) .. controls ++(\Xshift,-1em) and ++(0,1em) .. ([yshift=.5ex]\Value.north);
}
}

\newenvironment{verseanalysis}
{\begin{tikzpicture}[remember picture,overlay,>=latex]}
{\end{tikzpicture}}

\NewDocumentCommand\Asson{O{2.5\baselineskip}mm}{%
\stepcounter{asstmp}%
\foreach \Value [count=\xi] in {#3} {};
\node[common]
at ([yshift=-#1]{ $(ass#21)!0.5!(ass#2\xi)$ })
(asso-\theasstmp) {Assonance};
\foreach \Value [count=\j] in {#3}
{
\path[draw,->]
let
\p1=(asso-\theasstmp),
\p2=(\Value.south)
in
node
{\ifdim\x1>\x2\relax
\gdef\ShiftSign{-}%
\gdef\Angle{60}%
\gdef\Xshift{0em}%
\gdef\Mult{60}%
\else
\gdef\ShiftSign{+}%
\gdef\Angle{100}%
\gdef\Xshift{0em}%
\gdef\Mult{20}%
\fi
}
(asso-\theasstmp.\Angle-\ShiftSign\j*\Mult) .. controls ++(\Xshift,1em) and ++(0,-1em) .. ([yshift=-0.5ex]\Value.south);
}
}

\begin{document}

\TMark{all11}{L}azy \TMark{all12}{l}\TMark{ass11}{oo}ns are \TMark{all13}{l}\TMark{ass12}{oo}king at squ\TMark{ass21}{i}rrels and \TMark{all21}{b}\TMark{ass22}{i}rds in \TMark{all22}{b}\TMark{ass23}{i}rch trees

\begin{verseanalysis}
\Allit{1}{all11,all12,all13}
\Allit{2}{all21,all22}
\Asson{1}{ass11,ass12}
\Asson{2}{ass21,ass22,ass23}
\end{verseanalysis}

\vspace*{4cm}

On a pr\TMark{all11}{ou}d wh\TMark{all21}{i}te h\TMark{all22}{i}gh r\TMark{all12}{ou}nd n\TMark{all23}{i}ght cl\TMark{all13}{ou}d

\begin{verseanalysis}
\Allit[5\baselineskip][red!70!black]{2}{all21,all22,all23}
\Allit{1}{all11,all12,all13}
\end{verseanalysis}

\end{document}


• Cool - I'd like to express my full admiration for your programming skills! May I humbly ask if it would possible to align the two annotation boxes "Assonance" to the same height? As for the arrows, is it possible to have them not with a straight line, but S-shaped so that the tip of the arrow points perpenticularly to the character from above resp. from below? Thanks and best regards, Oli
– Oli
Oct 18, 2015 at 17:35
• @Oli Thnaks for your kind words. I incorporated your suggestions to my code and added some improvements; now you can have more than one level. Oct 19, 2015 at 14:59
• Fantastic, thanks a lot. May I bring up again the vertical alignment of the two annotation boxes "Assonance" in your first example? They are indeed of same height, but not aligned evenly. The left annotation box is hanging lower than the right one. Yet in the code - as far as I succeeded in understanding it - I coundn't indentify differing vertical offset commands. Would it be possible to fix that little cosmetic issue, please?
– Oli
Oct 20, 2015 at 19:09

You could use tikzmark. For example:

\documentclass[tikz,border=10pt]{standalone}
\tikzset{
ling feat/.style={draw, rounded corners, thick, inner color=gray!10, outer color=gray!20, drop shadow},
ling feat above/.style={ling feat, above=10mm of #1, anchor=south},
ling feat below/.style={ling feat, below=10mm of #1, anchor=north},
ling feat line/.style={-{Stealth[bend]}, semithick}
}
\begin{document}
\begin{tikzpicture}[remember picture]
\node (sent) {\subnode{a1c}{L}azy \subnode{a2c}{l}\subnode{b1c}{oo}ns are \subnode{a3c}{l}\subnode{b2c}{oo}king at squ\subnode{c1c}{i}rrels and \subnode{d1c}{b}\subnode{c2c}{i}rds in \subnode{d2c}{b}\subnode{c3c}{i}rch trees.};
\foreach \i in {a1,a2,a3,b1,b2,c1,c2,c3,d1,d2}
\node (\i) [fit=(\i c), inner sep=0pt] {};
\node (A1) [ling feat above=a2.north] {Alliteration};
\node (D1) [ling feat above=d1 |- a2.north] {Alliteration};
\node (B1) [ling feat below=b2.south] {Assonance};
\node (C1) [ling feat below=c2 |- b2.south] {Assonance};
\foreach \i/\j in {A1.240/a1,A1.320/a2,A1.330/a3,D1.240/d1,D1.300/d2}
\draw [ling feat line] (\i) [out=-90, in=90] to (\j);
\foreach \i/\j in {C1.150/c1,C1.140/c2,C1.60/c3,B1.110/b1,B1.30/b2}
\draw [ling feat line] (\i) [out=90, in=-90] to (\j);
\end{tikzpicture}
\end{document}


Here's the code I tried:

\documentclass{scrartcl}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{tikz-dependency}

\begin{document}
\begin{dependency}[theme=default]
\begin{deptext}[column sep=-.5ex]
\& L \& azy \& l \& oo \& ns are \& l \& oo \& king at \dots \\
\end{deptext}
\depedge[<->]{1}{3}{6}{Alliteration}
\depedge[<->]{4}{7}{Assonance}
\end{dependency}
\end{document}


The result was:

Apparent shortcomings:

• Third node at position 6 not interpreted correctly
• Arrows not pointing to the correct positions
• Spaces also within the words and not only between them
• Distance between text line and annotation boxes too long, i.o.w. arrows too long
• Both annotation boxes on top of text line and not one above and the other below
• If I may ask, why did you choose to put your attempt as an answer instead of editing the question? Oct 18, 2015 at 17:02
• You're right. My apologies for that. The simple reason is, that I'm not yet so familiar with all of the functionalities of this forum.
– Oli
Oct 18, 2015 at 17:23

Here's an idea using the text effects along path decoration. In this example, each character is typeset in a node named c-<word>-<letter>. The code for the arrows is, however, a bit crude and could probably be done more efficiently.

\documentclass[tikz,border=5]{standalone}
\usetikzlibrary{decorations.text, positioning}
\begin{document}
\begin{tikzpicture}
\path [decoration={text effects along path,
text=Lazy Loons are looking at squirrels and birds in birch trees.,
text effects/.cd,
path from text, text along path,
word count=\w, letter count=\l,
characters/.append={text height=1.5ex, name=c-\w-\l}},
decorate] (0,0);
\node [draw, above=1em of c-2-4] (a1) {Alliteration};
\foreach \i [count=\j] in {1-1, 2-1, 4-1}
\draw[->] (a1.150+\j*60) .. controls ++(0,-1em) and ++(0,1em) .. (c-\i.north);
\node [draw, above=1em of c-8-5] (a2) {Alliteration};
\foreach \i [count=\j] in {8-1, 10-1}
\draw[->] (a2.180+\j*60) .. controls ++(0,-1em) and ++(0,1em) .. (c-\i.north);
\node [draw, below=1em of c-3-1] (a3) {Assonance};
\foreach \i [count=\j] in {2-2, 4-2}
\draw[->] (a3.180-\j*60) .. controls ++(0,1em) and ++(0,-1em) .. (c-\i.south);
\node [draw, below=1em of c-8-1] (a4) {Assonance};
\foreach \i [count=\j] in {6-4, 8-2, 10-2}
\draw[->] (a4.210-\j*60) .. controls ++(0,1em) and ++(0,-1em) .. (c-\i.south);
\end{tikzpicture}
\end{document}