2

I am trying to create a macro to easily draw forks as this one:

enter image description here

I tried this:

 \newcommand{\fork}[6]{
 \begin{center}
 \begin{tikzcd}
 #1 \arrow[r, "#2"] & #3 \arrow[r,shift left, "#4"] 
 \arrow[r,shift right, "#5"'] & #6
 \end{tikzcd}
 \end{center} 
}

But I get an error "Single ampersand used with wrong catcode."

1 Answer 1

4

You don't really want to use the center environment, but the main problem is the &:

\newcommand{\fork}[6]{%
  \begin{tikzcd}[ampersand replacement=\&]
  #1 \arrow[r, "#2"] \& #3 \arrow[r,shift left, "#4"] 
  \arrow[r,shift right, "#5"'] \& #6
  \end{tikzcd}%
}

The key ampersand replacement is necessary each time a TikZ matrix (such as a tikzcd diagram) is used in the argument to another command.

Use it in a display environment, say

\[
\fork{K}{k}{A}{f}{0}{B}
\]

Here's another suggestion for coping with both equalizer and coequalizer diagrams. Each item in the diagram is defined with a key-value approach (use different keys, if you like); a * tells to draw a coequalizer diagram. Like in most key-value approaches, the order of the keys is irrelevant.

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

\ExplSyntaxOn

\keys_define:nn { soap/forks }
 {
  s .tl_set:N = \l__soap_fork_source_tl,
  t .tl_set:N = \l__soap_fork_target_tl,
  e .tl_set:N = \l__soap_fork_end_tl,
  u .tl_set:N = \l__soap_fork_up_tl,
  d .tl_set:N = \l__soap_fork_down_tl,
  c .tl_set:N = \l__soap_fork_center_tl,
  * .bool_set:N = \l__soap_fork_co_bool,
  * .default:n = true,
 }

\NewDocumentCommand{\fork}{m}
 {
  \keys_set:nn { soap/forks } { #1 }
  \begin{tikzcd}[ampersand~replacement=\&]
  \bool_if:NF \l__soap_fork_co_bool
   {% false, equalizer
    \l__soap_fork_end_tl
    \arrow[r,"\l__soap_fork_center_tl"] \&
   }
  \l__soap_fork_source_tl
  \arrow[r,shift~left,"\l__soap_fork_up_tl"]
  \arrow[r,shift~right,"\l__soap_fork_down_tl",swap] \&
  \l__soap_fork_target_tl
  \bool_if:NT \l__soap_fork_co_bool
   {% true, coequalizer
    \arrow[r,"\l__soap_fork_center_tl"] \&
    \l__soap_fork_end_tl
   }
  \end{tikzcd}
 }

\ExplSyntaxOff

\begin{document}

\begin{gather}
\fork{s=A,t=B,e=K,u=f,d=0,c=k}
\\
\fork{*,s=A,t=B,e=K,u=f,d=0,c=k}
\end{gather}

\end{document}

enter image description here

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .