我用它forest
来排版一些包含许多重复结构的树。例如:
\begin{forest}
[ [ NP [ N : \textit{John} ] ]
[ VP
[ V : \textit{ate} ]
[ NP
[ NP [ N : \textit{apples} ] ]
[ Conj : \textit{and} ]
[ NP [ N : \textit{bananas} ] ]
]
]
]
\end{forest}
特别注意[ NP [ N : \textit{...} ] ]
出现三次的结构(约翰,苹果,香蕉)。
我希望使用一些抽象(宏或森林自己的选项引擎等)来避免每次都必须输入整个[ NP [ N : \textit{...} ] ]
块,以达到某种效果如同(实际上不起作用的伪示例):
\newcommand{\NPN}[1]{[ NP [ N : \textit{#1} ] ]}
\begin{forest}
[ \NPN{John}
[ VP
[ V : \textit{ate} ]
[ NP
\NPN{apples}
[ Conj : \textit{and} ]
\NPN{bananas}
]
]
]
\end{forest}
这可能吗?理想情况下,我想forest
在这里使用,但如果其他树绘制包提供此功能,我可能也有兴趣了解如何做到这一点。
答案1
OP 的尝试不起作用,因为宏\NPN
在节点排版时展开(从而产生一个包含括号等的节点),但其意图是在解析树结构(括号)之前展开宏(这会发生得更早)。
现在,Forest 实际上可以在解析树结构之前扩展宏。诀窍是定义一个动作角色(下文中@
),并在每个需要扩展的宏之前使用它(将有一个扩展)。有关详细信息,请参阅手册的第 3.3 节。
\documentclass{article}
\usepackage{forest}
\bracketset{
action character=@,
}
\begin{document}
\newcommand{\NPN}[1]{[ NP [ N : \textit{#1} ] ]}
\begin{forest}
[ @\NPN{John}
[ VP
[ V : \textit{ate} ]
[ NP
@\NPN{apples}
[ Conj : \textit{and} ]
@\NPN{bananas}
]
]
]
\end{forest}
\end{document}
然而,如今我更倾向于使用动态树来实现相同的效果(请参阅手册第 3.11 节)。下面,我定义了NPN
一种样式,将节点的内容设置为,NP
并将一个N
节点(内容为N : noun
)插入其中。(请注意前面的逗号NPN
!如果没有它,Forest 会将其解释NPN
为内容,并且由于 的内部结构pgfkeys
,预期值(例如John
)将被忽略。)
\documentclass{article}
\usepackage{forest}
\forestset{
NPN/.style={
content=NP,
append={[N : \textit{#1}]},
},
}
\begin{document}
\begin{forest}
[
[,NPN=John,]
[ VP
[ V : \textit{ate} ]
[ NP
[,NPN=apples]
[ Conj : \textit{and} ]
[,NPN=bananas]
]
]
]
\end{forest}
\end{document}
(也可以定义将包含节点的节点NPN
附加到(当前节点))。但是,为了使这种样式在 OP 的情况下真正有用,其中模板同时出现在“常规”节点(如“Conf”)之前和之后,需要定义样式的和变体。)NP
N
append={[NP[N : #1]]}
[NP[N]]
append
prepend