# Problem declaring newcommand with tikzpicture inside

I plan to put some common commutative diagrams and short exact sequences as new commands in my *.sty file. However, putting this code in my *.sty file

\ProvidesPackage{myLayout}
\usepackage{ifthen,amsopn}
\newcommand{\SES}[3]{
\begin{center}
\begin{tikzpicture}[every node/.style={midway}]
\matrix[column sep={2em},
row sep={0em}] at (0,0)
{ \node(A) {$0$} ;
& \node(B) {#1} ;
& \node(C) {#2} ;
& \node(D) {#3} ;
& \node(E) {$0$} ; \\};
\draw[->] (A) -- (B)  node[anchor=south] {};
\draw[->] (B) -- (C)  node[anchor=south] {};
\draw[->] (C) -- (D)  node[anchor=south] {};
\draw[->] (D) -- (E)  node[anchor=south] {};
\end{tikzpicture}
\end{center}
}


Copy-pasting this whole thing to my *.tex document (except the \newcommand part) and replacing #1, #2, #3 with $A$, $B$ and $C$ gives me a wonderful exact sequence diagram.

I want to know what's going wrong when I paste the same exact code in \newcommand. Moreover, I'd like to know if there is a more efficient way to "save layouts" of tikzpicture so that I don't have to copy paste the same codes every time (especially if I'm just making minor adjustments).

The ultimate goal would be to just write one line like this

\SES{A}{B}{C}


for a short exact sequence.

A general and efficient solution would be a very nice plus.

Any help would be very much appreciated.

• I guess that you have to do \SES{$A$}{$B$}{$C$}. Or use $#1$ in the code. May 4, 2015 at 18:34
• I would set these up as standalone images somewhere, one per file, and then use create a command which passes the arguments off appropriately and \inputs the file. Or create them as pics in a TikZ library and then have the new command wrap the use of the pic.
– cfr
May 4, 2015 at 18:41
• @Sigur The & appears to be the problem. TeX says it has the wrong catcode.
– cfr
May 4, 2015 at 18:52

You can use ampersand replacement; however, I'd not use the center environment, for better flexibility (and use $...$ instead, around the command). You can also simplify the code using matrix of math nodes.

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{matrix}

\newcommand{\SES}[3]{%
\begin{tikzpicture}[every node/.style={midway},ampersand replacement=\&]
\matrix [matrix of math nodes,column sep=2em, row sep=0em] at (0,0) {
\node(A) {0} ;
\& \node(B) {#1} ;
\& \node(C) {#2} ;
\& \node(D) {#3} ;
\& \node(E) {0} ; \\};
\draw[->] (A) -- (B)  node[anchor=south] {};
\draw[->] (B) -- (C)  node[anchor=south] {};
\draw[->] (C) -- (D)  node[anchor=south] {};
\draw[->] (D) -- (E)  node[anchor=south] {};
\end{tikzpicture}%
}

\begin{document}

$\SES{A}{B}{C}$

\end{document}


However, I'd recommend using tikz-cd.

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

\newcommand{\SES}[3]{%
\begin{tikzcd}[ampersand replacement=\&]
0 \arrow[r] \& #1 \arrow[r] \& #2 \arrow[r] \& #3 \arrow[r] \& 0
\end{tikzcd}%
}

\begin{document}

$\SES{A}{B}{C}$

\end{document}


With the simplified syntax of tikz-cd you'll probably give up to defining several types of commutative diagrams with macros.

The problem is that latex is converting the & before tikz can parse it. See example on page 1048.

\documentclass{article}
\usepackage{tikz}

\newcommand{\SES}[3]{%
\begin{center}
\begin{tikzpicture}[every node/.style={midway}]
\let\&=\pgfmatrixnextcell
\matrix[column sep={2em},
row sep={0em}] at (0,0)
{ \node(A) {$0$} ;
\& \node(B) {#1} ;
\& \node(C) {#2} ;
\& \node(D) {#3} ;
\& \node(E) {$0$} ; \\};
\draw[->] (A) -- (B)  node[anchor=south] {};
\draw[->] (B) -- (C)  node[anchor=south] {};
\draw[->] (C) -- (D)  node[anchor=south] {};
\draw[->] (D) -- (E)  node[anchor=south] {};
\end{tikzpicture}
\end{center}
}

\begin{document}

\SES{$A$}{$B$}{$C$}

\end{document}