在下面的树中,边应该击中 ha、en 和 o 上方的叶子。但由于下标,边击中了完整节点的中间。
我找到了一个问题的“解决方案”,即在左侧插入与下标大小相同的幻像文本,但是这样做的缺点是使节点变大,从而使节点之间的间距显得不均匀:
有没有办法将节点向右移动而不使节点变大?
我也尝试使用 \rlap,但这会导致奇怪的重叠。
\documentclass{article}
\usepackage{forest}
\useforestlibrary{linguistics}
\forestapplylibrarydefaults{linguistics}
\newcommand{\sub}[1]{\(_{\mbox{\scriptsize\textrm{#1}}}\)}
\forestset{
empty nodes/.style={
delay={where content={}{shape=coordinate,for siblings={anchor=north}}{}}
}
}
\begin{document}
\begin{forest}%sm edges
for tree={s sep=-2.5}
[COMP-M
[COPCOMP-M
[{[ha]\sub{STM}}]
[{[en]\sub{STM}}]
[{[o]\sub{STM}},tier=word]
]
[,empty nodes
[{[ɑʀt\textsuperscript{s}t]},tier=word]
]
]
\end{forest}
\begin{forest}%sm edges
for tree={s sep=-2.5}
[COMP-M
[COPCOMP-M
[{\hphantom{\sub{STM}}[ha]\sub{STM}}]
[{\hphantom{\sub{STM}}[en]\sub{STM}}]
[{\hphantom{\sub{STM}}[o]\sub{STM}},tier=word]
]
[,empty nodes
[{[ɑʀt\textsuperscript{s}t]},tier=word]
]
]
\end{forest}
\end{document}
答案1
没有直接关系:我可能会将伪数学\(_{\mbox{\scriptsize\textrm{#1}}}\)
改为\textsubscript{\scriptsize\textrm{#1}}
。
您可以使用\rlap
将下标的宽度设置为零,从而将节点移至正确位置。但是,由于宽度为零,您需要手动调整节点之间的间距。
\documentclass[border=10pt]{standalone}
\usepackage{fontspec}
\setmainfont{Doulos SIL}
\usepackage{forest}
\useforestlibrary{linguistics}
\forestapplylibrarydefaults{linguistics}
\newcommand{\sub}[1]{\rlap{\textsubscript{\scriptsize\textrm{#1}}}}
\forestset{
empty nodes/.style={
delay={where content={}{shape=coordinate,for siblings={anchor=north}}{}}
}
}
\begin{document}
\begin{forest}%sm edges
for tree={s sep=3.25ex}
[COMP-M
[COPCOMP-M
[{[ha]\sub{STM}}]
[{[en]\sub{STM}}]
[{[o]\sub{STM}},tier=word]
]
[,empty nodes
[{[ɑʀt\textsuperscript{s}t]},tier=word]
]
]
\end{forest}
\end{document}
另一种方法是手动将 设置child anchor
为 90(= 北)和 135(西北)之间的某个值。此解决方案的优点是,您不会面临元素重叠的风险,因为元素重叠可能需要手动设置距离,如上面的解决方案中所示。缺点是它不太准确。
\documentclass[border=10pt]{standalone}
\usepackage{fontspec}
\setmainfont{Doulos SIL}
\usepackage{forest}
\useforestlibrary{linguistics}
\forestapplylibrarydefaults{linguistics}
\newcommand{\sub}[1]{\textsubscript{\scriptsize\textrm{#1}}}
\forestset{
empty nodes/.style={
delay={where content={}{shape=coordinate,for siblings={anchor=north}}{}}
}
}
\begin{document}
\begin{forest}%sm edges
for tree={s sep=1ex}
[COMP-M
[COPCOMP-M
[{[ha]\sub{STM}}, child anchor=120]
[{[en]\sub{STM}}, child anchor=120]
[{[o]\sub{STM}}, child anchor=120, tier=word]
]
[,empty nodes
[{[ɑʀt\textsuperscript{s}t]}, tier=word]
]
]
\end{forest}
\end{document}
答案2
半通用的自动化解决方案。代码中有注释。
\documentclass{article}
\usepackage[linguistics]{forest}
\forestset{
empty nodes/.style={
delay={where content={}{shape=coordinate,for siblings={anchor=north}}{}}
}
}
% flrlap = Forest Left/Right Lap
%
% Like \llap and \rlap, but for Forest nodes. The "\fllap"ed/"\frlap"ed part of the node
% will be "ignored" by parent--child edges, but taken into account in packing.
%
% (This has been tested with south-growing trees with north--south edges, and
% calign=midpoint. It surely won't work in general.)
%
\forestset{
% (1) New options for the nodes. They will hold the width of the left/right lap.
declare dimen={fllap}{0pt},
declare dimen={frlap}{0pt},
flrlaps/.style={
% (2) We have to improvise because Forest doesn't have an "after typesetting node"
% hook. So we'll (globally) append to macro \flrlaps while typesetting the nodes.
% Let's empty it out before we start.
before typesetting nodes={
TeX={\gdef\flrlaps{}},
},
% See below for (3).
%
% (4) Use the instructions gathered in \flrlaps to set fllap/flrap options of the
% nodes containing \fllap/\frlap.
before packing={
TeX={\expandafter\forestset\expandafter{\flrlaps}},
},
for tree={
% (5) This new edge path will take care of the parent--child edges. The trick is to
% xshift the edge ends by (fllap-frlap)/2.
edge path'={%
% The parent end. We use an internal macro, \forestOve, to easily access the
% parent options.
([xshift=(\forestOve{\forestoption{@parent}}{fllap}-
\forestOve{\forestoption{@parent}}{frlap})/2]!u.parent anchor)
--
% The child end is easy.
([xshift=(\forestoption{fllap}-\forestoption{frlap})/2].child anchor)
},
% (6) We need to shift the children (in the s-dimension) for an appropriate amount.
% Assume first, for simplicity, that we have a child aligned under the parent. We
% have to shift this child for (frlap-fllap)/2 (so just the negative of what we did
% to the edge.) But if our alignment point is between two children (as with the
% default calign=midpoint), then this becomes (frlap_1+frlap_2-fllap_1-fllap_2)/4,
% where the indices 1 and 2 refer to the primary and secondard calign child.
%
% We only do this for nodes without children, obviously.
if n children=0{}{
% We need to do this adjustment immediately after packing the node. If we didn't,
% the subtrees, while packing, can be wider than those we get at the end, so
% Forest would push them too much apart.
after packing node={
% We're at the parent node and want to add "(frlap_1+frlap_2-fllap_1-fllap_2)/4"
% to "s" of all children. What we're adding is constant, so we can precompute
% it. An "Ow+x+O", with one of the first four lines, accesses option
% fllap/frlap of the calign primary/secondary child; "w4" than wraps these
% values into the "s+" expression below. The final part is easy, but what about
% this "Ow+x+O"?
%
% "Ow+x+O". The first "O" gets the value of option "calign primary/secondary
% child". This value is the child number, and negative numbers start counting
% at the last child. We then "w"rap this child number into {!n...lap}, i.e. we
% replace ##1 in there with the child number. "+x" expands this, with the sole
% purpose of getting "n'" and "-<child number>" when the child number is
% negative --- ahem, while option "calign primary/secondary child" accepts
% negative numbers to count from the last child, the nodewalk step "n" doesn't.
% We basically end up with "!n(')=<absolute child number>.fl/rlap", and this is
% a nice "<relative node name>.<option>" for accessing fllap/frlap option of the
% child with the specified number, which "+O" will then pick up. Uff.
for children/.process=Ow+x+O Ow+x+O Ow+x+O Ow+x+O w4
{calign primary child}{!n\ifnum##1<0 '\fi={\ifnum##1<0 -\fi##1}.fllap}
{calign primary child}{!n\ifnum##1<0 '\fi={\ifnum##1<0 -\fi##1}.frlap}
{calign secondary child}{!n\ifnum##1<0 '\fi={\ifnum##1<0 -\fi##1}.fllap}
{calign secondary child}{!n\ifnum##1<0 '\fi={\ifnum##1<0 -\fi##1}.frlap}
{s+=(##2+##4-##1-##3)/4},
},
},
},
}
}
% (3) These macros will be used inside the nodes, to indicate the material
% which should "stick out" at the left/right.
\def\fllap#1{%
% Typeset the argument into a box.
\setbox0=\hbox{#1}%
% Globally append a forest instruction setting the fllap for this node to
% \flrlaps.
\xappto\flrlaps{for id={\forestoption{id}}{fllap+=\the\wd0},}%
% Use the box.
\unhbox0
}
\def\frlap#1{% Ditto.
\setbox0=\hbox{#1}%
\xappto\flrlaps{for id={\forestoption{id}}{frlap+=\the\wd0},}%
\unhbox0
}
\begin{document}
\begin{forest} flrlaps
[COMP-M
[COPCOMP-M, calign=2
[{[ha]\frlap{\textsubscript{STM}}}]
[{[en]\frlap{\textsubscript{STM}}}]
[{[o]\frlap{\textsubscript{STM}}},tier=word]
]
[,empty nodes
[{\fllap{\textsubscript{LEFT-STM}}[art\textsuperscript{s}t]},tier=word]
]
]
\end{forest}
\begin{forest} flrlaps
[COMP-M
[COPCOMP-M
[{[en]\frlap{\textsubscript{STM}}}]
[{[o]\frlap{\textsubscript{STM}}},tier=word]
]
[,empty nodes
[{\fllap{\textsubscript{LEFT-STM}}[art\textsuperscript{s}t]},tier=word]
]
]
\end{forest}