# Using macros with square brackets in forest node name

As a shortcut to do some annotation, I wrote myself some macros, one of which contains an optional argument in square brackets (see MWE below). Forest has trouble parsing this, though, and keeps telling me that an \item is missing in the forest environment for a reason I can't figure out.

MWE:

\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}

• Maybe [{\anno[\pass{subj}]{NP}} – egreg Dec 29 '16 at 19:13
• Nope, escaping with {...} in the node's name doesn't seem work either there. I thought it might be that it doesn't like \begin{center} but replacing that with \mbox{\centering ...} throws errors, too. – Jipí Dec 29 '16 at 19:17
• @Jipí linguistics sets align=c anyway, I think, which is a single-column tabular with c column specification. – cfr Dec 29 '16 at 23:06
• center is a trivial list environment. – cfr Dec 29 '16 at 23:07
• A terminological remark: what you refer to as node name in the title of the question is actually the node specification (which starts with the node content, possibly followed by a keylist of other node keys). (Nodes in forest do have names, however, which are set using key name, unsurprisingly.) – Sašo Živanović Dec 30 '16 at 3:30

Seems the center environment is to blame for that. But you don't really need it as far as I can see, so just remove it. You also need to put braces around \anno[..]{...}, so that forest isn't confused by the brackets.

\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}


• Seems like I overthought this, then, when the solution's that easy … – Jipí Dec 29 '16 at 19:24
• The reason \begin{center} ... \end{center} is problematic is presumably the same reason this would be problematic in any other tabular cell. linguistics sets align=c by default, I think, which is a tabular with a single c-aligned column. – cfr Dec 29 '16 at 23:05

While Torbjørn's answer works perfectly, I thought some additional info might be useful.

First, a Foresty way of doing it, which keeps the encoding of the tree simple.

\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}


Second, if one really needed to use LaTeX commands with optional arguments not protected by braces: use the expansion control of the bracket representation parser; see sections 3.3 (reference) and 2.8 (tutorial) of the manual.

As using macros defined by LaTeX's \newcommand is a bit complicated wrt expansion control, we start with a \deffed macro which contains brackets as part of the parameter text. There are two details which make the example below work. First, @+ (where @ is declared to be the action character) makes macros expand automatically even before reaching Forest proper. Second, the definition of \anno introduces a pair the braces which prevent the parser from going on and expanding macros used in the definition of \anno (\footnotesize, \updown etc.).

\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}


However, if \anno is defined using \newcommand to take an optional argument, the same tree specification will produce a flurry of errors. This is so because a LaTeX macro taking an optional argument must be executed, not just expanded. The bracket parser cannot deal with that, so it needs to yield control to the macro, which can be done by using a double action character before the macro control sequence. (The macro needs to yield the control back, which is done by \bracketResume.) To do this automatically, the example below defines an argumentless macro whose only job is to put the @@ infront of the macro we really want to execute.

\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}