#!/usr/local/bin/perl $Version = "0.03 (18 December 2001)" ; use Getopt::Std ; # Find out the font differences between two dvi files. # # What does it mean for 2 TeX fonts to be "different"? There are # four characteristics of a TeX font called from a .dvi file: # # 1. name (e.g., cmr10 or ptmb) # 2. font number # 3. scaling (e.g., 1000 or 1200) # 4. checksum # # # Options: # # -c : ignore checksum when finding font differences # -C : do NOT ignore checksum when finding font differences (default) # -n : ignore font number when finding font differences (default) # -N : do NOT ignore font number when finding font differences # -s : ignore font scaling when finding font differences # -S : do NOT ignore font scaling when finding font differences (default) # -l : also list fonts in both files # -O[#|F] : order by font number or name (later) # # Note: if -c is chosen, the checksum difference table will not appear. $usage_string = "fontdiff.pl $Version USAGE: fontdiff [options] dvi_file1 dvi_file2 OPTIONS -c : ignore checksum when finding font differences -C : do NOT ignore checksum when finding font differences (DEFAULT) -n : ignore font number when finding font differences (DEFAULT) -N : do NOT ignore font number when finding font differences -s : ignore font scaling when finding font differences -S : do NOT ignore font scaling when finding font differences (DEFAULT) -l : list fonts for each file Note: if -c is chosen, the checksum difference table will not appear. Thus, 'fontdiff' (with no options) is equivalent to 'fontdff -C -n -S' \n" ; # Set the default flags here: $ignore_FONTNUMBER = 1 ; $ignore_FONTSCALE = 0 ; $ignore_FONTCHECKSUM = 0 ; $show_ALLFONTS = 0 ; $number_of_args = $#ARGV ; getopts('cCsSnNl') ; if ($opt_c) { $ignore_FONTCHECKSUM = 1 ; } if ($opt_N) { $ignore_FONTNUMBER = 0 ; } if ($opt_S) { $ignore_FONTSCALE = 0 ; } if ($opt_s) { $ignore_FONTSCALE = 1 ; } if ($opt_l) { $show_ALLFONTS = 1 ; } # Check that there are at least three arguments. if ($number_of_args < 1) { print STDOUT "Not enough arguments.\n\n" ; print STDOUT $usage_string ; exit 0 ; } # Get the 2 filenames $dvifile1 = $ARGV[0] ; $dvifile2 = $ARGV[1] ; # ERROR CHECKING. # Check that these two files exist. if (!(-f $dvifile1)) { # Maybe we need to append a .dvi if (-f "$dvifile1.dvi") { $dvifile1 = "$ARGV[0]" . ".dvi" ; } else { print "ERROR. Cannot find file $dvifile1 or $dvifile1.dvi. Exiting.\n" ; exit 1 ; } } if (!(-f $dvifile2)) { # Maybe we need to append a .dvi if (-f "$dvifile2.dvi") { $dvifile2 = "$ARGV[1]" . ".dvi" ; } else { print "ERROR. Cannot find file $dvifile2 or $dvifile2.dvi. Exiting.\n" ; exit 1 ; } } # Check that these two files are in fact dvi files. $ret_value = `dvii -C $dvifile1` ; if (!($ret_value =~ /passed/)) { print "ERROR. $dvifile1 is not a valid .dvi file. Exiting.\n" ; exit 1 ; } $ret_value = `dvii -C $dvifile2` ; if (!($ret_value =~ /passed/)) { print "ERROR. $dvifile2 is not a valid .dvi file. Exiting.\n" ; exit 1 ; } $separator = "------------------------------" ; # At this point we have two valid .dvi files. Get their fonts. $fontlist1 = `dvii -f $dvifile1` ; $fontlist2 = `dvii -f $dvifile2` ; # Make the lists into arrays @fontarray1 = split /\n/, $fontlist1 ; @fontarray2 = split /\n/, $fontlist2 ; # Remove the font numbering, but only if we are ignoring font number. if ($ignore_FONTNUMBER) { foreach $element (@fontarray1) { $element =~ s/f:\[([0-9]+)/f:[NN/ ; } foreach $element (@fontarray2) { $element =~ s/f:\[([0-9]+)/f:[NN/ ; } } # Remove the font scaling, but only if we are ignoring scaling. if ($ignore_FONTSCALE) { foreach $element (@fontarray1) { $element =~ s?([0-9]+)\]::?SSSS]::? ; } foreach $element (@fontarray2) { $element =~ s?([0-9]+)\]::?SSSS]::? ; } } # Remove duplicate entries in the two lists. undef %saw; @compressed1 = grep(!$saw{$_}++, @fontarray1); undef %saw; @compressed2 = grep(!$saw{$_}++, @fontarray2); # From the PERL FAQ... #@union = @intersection = @difference = (); #%count = (); #foreach $element (@fontarray1, @fontarray2) { $count{$element}++ } #foreach $element (keys %count) { # push @union, $element; # push @{ $count{$element} > 1 ? \@intersection : \@difference }, $element; #} # Make hashes... foreach $element (@compressed1) { $hash1{$element} = 1 ; if (!($ignore_FONTCHECKSUM)) { # Get checksum if ($element =~ m/::([0123456789abcdef]{8})$/i) { $checksum = $1 ; } $checksum1{$element} = $checksum ; } } foreach $element (@compressed2) { $hash2{$element} = 1 ; if (!($ignore_FONTCHECKSUM)) { # Get checksum if ($element =~ m/::([0123456789abcdef]{8})$/i) { $checksum = $1 ; } $checksum2{$element} = $checksum ; } } print "Fonts in $dvifile1 NOT in $dvifile2:\n" ; if ($show_ALLFONTS) { print "NOTE: fonts marked with * are in BOTH files\n" ; } print "$separator\n" ; foreach $element (@compressed1) { if ($hash2{$element} != 1) { print " $element\n" ; } else { if ($show_ALLFONTS) { print "* $element\n" ; } } } print "$separator\n" ; print "\n" ; print "Fonts in $dvifile2 NOT in $dvifile1:\n" ; if ($show_ALLFONTS) { print "NOTE: fonts marked with * are in BOTH files\n" ; } print "$separator\n" ; foreach $element (@compressed2) { if ($hash1{$element} != 1) { print " $element\n" ; } else { if ($show_ALLFONTS) { print "* $element\n" ; } } } print "$separator\n" ; # CHECKSUM DIFFERENCES # Find fonts in common that have different checksums. if (!($ignore_FONTCHECKSUM)) { print "\nFonts in common that have DIFFERENT checksums:\n" ; print "$separator\n" ; foreach $element (@compressed1) { if ($hash2{$element} == 1) { # Find the checksums of each. $cs1 = $checksum1{$element} ; $cs2 = $checksum2{$element} ; # If they differ, print it out. if (!($cs1 eq $cs2)) { print "$element:\n" ; print "in $dvifile1 has checksum $cs1\n" ; print "in $dvifile2 has checksum $cs2\n" ; } } } print "$separator\n" ; } ## HISTORY # "0.02 (23 September 2001)" - initial version # "0.03 (18 December 2001)" - fixed scale ignore code