在“森林”中定义自定义子树宏?

在“森林”中定义自定义子树宏?

我用它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”)之前和之后,需要定义样式的和变体。)NPNappend={[NP[N : #1]]}[NP[N]]appendprepend

相关内容