在森林节点名称中使用带方括号的宏

在森林节点名称中使用带方括号的宏

作为进行注释的捷径,我为自己编写了一些宏,其中一个宏包含一个方括号中的可选参数(请参阅下面的 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}

相关内容