Creating macros for common commutative diagrams in tikz

You'll need to replace the ampersands in the TikZ matrix using the key ampersand replacement=<macro>, where <macro> can be \&, for example.

Here's your code as a command. I used the approach described in PGF/TikZ: How to store strings in array? for using a list instead of separate arguments for the labels. Your diagram

can then be created using

\monoid{
    (A\otimes A)\otimes A,
    A\otimes (A\otimes A),
    A\otimes A,
    A\otimes A,
    A,
    $\mu\otimes Id$,
    $\mu$,
    $ Id\otimes\mu$,
    $ \mu$,
    $\alpha$
}

Here's the full code:

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

\usepackage{xparse}
\usepackage{etoolbox}
\newcounter{listtotal}\newcounter{listcntr}%
\NewDocumentCommand{\argument}{o}{%
  \setcounter{listtotal}{0}\setcounter{listcntr}{-1}%
  \renewcommand*{\do}[1]{\stepcounter{listtotal}}%
  \expandafter\docsvlist\expandafter{\argumentarray}%
  \IfNoValueTF{#1}
    {\namesarray}% \names
    {% \names[<index>]
     \renewcommand*{\do}[1]{\stepcounter{listcntr}\ifnum\value{listcntr}=#1\relax##1\fi}%
     \expandafter\docsvlist\expandafter{\argumentarray}}%
}

\newcommand{\monoid}[1]{
\def\argumentarray{#1}
\begin{tikzpicture}[baseline=(current bounding box.center)]
    \matrix(m)[
        matrix of math nodes,
        ampersand replacement=\&,
        row sep=2.6em,
        column sep=2.8em,
        text height=2ex,
        text depth=0.5ex
    ]
    {
    \argument[0]    \&              \& \argument[1]\\
    \argument[2]    \&              \& \argument[3]\\
                    \& \argument[4] \& \\
    };
\path[->,font=\normalsize,>=angle 90]
(m-1-1) edge node[auto] {\argument[5]} (m-2-1)
(m-2-1) edge node[auto] {\argument[6]} (m-3-2)
(m-1-3) edge node[auto] {\argument[8]} (m-2-3)
(m-2-3) edge node[auto] {\argument[9]} (m-3-2);
\path[<->, font=\normalsize,>=angle 90]
(m-1-1) edge node[auto] {\argument[10]} (m-1-3);
\end{tikzpicture}
}
\begin{document}
\monoid{
    (A\otimes A)\otimes A,
    A\otimes (A\otimes A),
    A\otimes A,
    A\otimes A,
    A,
    $\mu\otimes Id$,
    $\mu$,
    $ Id\otimes\mu$,
    $ \mu$,
    $\alpha$
}

\end{document}

Another approach:

  • Use tikz-cd for simple contruction of commutative diagrams
  • Use the arrayjobx package for the elements

Benefits:

  • Shorter diagram code, arrows directly within the elements
  • Instead of writing 9 parameters each time you call \monoid, you could modify just specific array arguments if diagrams are similar, such as by \monoidelements(1)={A'\otimes A'} and calling \monoid again

\documentclass{article}
\usepackage{arrayjobx}
\newarray{monoidelements}

\usepackage{tikz-cd}
\newcommand{\monoid}[1]{
  \begin{tikzcd}[->,font=\normalsize,>=angle 90,ampersand replacement=\&]
  #1(1) \arrow{d}{#1(6)} \arrow[<->]{rr}{\alpha}\& \& #1(2) \arrow{d}{#1(7)}\\
  #1(3) \arrow{dr}{#1(8)} \& \& #1(4)\arrow{dl}{#1(9)}\\
   \& #1(5) \&
  \end{tikzcd}}

\begin{document}
\readarray{monoidelements}{(A\otimes A)\otimes A\otimes A&A\otimes (A\otimes A)
  &A\otimes A&A\otimes A&A&\mu\otimes Id&Id\otimes\mu&\mu&\mu\otimes Id}
\monoid{\monoidelements}
\end{document}

Monoid


An answer which is too long for being a comment, as it's only a rewriting of Jake's answer using a shorter syntax based on expl3:

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

\usepackage{xparse}
\ExplSyntaxOn
\seq_new:N \l_jake_monoid_seq
\NewDocumentCommand{\monoid}{m}
 {
  \seq_set_split:Nnn \l_jake_monoid_seq { , } { #1 }
  \domonoid
 }
\NewDocumentCommand{\argument}{o}
 {
  \IfNoValueTF{#1}
   { \seq_use:N \l_jake_monoid_seq }
   { \seq_item:Nn \l_jake_monoid_seq { #1 } }
 }
\ExplSyntaxOff
\NewDocumentCommand{\domonoid}{}
 {
  \begin{tikzpicture}[baseline=(current bounding box.center)]
    \matrix(m)[
        matrix of math nodes,
        ampersand replacement=\&,
        row sep=2.6em,
        column sep=2.8em,
        text height=2ex,
        text depth=0.5ex
    ]
    {
    \argument[0]    \&              \& \argument[1]\\
    \argument[2]    \&              \& \argument[3]\\
                    \& \argument[4] \& \\
    };
  \path[->,font=\normalsize,>=angle 90]
  (m-1-1) edge node[auto] {\argument[5]} (m-2-1)
  (m-2-1) edge node[auto] {\argument[6]} (m-3-2)
  (m-1-3) edge node[auto] {\argument[8]} (m-2-3)
  (m-2-3) edge node[auto] {\argument[9]} (m-3-2);
  \path[<->, font=\normalsize,>=angle 90]
  (m-1-1) edge node[auto] {\argument[10]} (m-1-3);
  \end{tikzpicture}
 }
\begin{document}
\monoid{
    (A\otimes A)\otimes A,
    A\otimes (A\otimes A),
    A\otimes A,
    A\otimes A,
    A,
    $\mu\otimes \mathit{Id}$,
    $\mu$,
    $ \mathit{Id}\otimes\mu$,
    $ \mu$,
    $\alpha$
}

\end{document}

The \monoid macro does two things: it sets a sequence from its argument and calls \domonoid which is identical to Jake's \monoid. Notice that \domonoid must be defined with \ExplSyntaxOff, because spaces in TikZ keys are significant.

The definition of \argument is much easier than with etoolbox.

Note: in order to get a better form of Id, it's better to use \mathit{Id}.


We can use similar ideas also for Stefan Kottwitz's answer

\documentclass{article}
\usepackage{xparse}
\usepackage{tikz-cd}
\NewDocumentCommand{\monoid}{m}
 {
  \makeargument{#1}    
  \begin{tikzcd}[->,font=\normalsize,>=angle 90,ampersand replacement=\&]
  \argument{0} \arrow{d}{\argument{5}} \arrow[<->]{rr}{\alpha}\& \& \argument{1} \arrow{d}{\argument{6}}\\
  \argument{2} \arrow{dr}{\argument{7}} \& \& \argument{3}\arrow{dl}{\argument{8}}\\
   \& \argument{4} \&
  \end{tikzcd}
 }
\ExplSyntaxOn
\seq_new:N \l_sk_monoid_seq
\cs_new:Npn \makeargument #1
 { \seq_set_split:Nnn \l_sk_monoid_seq { & } { #1 } }
\cs_new:Npn \argument #1
 { \seq_item:Nn \l_sk_monoid_seq {#1} }
\ExplSyntaxOff

\begin{document}
\monoid{
  (A\otimes A)\otimes A\otimes A &
  A\otimes (A\otimes A) &
  A\otimes A &
  A\otimes A &
  A &
  \mu\otimes\mathit{Id} &
  \mathit{Id}\otimes\mu &
  \mu &
  \mu\otimes\mathit{Id}
}
\end{document}