我需要使用森林创建几棵语法树,并且有些结构会在多棵树中反复出现。我该如何实现这一点?到目前为止,我所做的尝试都\newcommand
没有奏效。作为一个基本示例,我希望能够输入类似以下内容:
\newcommand{\asdf}[1]{a [#1] [c]}
...
\begin{forest}
[x
[y]
[\asdf{b}]
]
\end{forest}
并生成这棵树:
我究竟做错了什么?
编辑:这是我正在尝试做的更完整的示例:
\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}