在 tikz 中创建常见交换图的宏

在 tikz 中创建常见交换图的宏

我目前正在排版一份文档,该文档需要许多形状和结构相同但顶点和边上的标签不同的交换图。例如,我想要一个描述代数结合结构的交换图。我可以用以下方法做到这一点:

\begin{equation}
\begin{tikzpicture}[baseline=(current bounding box.center)]
\matrix(m)[matrix of math nodes,
row sep=2.6em, column sep=2.8em,
text height=2ex, text depth=0.5ex]
{(A\otimes A)\otimes A& & A\otimes (A\otimes A)\\
A\otimes A& &A\otimes A\\
 &A& \\};
\path[->,font=\normalsize,>=angle 90]
(m-1-1) edge node[auto] {$\mu\otimes Id$} (m-2-1)
(m-2-1) edge node[auto] {$\mu$} (m-3-2)
(m-1-3) edge node[auto] {$ Id\otimes\mu$} (m-2-3)
(m-2-3) edge node[auto] {$ \mu$} (m-3-2);
\path[<->, font=\normalsize,>=angle 90]
(m-1-1) edge node[auto] {$\alpha$} (m-1-3);
\end{tikzpicture}
\end{equation}

在同一节中,我还想使用交换图来表达群的单半群结构。在我的文档中,这是完全相同的代码,但标签不同。随着我的继续,我知道这是一个我可能会经常使用的图表,并且不想将这个确切的代码复制并粘贴到每个新文档中。

我天真地尝试使用\newcommand{\monoid}[8]{...}来包装整个内容,但是这没有用。有没有办法在这个环境周围定义一个宏,这样我就可以只指定我需要的参数,而不必每次都复制和粘贴整个块,这样就很混乱了?

答案1

您需要使用键 替换 TikZ 矩阵中的“与”符号ampersand replacement=<macro>,其中<macro>可以是\&,例如 。

这是您的代码作为命令。我使用了PGF/TikZ:如何将字符串存储在数组中?使用列表而不是单独的标签参数。您的图表

然后可以使用创建

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

完整代码如下:

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

答案2

另一种方法:

  • 用于tikz-cd简单构造交换图
  • 使用arrayjobx元素的包

好处:

  • 更短的图表代码,箭头直接位于元素内
  • 您不必每次调用时都编写 9 个参数\monoid,如果图表类似,您可以只修改特定的数组参数,例如通过并再次\monoidelements(1)={A'\otimes A'}调用\monoid

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

幺半群

答案3

作为评论,这个答案太长了,因为它只是使用基于的较短语法重写了Jake的答案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}

\monoid宏执行两项操作:它从其参数设置一个序列,并调用\domonoid与 Jake 的相同的序列\monoid。请注意\domonoid 必须用 来定义\ExplSyntaxOff,因为 TikZ 键中的空格很重要。

的定义\argument很多比 更容易etoolbox

注意:为了得到更好的形式ID,最好使用\mathit{Id}


我们也可以对 Stefan Kottwitz 的回答使用类似的想法

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

相关内容