17

I have a long set of lecture notes where the commutative diagrams are written in xy using the \xymatrix format. I would like to switch over to tikz-cd. The syntax for the two are pretty similar with some minor differences, so it is conceivable to me that someone has either written, or could easily write, a script that will automatically convert all \xymatrix{...} occurrences to a tikz-cd format that works for all non-exotic commutative diagrams. If somebody knows of such a script or can give me such a script, I would be very happy!

Note that I am willing to do the effort of fixing diagrams that involve curved lines or other non-standard things if that is too hard for a script.

I am not working on a unix machine although I have access to a Macbook that I could open in unix if necessary.

Here is a sample in \xymatrix{...}

\xymatrix{\Delta_{q-2}\ar[r]^{F_{q-1}^i}\ar[d]_{F_{q-1}^{j-1}}& \Delta_{q-1}\ar[d]^{F_q^j}\\
 \Delta_{q-1}\ar[r]_{F_{q}^i} & \Delta_q}

And the corresponding tikz-cd

\begin{tikzcd}
\Delta_{q-2}\ar{r}{F_{q-1}^i}\ar{d}[swap]{F_{q-1}^{j-1}}& \Delta_{q-1}\ar{d} {F_q^j}\\ 
\Delta_{q-1}\ar{r}[swap]{F_{q}^i} & \Delta_q
\end{tikzcd}

Please note that I have at least 50 occurrences of xymatrix so I would like a script that converts a whole file.

2
  • 1
    could you provide a sample of code in xymatrix and a sample of how you'd like it to look in tikz-cd?
    – cmhughes
    Feb 4, 2014 at 18:58
  • 1
    @cmhughes, Ok, I'll do that tonight. Feb 4, 2014 at 19:13

1 Answer 1

10
+50

It's not extremely pretty, but it works:

#!/usr/bin/perl

use strict;
use warnings;
use feature qw/say/;
use Regexp::Common;

my $file = 'a.tex';             # Change this to your filename
open my $fh, '<', $file;
my $content = do { local $/; <$fh> };

my $bal_rx = $RE{balanced}{-parens=>'{}'};
my $ar_rx = qr/\s*
            \\ar
            (?<dash> @\{-->\} )?
            \[(?<dir> [udlr]+ )\]
            (?: (?<p1> [_^] ) (?<ar1> $bal_rx) )?
            (?: (?<p2> [_^] ) (?<ar2> $bal_rx) )?
            \s*/x;

sub conv_block {
    my $x = shift;
    my @s;
    while ($x =~ s/$ar_rx//){
        my $dir = $+{dir};
        my $dash = $+{dash} ? '[dashed]' : '';
        my ($t1, $t2) = ('', '');
        if ($+{ar1}) {
            $t1 = $+{ar1};
            $t1 = '[swap]' . $t1 if $+{p1} eq '_';
        }
        if ($+{ar2}) {
            $t1 = $+{ar2};
            $t2 = '[swap]' . $t2 if $+{p2} eq '_';
        }
        push @s, "\\ar${dash}{$dir}$t1$t2";
    }
    return $x . ' ' . (join ' ', @s);
}

sub conv_matrix {
    my $matrix = shift;
    $matrix =~ s/^\{(.*)\}$/$1/s;
    my @rows = split /\s* \\\\ \s*/x, $matrix;
    my @cols = map { [split /\s* & \s*/x, $_] } @rows;
    my $res = '';
    $res .= "\\begin{tikzcd}\n";
    $res .= join " \\\\\n", map { join " &\n", map {conv_block $_} @$_ } @cols;
    $res.= "\n\\end{tikzcd}\n";
    return $res;
}

$content =~ s/\\xymatrix $bal_rx/conv_matrix $1/gxe;
open my $out, '>', "${file}.new";
print $out $content;

You need Perl and the Regexp::Common library. I haven't extensively tested it, but it works in simple cases.

14
  • I will have to see if I have perl. But can I do this for the whole tex file or do I need to do this occurrence by occurrence. Also this is only a sample. There are other standard xy things I would like to switch to tikzcd. Feb 5, 2014 at 14:05
  • You need to input it diagram by diagram. It wouldn't be very easy to rewrite it to work on an entire TeX file (I can try). What other things do you want to convert? Feb 5, 2014 at 14:09
  • There are dashed arrows and curved arrows. I don't have many curved arrows so dashed is more important. Feb 5, 2014 at 14:17
  • But converting the whole file is more important. There are probably 50 or more xymatrix diagrams in the lecture notes. So doing it one by one is too much. I could essentially do it manually one by one of it was only a couple because the syntax is similar. But I would like to do the whole thing in an automated way. Feb 5, 2014 at 14:19
  • There you go, this will now convert the whole file and output the result in a new file. Feb 5, 2014 at 14:24

You must log in to answer this question.

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