# Creating a \newcommand for a tikz diagram

The document I'm writing is full of diagrams of arrows, therefore I'd like to create a newcommand \diagram that avoids me to write every time the settings of the tikzpictures. I put

\newcommand{\diagram}[2]{
\begin{tikzpicture} [baseline=(current bounding box.center),
equal/.style={-,double distance=3pt}]
\matrix (m) [matrix of math nodes,
row sep=2em, column sep=2em,
text height=1.5ex, text depth=0.25ex]
{ #1 };
#2
\end{tikzpicture}
}


so that in the code i should just write \diagram{%matrix_of_nodes}{%paths}.

For example

\diagram{A & B \\
C & D \\}
{\path[->,font=\scriptsize]
(m-1-1) edge (m-2-2);}


But when I compile the file (I'm using TexMaker) it returns me the error

"! Package pgfbasematrix Error: Single ampersand used with wrong catcode."

And it highlights the line where the edge is defined. This problem does not occur if I write the whole script, so I don't understand where the problem could be.

Can anybody help me?

• I think it is a bad idea to pass the entire tikz code as an argument. What about using \newenvironment{diagram} instead of a macro? – Bordaigorl Jul 16 '15 at 12:57
• That's what I was about to suggest: it seems a much more natural way of doing this. – cfr Jul 16 '15 at 12:58
• @cfr still, I just realised, the problem arises because of the first argument, which contains ampersands... – Bordaigorl Jul 16 '15 at 13:02
• @Bordaigorl Yes. You can get around that but I think an environment would be better here anyway. – cfr Jul 16 '15 at 13:05
• I'm sorry, I'm quite new to latex and I didn't know of that possibility, nor that having ampersands within an argument could be a problem (I also created a \newcommand for matrices and it worked fine). Thanks for your help anyway, I'll just create a \newenvironment. – LK512 Jul 16 '15 at 13:07

The problem arises from the use of & in the argument, which is problematic since they are a special character and PGF wants to treat them in a special way.

A solution could be to use environments (which I find nicer anyway) and a trick to avoid needing an argument:

\documentclass[tikz,border=10pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{matrix}
\newenvironment{diagram}{
\begin{tikzpicture} [baseline=(current bounding box.center),
equal/.style={-,double distance=3pt}]
\matrix (m) [matrix of math nodes,
row sep=2em, column sep=2em,
text height=1.5ex, text depth=0.25ex]
}{
\end{tikzpicture}
}

\begin{document}
\begin{diagram}{A & B \\ C & D \\};
\path[->,font=\scriptsize]
(m-1-1) edge (m-2-2);
\end{diagram}
\end{document}


If you want you can also change the character used to delimit columns using the ampersand replacement key:

\documentclass[tikz,border=10pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{matrix}
\newenvironment{diagram}[1]{
\begin{tikzpicture} [ampersand replacement=\&,baseline=(current bounding box.center),
equal/.style={-,double distance=3pt}]
\matrix (m) [matrix of math nodes,
row sep=2em, column sep=2em,
text height=1.5ex, text depth=0.25ex]{#1};
}{
\end{tikzpicture}
}

\begin{document}

\begin{diagram}{A \& B \\ C \& D \\}
\path[->,font=\scriptsize]
(m-1-1) edge (m-2-2);
\end{diagram}
\end{document}


note the absence of the ; after the argument and the use of \& instead of &.

With this trick you can also define the macro as you originally intended:

\documentclass[tikz,border=10pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{matrix}
\newcommand{\diagram}[2]{
\begin{tikzpicture} [ampersand replacement=\&,baseline=(current bounding box.center),
equal/.style={-,double distance=3pt}]
\matrix (m) [matrix of math nodes,
row sep=2em, column sep=2em,
text height=1.5ex, text depth=0.25ex]{#1};
#2
\end{tikzpicture}
}

\begin{document}
\diagram{A \& B \\ C \& D \\}{\path[->,font=\scriptsize] (m-1-1) edge (m-2-2);}
\end{document}


But I'd still use environments, it just feels more natural and you avoid troubles when #2 too has special characters in it.

# If you did that just to avoid repetition in style defs:

You could also reduce redundancy by using styles:

\documentclass[tikz,border=10pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{matrix}

\tikzset{
diagram/.style = {
baseline=(current bounding box.center),
equal/.style={-,double distance=3pt},
every matrix/.style={
matrix of math nodes,
row sep=2em, column sep=2em,
text height=1.5ex, text depth=0.25ex
}
}
}

\begin{document}
\begin{tikzpicture}[diagram]
\matrix (m) {A & B \\ C & D \\};
\path[->,font=\scriptsize] (m-1-1) edge (m-2-2);
\end{tikzpicture}
\end{document}


Now the repetition for each diagram is minimal and you have a lot more flexibility.

• Your first solution was more than adequate so solve my problem, but thanks for the further explanation, it's always useful. – LK512 Jul 16 '15 at 13:58

Using ampersand replacement=\& seems the best strategy; however, I recommend you to give tikz-cd a try:

\documentclass[tikz,border=10pt]{standalone}
\usepackage{tikz-cd}

\begin{document}

\begin{tikzcd}[row sep=2em,column sep=2em]
A \arrow[dr] & B \\
C & D
\end{tikzcd}

\end{document}


• Thank you for the advice! However i needed to "compress" the environment because I use special edge/node styles that i have to declare every time at the beginning of the diagram, as you can see from the code i posted (the small diagram i drew was just an example to show the syntax of my new command). If tikzcd allows to do that with less effort I'm definitely interested to know about it. – LK512 Jul 16 '15 at 13:56
• @LK512 As far as I know, tikz-cd eventually translates everything in terms of \matrix and edge connections. – egreg Jul 16 '15 at 14:00
• @LK512 if you are mainly worried about setting styles at the start you can have a look in the manual how to define your own that can be used as a shortcut, just as in my diagram/.style={...your styles...} – Bordaigorl Jul 16 '15 at 14:00
• @LK512 I updated my solution to show you what I mean – Bordaigorl Jul 16 '15 at 14:06