In multiline mode (align=center
) in forest, there is extra vertical space around the node. The first tree below is not in multiline mode. The second is in multiline mode, and there is extra space above and below the node text, even with only one line. How can I make the second tree look like the first? (Many of the nodes in my actual tree do have multiple lines, which is why I am using multiline.)
\documentclass{standalone}
\usepackage{forest}
\begin{document}
\begin{forest}
[A, for tree={parent anchor=south, child anchor=north, draw}
[B]
[C
[D]
[E]
]
]
\end{forest}
\begin{forest}
[A, for tree={parent anchor=south, child anchor=north, align=center, draw}
[B]
[C
[D]
[E]
]
]
\end{forest}
\end{document}
I tried reducing inner ysep
, and it initially appeared to help (the space around the node text is smaller but still off-center), but then I have problems with some nodes overlapping:
\documentclass{standalone}
\usepackage{forest}
\begin{document}
\begin{forest}
[A, for tree={draw, parent anchor=south, child anchor=north, align=center, inner ysep=1pt }
[B\\long node]
[C
[D\\long multiline, triangle]
]
]
\end{forest}
\end{document}
I should also mention that I am not using draw
to box the nodes in my real trees, just bare node text. I use it here because it makes it clear that it is the node size, not the edge position, that is the issue. This extra space makes it look like the edges are starting farther from the nodes, rather than the nodes being taller.
Best Answer
This is a hack. It is provided as is. There are no guarantees. I don't even guarantee that it has anything to do with forest, multiline nodes or TeX. At this point, in case it is not clear, I should state that I guarantee nothing whatsoever. If the code dials the CIA, MI5 and the KGB and offers them your cat in exchange for a tube of Smarties, don't say I didn't warn you.
Caveat emptor...
Here's the idea:
If we put a
tabular
into a node in a tree which does not usealign
to create multiline nodes, we get just the same results as we do usingalign
. However,tabular
itself doesn't add vertical space, so we can't set that space to 0 as it is already zero.If we put a
minipage
into a node in the same tree, the spacing is the same as putting the contents of theminipage
in the node alone. (Assuming the node has only one line.)So, if we could create multiline nodes as
minipage
s rather thantabular
s, then it would work as desired. (Whether what is desired is desirable is left for you to determine, gentle reader.)This is not as straightforward as it sounds because a
minipage
, unlike atabular
requires a width and we don't want to have to set a width for all nodes in the tree.Surely, there are easier ways to do this and doubtless there are far more efficient ones. Especially a TeX guru would likely do this far better.
At this point, the gentle reader is urged to review again the statement above concerning guarantees and the danger to the cats of all readers, however gentle.
We start by creating a new style
squat multiline
for trees of this kind:We need a couple of custom forest options:
Now we start manipulating the nodes. We do this in cycles to ensure that each set of keys are processed for each node before the next set of keys is processed for each node.
This is round one:
In effect, this saves the content of the node. It copies it, basically. We delay this else the content won't be set when we try to copy it.
Now for the next round:
This wraps the content in a
tabular
environment like that used byalign=center
. We are going to use this to get the width for theminipage
.We typeset the node now, earlier than usual, because we need to get the width next.
The final round:
We set
thiswidth
using the width of the node as it currently is.Now we reset the content of the node in a
minipage
of widththiswidth
. We use the copy of the contents fromthiscontent
because otherwise we'll get thetabular
wrapper as well.We've already got one lot of
inner xsep
because it was included when we typeset the node originally. So we set it to 0 to avoid getting double the usual amount:We need to tell forest to typeset the node again:
Just the usual anchors from the original example:
Now we can use the new style. The first example compares the default spacing with that used by
squat multiline
when the content of the nodes are identical:Then the example with larger nodes and a roof:
The style does not appear be responsible for the slight misalignment of the roof here as I get the same issue when I compare the default style with drawn nodes.
Comparison:
In any case, I assume that the combination of a roof and
draw
is unlikely to be desirable, and the misalignment is only noticeable because the nodes are drawn for purposes of illustration.Complete code: