作为进行注释的捷径,我为自己编写了一些宏,其中一个宏包含一个方括号中的可选参数(请参阅下面的 MWE)。不过,Forest 无法解析这个宏,并不断告诉我环境\item
中缺少一个forest
,原因我不明白。
梅威瑟:
\documentclass{article}
\usepackage[linguistics]{forest}
\newcommand{\pass}[1]{($\uparrow$ \textsc{#1}) = $\downarrow$} % (↑ X) = ↓
\newcommand{\updown}{$\uparrow$ = $\downarrow$} % ↑ = ↓
% Feature annotation above; no value in [] prints ↑ = ↓
\newcommand{\anno}[2][\updown]{%
\begin{center}%
{\footnotesize #1}\\%
#2%
\end{center}%
}
\begin{document}
\begin{forest}
[S
[\anno[\pass{subj}]{NP}
[\anno{N}]
]
[\anno{VP}
[\anno{V'}
[\anno{V}]
[\anno[\pass{obj}]{NP}
[\anno{N}]
]
]
]
]
\end{forest}
\end{document}
答案1
看来center
环境是罪魁祸首。但据我所知,你真的不需要它,所以只需将其删除即可。你还需要在 周围加上括号\anno[..]{...}
,这样forest
就不会被括号弄糊涂了。
\documentclass{article}
\usepackage[linguistics]{forest}
\newcommand{\pass}[1]{($\uparrow$ \textsc{#1}) = $\downarrow$} % (↑ X) = ↓
\newcommand{\updown}{$\uparrow$ = $\downarrow$} % ↑ = ↓
% Feature annotation above; no value in [] prints ↑ = ↓
\newcommand{\anno}[2][\updown]{% removed center environment
{\footnotesize #1}\\
#2%
}
\begin{document}
\begin{forest}
[S
[{\anno[\pass{subj}]{NP}} % note extra braces
[\anno{N}]
]
[\anno{VP}
[\anno{V'}
[\anno{V}]
[{\anno[\pass{obj}]{NP}} % note extra braces
[\anno{N}]
]
]
]
]
\end{forest}
\end{document}
答案2
尽管 Torbjørn 的答案非常完美,但我认为一些额外的信息可能会有用。
首先,采用 Foresty 的方式,使树的编码保持简单。
\documentclass{article}
\usepackage[linguistics]{forest}
\begin{document}
\forestset{
declare toks={pass}{},
annotations/.style={
delay={
for descendants={
if pass={}{
content={%
\footnotesize $\uparrow$ = $\downarrow$\\
##1
}
}{
content={%
\footnotesize ($\uparrow$ \textsc{\forestoption{pass}}) = $\downarrow$\\
##1
}
}
}
}
}
}
\begin{forest}
annotations
[S
[NP,pass=subj
[N]
]
[VP
[V'
[V]
[NP,pass=obj
[N]
]
]
]
]
\end{forest}
\end{document}
第二,如果真的需要使用带有不受括号保护的可选参数的 LaTeX 命令:使用括号表示解析器的扩展控制;请参阅手册的第 3.3 节(参考)和 2.8 节(教程)。
由于使用 LaTeX 定义的宏\newcommand
在扩展控制方面有点复杂,我们从一个\def
包含括号作为参数文本一部分的 fed 宏开始。有两个细节使下面的示例起作用。首先,@+
(其中@
声明为动作字符)使宏在到达 Forest 之前自动扩展。其次,的定义引入了一对括号,阻止解析器继续扩展(等)\anno
定义中使用的宏。\anno
\footnotesize
\updown
\documentclass{article}
\usepackage[linguistics]{forest}
\newcommand{\pass}[1]{($\uparrow$ \textsc{#1}) = $\downarrow$} % (↑ X) = ↓
\newcommand{\updown}{$\uparrow$ = $\downarrow$} % ↑ = ↓
\def\anno[#1]#2{%
{%
{\footnotesize #1}\\
#2
}%
}
\begin{document}
\bracketset{action character=@}
\begin{forest} @+
[S
[\anno[\pass{subj}]{NP}
[\anno[\updown]{N}]
]
[\anno[\updown]{VP}
[\anno[\updown]{V'}
[\anno[\updown]{V}]
[\anno[\pass{obj}]{NP}
[\anno[\updown]{N}]
]
]
]
]
\end{forest}
\end{document}
但是,如果\anno
使用 来定义\newcommand
以接受可选参数,则相同的树规范将产生一系列错误。这是因为必须执行接受可选参数的 LaTeX 宏,而不仅仅是展开。括号解析器无法处理这种情况,因此它需要将控制权交给宏,这可以通过在宏控制序列前使用双重动作字符来完成。(宏需要将控制权交还,这可以通过 来完成\bracketResume
。)为了自动执行此操作,下面的示例定义了一个无参数宏,其唯一工作是将 放在@@
我们真正想要执行的宏前面。
\documentclass{article}
\usepackage[linguistics]{forest}
\newcommand{\pass}[1]{($\uparrow$ \textsc{#1}) = $\downarrow$} % (↑ X) = ↓
\newcommand{\updown}{$\uparrow$ = $\downarrow$} % ↑ = ↓
% Feature annotation above; no value in [] prints ↑ = ↓
\newcommand{\internalanno}[2][\updown]{%
\bracketResume
{{\footnotesize #1}\\
#2}%
}
\def\anno{@@\internalanno}
\begin{document}
\bracketset{action character=@}
\begin{forest} @+
[S
[\anno[\pass{subj}]{NP}
[\anno{N}]
]
[\anno{VP}
[\anno{V'}
[\anno{V}]
[\anno[\pass{obj}]{NP}
[\anno{N}]
]
]
]
]
\end{forest}
\end{document}