我已经为 编写了一个自定义样式forest
,以使树看起来像我希望的那样。该样式的理念是保持分支的角度固定,并自动“正确”处理空节点 - 即,对于空头节点,对称对齐线条,对于空非头节点,继续使用不间断的线条。问题是,我编写的样式给了我想要的输出,但同时有时(对我来说是不可预测的)给出了超出我排除故障能力的错误。
所需的输出看起来或多或少像这样(尽管 c 的分支有点短):
样式看起来像这样(带有一些代码注释以使内容更清晰):
default/.style={baseline, % align tree properly to example numbering
for tree={ %give every node in the tree these properties
parent anchor=south, child anchor=north, % make lines go from bottom of parent to top of child properly
calign=fixed edge angles,calign angle=60, % make all lines have the same angle
delay={ % do this stuff after processing how many nodes you have:
where content={} % for all nodes with empty content...
{if n children={0} % if they are heads...
{content=\strut} % ...insert a strut;
{shape=coordinate, % if they are not heads, make them points...
for parent={for children={l*=0.8}} % <<If commented out, errors ensue!
%for parent={for children={align=north,l*=0.8}} % <<If commented in, errors ensue!
}
}
{ % for all nodes with non-empty content:
if n children={0} % if they are heads...
{ align=center } % allow line breaking; note that trying to allow line breaking for all nodes adds some weird extra space below the node text, and when TiKZ tries to put this extra space into the point nodes stuff explodes
{} % otherwise do nothing
}
},
},
}
该风格编译时没有错误。然而,如果我注释掉以 开头的行for parent
,或者添加类似的内容align=north
(如上面注释掉的行),我会出现错误 - 但仅限于较大的树。
例如,无论我做什么,下面的小树都可以很好地编译:
\begin{forest}
default
[a
[b]
[ [c] [d]
]
]
\end{forest}
dimension too large
但是,如果我省略该行,下面稍大一点的树就会出现错误for parent
,如果我添加,就会出现除以零的错误align=north
。
\begin{forest}
default
[a
[b]
[ [c]
[ [d] [e]
]
]
]
\end{forest}
究竟是什么导致了这些错误?我无法预测会出现什么问题,这让我很不舒服,而且我觉得如果我的风格如此脆弱,我可能做错了什么。有什么想法吗?(我说清楚了吗?)
答案1
align
left
期望值为、right
或center
指定数组,例如或任何其他值|c|lp{4cm}
。当行被注释时,错误会抱怨
! LaTeX Error: Illegal character in array arg.
因为n
不是已知的列类型。
您可能想要anchor=north
,或者您可能想要别的东西 - 我不确定这应该做什么。
即使进行了上述修复,您仍会因为注释中提到的 PGF 错误而收到错误。我编写了一种pretty nice empty nodes
用于这些情况的样式,它几乎(但不完全)像nice empty nodes
。在这里,我提供了my pretty nice empty nodes
和,my nice empty nodes
它们根据您想要的树的设置进行了修改。
我原来的解决方案适用于版本 1 或版本 2森林。但是,如果您使用的是当前版本的软件包,则此更新的代码更简单、更灵活。如果您需要可与早期版本的软件包配合使用的代码,请参阅下面的原始解决方案。
\documentclass[tikz,border=10pt,multi]{standalone}
\usepackage[linguistics]{forest}% needs version 2
\begin{document}
\forestset{
my nice empty nodes/.style={% modified from manual page 52 of v1 manual (updated version is now on page 65)
for tree={
calign=fixed edge angles,
calign angle=60,
},
delay={
where n children=0{
if content={}{
content=\strut,
anchor=parent,
}{
align=center
},
}{
if content={}{
shape=coordinate,
!u.for children={
anchor=parent
}
}{}
}
},
},
my pretty nice empty nodes/.style={
for tree={
calign=fixed edge angles,
calign angle=60,
parent anchor=children,
delay={
where n children=0{
if content={}{
content=\strut,
anchor=parent,
}{
align=center
},
}{
if content={}{
inner sep=0pt,
edge path={\noexpand\path [\forestoption{edge}] (!u.parent anchor) -- (.children)\forestoption{edge label};}
}{}
}
}
}
}
}
\begin{forest}
baseline,
sn edges,
my nice empty nodes
[a
[b]
[ [c] [d]
]
]
\end{forest}
\begin{forest}
baseline,
sn edges,
my pretty nice empty nodes
[a
[b]
[ [c]
[ [d] [e]
]
]
]
\end{forest}
\end{document}
这是第二棵树,有虫子咬过的地方,如下图所示my pretty nice empty nodes
:
兼容版本
这是我的原始代码。它与版本 1 和版本 2 都运行良好森林,但如果您不需要向后兼容,建议使用上述更新的解决方案。
\documentclass[tikz,border=10pt,multi]{standalone}
\usepackage{forest}
\begin{document}
\forestset{
sn edges/.style={% manual page 8
for tree={
parent anchor=south,
child anchor=north
}
},
my nice empty nodes/.style={% modified from manual page 52
for tree={
calign=fixed edge angles,
calign angle=60,
},
delay={
where n children=0{
if content={}{
content=\strut,
anchor=north,
}{
align=center
},
}{
if content={}{
shape=coordinate,
for parent={
for children={
anchor=north
}
}
}{}
}
},
},
my pretty nice empty nodes/.style={
for tree={
calign=fixed edge angles,
calign angle=60,
parent anchor=south,
delay={
where n children=0{
if content={}{
content=\strut,
anchor=north,
}{
align=center
},
}{
if content={}{
inner sep=0pt,
edge path={\noexpand\path [\forestoption{edge}] (!u.parent anchor) -- (.south)\forestoption{edge label};}
}{}
}
}
}
}
}
\begin{forest}
baseline,
sn edges,
my nice empty nodes
[a
[b]
[ [c] [d]
]
]
\end{forest}
\begin{forest}
baseline,
sn edges,
my pretty nice empty nodes
[a
[b]
[ [c]
[ [d] [e]
]
]
]
\end{forest}
\end{document}
以下是my nice empty nodes
版本:
这是第二棵树,有虫子咬过的地方,如下图所示my pretty nice empty nodes
: