买者自负 ...

买者自负 ...

我试图让示例编号与树的顶部对齐,并让任何附加文本与树的底部对齐,但我似乎只能做到其中之一。

此代码:

\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}

生产示例编号、树顶部和示例文本对齐,而此代码:

\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}

产生这个:示例编号、树顶部和示例文本对齐

在我看来,这两种写法都很丑陋,而且据我所知,它们都违反了语言学的惯例。我想要的是这样的:

示例数字与树顶部对齐,示例文本与树底部对齐

我尝试简单地将底部节点设置为基线并在示例开始后添加换行符,但这会在示例的编号和其内容之间引入分页符,这也非常糟糕。

答案1

您可能已经了解到,这不是一件完全简单的事情,尤其是考虑到您对 Sašo 的回答的评论中所提出的要求。

因此,我的解决方案远不能保证万无一失。它通过了最低限度的测试,但它依赖于一个实验性的软件包。xcoffins此外,它还涉及使用我编写的代码,这对任何冒险走这条路的旅行者来说无疑是一个相当大的危险。

买者自负 ...


我定义了一个新命令\excoffintrees供在exe环境中使用。它应该被使用而不是\ex因为它会\ex自行发出。该命令被定义为支持以下形式:

  • 对于一棵树:

    • \excoffintrees{<forest tree>}[<optional text>]
    • \excoffintrees*{<forest tree>}[<optional text>]
  • 对于2棵树:

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

虽然我说了<forest tree>,但实际上,你可以在这里放任何类似的东西。我为树设计了它,但代码并不特定于它们。

带星号的形式将树之间的任何文本对齐在顶部。不带星号的形式将其对齐在底部。

请注意,内容不能分页,因此过长的文本不应作为最后的参数附加。

此外,在两棵树之间使用一些简短而甜蜜的东西才真正有意义,如果这里的内容太多,肯定看起来不对!

不过,我们可以这样写

\begin{exe}

照常启动环境。

  \excoffintrees

将会发出\ex,所以我们不需要明确地将其包含在内(如果我们这样做它会给出一个错误 - 它可能会抱怨缺失\item或类似的模糊内容)。

  {%

这是我们的第一棵树。

      \begin{forest}
          [This

为了对齐树木,我们使用

\forestset{default preamble=!r.baseline}

, baseline如果愿意,您也可以在树规范中添加。或者在本地更改一组树的默认值。

现在树的其余部分:

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

很无聊。这实际上只是以一种非常迂回的方式与数字对齐。最好就\ex在这里使用。

  \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}

其结果如下:

棺材里的树

或使用带星号的形式:

棺材里有更多树

完整代码:

\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}

答案2

我认为这很难做到外部森林:从 TeX 的角度来看,树只是一个盒子。

但是,通过使用类似的东西在所需的森林节点旁边添加 tikz 节点,可以轻松实现效果tikz+={\node[anchor=base west] at (.base east){and some text};}

在下面的代码中,我编写了样式bottom text,它找出最右边的最低节点,并将文本放在它旁边。

显然,这不能处理多行附加文本等,但我想它应该足够好了。

\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}

y更新:计算最深并将其(全局)存储在 LaTeX 长度寄存器中的版本,然后可以在 中使用\raisebox

当然,这个解决方案仍然无法处理换行符,而且我实际上不知道通常如何处理它们。

\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}

相关内容