3

I am trying to get the example number to align with the top of the tree and any additional text to align with the bottom of the tree, but I seem to be able to do only one of those.

This code:

\documentclass{scrartcl}

\usepackage[linguistics]{forest}
\usepackage{gb4e}

\begin{document}
\begin{exe}
    \ex
    \begin{forest}
        [This
            [is
                [a]
                [tree]
            ]
            [just]
        ]               
    \end{forest}
    and some text.
\end{exe}
\end{document}

produces Example number, top of tree and example text aligned, whereas this code:

\documentclass{scrartcl}

\usepackage[linguistics]{forest}
\usepackage{gb4e}

\begin{document}
\begin{exe}
    \ex
    \begin{forest}
        [This
            [is
                [a]
                [tree, baseline]
            ]
            [just]
        ]               
    \end{forest}
    and some text.
\end{exe}
\end{document}

produces this: example number, top of tree and example text aligned

Both of them look ugly to me and are against common practice in linguistics as far as I can tell. What I want would be something like this:

example number aligned with top of tree, example text aligned with bottom of tree

I tried simply setting the bottom nodes to baseline and adding a line break after the beginning of the example, but that will introduce page breaks between the example's number and its content, which is really bad as well.

  • I would be happy if someone could tell me whether this actually is the way it's usually done in linguistics. I guess you just don't see trees + text in examples all that often. – sgf Jul 30 '16 at 12:53
  • 1
    Since you asked, I don't think I've ever seen examples with a tree and text next to it. What you do often see is some text (next to the example number) and a tree immediately below that text. Sometimes in the documentation for example packages (and in questions on this site) this is called a "preamble line." – Jason Zentz Jul 30 '16 at 15:15
2

As you may already have gathered, this is not an entirely straightforward thing to do, especially given the desiderata in your comment on Sašo's answer.

For that reason, my solution is far from guaranteed. It passes minimal testing, but it relies on an experimental package, xcoffins. Also, it involves using code written by me, which is doubtless a considerably greater peril to any traveller who ventures down this path.

Caveat emptor ...


I define a new command \excoffintrees for use in the exe environment. It should be used instead of \ex as it will issue \ex itself. The command is defined to support the following forms:

  • for 1 tree:

    • \excoffintrees{<forest tree>}[<optional text>]
    • \excoffintrees*{<forest tree>}[<optional text>]
  • for 2 trees:

    • \excoffintrees{<forest tree>}[<optional text between>]{<forest tree>}[<optional text>]
    • \excoffintrees*{<forest tree>}[<optional text between>]{<forest tree>}[<optional text>]

Although I say <forest tree>, actually, you could put anything similar here. I designed it for trees, but the code isn't specific to them.

The starred form aligns any text between trees at the top. The unstarred form aligns it at the bottom.

Note that the contents cannot be broken over a page, so excessively long text should not be appended as the final argument.

Moreover, it only really makes sense to use something short and sweet between two trees and it will certainly not look right if too much is included here!

The idea, however, is that we can write something like

\begin{exe}

Start the environment as usual.

  \excoffintrees

will issue \ex, so we don't need to include it explicitly (and it would give an error if we did - probably it would complain about a missing \item or something obscure like that).

  {%

This is our first tree.

      \begin{forest}
          [This

To align the trees, we use

\forestset{default preamble=!r.baseline}

You could alternatively add , baseline within the tree specification, if preferred. Or change the default locally for a group of trees.

Now the rest of the tree:

              [is
                  [another]
                  [tree]
              ]
              [just]
          ]
      \end{forest}
  }

Pretty boring. All this really does is align with the number in a very roundabout way. It would be better to just use \ex here.

  \excoffintrees
  {%
      \begin{forest}
          [This
              [is
                  [another]
                  [tree]
              ]
              [just]
          ]
      \end{forest}
  }%

This is a bit more interesting as we have some optional text. Not a lot, but a little. Since there's only one tree, this gets aligned to the baseline of the lowest node in the tree.

  [%
    and little more.
  ]

  \excoffintrees
  {%
      \begin{forest}
          [This
              [is
                  [another]
                  [tree]
              ]
              [just]
          ]
      \end{forest}
  }%

This time we have a lot more stuff after the tree and see that it flows naturally onto subsequent lines.

  [%
    and much more \dots.
    \kant[2]
  ]


  \excoffintrees
  {%
      \begin{forest}
          [This
              [is
                  [another]
                  [tree]
              ]
              [just]
          ]
      \end{forest}
  }%

This one has just a little bit of text after the first tree ...

  [%
    and there
  ]%

... and then another tree, so the preceding text will align to the bottom level of the deepest tree ...

  {%
    \begin{forest}
      [is
        [another tree]
        ]
      ]
    \end{forest}
  }%

... and the final, longer text aligned to the bottom of the lowest node of both trees for the first partial line, and then flowing below the trees into subsequent lines.

  [%
    to complete the sequence.
    \kant[1]
  ]
\end{exe}

This produces the following result:

trees in coffins

or with the starred form:

more trees in coffins

Complete code:

\documentclass[a4paper]{article}
\usepackage[linguistics]{forest}
\usepackage[T1]{fontenc}
\usepackage{gb4e,xcoffins,calc,microtype,kantlipsum}
\forestset{default preamble=!r.baseline}
\NewCoffin\excoffina
\NewCoffin\excoffinb
\NewCoffin\excoffinc
\NewCoffin\excoffind
\newlength\mylength
\newlength\mytemplength
\newlength\mywidth
\makeatletter
\NewDocumentCommand\excoffintrees { s m +O {\makebox[0pt]{\phantom{Xyp}}} g +O {\makebox[0pt]{\phantom{Xyp}}} }
{%
  \setlength\mywidth{\textwidth-\leftmargin}%
  \IfValueTF{#4}{%
    \def\ex@coffintree@tree{#4}%
    \long\def\ex@coffintrees@longtext{#5}%
    \long\def\ex@coffintrees@tween{#3}%
  }{%
    \let\ex@coffintree@tree\relax
    \long\def\ex@coffintrees@longtext{#3}%
    \long\def\ex@coffintrees@tween{\makebox[0pt]{\phantom{Xyp}}}%
  }%
  \ex\makebox[0pt]{\relax}%
  \SetHorizontalCoffin\excoffina
  {%
      #2%
  }%
  \SetHorizontalCoffin\excoffinb
  {%
    \ex@coffintrees@tween
  }%
  \SetHorizontalCoffin\excoffinc
  {%
    \ex@coffintree@tree
  }%
  \JoinCoffins\excoffina[H,r]\excoffinc[H,l](\CoffinWidth{\excoffinb},0pt)%
  \setlength\mylength{\CoffinDepth{\excoffina}-\CoffinHeight{\excoffinb}}%
  \IfBooleanTF{#1}{%
    \setlength\mytemplength{\mylength}%
  }{%
    \setlength\mytemplength{0pt}%
  }%
  \SetVerticalCoffin\excoffind{\mywidth}
  {%
    \hspace*{\CoffinWidth{\excoffina}}\ex@coffintrees@longtext
  }%
  \JoinCoffins\excoffind[T,l]\excoffina[H,l](0pt,\mylength)%
  \JoinCoffins\excoffind[\excoffind-T,\excoffina-r]\excoffinb[H,l](0pt,\mytemplength)%
  \TypesetCoffin\excoffind[\excoffina-H,l]
  \par
}
\makeatother
\begin{document}
\begin{exe}
  \excoffintrees
  {%
      \begin{forest}
          [This
              [is
                  [another]
                  [tree]
              ]
              [just]
          ]
      \end{forest}
  }
  \excoffintrees
  {%
      \begin{forest}
          [This
              [is
                  [another]
                  [tree]
              ]
              [just]
          ]
      \end{forest}
  }%
  [%
    and little more.
  ]
  \excoffintrees
  {%
      \begin{forest}
          [This
              [is
                  [another]
                  [tree]
              ]
              [just]
          ]
      \end{forest}
  }%
  [%
    and much more \dots.
    \kant[2]
  ]
  \excoffintrees
  {%
      \begin{forest}
          [This
              [is
                  [another]
                  [tree]
              ]
              [just]
          ]
      \end{forest}
  }%
  [%
    and there
  ]%
  {%
    \begin{forest}
      [is
        [another tree]
        ]
      ]
    \end{forest}
  }%
  [%
    to complete the sequence.
    \kant[1]
  ]
\end{exe}
\begin{exe}
  \excoffintrees*
  {%
      \begin{forest}
          [This
              [is
                  [another]
                  [tree]
              ]
              [just]
          ]
      \end{forest}
  }
  \excoffintrees*
  {%
      \begin{forest}
          [This
              [is
                  [another]
                  [tree]
              ]
              [just]
          ]
      \end{forest}
  }%
  [%
    and little more.
  ]
  \excoffintrees*
  {%
      \begin{forest}
          [This
              [is
                  [another]
                  [tree]
              ]
              [just]
          ]
      \end{forest}
  }%
  [%
    and much more \dots.
    \kant[2]
  ]
  \excoffintrees*
  {%
      \begin{forest}
          [This
              [is
                  [another]
                  [tree]
              ]
              [just]
          ]
      \end{forest}
  }%
  [%
    and there
  ]%
  {%
    \begin{forest}
      [is
        [another tree]
        ]
      ]
    \end{forest}
  }%
  [%
    to complete the sequence.
    \kant[1]
  ]
\end{exe}
\end{document}
|improve this answer|||||
  • this is beautiful! I think I'm gonna make it so the second tree actually bottom-aligns with the first one, because both solutions look slightly off to me if the second tree is smaller, but I can do that bit by myself I think. Thanks! – sgf Jul 31 '16 at 21:55
  • Great! Sounds good :-). I wondered about that alignment myself, but I went with what you'd asked rather than trying to second guess you ;). – cfr Jul 31 '16 at 22:10
4

I believe this is quite hard to do outside forest: from TeX's perspective, a tree is just a box.

However, the effect is easy to achieve by adding a tikz node next to the desired forest node using something like tikz+={\node[anchor=base west] at (.base east){and some text};}.

In the code below, I wrote style bottom text which figures out which is the lowest rightmost node and puts the text next to it.

Obviously, this doesn't handle multiline additional text etc, but I guess it should be good enough for a start.

\documentclass{scrartcl}

\usepackage[linguistics]{forest}
\usepackage{gb4e}

\forestset{
  bottom text/.style={
    before drawing tree={
      sort by={-y,x},
      for max={tree}{
        tikz+={\node[anchor=base west] at (.base east){#1};}
      }
    }
  }
}

\begin{document}
\begin{exe}
    \ex
      \begin{forest}
        bottom text={and some text.},
        [This
            [is
                [a]
                [tree]
            ]
            [just]
        ]               
    \end{forest}
\end{exe}
\end{document}

UPDATE: a version which calculates the deepest y and stores it (globally) in a LaTeX length register, which can then be used in a \raisebox.

Of course, this solution still cannot deal with line breaks, and I actually wouldn't know how to deal with them in general.

\documentclass{scrartcl}

\usepackage[linguistics]{forest}
\usepackage{gb4e}

\newlength\miny
\forestset{
  calculate min y/.style={
    before drawing tree={
      sort by={y},
      for min={tree}{TeX={\global\setlength{\miny}{\forestoption{y}}}}
    }
  }
}

\begin{document}
\begin{exe}
    \ex
      \begin{forest} calculate min y,
        [This
            [is
                [a]
                [tree]
            ]
            [just]
        ]               
      \end{forest}
      \raisebox{\miny}{and some text}
      and maybe another tree.
  \end{exe}

\end{document}
|improve this answer|||||
  • Thanks! I would have preferred a solution outside forest to be more flexible and to more easily add another tree (so i can do e.g. (1) tree1 --> tree2 or (1) tree1 or tree2) Wouldn't it possibly work to create a command that creates a box, aligns its top with the top of the tree, and contains text up to a line break which it shows on the bottom of the tree? I suspect something like that might be possible, but the command would have to be able to check for linebreaks to see what goes in the box and what comes after, which is beyond my skill at latex. – sgf Jul 30 '16 at 12:52
  • @thisismynamenow I updated my solution so it now supports either. I think this is better as bottom alignment can look very odd indeed, depending on the two trees between which the text is placed. – cfr Jul 31 '16 at 21:10
  • I think coffins makes this a lot easier. But it is not, of course, a forest solution or, even, a TikZ one. – cfr Jul 31 '16 at 21:10

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.