# Optional arguments and &

I defined a simple diagram environment with

\usepackage{tikz-cd}
\newenvironment{diagram}
{ $$\begin{tikzcd} } { \end{tikzcd}$$ }


and it worked fine. In particular this compiled:

\documentclass{article}
\usepackage{tikz-cd}

\newenvironment{diagram}
{ $$\begin{tikzcd} } { \end{tikzcd}$$ }

\begin{document}
\begin{diagram}
&
\end{diagram}
\end{document}


Later on I realized I need to call tikzcd with different arguments in a number of places, so I changed the environment definition to include an optional argument, but now

\documentclass{article}
\usepackage{tikz-cd}

\newenvironment{diagram}[1][]
{ $$\begin{tikzcd}[#1] } { \end{tikzcd}$$ }

\begin{document}
\begin{diagram}
&
\end{diagram}
\end{document}


fails to compile, and the diagram code above needs to be changed to {}& to work again. So presumably applying this change whenever a diagram starts with an ampersand would solve my problem, but I'd like to know

1. why does this happen in the first place, so that I can avoid similar problems in the future

and, seeing that

\begin{tikzcd}
&
\end{tikzcd}


works just fine and tikzcd takes optional arguments too,

1. is there a better way to solve this than adding superfluous braces in a large number of diagrams?
• Welcome to TeX.SX! You can have a look at our starter guide to familiarize yourself further with our format. – moewe Oct 13 '14 at 4:26
• With a quick test document I don't see any effect of including the optional argument code. Could you edit the question to include an example that works in the first version but fails in the second one (with the optional argument)? – Joseph Wright Oct 13 '14 at 6:00
• @JosephWright: I've edited the question, sorry for not including the MWE's in the first place. @ moewe: thanks for the welcome :) – user54748 Oct 13 '14 at 14:12

When an optional argument is allowed, LaTeX scans forward to find [, ignoring spaces as it goes. In the case of

\begin{diagram}
& x
\end{diagram}


it stops scanning at & and this is the problem: the token & is put back to be read again, but tikz-cd wants to redefine & for its purposes and it can do nothing on the already read token.

Solution: use \NewDocumentEnvironment of xparse that scan forward for [ without ignoring spaces. Caveat: \begin{diagram} [<option>] would become illegal; no space should be between } and [.

\documentclass{article}
\usepackage{tikz-cd,xparse}

\NewDocumentEnvironment{diagram}{O{}} % an optional argument, empty default
{$$\begin{tikzcd}[#1]} {\end{tikzcd}$$}

\begin{document}
\begin{diagram}
& x
\end{diagram}
\end{document}