texdiff 用于 subversion 中的多文件文档

texdiff 用于 subversion 中的多文件文档

我一直在寻找一种方便的方法来突出显示生成的 PDF 中 Latex 文档的 subversion 修订版本之间的更改。我正在处理一个相当复杂的文档,该文档汇集了各种 .tex 文件。通过使用多个\input{}s,latexdiff-svn似乎没有提供解决方案。文本差异尽管它更适合处理多文件文档,但不幸的是它并不具备处理 SVN 差异所需的魔力。

我已经想出了一个对我有用的解决方案,但我想知道是否还有我遗漏的更连贯的东西。

我的解决方案是一个相当简短的脚本,它执行以下操作:

  1. 给定一个修订号,向 SVN 询问从该修订号到 HEAD 之间发生变化的所有文件。
  2. 仅将这些文件导出到临时位置,然后运行文本差异导出副本和工作副本之间。
  3. 建立另一个临时目录,用于存储文本差异或者,如果没有做任何更改,则为工作副本的副本。该目录包含我构建文档所需的所有 .tex 文件。sed确保所有\input{}命令指向正确(即临时)的位置。

这招管用!但是,一个解决方案直接与svn 差异会更整洁。我之前尝试过svn 差异并试图直接把它钩到文本差异,但当我意识到我破坏了所有很好的括号匹配时,我放弃了文本差异确实如此。我的搜索毫无结果。虽然我对我的解决方案很满意,但有人知道一种更简洁的方法来实现我想要的吗?

答案1

我知道编写了以下 Perl 脚本,它svn diff调用概括模式来获取已更改的文件。它将这些文件提取svn cat到两个不同的目录中,并调用latexdiff每个已修改的文件。它修改TEXINPUTS变量以首先从差异目录而不是当前目录。这样可以避免复制所有未更改的文件。最后使用 编译主文件latexmk

用法是perl <scriptfile> <mainfile> <rev a> <rev b>

到目前为止,它绝对不是万无一失的,但比评论中链接的 shell 脚本更通用。请测试它并提供一些反馈。

#!/usr/bin/env perl
use strict;
use warnings;

my @FILES;

my $rpath = '.r';

my ($mainfile,$REVA,$REVB) = @ARGV;
my $dpath = ".diff-${REVA}-${REVB}";

open(my $pipe, '-|', "svn diff --summarize -r${REVA}:${REVB}") or die;
while (<$pipe>) {
    next if not /^M.{7}(.*\.tex)$/;
    push @FILES, $1;
}
close ($pipe);

exit (1) if not @FILES;

mkdir $rpath . $REVA;
mkdir $rpath . $REVB;
mkdir $dpath;

foreach my $file (@FILES) {
    print $file, "\n";
    $file =~ /^(.*)\//;
    my $dir  = $1 || "";
    my $dira = $rpath . $REVA . '/' . $dir;
    my $dirb = $rpath . $REVB . '/' . $dir;
    my $ddir = $dpath         . '/' . $dir;
    mkdir $dira if not -e $dira;
    mkdir $dirb if not -e $dirb;
    mkdir $ddir if not -e $ddir;
    system("svn cat -r${REVA} '$file' > '${rpath}${REVA}/$file'");
    system("svn cat -r${REVB} '$file' > '${rpath}${REVB}/$file'");
    system("latexdiff '${rpath}${REVA}/$file' '${rpath}${REVB}/$file' > '${dpath}/$file'");
}

if (not exists $ENV{"TEXINPUTS"} || $ENV{"TEXINPUTS"} eq '') {
    $ENV{"TEXINPUTS"} = "$dpath:.:";
}
else {
    $ENV{"TEXINPUTS"} = "$dpath:" . $ENV{"TEXINPUTS"};
}

system("latexmk -pdf $mainfile")

答案2

我创建了一个批处理文件,其中包含一些脚本,用于将多文件 LaTeX 项目与 Subversion 结合使用。其目的是:

  • 扁平化文档,即创建一个包含项目所有元素的单个文件
  • 将此版本与存储库中的先前版本进行比较
  • 生成突出显示更改的 PDF
  • 创建一个扁平文档的版本,其中每个句子都以新行开始(在比较源文件时很有用)
  • 创建一个删除可以发送给其他人的评论和待办事项的版本。

为此,我使用了三个公开可用的脚本。批处理文件、脚本链接和说明可以在我的网站上找到:http://www.jwe.cc/2012/02/workflow-with-subversion-and-latex/

答案3

Martin Scharrer 的 Perl 脚本运行良好。谢谢!我不得不做一些更改才能使脚本在我的系统上运行。(我会将此作为评论添加到答案中,但我还没有足够的“声誉”。)

`--> diff diff_latex_orig.pl diff_latex.pl
3a4
> use File::Path qw(make_path);
12,13c13,14
< open(my $pipe, '-|', "svn diff --summarize -r${REVA}:${REVB}") or die;
< while () {
---
> open(XX, '-|', "svn diff --summarize -r${REVA}:${REVB}") or die;
> while (<XX>) {
17c18
< close ($pipe);
---
> close (XX);
32,34c33,35
<     mkdir $dira if not -e $dira;
<     mkdir $dirb if not -e $dirb;
<     mkdir $ddir if not -e $ddir;
---
>     make_path($dira);
>     make_path($dirb);
>     make_path($ddir);

另外,我必须手动将序言添加到顶层.tex文件。

%DIF PREAMBLE EXTENSION ADDED BY LATEXDIFF
%DIF UNDERLINE PREAMBLE
\RequirePackage[normalem]{ulem}
\RequirePackage{color}\definecolor{RED}{rgb}{1,0,0}\definecolor{BLUE}{rgb}{0,0,1}
\providecommand{\DIFadd}[1]{{\protect\color{blue}\uwave{#1}}}
\providecommand{\DIFdel}[1]{{\protect\color{red}\sout{#1}}}
%DIF SAFE PREAMBLE
\providecommand{\DIFaddbegin}{}
\providecommand{\DIFaddend}{}
\providecommand{\DIFdelbegin}{}
\providecommand{\DIFdelend}{}
%DIF FLOATSAFE PREAMBLE
\providecommand{\DIFaddFL}[1]{\DIFadd{#1}}
\providecommand{\DIFdelFL}[1]{\DIFdel{#1}}
\providecommand{\DIFaddbeginFL}{}
\providecommand{\DIFaddendFL}{}
\providecommand{\DIFdelbeginFL}{}
\providecommand{\DIFdelendFL}{}
%DIF END PREAMBLE EXTENSION ADDED BY LATEXDIFF

答案4

rcs-latexdiff工具可以做到这一点。它可以在 RCS 存储库中创建同一文件的不同版本的 latexdiff。它还可以管理包含的文件(它查找包含的文件,并通过 svn cat 命令获取每个修订版的文件)。

基本用法是:

$ rcs-latexdiff [OPTIONS] filename old_commit new_commit

例如,

$ rcs-latexdiff paper.tex 19 20

创建输出文件差异文本这是 paper.tex 文件的最后两个修订版本的 latexdiff(如果提交 20 是 HEAD)。您还可以使用诸如 BASE、COMMITTED、PREV 等关键字。

然后,您可以使用自己喜欢的编译器编译输出文件。请注意,由于 SVN 是基于服务器的,因此有时该过程可能会很长。

此工具的最终目标是支持所有 RCS 软件。目前,它仅支持 SVN 和 Git。您可以在以下位置找到安装说明Github 页面。请随意使用、报告错误并做出贡献 ;)

相关内容