TransWikia.com

linguistics-style trees in Metapost

TeX - LaTeX Asked on December 17, 2021

I’m trying to find the best way to draw linguistics-style trees in a way which is as agnostic as possible to the variety of TeX which is used (LaTeX, ConTeXt, or plain ol’ TeX). Most of the ways to draw trees are, understandably, made for LaTeX (the qtree variants and forest), and aren’t easily adapted to ConTeXt or plain TeX.

My first thought was to use METAPOST to draw the trees and include the results as PDF or PS graphics, since this removes any dependency on TeX varieties. I found the metaobj package for METAPOST which makes drawing trees easy-ish. For example, I have the following MWE:

input metaobj;

prologues:=3;

beginfig(1);

    setObjectDefaultOption("Tree")("hbsep")(5mm);
    setObjectDefaultOption("Tree")("treenodehsize")(2cm);
    setCurveDefaultOption("arrows")("draw");

    t:=_T(Tr_(btex VoiceP etex))
        (
            Tr_(btex vbox{hbox{DP}hbox{He}} etex),
            _T(Tr_(""))
            (
                Tr_(btex Voice etex),
                Tr_(btex vbox{hbox{$v$P}hbox{runs}} etex)
            )
        );

    Obj(t).c=origin;
    draw_Obj(t);
    
endfig;

Metapost Tree

For comparison, I’ll include the same tree made with qtree:

documentclass{standalone}

usepackage{qtree}

begin{document}
    Tree [.VoiceP [.DP\He ] [ [.Voice ] [.$v$P\runs ] ] ]
end{document}

QTree Tree

The METAPOST version gets 90% of the way there, but there are some problems with the way that metaobj trees are drawn:

  1. A node’s branches are each drawn from a different point, instead of a common point at the center-bottom of the node.
  2. The branching angle and branch lengths are not consistent across the tree. Ideally, these would be the same so that the height of the node text wouldn’t change the tree structure too much and node-less branches wouldn’t be bent.
  3. I’m not sure how to center multi-line labels.

How can metaobj/METAPOST be used to get the desired tree style? And, taking a step back from METAPOST, is this the best way to draw trees in this style in a way which is agnostic to the TeX variant used? I went with METAPOST since it produced diagrams which could easily be used in any flavor of TeX, it allows for the inclusion of TeX code in the drawing routine (for example, to switch fonts), and it produces high-quality graphics with support for lots of useful things (for example, drawing movement arrows using regular METAPOST arrows, colors, all the regular drawing capabilities, support for multiple figures in the same file, etc).

2 Answers

Disclaimer: this is in Metapost but it's not really a proper answer to the question.

It is, of course, possible to draw anything nicely with Metapost, such as this version of your tree:

enter image description here

but as you can see below, I did not do that using a qtree-like syntax. Whether you think this is "easy" is a matter of opinion, experience, number of trees you want to do, etc.

You could invest time in writing some MP that processed qtree notation, or in patching metaobj, or in writing macros for your own notation, or you could just draw trees one at a time, like this:

prologues := 3;
outputtemplate := "%j%c.eps";

beginfig(1);

    numeric dx, dy;
    dx = 34; dy = -13; 

    z0 = origin;
    z1 = z0 + (-dx, dy);
    z2 = z0 + (+dx, dy);

    z21 =  z2 + 3/4(-dx, dy);
    z22 =  z2 + 3/4(+dx, dy);

    z100 = (x1, 3dy); 
    z200 = (x22, 3dy);

    draw z1 -- z0 -- z2;
    draw z21 -- z2 -- z22;

    label.top(btex VoiceP etex, z0);

    picture p[];
    p1  = thelabel.bot(btex DP etex, z1);
    p21 = thelabel.bot(btex Voice etex, z21);
    p22 = thelabel.bot(btex {it v/}P etex, z22);
    p100 = thelabel.bot(btex strut He etex, z100);
    p200 = thelabel.bot(btex strut runs etex, z200);
    forsuffixes $=1, 21, 22:
        draw p$;
    endfor
    forsuffixes $=100, 200: 
        draw p$ withcolor 2/3 blue;
    endfor
    
    vardef connect(suffix a, b) = 
        draw point 1/2 of bbox p.a -- point 5/2 of bbox p.b dashed withdots scaled 1/4;
    enddef;
    connect(1, 100);
    connect(22, 200);

    undraw bbox currentpicture; % add a small margin
    
endfig;
end.

On the specific issues you have with metaobj:

  • I cannot see any simple way to get it to draw the lines as you want -- it is aiming at the centre of each node and cutting the lines at the bounding boxes, this will mean that the lines are usually at different angles. There does not seem to be any option available to make it draw lines at regular angles.

  • Centering multiline labels is a plain TeX issue, rather than a metaobj problem. Each label goes in an hbox as usual, so you could add a block like this near the top of your file

     verbatimtex
     defs#1{vbox{let\crhalign{hfil ##hfilcr #1crcr}}}.  
     etex
    

    then you can do things like: label(btex s{Above\below} etex, origin);

Answered by Thruston on December 17, 2021

Disclaimer: It is not a solution in Metapost, but it could be useful.

As Alan Munn commented, TikZ/PGF is generic, so tikz-qtree and should be portable to Plain TeX and ConTeXt. forest is also based on TikZ/PGF, but it is tricky due to its LaTeX dependencies. The following is an example of tikz-qtree in ConTeXt I'm not proud of, but it is a proof of concept.

usemodule[tikz]

unprotect
%Shamelessly taken from:
%https://wiki.contextgarden.net/LaTeX_Math_in_ConTeXt
let@@end=end
appendtoks
letend=@@end
to everystoptext

%This is really ad hoc.
%It will possibly break things when you try
%loading other packages better suited
%to LaTeX
defbegin#1{%
    csname #1endcsname}
defend#1{%
    csname end#1endcsname}

input pgfsubpic.tex
input pgftree.tex
input tikz-qtree.tex
protect  

starttext
starttikzpicture
[level distance=40pt]
Tree [.S [.NP [.N this ] ]
[.VP [.V is ]
[.NP edge[roof]; {a noun phrase} ] ] ]
stoptikzpicture
stoptext

enter image description here

For some reason, a similar approach for Plain doesn't work for me and I didn't expected as I'm not a Plain user, but is feasible as you can see.

Answered by user220367 on December 17, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP