编辑

编辑

我需要使用森林创建几棵语法树,并且有些结构会在多棵树中反复出现。我该如何实现这一点?到目前为止,我所做的尝试都\newcommand没有奏效。作为一个基本示例,我希望能够输入类似以下内容:

\newcommand{\asdf}[1]{a [#1] [c]}

...

\begin{forest}
[x
    [y]
    [\asdf{b}]
]
\end{forest}

并生成这棵树:

一棵树,其根节点为 x,节点 y 和 a 为 x 的子节点,节点 b 和 c 为 a 的子节点

我究竟做错了什么?

编辑:这是我正在尝试做的更完整的示例:

\documentclass{article}
\usepackage{forest}
\usepackage{ulem}
\usepackage{textcomp}

\renewcommand{\ln}{\textit{n}}
\newcommand{\uX}[1]{\sout{u#1}}
\newcommand{\mvmt}[1]{\textlangle#1\textrangle}
\newcommand{\basen}[1]{
\ln
[\ln
    [#1{[N]}]
    [\ln {[\uX{N*}]}]
]
[\mvmt{#1[N]}]
}

\begin{document}

\begin{forest}
[D
    [the{[D,\uX{\ln}]}]
    [\basen{dog}]
]
\end{forest}
\end{document}

预期结果如下:

在此处输入图片描述

抱歉,一开始没有说清楚!

答案1

forest环境中,Forest 的解析器负责读取内容并扩展内容等。这意味着普通解析被暂停,并且宏不会像您预期的那样进行扩展。

Forest 提供了一种机制(实际上是几种机制),用于暂时关闭其专业解析器并启用普通扩展。在您的示例中,管理它的最简单方法是简单地设置一个action character并在宏前面加上该字符。该字符可以是任何您喜欢的不会干扰其他内容的字符。(例如,使用或或其他东西\asdf显然行不通。)我通常使用。[]@

唯一的潜在陷阱是在环境启动后尝试定义角色forest。那时已经太晚了,因为 Forest 的解析器已经在运行。相反,请\bracketset{}在 Forest 环境之外使用。

这听起来有点复杂,其实不然。实际上,你只需要:

\documentclass[border=9pt]{standalone}

\usepackage{forest}
\newcommand{\asdf}[1]{a [#1] [c]}

\begin{document}

\bracketset{action character=@}
\begin{forest}
  [x
    [y]
    [@\asdf{b}]
  ]
\end{forest}

\end{document}

具有扩展宏的树

编辑

对于编辑问题中更复杂的情况,可以使用完全相同的方法。

\begin{forest}
  [D
    [the{[D,\uX{\lynx}]}]% avoid changing \ln
    [@\basen{dog}]
  ]
\end{forest}

给出

使用扩展宏输出更复杂情况

完整代码:

\documentclass[border=9pt]{standalone}
\usepackage{forest}
\usepackage{ulem}
\usepackage{textcomp}

\newcommand{\asdf}[1]{a [#1] [c]}
\newcommand{\lynx}{\textit{n}}
\newcommand{\uX}[1]{\sout{u#1}}
\newcommand{\mvmt}[1]{\textlangle#1\textrangle}
\newcommand{\basen}[1]{
  \lynx
  [\lynx
    [#1{[N]}]
    [\ln {[\uX{N*}]}]
  ]
  [\mvmt{#1[N]}]
}

\begin{document}

\bracketset{action character=@}
\begin{forest}
  [x
    [y]
    [@\asdf{b}]
  ]
\end{forest}


\begin{forest}
  [D
    [the{[D,\uX{\lynx}]}]
    [@\basen{dog}]
  ]
\end{forest}

\end{document}

相关内容