4

I've extended myself too much, so the short question is:

Why can't I define macros with the tikzcdpackage as defined below? (right above the "Old Solution" section)


Description

I recently developed a notation for functors and it was tempting to use the tikzcd environment. However, the problem is that 1) The macro must have more than 9 entries (I found a solution here). 2) The spacing was pretty terrible.

I finded a solution using array and some rotations (the solution code will be at the end), but mostly it works fine.

Old solution output

But, when using big categories names or whatever, space between terms becomes way to strange and preety lame. Back to tikzcd, I've almost with some additional tricks (but mostly "fairier"):

\begin{tikzcd}[row sep={0.22em}, column sep={0.01em}]
    {F}: & {\boldsymbol{\mathscr C}} \arrow[rr] &\hspace{0.5cm}& {\boldsymbol{\mathscr D}}        &   \\
    & {X} \arrow[dd,"{\phi}"'] \arrow[rr, mapsto] & & {F(X)} \arrow[dd,"{F(\phi)}"'] & {x} \arrow[dd,mapsto]\\
    & \,                                         & &              &   \\ 
    & {Y} \arrow[rr,mapsto]                     & & {Y}         & {F(\phi)(x)}
\end{tikzcd}

Which produces:

enter image description here

Now the arrows adjust itself to each case. So im done and wanted to define that macro. Copying what I did in the old way, it should be:

%----------------
% Black Tex Magic
%----------------
% Provide a way to declare and renew a command in one command
\newcommand{\neworrenewcommand}[1]{\providecommand{#1}{}\renewcommand{#1}}

% Covariant functor
\newcommand{\covfunctor}[9]{
    \neworrenewcommand{\ccovfunctor}[2]{
        \begin{tikzcd}[row sep={0.22em}, column sep={0.01em}]
            {#1}: & {#2} \arrow[rr]                            &\hspace{0.5cm} & {#3}        &   \\
            & {#4} \arrow[dd,"{#8}"'] \arrow[rr, mapsto] & & {#5} \arrow[dd,"{#9}"'] & {##1} \arrow[dd,mapsto]\\
            & \,                                         & &              &   \\ 
            & {#6} \arrow[rr,mapsto]                     & & {#7}         & {##2}
        \end{tikzcd}
    }
    \ccovfunctor
}

Well... nothing could be that simple in TeX: It compiles an error but it doesn't show me exactly what it is. So... what went wrong?

Old Solution

It uses the same \neworrenewcommand as above.

\usepackage{rotating}
\usepackage{scalerel}
\newcommand{\covfunctor}[9]{
    \neworrenewcommand{\ccovfunctor}[2]{
        \begin{array}{rcccc}
            {#1}: & \hphantom{{#8}} {#2} & \longrightarrow & {#3} &  \\
            &   \hphantom{{#8}} {#4}    &   \longmapsto   & {#5} & {##1}\\
            &  \begin{turn}{90}
                \ensuremath{\overset{\begin{turn}{270}
                            \scaleobj{0.7}{\ensuremath{{#8}}}
                    \end{turn}}{\longleftarrow}}
            \end{turn} &  & \begin{turn}{90}
                \ensuremath{\overset{\begin{turn}{270}
                            \scaleobj{0.7}{\ensuremath{{#9}}}
                    \end{turn}}{\longleftarrow}}
            \end{turn} \hphantom{\scaleobj{0.7}{{#9}}} & \begin{turn}{90}
                \reflectbox{\ensuremath{\longmapsto}}
            \end{turn}\\
            &  \hphantom{{#8}} {#6} & \longmapsto & {#7} & {##2}
        \end{array}
    }
    \ccovfunctor
}
2
  • 1
    A general remark: When you want a macro with more than 9 arguments, it’s usually better to use some kind of keyval syntax.
    – Gaussler
    Sep 5, 2021 at 17:52
  • I agree with Gaussler. Although in this case, are you really using this as a function? Are you going to be having two or more of these, but with different entries? If not, it would just be easier to type the diagram instead of having a macro type the diagram.
    – Teepeemm
    Sep 5, 2021 at 19:57

2 Answers 2

4

I believe everything is in the link you posted and in your code. Note that &\hspace{0.5cm}& is not right, you should write &[1cm]& and it is not necessary an extra row, this space can be adjusted with \\[5mm].

\documentclass{article}
\usepackage{mathtools}
\usepackage{mathrsfs}
\usepackage{tikz-cd}

%This is a first attemp with only 7 arguments
\newcommand{\funtordia}[7]{%
  \begin{tikzcd}[row sep={0.22em}, column sep={0.01em}, ampersand replacement=\&]
    #1: \& \mathscr{#2} \arrow[rr] \&[1cm]\& \mathscr{#3} \&   \\
    \& #5 \arrow[d,"#4"'] \arrow[rr, mapsto] \& \& #1(#5) \arrow[d,"#1(#4)"'] \& #7 \arrow[d,mapsto]\\[5mm]
    \& #6 \arrow[rr,mapsto]                     \& \& #1(#6)         \& #7\cdot #4
  \end{tikzcd}
}

%This is taken from the egreg's answer in the link you posted
\ExplSyntaxOn
\NewDocumentCommand{\NewWeirdCommand}{mm}
 {% #1 = command to define, #2 = replacement text
  \cs_new:Npn #1 ##1
   {
    \tl_set:Nn \l__covfun_args_tl { ##1 }
    #2
   }
 }
\NewDocumentCommand{\Arg}{m}
 {
  \tl_item:Nn \l__covfun_args_tl { #1 }
 }

\tl_new:N \l__covfun_parse_args_tl
\ExplSyntaxOff

\NewWeirdCommand{\covfunctor}{%
  \begin{tikzcd}[row sep={0.22em}, column sep={0.01em}, ampersand replacement=\&]
    \Arg{1}: \& \mathscr{\Arg{2}} \arrow[rr] \&[1cm]\& \mathscr{\Arg{3}} \&   \\
    \& \Arg{5} \arrow[d,"\Arg{4}"'] \arrow[rr, mapsto] \& \& \Arg{8} \arrow[d,"\Arg{7}"'] \& \Arg{10} \arrow[d,mapsto]\\[5mm]
    \& \Arg{6} \arrow[rr,mapsto]                     \& \& \Arg{9}         \& \Arg{11}
  \end{tikzcd}
}

\begin{document}

\funtordia{G}{D}{C}{d}{D}{D'}{y}%
\qquad%
\covfunctor{{F}{A}{B}{a}{A}{A'}{b}{B}{B'}{x}{y}}

\end{document}

which generates the following enter image description here

2
  • 3
    You have done a great job.
    – Sebastiano
    Sep 5, 2021 at 21:56
  • Thanks! it worked perfectly. Just a litle twiks and i also did it the contra-variant case. Sep 7, 2021 at 13:05
4

Using eleven arguments is very error prone. I suggest a different approach with a more natural syntax “by column”. The idea is to store the column data and to pick the needed items when they're needed in the diagram.

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

\ExplSyntaxOn

% the syntax will be by columns:
% \describefunctor{F}{\mathcal{C},X,\phi,Y}{\mathcal{D},F(X),F(\phi),F(Y)}[x,F(\phi)(x)]
% with the last column optional

\NewDocumentCommand{\describefunctor}{mmmo}
 {
  \IfNoValueTF{#4}
   {
    \bool_set_false:N \l__mezzovilla_three_bool
    \mezzovilla_functor:nnnn { #1 } { #2 } { #3 } { }
   }
   {
    \bool_set_true:N \l__mezzovilla_three_bool
    \mezzovilla_functor:nnnn { #1 } { #2 } { #3 } { #4 }
   }
 }

\clist_new:N \l__mezzovilla_functor_one_clist
\clist_new:N \l__mezzovilla_functor_two_clist
\clist_new:N \l__mezzovilla_functor_three_clist
\bool_new:N \l__mezzovilla_three_bool

\cs_new_protected:Nn \mezzovilla_functor:nnnn
 {
  \clist_set:Nn \l__mezzovilla_functor_one_clist { #2 }
  \clist_set:Nn \l__mezzovilla_functor_two_clist { #3 }
  \clist_set:Nn \l__mezzovilla_functor_three_clist { #4 }
  \begin{tikzcd}[ampersand~replacement=\&]
  #1\colon \&[-3em]
  \__mezzovilla_item:nn { one } { 1 } \arrow[r] \&
  \__mezzovilla_item:nn { two } { 1 }
  \bool_if:NT \l__mezzovilla_three_bool { \&[-1.5em] }
  \\[-1.5em]
  \& \__mezzovilla_item:nn { one } { 2 }
     \arrow[r,mapsto]
     \arrow[d,swap,"\__mezzovilla_item:nn { one } { 3 }"]
  \& \__mezzovilla_item:nn { two } { 2 }
     \arrow[d,swap,"\__mezzovilla_item:nn { two } { 3 }"]
  \bool_if:NT \l__mezzovilla_three_bool
   { \& \__mezzovilla_item:nn { three } { 1 } \arrow[d,mapsto] }
  \\
  \& \__mezzovilla_item:nn { one } { 3 }
     \arrow[r,mapsto]
  \& \__mezzovilla_item:nn { two } { 3 }
  \bool_if:NT \l__mezzovilla_three_bool
   { \& \__mezzovilla_item:nn { three } { 2 } }
  \end{tikzcd}
 }

\cs_new:Nn \__mezzovilla_item:nn
 {
  \clist_item:cn { l__mezzovilla_functor_#1_clist } { #2 }
 }

\ExplSyntaxOff

\begin{document}

\[
\describefunctor{F}{\mathcal{C},X,\phi,Y}{\mathcal{D},F(X),F(\phi),F(Y)}[x,F(\phi)(x)]
\]

\[
\describefunctor{F}{\mathcal{C},X,\phi,Y}{\mathcal{D},F(X),F(\phi),F(Y)}
\]

\end{document}

enter image description here

2
  • +1 because there’s always something to learn in your answers (even when mine is a copy-paste of your code in other post) Sep 7, 2021 at 13:42
  • I really liked this approach, making it possible to omit the map of each funtor. Unfortunately, there was some error when I didn't include a name for the funtor image. I tried with ..., { }, ... and other "gambiarras" (no nice translation, kind of a trick) but it was unable to compile. I saved the alternative in the same way, thank you very much. Sep 11, 2021 at 15:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.