<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">#!/usr/bin/env perl 
#
# latexdiff-vc  - wrapper script for applying latexdiff to rcs managed files
#                 and for automatised creation of postscript or pdf from difference file
#
#   Copyright (C) 2005-12  F J Tilmann (tilmann@gfz-potsdam.de, ftilmann@users.berlios.de)
#
# Project webpages:   http://latexdiff.berlios.de/
# CTAN page:          http://www.ctan.org/tex-archive/support/latexdiff
#
#
#   Contributors: S Utcke, H Bruyninckx
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#    You should have received a copy of the GNU General Public License
#    along with this program.  If not, see &lt;http://www.gnu.org/licenses/&gt;.
#
# Detailed usage information at the end of the file
#
# version 1.0.2: - option --so to use latexdiff-so
# version 1.0.1 (change version numbering to match that of latexdiff)
#   - Option --fast to use latexdiff-fast, 
#   - git support (thanks to BjÃ¸rn Magnus Mathisen, Santi BÃ©jar, Pietro Battiston and Stefan Alfredson for patches) - UNTESTED
# version 0.25:
#   - bbl is allowed as alternative extension (instead of .tex)
# version 0.26a
#   - Bug fix: it copes now correctly with the possibility that there are no changes between current
#         and archived version
use Getopt::Long ;
use Pod::Usage qw/pod2usage/ ;
use File::Temp qw/tempdir/ ;
use File::Basename qw/dirname/;
use strict ;
use warnings ;

my $versionstring=&lt;&lt;EOF ;
This is LATEXDIFF-VC 1.0.2
  (c) 2005-2012 F J Tilmann
EOF


# Option names
my ($version,$help,$fast,$so,$postscript,$pdf,$force,$dir,$cvs,$rcs,$svn,$git,$diffcmd,$patchcmd,@revs);
# Preset Variables
my $latexdiff="latexdiff"; # Program for making the comparison
my $vc="";
my $tempdir=tempdir(CLEANUP =&gt; 1);
# Variables
my ($file1,$file2,$diff,$diffbase,$answer,$options,$infile,$append,$dirname,$cwd);
my (@files,@ldoptions,@tmpfiles,@ptmpfiles,@difffiles); # ,

Getopt::Long::Configure('pass_through','bundling');

GetOptions('revision|r:s' =&gt; \@revs,
           'cvs' =&gt; \$cvs,
           'rcs' =&gt; \$rcs,
           'svn' =&gt; \$svn,
           'git' =&gt; \$git,
           'dir|d:s' =&gt; \$dir,
	   'fast' =&gt; \$fast,
	   'so' =&gt; \$so,
           'postscript|ps' =&gt; \$postscript,
           'pdf' =&gt; \$pdf,
           'force' =&gt; \$force,
           'version' =&gt; \$version,
	   'help|h' =&gt; \$help);

if ( $help ) {
  pod2usage(1) ;
}

if ( $version ) {
  die $versionstring ; 
}

if ( $so ) {
  $latexdiff='latexdiff-so';
}
if ( $fast ) { 
  die "Cannot specify more than one of --fast or --so " if ($so);
  $latexdiff='latexdiff-fast';
}

if ( $cvs ) {
  $vc="CVS";
}
if ( $rcs ) {
  die "Cannot specify more than one of --cvs, --rcs --svn or --git." if ($vc);
  $vc="RCS";
}
if ( $svn ) {
  die "Cannot specify more than one of --cvs, --rcs --svn or --git." if ($vc);
  $vc="SVN";
}
if ( $git ) {
  die "Cannot specify more than one of --cvs, --rcs, --svn or --git." if ($vc);
  $vc="GIT";
}


# check whether the first file name or first passed-through option for latexdiff got misinterpreted as an option to an empty -r option
if ( @revs &amp;&amp; ( -f $revs[$#revs] || $revs[$#revs] =~ /^-/ ) ) {
  unshift @ARGV,$revs[$#revs];
  $revs[$#revs]="";
}
# check whether the first file name or first passed-through option for latexdiff got misinterpreted as an option to an empty -d option
if ( defined($dir) &amp;&amp; ( -f $dir || $dir =~ /^-/ ) ) {
  unshift @ARGV,$dir;
  $dir="";
}

#print "DEBUG: latexdiff-vc command line: ", join(" ",@ARGV), "\n"; 

$file2=pop @ARGV;
( defined($file2) &amp;&amp; $file2 =~ /\.(tex|bbl)$/ ) or pod2usage("Must specify at least one tex or bbl file");

if (! $vc &amp;&amp; scalar(@revs)&gt;0 ) {
  # have to guess $vc
  # check whether we have a special name
  if ( $0 =~ /-cvs$/ ) {
    $vc="CVS";
  } elsif ( $0 =~ /-rcs$/ ) {
    $vc="RCS";
  } elsif ( $0 =~ /-svn$/ ) {
    $vc="SVN";
  } elsif ( $0 =~ /-git$/ ) {
    $vc="GIT";
  } elsif ( -e "CVSROOT" || defined($ENV{"CVSROOT"}) ) {
    print STDERR "Guess you are using CVS ...\n";
    $vc="CVS";
  } elsif ( -e "$file2,v" ) {
    print STDERR "Guess you are using RCS ...\n";
    $vc="RCS";
  } elsif ( -d ".svn" ) {
    print STDERR "Guess you are using SVN ...\n";
    $vc="SVN";
  } elsif ( -d ".git" ) {
    print STDERR "Guess you are using GIT ...\n";
    $vc="GIT";
  } else {
    print STDERR "Cannot figure out version control system, so I default to CVS\n";
    $vc="CVS";
  }
}

if (defined($dir) &amp;&amp; $dir=~/^\.\/?/ ) {
  print STDERR "You wrote -dir=.  but you do not really like to do that, do you ?\n";
  exit 10
}

if ( scalar(@revs)&gt;0 ) {
  if ( $vc eq "CVS" ) { 
    $diffcmd  = "cvs diff -u -r"; 
    $patchcmd = "patch -R -p0";
  } elsif ( $vc eq "RCS" ) {
    $diffcmd  = "rcsdiff -u -r";  
    $patchcmd = "patch -R -p0";
  } elsif ( $vc eq "SVN" ) {
    $diffcmd  = "svn diff -r ";  
    $patchcmd = "patch -R -p0";
  } elsif ( $vc eq "GIT" ) {
    $diffcmd  = "git diff -r --relative --no-prefix ";  
    $patchcmd = "patch -R -p0";
    # alternatively:
    # $diffcmd  = "git diff ";
    # $patchcmd = "patch -R -p1";
  } else {
    print STDERR "Unknown versioning system $vc \n";
    exit 10;
  }
}


# make file list (last arguments), initial arguments have to be passed to latexdiff
# We assume an argument is a valid file rather than a latexdiff argument
# if it has extension .tex or .bbl

@files=($file2);
while( $file1=pop @ARGV ) {
  if ( $file1 =~ /\.(tex|bbl)$/ ) {
    # $file1 looks like a valid file name and is prepended to file list
    unshift @files, $file1 ;
  } else {
    # $file1 looks like an option for latexdiff, push it back to argument stack
    unshift @ldoptions, $file1 ;
  }
}

if ( scalar(@revs) == 0 ) {
  pod2usage("When -r option is not used, two .tex files (old and new) must be given on the command line") unless @files==2;
    #  compare two files
  $file1=shift @files ;
}

if ( scalar(@revs) == 2 ) {
  $append = "-diff$revs[0]-$revs[1]";
} elsif ( scalar(@revs) == 1 || $revs[0] ) {
  $append = "-diff$revs[0]";
} else {
  $append = "-diff";
}

if ( defined ($dir) &amp;&amp; ! $dir ) {
  # bare -d option =&gt; choose directory name
  ($dir=$append) =~ s/^-//;
}

if ( ($vc eq "SVN" || $vc eq "CVS") &amp;&amp; scalar(@revs)) {
  length($revs[$#revs]) &gt; 0 or $revs[$#revs]="HEAD";
  length($revs[0]) &gt; 0 or $revs[0]="HEAD";
}

#exit ; 


# cycle through all files

@difffiles=();
while ( $infile=$file2=shift @files ) {
  print STDERR "Working on  $infile \n";
  if ( scalar(@revs) == 1 ) {
    ($file1=$infile) =~ s/\.(tex|bbl)/-oldtmp-$$.$1/ ;
    push @tmpfiles,$file1;
    # compare file with previous version ($revs[0]="") or specified version
    ### system("$diffcmd$revs[0] $infile| $patchcmd -o$file1") ;
    if (system("$diffcmd$revs[0] $infile | $patchcmd -o$file1")==0  and -z $file1 ) {
      # no differences detected, i.e. file is equal to current version
      system("\cp $infile $file1");
    }
  } elsif ( scalar(@revs) == 2 ) {
    ($file1=$infile) =~ s/\.(tex|bbl)/-oldtmp-$$.$1/ ;
    $file2 =~ s/\.(tex|bbl)/-newtmp-$$.$1/ ;
    push @tmpfiles,$file2;
      ;
    if (system("$diffcmd$revs[1] $infile | $patchcmd -o$file2")==0 and -z $file2 ) {
      system("\cp $infile $file2");
    }
    if (system("$diffcmd$revs[0] $infile | $patchcmd -o$file1")==0 and -z $file1 ) {
	system("\cp $infile $file1");
    };
  }

  if ( -z $file1 || -z $file2) {
    print STDERR "One or both of the files to compare are empty. Possibly something went wrong in the retrieval of older versions. Aborting ...\n" ;
    exit(10);
  }

  # Get name of difference file
  if ( defined($dir) ) {
    $diff="$dir/$infile" ; 
  } else {
    ($diff=$infile) =~ s/\.(tex|bbl)$/$append.$1/ ;
  }
  # make directories if needed
  $dirname=dirname($diff) ;
  system("mkdir -p $dirname") unless ( -e $dirname );

  # Remaining options are passed to latexdiff
  $options = join(" ",@ldoptions);

  if ( -e $diff &amp;&amp; ! $force ) {
    print STDERR "OK to overwrite existing file $diff (y/n)? ";
    $answer = &lt;STDIN&gt; ;
    unless ($answer =~ /^y/i ) {
      unlink @tmpfiles;
      die "Abort ... " ;
    }
  }
  print "Running $latexdiff\n";
  unless ( system("$latexdiff $options $file1 $file2 &gt; $diff") == 0 ) { 
    print STDERR  "Something went wrong in $latexdiff. Deleting $diff and abort\n" ; unlink $diff ; exit(5) 
  };
  print "Generated difference file $diff\n";

  if ( ( $postscript or $pdf ) and !( scalar(@revs) &amp;&amp; greptex( qr/\\document(?:class|style)/ , $diff ) ) ) {
    # save filename for later processing if postscript or pdf conversion is requested and either two-file mode was used (scalar(@revs)==0) or the diff file contains documentclass statement (ie. is a root document)
    push @difffiles, $diff ;
  }
  
  unlink @tmpfiles;
}

foreach $diff ( @difffiles ) {
  chomp($cwd=(`pwd`));
  if  (defined($dir)) {
    ( $diff =~ s/$dir\/?// ) ;
    chdir $dir ; 
  }
  @ptmpfiles=();
  ( $diffbase=$diff) =~ s/\.(tex)$// ;

  # adapt magically changebar styles to [pdftex] display driver if pdf output was selected
  if ( $pdf ) {
    system("sed \"s/Package\\[dvips\\]/Package[pdftex]/\" $diff &gt; $diff.tmp$$ ; \\mv $diff.tmp$$ $diff");
  }
  print STDERR "PDF: $pdf Postscript: $postscript cwd $cwd\n";

  if ( system("grep -q \'^[^%]*\\\\bibliography\' $diff") == 0 ) { 
    if ( $postscript) {
      system("latex --interaction=batchmode $diff; bibtex $diffbase");
      push @ptmpfiles, "$diffbase.bbl","$diffbase.bbl" ; 
    } elsif ( $pdf ) {
      system("pdflatex --interaction=batchmode $diff; bibtex $diffbase");
      push @ptmpfiles, "$diffbase.bbl","$diffbase.bbl" ; 
    }
  }

  if ( $postscript ) {
    my $dvi="$diffbase.dvi";
    my $ps="$diffbase.ps";

    system("latex --interaction=batchmode $diff; latex $diff; dvips -o $ps $dvi");
    push @ptmpfiles, "$diffbase.aux","$diffbase.log",$dvi ;
    print "Generated postscript file $ps\n";
  } 
  elsif ( $pdf ) {
    system("pdflatex --interaction=batchmode $diff; pdflatex $diff");
    push @ptmpfiles, "$diffbase.aux","$diffbase.log";
  }
  unlink @ptmpfiles;
  chdir $cwd;
}

# greptex returns 1 if regex is not matched in filename
# 0 if there is a match
sub greptex {
  my ($regex,$filename)=@_;
  my ($i)=0;
  open (FH, $filename) or die("Couldn't open $filename: $!");
  while (&lt;FH&gt;) {
    next if /^\s*%/;    # skip comment lines
    if ( m/$regex/ ) {
      close(FH);
      return(0);
    }
    # only scan 25 lines
    $i++;    
    last if $i&gt;25 ;
  }
  close(FH);
  return(1);
}


=head1 NAME

latexdiff-vc - wrapper script that calls latexdiff for different versions of a file under version management (CVS, RCS or SVN)

=head1 SYNOPSIS

B&lt;latexdiff-vc&gt; [ F&lt;latexdiff-options&gt; ] [ F&lt;latexdiff-vc-options&gt; ]  B&lt;-r&gt; [F&lt;rev1&gt;] [B&lt;-r&gt; F&lt;rev2&gt;]  F&lt;file1.tex&gt; [ F&lt;file2.tex&gt; ...]

 or

B&lt;latexdiff-vc&gt; [ F&lt;latexdiff-options&gt; ]  [ F&lt;latexdiff-vc-options&gt; ][ B&lt;--postscript&gt; | B&lt;--pdf&gt; ]  F&lt;old.tex&gt; F&lt;new.tex&gt;

=head1 DESCRIPTION

I&lt;latexdiff-vc&gt; is a wrapper script that applies I&lt;latexdiff&gt; to a
file, or multiple files under version control (CVS, RCS or SVN), and optionally runs the
sequence of C&lt;latex&gt; and C&lt;dvips&gt; or C&lt;pdflatex&gt; commands necessary to
produce pdf or postscript output of the difference tex file(s). It can
also be applied to a pair of files to automatise the generation of difference
file in postscript or pdf format.

=head1 OPTIONS

=over 4

=item B&lt;--rcs&gt;, B&lt;--svn&gt;, B&lt;--cvs&gt;, or B&lt;--git&gt;

Set the version system. 
If no version system is specified, latexdiff-vc will venture a guess.

latexdiff-cvs and latexdiff-rcs are variants of latexdiff-vc which default to 
the respective versioning system. However, this default can still be overridden using the options above.

=item B&lt;-r&gt;, B&lt;-r&gt; F&lt;rev&gt; or B&lt;--revision&gt;, B&lt;--revision=&gt;F&lt;rev&gt;

Choose revision (under RCS, CVS, SVN or GIT). One or two B&lt;-r&gt; options can be
specified, and they result in different behaviour:

=over 4

=item B&lt;latexdiff-vc&gt; -r F&lt;file.tex&gt; ...

compares F&lt;file.tex&gt; with the most recent version checked into RCS.

=item B&lt;latexdiff-vc&gt; -r F&lt;rev1&gt; F&lt;file.tex&gt; ...

compares F&lt;file.tex&gt; with revision F&lt;rev1&gt;.

=item B&lt;latexdiff-vc&gt; -r F&lt;rev1&gt; -r F&lt;rev2&gt; F&lt;file.tex&gt; ...

compares revisions F&lt;rev1&gt; and F&lt;rev2&gt; of F&lt;file.tex&gt;.

Multiple files can be specified for all of the above options. All files must have the
extension C&lt;.tex&gt;, though.

=item B&lt;latexdiff-vc&gt;  F&lt;old.tex&gt; F&lt;new.tex&gt;

compares two files.

=back

The name of the difference file is generated automatically and
reported to stdout.

=item B&lt;-d&gt; or B&lt;--dir&gt;  B&lt;-d&gt; F&lt;path&gt; or B&lt;--dir=&gt;F&lt;path&gt;

Rather than appending the string C&lt;diff&gt; and optionally the version
numbers given to the output-file, this will prepend a directory name C&lt;diff&gt; 
to the
original filename, creating the directory and subdirectories should they not exist already.  This is particularly useful in order to clone a
complete directory hierarchy.  Optionally, a pathname F&lt;path&gt; can be specified, which is prepended instead of C&lt;diff&gt;.

=item B&lt;--fast&gt; or B&lt;--so&gt;

Use C&lt;latexdiff-fast&gt; or C&lt;latexdiff-so&gt;, respectively (instead of C&lt;latexdiff&gt;).

=item B&lt;--ps&gt; or B&lt;--postscript&gt;

Generate postscript output from difference file.  This will run the
sequence C&lt;latex; latex; dvips&gt; on the difference file (do not use
this option in the rare cases, where three C&lt;latex&gt; commands are
required if you care about correct referencing).  If the difference
file contains a C&lt;\bibliography&gt; tag, run the sequence C&lt;latex;
bibtex; latex; latex; dvips&gt;.

=item B&lt;--pdf&gt;

Generate pdf output from difference file using C&lt;pdflatex&gt;. This will
run the sequence C&lt;pdflatex; pdflatex&gt; on the difference file, or
C&lt;pdflatex; bibtex; pdflatex; pdflatex&gt; for files requiring bibtex.

=item B&lt;--force&gt;

Overwrite existing diff files without asking for confirmation. Default 
behaviour is to ask for confirmation before overwriting an existing difference
file.

=item B&lt;--help&gt; or
B&lt;-h&gt;

Show help text

=item B&lt;--version&gt;

Show version number

=back

All other options are passed on to C&lt;latexdiff&gt;.

=head1 SEE ALSO

L&lt;latexdiff&gt;

=head1 PORTABILITY

I&lt;latexdiff-vc&gt; uses external commands and is therefore
limited to Unix-like systems. It also requires the RCS version control
system and latex to be installed on the system.  Modules from Perl 5.8
or higher are required.

=head1 BUG REPORTING

 Please submit bug reports through
the latexdiff project page I&lt;http://developer.berlios.de/projects/latexdiff/&gt; or send
to I&lt;tilmann@gfz-potsdam.de&gt;.  Include the serial number of I&lt;latexdiff-vc&gt;
(option C&lt;--version&gt;)
.
=head1 AUTHOR

Copyright (C) 2005,2012 Frederik Tilmann

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License Version 3
Contributors: S Utcke, H Bruyninckx

=cut

</pre></body></html>