Skip to content

Commit

Permalink
Generate missing .bbl files for --flatten option by running bibtex. B…
Browse files Browse the repository at this point in the history
…ased on PR #127
  • Loading branch information
ftilmann committed Jul 14, 2024
1 parent bba53fd commit 4e52e1e
Showing 1 changed file with 58 additions and 30 deletions.
88 changes: 58 additions & 30 deletions latexdiff-vc
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@
#
# TODO/IDEAS: - option to call external pre-processing codes
#
# version 1.3.4a:
# version 1.3.4a:
# - Enhancement: if --flatten option is used, and no bbl file is included in the version management, then latexdiff-vc will try to run bibtex to generate the bbl file. Implements the suggestion of PR #127
# - bug fix: minor fix for --only-changed that makes detection of changed pages more reliable [ PR #297 contributed by user nelijuc ]
#
# version 1.3.2:
Expand Down Expand Up @@ -75,7 +76,7 @@
use Getopt::Long ;
use Pod::Usage qw/pod2usage/ ;
use File::Temp qw/tempdir/ ;
use File::Basename qw/dirname/;
use File::Basename qw/dirname fileparse/;
use File::Copy;
use File::Path;

Expand All @@ -102,6 +103,8 @@ my ($configlatexdiff,@config,$config,$assign);
#my $latexcmd="latex"; # latex compiler if not further identified
my $vc="";
my $tempdir=tempdir(CLEANUP => 1); # generate a temp dir, which will automatically be deleted at program exit
#printf STDERR "DEBUG: tempdir $tempdir\n";

# Variables
my ($file1,$file2,$diff,$diffbase,$rootdir,$answer,$options,$infile,$append,$dirname,$cwd);
my (@files,@ldoptions,@tmpfiles,@ptmpfiles,@difffiles,$extracomp); # ,
Expand Down Expand Up @@ -431,34 +434,43 @@ while ( $infile=$file2=shift @files ) {
print STDERR "Working on $infile \n";
if ( scalar(@revs) == 1 ) {
if ( defined($flatten) ) {
my $olddir=$tempdir . "/latexdiff-vc-$revs[0]";
print STDERR "Checking out old dir into: $olddir (rev: $revs[0])\n";
checkout_dir($revs[0],$olddir);
my $olddir=$tempdir . "/latexdiff-vc-$revs[0]";
print STDERR "Checking out old dir into: $olddir (rev: $revs[0])\n";
checkout_dir($revs[0],$olddir,$infile);
### print STDERR "DEBUG olddir $olddir";
### unless (-e $olddir) { mkdir $olddir or die "Cannot mkdir $olddir ." ;}
### print STDERR "DEBUG svn checkout -r $revs[0] $rootdir $olddir";
### system("svn checkout -r $revs[0] $rootdir $olddir")==0 or die "Something went wrong in executing: svn checkout -r $revs[0] $rootdir";
$file1=$olddir ."/".$infile;
} else {
($file1=$infile) =~ s/\.(tex|bbl|flt)/-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
copy($infile,$file1) || die "copy($infile,$file1) failed: $!";
}
}
$file1=$olddir ."/".$infile;

# generate bibliography for new file if
if ( greptex('^[^%]*\\\\bibliography\\{',$infile) == 0) {
my ($filebase,$filedir)=fileparse($infile,".tex");
if ( ! -e "$filedir$filebase.bbl" ) {
system("$CFG{LATEX} --interaction=batchmode '$infile'; $CFG{BIBTEX} '$filedir$filebase'")
or die "Something went wrong in executing: $CFG{LATEX} --interaction=batchmode '$infile'; $CFG{BIBTEX} '$filedir$filebase'" ;
}
}
} else {
($file1=$infile) =~ s/\.(tex|bbl|flt)/-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
copy($infile,$file1) || die "copy($infile,$file1) failed: $!";
}
}
} elsif ( scalar(@revs) == 2 ) {
if ( defined($flatten) ) {
my $olddir=$tempdir . "/latexdiff-vc-$revs[0]";
print STDERR "Checking out old dir into: $olddir (rev: $revs[0])\n";
checkout_dir($revs[0],$olddir);
checkout_dir($revs[0],$olddir,$infile);
$file1=$olddir ."/".$infile;

my $newdir=$tempdir . "/latexdiff-vc-$revs[1]";
print STDERR "Checking out new dir into: $newdir\n";
checkout_dir($revs[1],$newdir);
checkout_dir($revs[1],$newdir,$infile);
$file2=$newdir ."/".$infile;
} else {
($file1=$infile) =~ s/\.(tex|bbl|flt)/-oldtmp-$$.$1/ ;
Expand All @@ -485,7 +497,7 @@ while ( $infile=$file2=shift @files ) {
} else {
($diff=$infile) =~ s/\.(tex|bbl|flt)$/$append.$1/ ;
}

### print STDERR "DEBUG: diff $diff";
# make directories if needed
$dirname=dirname($diff) ;
Expand All @@ -506,13 +518,14 @@ while ( $infile=$file2=shift @files ) {
die "Abort ... " ;
}
}

print STDERR "Running: $CFG{LATEXDIFF} $options \"$file1\" \"$file2\" > \"$diff\"\n";
unless ( system("$CFG{LATEXDIFF} $options \"$file1\" \"$file2\" > \"$diff\"") == 0 ) {
print STDERR "Something went wrong in $CFG{LATEXDIFF}. Deleting $diff and abort\n" ; unlink $diff ; exit(5)
};
print "Generated difference file $diff\n";

if ( $run and !( scalar(@revs) && greptex( qr/\\document(?:class|style)/ , $diff ) ) ) {
if ( $run and !( scalar(@revs) && greptex( qr/\\document(?:class|style)/ , $diff,25) ) ) {
# 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 ;
}
Expand All @@ -537,7 +550,8 @@ foreach $diff ( @difffiles ) {
if ( $run ) {
print STDERR "PDF: $pdf Postscript: $postscript cwd $cwd\n" if $debug;

if ( system("grep -q \'^[^%]*\\\\bibliography{\' \"$diff\"") == 0 ) {
# if ( system("grep -q \'^[^%]*\\\\bibliography{\' \"$diff\"") == 0 ) {
if ( greptex('^[^%]*\\\\bibliography{',$diff ) == 0 ) {
system("$CFG{LATEX} --interaction=batchmode \"$diff\"; $CFG{BIBTEX} \"$diffbase\";");
push @ptmpfiles, "$diffbase.bbl","$diffbase.bbl" ;
}
Expand Down Expand Up @@ -661,12 +675,14 @@ sub compresspages {
return @res;
}

# checkout_dir(rev,dirname)
# checkout_dir(rev,dirname, <file>)
# checks out revision rev and stores it in dirname
# uses global variables: $vc, $rootdir
# If argument <file> is provided, check if this file imports a bibliography and generate it if necessary
# uses global variables: $vc, $rootdir, $CFG
sub checkout_dir {
my ($rev,$dirname)=@_;
my ($rev,$dirname,$file)=@_;

my ($filebase,$filedir);
unless (-e $dirname) { mkpath([ $dirname ]) or die "Cannot mkdir $dirname ." ;}
if ( $vc eq "SVN" ) {
system("svn checkout -r $rev $rootdir $dirname")==0 or die "Something went wrong in executing: svn checkout -r $rev $rootdir $dirname";
Expand All @@ -678,13 +694,25 @@ sub checkout_dir {
} else {
die "checkout_dir: only works with SVN, HG and GIT VCS system (selected: $vc)";
}
# Check if the main file needs a bbl generated
if ( defined($file) and greptex('^[^%]*\\\\bibliography\\{',$file) == 0) {
($filebase,$filedir)=fileparse($file,".tex");
if ( ! -e "$filedir$filebase.bbl" ){
printf STDERR "Running $CFG{BIBTEX} to generate $filedir$filebase.bbl.\n";
system("cd '$dirname'; $CFG{LATEX} --interaction=batchmode '$file'; $CFG{BIBTEX} '$filedir$filebase'")==0
or die "Something went wrong in executing: cd '$dirname'; $CFG{LATEX} --interaction=batchmode '$file'; $CFG{BIBTEX} '$filedir$filebase'" ;
}
# else { # DEBUG
# printf STDERR "DEBUG: Skipping bbl file generation as $filedir$filebase.bbl already exists.\n"
# } #DEBUG
}
}

# greptex returns 1 if regex is not matched in filename
# only the 25 first non-comment lines are scanned
# greptex($regex,$filename, <lines>) returns 1 if regex is not matched in filename
# only the first <lines> non-comment lines are scanned; by default everythin is scanned
# 0 if there is a match
sub greptex {
my ($regex,$filename)=@_;
my ($regex,$filename,$nlines)=@_;
my ($i)=0;
open (FH, $filename) or die("Couldn't open $filename: $!");
while (<FH>) {
Expand All @@ -693,9 +721,9 @@ sub greptex {
close(FH);
return(0);
}
# only scan 25 lines
# only scan <nlines> lines, if optional parameter proviede
$i++;
last if $i>25 ;
last if defined($nlines) and $i>$nlines ;
}
close(FH);
return(1);
Expand Down Expand Up @@ -779,7 +807,7 @@ complete directory hierarchy. Optionally, a pathname F<path> can be specified,
=item B<--flatten,--flatten=keep-intermediate>
If combined with C<--git>, C<--svn> or C<--hg> option or the corresponding modes, check out the revisions to compare in a separate temporary directory, and then pass on option C<--flatten> to latexdiff. The directory in which C<latexdiff-vc> is invoked defines the subtree which will be checked out.
Note that if additional files are needed which are not included in the flatten procedure (package files, included graphics), they need to be accessible in the current directory. If you use bibtex, it is recommended to include the C<.bbl> file in the version management.
Note that if additional files are needed which are not included in the flatten procedure (package files, included graphics), they need to be accessible in the current directory. If you use bibtex, it is recommended to include the C<.bbl> file in the version management. From latexdiff-vc >=1.3.4 there will be an attempt to create the C<.bbl> file by running bibtex in the retrieved subdirectories; note that the bibtex is run in the temporary subdirectories so any .bib or .bst files either need to be under version management, or in the global search paths for bibtex (shell environment variables C<BIBINPUTS> and C<BSTINPUTS>).
The generic usage of this function is : C<latexdiff-vc --flatten -r rev1 [-r rev2] master.tex> where master.tex is the project file containing the highest level of includes etc.
Expand Down

0 comments on commit 4e52e1e

Please sign in to comment.