我试图让示例编号与树的顶部对齐,并让任何附加文本与树的底部对齐,但我似乎只能做到其中之一。
此代码:
\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}