2

I'm using the forest package for some linguistics diagrams at the moment and I need to number them. However, the label for the numbering is aligned with the bottom of the digram when I want to have it aligned with the top.

Using some dummy examples, here's the current code:

\documentclass{article}
\usepackage{fontspec}
\setmainfont{Brill}
\usepackage{forest}
\forestset{syll/.style=
   {for tree={parent anchor=south,child anchor=north,
              align=center,base=bottom sep=0pt,
              where n children=0{tier=seg}{}}}}
\usepackage{multicol}
\usepackage{gb4e}
\begin{document}
\begin{exe}
\ex
\begin{forest}syll
[,phantom, s sep=1em
[σ [O [p,tier=seg ]]
      [R [μ [aː,name=aa] ] [μ,name=M [,phantom] ]]]
[σ [O [p,tier=seg ]]
      [R [μ [a] ]]]
]
\draw (M.south) -- (aa.north);
\end{forest}
\end{exe}
\begin{exe}
\ex
\begin{multicols}{2}
\begin{xlist}
\ex
\begin{forest}syll
[,phantom, s sep=1em
[σ [O [p,tier=seg ]]
      [R [μ [aː,name=aa] ] [μ,name=M [,phantom] ]]]
[σ [O [p,tier=seg ]]
      [R [μ [a] ]]]
]
\draw (M.south) -- (aa.north);
\end{forest}
\ex
\begin{forest}syll
[,phantom, s sep=1em
[σ [O [l ]]
      [R [μ [a]] [μ [l,name=LL]]]]
[σ [O,name=O [,phantom] ]
      [R [μ [a] [l]]]]
]
\draw[dashed] (O.south) -- (LL.north);
\end{forest}
\end{xlist}
\end{multicols}
\end{exe}
\end{document}

This gives me something like this:

When I want something more like this:

I'm using TeXmaker and compiling using XeLaTeX.

  • Please see my edit, where I figured out the appropriate incantation to make a new environment that does this automatically. – Steven B. Segletes May 31 '16 at 13:54
  • This is not quite a duplicate of gb4e item numbers with tikz-qtree trees because that is for tikz-qtree, but really the underlying issue for both is that this has to do with the external alignment of a tikzpicture (which is what a forest tree really is). You would have the same issue if you made some other kind of diagram in tikz and wanted to put it within a numbered example (whether using gb4e, linguex, or expex). – Jason Zentz May 31 '16 at 15:19
3

EDITED to create new environment newforest, to automatically do the shift.

This is the meat of the EDIT

\usepackage{xpatch,letltxmacro}
\LetLtxMacro\newforest\forest
\LetLtxMacro\endnewforest\endforest
\xpretocmd{\newforest}{\setbox\ForBox=\hbox\bgroup}{}{}
\xapptocmd{\endnewforest}{\egroup\begingroup%
  \raisebox{\dimexpr\baselineskip-\ht\ForBox}{\usebox{\ForBox}}\endgroup}{}{}
\newsavebox{\ForBox}

based on the answer at Patch tabular environment with colorbox

Note: I converted to pdflatex, since I did not have Brill font.

\documentclass{article}
%\usepackage{fontspec}
%\setmainfont{Brill}
\usepackage{forest}
\forestset{syll/.style=
   {for tree={parent anchor=south,child anchor=north,
              align=center,base=bottom sep=0pt,
              where n children=0{tier=seg}{}}}}
\usepackage{multicol}
\usepackage{gb4e}
\usepackage{xpatch,letltxmacro}
\LetLtxMacro\newforest\forest
\LetLtxMacro\endnewforest\endforest
\xpretocmd{\newforest}{\setbox\ForBox=\hbox\bgroup}{}{}
\xapptocmd{\endnewforest}{\egroup\begingroup%
  \raisebox{\dimexpr\baselineskip-\ht\ForBox}{\usebox{\ForBox}}\endgroup}{}{}
\newsavebox{\ForBox}
\begin{document}
\begin{exe}
\ex
\begin{newforest}syll
[,phantom, s sep=1em
[$\sigma$ [O [p,tier=seg ]]
      [R [$\mu$ [aː,name=aa] ] [$\mu$,name=M [,phantom] ]]]
[$\sigma$ [O [p,tier=seg ]]
      [R [$\mu$ [a] ]]]
]
\draw (M.south) -- (aa.north);
\end{newforest}
\end{exe}
\begin{exe}
\ex
\begin{multicols}{2}
\begin{xlist}
\ex
\begin{newforest}syll
[,phantom, s sep=1em
[$\sigma$ [O [p,tier=seg ]]
      [R [$\mu$ [aː,name=aa] ] [$\mu$,name=M [,phantom] ]]]
[$\sigma$ [O [p,tier=seg ]]
      [R [$\mu$ [a] ]]]
]
\draw (M.south) -- (aa.north);
\end{newforest}
\ex
\begin{newforest}syll
[,phantom, s sep=1em
[$\sigma$ [O [l ]]
      [R [$\mu$ [a]] [$\mu$ [l,name=LL]]]]
[$\sigma$ [O,name=O [,phantom] ]
      [R [$\mu$ [a] [l]]]]
]
\draw[dashed] (O.south) -- (LL.north);
\end{newforest}
\end{xlist}
\end{multicols}
\end{exe}
\end{document}

enter image description here

  • That worked exactly as I wanted. Thanks a lot! – Miztli May 31 '16 at 14:05
  • 1
    Ingenious but wouldn't it be easier to use Forest's option? – cfr May 31 '16 at 14:47
  • 1
    @cfr That would require that I learn 'forest`, now wouldn't it :^)? +1 to you. – Steven B. Segletes May 31 '16 at 15:03
  • True. And you ought to have +1 for generality. Though, actually, I think it is TikZ rather than Forest, really. (But you have to know how Forest passes the option, I guess ...) – cfr May 31 '16 at 15:05
6

Forest provides the option baseline which aligns the current node with TeX's baseline when setting the tree. For this case, we can include the option in the definition of the syll style and automatically set the option. The code below sets the root node as the baseline if it is not empty or its first child otherwise.

\documentclass{article}
\usepackage{fontspec}
\setmainfont{Brill}
\usepackage{forest}
\forestset{%
  syll/.style={%
    for tree={
      parent anchor=south,
      child anchor=north,
      align=center,
      base=bottom sep=0pt,
      if n children=0{%
        tier=seg,
      }{},
    },
    where level=0{%
      delay={%
        if content={}{for n=1{baseline}}{baseline}
      }
    }{},
  },
}
\usepackage{multicol}
\usepackage{gb4e}
\begin{document}
\begin{exe}
\ex
\begin{forest}syll
[,phantom, s sep=1em
[σ [O [p,tier=seg ]]
      [R [μ [aː,name=aa] ] [μ,name=M [,phantom] ]]]
[σ [O [p,tier=seg ]]
      [R [μ [a] ]]]
]
\draw (M.south) -- (aa.north);
\end{forest}
\end{exe}
\begin{exe}
\ex
\begin{multicols}{2}
\begin{xlist}
\ex
\begin{forest}syll
[,phantom, s sep=1em
[σ [O [p,tier=seg ]]
      [R [μ [aː,name=aa] ] [μ,name=M [,phantom] ]]]
[σ [O [p,tier=seg ]]
      [R [μ [a] ]]]
]
\draw (M.south) -- (aa.north);
\end{forest}
\ex
\begin{forest}syll
[,phantom, s sep=1em
[σ [O [l ]]
      [R [μ [a]] [μ [l,name=LL]]]]
[σ [O,name=O [,phantom] ]
      [R [μ [a] [l]]]]
]
\draw[dashed] (O.south) -- (LL.north);
\end{forest}
\end{xlist}
\end{multicols}
\end{exe}
\end{document}

baseline alignment

Note that I've changed where n children=0 ... to an if since it is inside the scope of a for tree already and where, unlike if, inserts for tree automatically. It doesn't really do any harm here but for tree={for tree={...}} is unnecessarily complicated and just makes Forest run through all the nodes in the tree n times, where n is the number of nodes in the tree. (At least, I assume so. Unless Forest does something clever to catch this kind of case.)

If you have version 2+ of Forest, you might also wish to look at the linguistics library which applies some options by default, saving you the trouble.

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.