1

I'm trying to write a macro to let me write shorthand for tikz-cd arrows. For instance instead of having to write out the full command

\arrow[swap, dotted]{r}{f^*}

I'd like to have a shorthand like

\A[s.]{r}{f^*}

where the \A command processes the s to mean swap and the . to mean dotted. Using the xstring package it was pretty easy to write a command that takes s. as an input and outputs swap,dotted, but I don't know how to then feed that in as an argument for \arrow. I asked a simpler question earlier today which I thought would show me how to deal with the problem in general, but it turns out that dealing with how latex expands macros is a lot more complicated than I realized.

Anyway, the code I tried writing (after incorporating Steven B. Segletes's suggestions for how to solve my easier problem) is this:

\documentclass{article}

\usepackage{xstring} 
\usepackage{xifthen}

\usepackage{tikz-cd}

\newcommand{\arrowformatting}[1]{%
    \IfSubStr{#1}{s}{swap,}{}%
    \IfSubStr{#1}{.}{dotted,}{}%
    % Add more commands here later
}

\newcommand{\A}[3][]{%
    \ifthenelse{\isempty{#1}}{%
        \arrow{#2}{#3}%
    }{%
        \expandafter\arrow\expandafter[\arrowformatting{#1}]{#2}{#3}%
    }%
}

\begin{document} 

\[ \begin{tikzcd}
    A \A[s.]{r}{f^*} & B 
\end{tikzcd} \]

\end{document}

The function \arrowformatting works correctly on its own - if I call \arrowformatting{s.} in the document it prints out swap,dotted, like expected. But if I use the \A command as shown, it gives me an error

! Argument of \XC@definec@lor has an extra }.
<inserted text> 
                \par 
l.29 \end{tikzcd}
                  \]

Is there an easy way to fix this and get the output of \arrowformatting to be interpreted as input to \arrow like I want? Or am I going to run into lots of complicated order-of-expansion issues, and would I be better off trying something else (like I believe there's a package that lets you run python code within latex, and hopefully that could generate the correct \arrow command I want)?

  • In terms of your actual question, it is relevant that the macros of the xstring package are not purely expandable, so simply playing with the order of expansion will not suffice here. – Charles Staats Apr 11 '14 at 14:58
3

You can accomplish something similar to this by creating TikZ styles called s and .:

\documentclass[margin=10pt,convert]{standalone}
\usepackage{tikz-cd}
\tikzset{commutative diagrams/.cd, 
    s/.style = {swap},
    ./.style = {dotted},
    s./.style = {s,.}
    }
\newcommand{\A}{\ar}

\begin{document}

% Two different keys, separated by commas:
\begin{tikzcd}
A \ar[s,.]{r}{f^*} & B
\end{tikzcd}

% A single, specially defined key `s.`:
\begin{tikzcd}
A \A[s.]{r}{f^*} & B
\end{tikzcd}
\end{document}

I also created a style called s. to demonstrate that such a thing is possible. However, this is not a practical way to omit the commas if you want to be able to handle all possible permutations of more than two or three abbreviation keys.

The output:

enter image description here

  • Thanks! That seems like a nice and easy alternative solution - I didn't realize you could make your own styles in tikzcd. I'm still a bit curious whether it's possible to make what I wanted to do work – djc Apr 11 '14 at 19:44
  • I'd also be interested to see a solution to that. I've tried before to work one out, but have been unable to do so. – Charles Staats Apr 11 '14 at 19:50
0

I guess this is a little late, but using /utils/exec= and \pgfkeysalso you can get what you want:

\documentclass{article}

\usepackage{xstring}
\usepackage{tikz-cd}

\newcommand{\arrowformatting}[1]{%
    \IfSubStr{#1}{s}{\pgfkeysalso{swap}}{}%
    \IfSubStr{#1}{.}{\pgfkeysalso{dotted}}{}%
    % Add more commands here later
}

\newcommand{\A}[3][]{%
        \arrow[/utils/exec=\arrowformatting{#1}]{#2}{#3}%
}

\begin{document}

\[ \begin{tikzcd}
    A \A[s.]{r}{f^*} & B
\end{tikzcd} \]

\end{document} 

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.