[Tex/LaTex] Is it possible to emulate qtree with forest

forestqtreetikz-pgftrees

This question was actually asked by Alan Munn in a comment to How do I create a LCM tree diagram?. I repeat (and self-answer) it here because the answer is too long to fit the margin 🙂

qtree is a well-known and heavily used package for drawing trees using the so-called bracket notation. (The bracket notation is especially familiar to linguists.) forest is my own, recent package for the same job. Due to the awesome power of pgf/tikz (in particular, the pgfkeys utility), which it is based on, forest is an extremely flexible package. —From the feedback I got so far, including feedback from this site, I don't seem to be the only one who believes so. Which makes me happy. 🙂

Although both qtree and forest encode trees using the bracket notation, the exact syntax is somewhat different. While forest requires that each node (including its children) be enclosed in square brackets (like this: [node [child node] ... [child node]]), qtree relaxes this requirement in the case of terminal nodes (leaves): they can be separated simply by whitespace, like this: [.node leaf ... leaf ]. Furthermore, the packages differ in the encoding of node labels: as showh above, in qtree a bracketed (usually non-terminal) node's label must be preceded by a dot (.).

(forest uses the same syntax as synttree; another package that uses (and extends) qtree's syntax is (obviously) tikz-qtree. As I mentioned in a comment in the above-mentioned question, I have decided for synttree-like syntax purely out of personal taste. I guess I found it more consistent.)

As Alan pointed out, the difference in the syntax makes the potential transition from qtree to forest harder: nobody wants to throw away tons of trees (s)he has painstakingly drawn. Thus Alan's question: would it be possible for forest to support both syntactic dialects?

Best Answer

I'm happy to report that the answer is yes, at least to some extent. I have created a style for forest which achieves code compatibility: the documents containing qtree trees can be used as they are, changing only \usepackage{qtree} to \usepackage{forest-qtree}. (Note an exception to this statement: any commas in the node labels must be enclosed in braces; explanation below.) (For the style to work, forest v1.03 is needed. Since I have just published it today --- yes, I have found some bugs while working on the emulator :-) --- it might not yet be available at CTAN; if so, please download it from GitHub: dtx, ins.)

I have managed to process the qtree manual ("forestified" tex, pdf) with the emulator, omitting only the trees exemplifying qtree's low-level interface. In detail, the emulation covers the [.label child ... [.subtree ...] child ... child ].label syntax, \qroofs, invocation via \Tree, label-less nodes, sub- and superscripts and primes, hooks, escapes, subtree framing, and centering (on the fly and the package options). Essentially, only the length parameters and spacing adjustments are not emulated; and as far as the latter are concerned, I believe that forest (due to its positioning algorithm) does not really need them. ;-)

There is also a dark side to the story, though.

First, the emulation does not produce a visually identical result. The structure of the resulting trees is the same, but the typesetting details are not. This could be improved upon, but I have refrained from doing so, since I believe that the best choice of formatting parameters producing the desired effect(s) will differ from document to document.

Second, the emulation might ease the transition, but it certainly wouldn't be practical to use it in new code. Let me explain.

Assume we have a node containing two leaves. forest representation: [node [child1] [child2]] (spaces between nodes are irrelevant); qtree representation: [.node child1 child2 ] (spaces relevant!). Verdict: qtree's version is easier to write. However ...

... assume we want to put the first child in a frame. In forest, this is achieved by specifying draw on the node (this draw is simply forwarded to tikz's \node), like this: [node [child1,draw] [child2]]. An attempt to do the same in the qtree emulation will fail: [.node child1,draw child2 ] fails with a "unknown key draw child2" error (child1 is typeset, but not framed). This is so because forest uses pgfkeys to parse node-specifications and in pgfkeys, keys are separated by commas. There is no way around this: one must write [.node {child1,draw} child2 ], which obviously eliminates the original advantage of qtree-like syntax; the only thing achieved is that one must change braces to brackets if he decides to give child1 children of its own ...

Btw, emulation obviously also carries a performance penalty, and furthermore, since it is implemented by changing the geometry of the tree on the fly (yes, forest can do that!), this can easily lead to interferences in trees formatted using complex styles.

Related Question