3

I want to be able to typeset syntactic trees in a way that will achieve the following:

  • straight spine when there is no label on the nonterminal node
  • obtuse angle at each (binary) branch (so the tree is not too tall)

I'm having trouble making forest or (tikz-)qtree to achieve this easily. Surely there is someone with a solution to this problem out there.

Basically I want to achieve this (basically what I am asking is: what's some code to output something that looks similar to this:):

what I want

but what I get with tikz-qtree is

qtree

which I got using the following code:

\usepackage{tikz,tikz-qtree-compat}
    \tikzset{baseline=0pt,level distance=20pt,sibling distance=0pt}
\begin{document}
    \Tree [.CP [.who ] [ [.$\lambda_1$ ]
        [.IP [.$t_1$ ] [.registered ] ] ] ] 
\end{document}

or, with forest:

forest

using the following code:

\usepackage[linguistics]{forest}
\newcommand{\tree}[1]{
    \begin{forest}
        for tree={
        inner sep=0pt,
        % where n children=0{font=\itshape}{},
     %    calign=fixed edge angles,
        parent anchor=south,
      },
      before typesetting nodes={% page 52: example (81)
        where content={}{% shape=coordinate gives an error if used here but this is *almost* right - it just leaves a little, tiny gap
          text width=.001pt,
          inner sep=0pt,
          before drawing tree={% here we make sure that the tiny gap disappears so only the size is not quite dimensionless
            shape=coordinate,
            typeset node,
          },
          for parent={
            for children={
              anchor=north,
            }
          }
        }{}
      }
      #1
    \end{forest}
}

\begin{document}
    \tree{
        [CP [who] [ [$\lambda_1$] 
        [IP [$t_1$] [registered]]]]
    }
\end{document}

Does anyone have an easy way of getting nice trees like in the first image (where not all nonterminals have labels, but some do, and the spine is nice and straight, but the trees are not too tall (i.e. distance between levels is small, in particular when the node labels are short. Perhaps another way to state this: lower limit on the angle at each branch, while keeping horizontal distance at a minimum too)? I imagine this should be a commonly desired thing among linguists. I'd be happy to learn there's an easy way of doing this... thanks!

4

I haven't used TeX much in the past few years, but I do have existing code that produces the result you're looking for. My nice trees style is cobbled together from several sources (some cited below in the code below, likely some not), and I don't think I can explain exactly what every line is doing. If I recall correctly, I would have to switch to somewhat nice trees on a per-tree basis if there were "divide by 0" errors (as @AlanMunn indicated in the comments on your question, this has been a perennial topic on the site, and there are no perfect solutions as of yet). Still, I'm sharing because your MWE's tree does compile fine (with your desired requirements met) with nice trees. I believe the key for your purposes is calign=fixed edge angles, calign angle=60.

enter image description here

\documentclass{article}
\usepackage{forest}
\forestset{
    nice trees/.style={
        for tree={
            parent anchor=south,
            child anchor=north,
            align=center,
            base=top,
            inner sep=1pt,
            l-=4ex,
            before typesetting nodes={% based on nice empty nodes - page 52 of the manual, used in Jason Zentz's answer: http://tex.stackexchange.com/a/216103/
                if content={}{
                    for parent={
                        for children={anchor=north},
                        calign=fixed edge angles,
                        calign angle=60,              
                    },
                    shape=coordinate,
                    calign=fixed edge angles,
                    calign angle=60,       
                }{},
                if n children=0{delay=with translation}{}  % from http://tex.stackexchange.com/a/205311, in order to reduce the width of triangles/roofs
            },
        },
    },
    somewhat nice trees/.style={
        for tree={
            parent anchor=south,
            child anchor=north,
            align=center,
            base=top,
            inner sep=1pt,
            l-=4ex,
            before typesetting nodes={% based on nice empty nodes - page 52 of the manual, used in Jason Zentz's answer: http://tex.stackexchange.com/a/216103/
                if content={}{
                    for parent={
                        for children={anchor=north},
                        calign=fixed edge angles,
                        calign angle=60,              
                    },
                    inner sep=0pt,
                    edge path={\noexpand\path [\forestoption{edge}] (!u.parent anchor) -- (.south)\forestoption{edge label};}, %from http://tex.stackexchange.com/a/281546
                    calign=fixed edge angles,
                    calign angle=60,       
                }{},
                if n children=0{delay=with translation}{}  % from http://tex.stackexchange.com/a/205311, in order to reduce the width of triangles/roofs
            },
        },
    }
}


\begin{document}
\begin{forest}
nice trees
        [CP [who] [ [$\lambda_1$] 
        [IP [$t_1$] [registered]]]]
\end{forest}

\end{document}
  • 1
    Thank you for putting this answer here. It works for my MWE, indeed, so it’s useful to me. I hope it’s useful to others as well. – postylem Jan 24 at 0:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.