# Shorter trees with horizontal terminal nodes and empty nodes (with forest)

I'm submitting a computational paper to an ACL-style journal. I need trees that have horizontally-aligned terminal nodes and no node labels (parser doesn't provide them). This question relates to this one; I took code from some comments (updated a little) resulting in trees that are short enough to fit in my paper, but they are terribly ugly.

MWE:

\documentclass[11pt,letterpaper]{article}
\usepackage[letterpaper]{geometry}
\usepackage{acl2012}
\usepackage{caption}
\usepackage{subcaption}
\usepackage{amsmath}
\usepackage{forest}
\forestset{
nice empty nodes/.style={
for tree={
s sep=0.1em,
l sep=0.33em,
inner ysep=0.4em,
inner xsep=0.05em,
l=0,
calign=midpoint,
fit=tight,
where n children=0{
tier=word,
minimum height=1.25em,
}{},
where n children=2{
l-=1em,
}{},
parent anchor=south,
child anchor=north,
delay={if content={}{
inner sep=0pt,
edge path={\noexpand\path [\forestoption{edge}]
(!u.parent anchor)
-- (.south)\forestoption{edge label};}
}{}}
},
},
}

\begin{document}
\begin{forest}
nice empty nodes
[ [ [ [He] [swung] ] [ [at] [the] ] ] [ [ [brute] [\textbf{with}] ] [ [\textbf{his}] [, phantom ] [ [\textbf{sword}] [$.$] ] ] ] ]
\end{forest}

\begin{forest}
nice empty nodes
[ [He] [ [ [ [swung] [ [at] [ [the] [brute] ] ] ] [ [\textbf{with}] [ [\textbf{his}] [\textbf{sword}] ] ] ] [$.$] ] ]
\end{forest}%
\end{document}


It produces these two trees:

I spent about 15 hours on the issue, as did 3 or 4 others in my group, so it seems like a toughy...

Desiderata:

1. straight lines between the root node and the leftmost and rightmost terminal nodes
2. a tree that is as small as possible, vertically
3. Word spacing that's not too crazy (doesn't have to be completely even)
4. no weird things happening with changing line depth based on variations in height of symbols (e.g., periods and tall letters)

Potentially something that looks like the next tree, but that doesn't require so much manual tikz time and isn't so vertically tall...

Any advice?

• Your knowledge is much more advanced than mine at this point, so I can't provide a complete answer, but try including the two lines calign=fixed edge angles and calign primary angle=-75,calign secondary angle=75, under your current line calign=midpoint, and continue adapting the other features. I have no idea what the rest of your code does in detail, but I hope you do. – thymaro Oct 22 '17 at 20:53
• Hi Adina, are you sure those are the structures you want? :) 'at the' as a constituent...? – Alan Munn Oct 24 '17 at 19:28

## 1 Answer

Frankly, Forest is not good at drawing this style of tree. This means that any solution will make compromises and will work even tolerably well for only a limited variety of trees.

(4) is easy. The remaining desiderata are essentially inconsistent, given the way Forest draws trees.

Here are a couple of possibilities.

\documentclass[border=10pt]{standalone}
\usepackage{forest}
\forestset{
somewhat nice/.style={
for tree={
fit=band,
parent anchor=children,
child anchor=parent,
anchor=parent,
delay={
if content={}{
inner sep=0pt,
edge path'={(!u.parent anchor) -- (.children)},
}{content/.wrap value=\strut ##1},
},
},
before drawing tree={
tempdima/.min={y}{tree},
where n children=0{y/.register=tempdima}{},
},
before computing xy={
for tree={
l/.process={ dOw+nw2+d  {40pt} {level} {##1+1} {##1/##2} }
}
}
},
}
\begin{document}
\begin{forest}
somewhat nice
[ [ [ [He] [swung] ] [ [at] [the] ] ] [ [ [brute] [\textbf{with}] ] [ [\textbf{his}] [, phantom ] [ [\textbf{sword}] [$.$] ] ] ] ]
\end{forest}

\begin{forest}
somewhat nice
[ [He] [ [ [ [swung] [ [at] [ [the] [brute] ] ] ] [ [\textbf{with}] [ [\textbf{his}] [\textbf{sword}] ] ] ] [$.$] ] ]
\end{forest}

\end{document}


This does a not-too-bad job of the first tree, I think, given the difficulties involved. It improves the second, though to a lesser extent.

Or, possibly,

\documentclass[border=10pt]{standalone}
\usepackage{forest}
\forestset{
declare dimen register={base ht},
base ht'=40pt,
somewhat nice/.style={
for tree={
fit=band,
parent anchor=children,
child anchor=parent,
anchor=parent,
delay={
if content={}{
inner sep=0pt,
edge path'={(!u.parent anchor) -- (.children)},
}{content/.wrap value=\strut ##1},
},
},
before drawing tree={
tempdima/.min={y}{tree},
where n children=0{y/.register=tempdima}{},
},
before computing xy={
for tree={
l/.process={ ROw+nw2+d  {base ht} {level} {##1+1} {##1/##2} }
}
}
},
}
\begin{document}
\begin{forest}
somewhat nice
[ [ [ [He] [swung] ] [ [at] [the] ] ] [ [ [brute] [\textbf{with}] ] [ [\textbf{his}] [, phantom ] [ [\textbf{sword}] [$.$] ] ] ] ]
\end{forest}

\begin{forest}
base ht'=30pt,
somewhat nice,
for tree={
calign=fixed edge angles,
calign angle=40,
},
before packing={
for nodewalk={
r,
while nodewalk valid={1}{1},
fake=r,
while nodewalk valid={l}{l}
}{calign angle=60},
}
[ [He] [ [ [ [swung] [ [at] [ [the] [brute] ] ] ] [ [\textbf{with}] [ [\textbf{his}] [\textbf{sword}] ] ] ] [$.$] ] ]
\end{forest}

\end{document}

• Yea absolutely, forest doesn't seem ideal for this task... I had the intuition that it might fare better than qtree, but if there's yet another package that might be easier, let me know; I'd be fine with switching. – Adina W. Oct 25 '17 at 21:38
• @AdinaW. Well, it probably does better than qtree. Ask Alan Munn for suggestions. He's a tree-drawing-linguist. I never have to draw this particular kind of tree myself. – cfr Oct 30 '17 at 4:37