# tikzcd doesn’t work in custom environment

I have a document class test.cls, in which I have defined a custom environment myenvironment using the environ package as follows:

\NeedsTeXFormat{LaTeX2e}
\ProvidesClass{test}
\RequirePackage{changepage}
\RequirePackage{environ}
\NewEnviron{myenvironment}{
\BODY
}


Now if I try to use tikz-cd inside myenvironment, it fails, e.g. this gives an error:

\begin{myenvironment}
$\begin{tikzcd} 1 \ar[r] \ar[d] & 2 \ar[d] \\ 3 \ar[r] & 4 \\ \end{tikzcd}$
\end{myenvironment}


On the other hand, if I simply write it like this—that is, I substitute what the environment would do—, everything is fine:

\begin{adjustwidth}{10pt}{10pt}
$\begin{tikzcd} 1 \ar[r] \ar[d] & 2 \ar[d] \\ 3 \ar[r] & 4 \\ \end{tikzcd}$


What could be the problem?

• Why do you have to collect the contents of myenvironment? Isn't LaTeX's \newenvironment is enough here? – Phelype Oleinik Oct 22 '18 at 20:50
• Indeed it is enough, I guess I just got too used to the environ package to notice. I’ve tried it now and it solves the problem. I still wonder why it doesn’t work with environ though. – Hermetically Sealed Halibut Oct 22 '18 at 20:55
• I posted an answer explaining why it doesn't work :) – Phelype Oleinik Oct 22 '18 at 21:14

You have to be very careful when collecting an environment with environ, as this usually brings problems. When environ collects its the environment it "freezes" the tokens of the environment. That is, everything will mean what it was when the outer environment was called. This will break every environment that somewhere redefines the category codes of any character (verbatim environments, for example), or that redefine some character.

In this particular case, the meaning of the & changes when you enter tikzcd. See:

\documentclass{article}
\usepackage{amsmath}
\usepackage{tikz-cd}
\begin{document}

When \texttt{environ} collects the environment:

{\ttfamily\meaning&}

\bigskip

What \texttt{tikzcd} expects \texttt{\&} to be:

\begin{tikzcd}
\vbox to \textwidth{\ttfamily\meaning&}
\end{tikzcd}
\end{document}


So basically, inside tikzcd, & means one thing, but when environ reads it, it freezes the alignment tab character & meaning, so it won't work.

So use environ only when you are sure that you need it and you are sure that it won't break anything.

In your case you don't need environ at all because you aren't applying any operation to the collected contents, so this:

\newenvironment{myenvironment}
{%
}%
{%
}


will suffice.

It doesn't work because myenvironment absorbs the body of the environment as a macro argument; in these cases you have to pass ampersand replacement=\& to tikzcd and use \& instead of &, so

\begin{myenvironment}
$\begin{tikzcd}[ampersand replacement=\& 1 \ar[r] \ar[d] \& 2 \ar[d] \\ 3 \ar[r] \& 4 \\ \end{tikzcd}$
\end{myenvironment}


However, there's no need for environ here:

\newenvironment{myenvironment}

\newenvironment{myenvironment}