有没有人有可以将 \xymatrix 转换为 tikzcd 的脚本?

有没有人有可以将 \xymatrix 转换为 tikzcd 的脚本?

我有一套很长的讲义,其中交换图是xy使用\xymatrix格式编写的。我想切换到tikz-cd。两者的语法非常相似,只有一些细微的差别,因此我可以想象有人已经编写或可以轻松编写一个脚本,该脚本会自动将所有\xymatrix{...}出现的情况转换为tikz-cd适用于所有非奇异交换图的格式。如果有人知道这样的脚本或可以给我这样的脚本,我会非常高兴!

请注意,如果脚本无法解决涉及曲线或其他非标准内容的图表,我愿意尽力修复。

虽然我可以使用 Macbook(如果需要的话,可以在 unix 中打开它),但我并不是在 unix 机器上工作。

以下是一个示例\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}

以及相应的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}

请注意,我至少有 50 次 xymatrix 出现,所以我想要一个可以转换整个文件的脚本。

答案1

它不是非常漂亮,但它可以工作:

#!/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;

您需要 Perl 和 Regexp::Common 库。我尚未对其进行广泛测试,但它在简单情况下有效。

相关内容