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}
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}