#!/usr/bin/perl #------------------------------------------------------------------------------ # $Id: hdiff,v 1.1 2000/03/26 19:52:21 peters Exp peters $ # # NAME: hdiff # # PURPOSE: HTML diff. Produces a colourised HTML diff output which is # much easier to read than standard diff output. # # SOURCE: www.ginini.com/software/hdiff # # hdiff is derived from cvs2html from www.sslug.dk/cvs2html #------------------------------------------------------------------------------ require 5.000; use Getopt::Std; # # You must use a version of diff that has unified output. GNU diff has this # option, so you can leave the default setting as is on Linux based systems. # For most other Unix systems, grab a copy of GNU diff from # ftp://ftp.gnu.org/gnu/diffutils # $diff='/usr/bin/diff'; # # Colors and font to show the diff type of code changes # $diffcolorHeading='#99CCCC'; # color of 'Line'-heading of each diffed file $diffcolorEmpty='#CCCCCC'; # color of 'empty' lines $diffcolorAdd='#FF9999'; # Removed line(s) (left) ( - ) $diffcolorChange='#99FF99'; # Changed line(s) ( both ) $diffcolorRemove='#CCCCFF'; # Added line(s) ( - ) (right) $diffcolorDarkChange ='#99CC99';# lines, which are empty in change $difffontface="Helvetica,Arial"; $difffontsize="-1"; #----------------------------------------------------------------------------- # END OF CONFIGURABLE OPTIONS #----------------------------------------------------------------------------- # # Process options # getopts('h:f'); die "Usage: $0 [-f ] [-h ] [file1] [file2]\n" if (scalar @ARGV != 2); $File1=$ARGV[0]; $File2=$ARGV[1]; die "$File1 not found\n" if (! -f $File1); die "$File2 not found\n" if (! -f $File2); HtmlHeader(); human_readable_diff("$Title",$File1,$File2); HtmlFooter(); exit 0; #-------------------------------------------------------------------------- sub htmlify { local($string, $pr) = @_; # Special Characters; RFC 1866 $string =~ s/&/&/g; $string =~ s/\"/"/g; $string =~ s//>/g; # get URL's as link .. $string =~ s§(http|ftp)(://[-a-zA-Z0-9%.~:/]+)([?&]([-a-zA-Z0-9%.~:_]+)=([-a-zA-Z0-9%.~:_])+)*§$1$2$3§; # get e-mails as link $string =~ s§([-a-zA-Z0-9.]+@([-a-zA-Z0-9]+\.)+[A-Za-z]{2,4})§$1§; # get #PR as link .. if ($pr && defined $prcgi) { $string =~ s!\b((pr[:#]?\s*#?)|((bin|conf|docs|gnu|i386|kern|misc|ports)\/))(\d+)\b!$&!ig; } return $string; } sub spacedHtmlText { my($string, $pr) = @_; # Cut trailing spaces s/\s+$//; # Expand tabs $string =~ s/\t+/' ' x (length($&) * $tabstop - length($`) % $tabstop)/e if (defined $tabstop); # replace and (§ is to protect us from htmlify) # gzip can make excellent use of this repeating pattern :-) $string =~ s/§/§%/g; #protect our & substitute if ($hr_breakable) { # make every other space 'breakable' $string =~ s/ / §nbsp; §nbsp; §nbsp; §nbsp;/g; # $string =~ s/ / §nbsp;/g; # 2 * # leave single space as it is } else { $string =~ s/ /§nbsp;§nbsp;§nbsp;§nbsp;§nbsp;§nbsp;§nbsp;§nbsp;/g; $string =~ s/ /§nbsp;/g; } $string = htmlify($string); # unescape $string =~ s/§([^%])/&$1/g; $string =~ s/§%/§/g; return $string; } sub flush_diff_rows ($$$$) { local $j; my ($leftColRef,$rightColRef,$leftRow,$rightRow) = @_; if ($state eq "PreChangeRemove") { # we just got remove-lines before for ($j = 0 ; $j < $leftRow; $j++) { print "@$leftColRef[$j]"; print " \n"; } } elsif ($state eq "PreChange") { # state eq "PreChange" # we got removes with subsequent adds for ($j = 0; $j < $leftRow || $j < $rightRow ; $j++) { # dump out both cols print ""; if ($j < $leftRow) { print "@$leftColRef[$j]"; } else { print " "; } if ($j < $rightRow) { print "@$rightColRef[$j]"; } else { print " "; } print "\n"; } } } sub HtmlHeader { if ($opt_h) { open(HEADER,"$opt_h") or die "Can not open $opt_h $!\n"; print
; close(HEADER); } else { print qq(\n\n); print qq(hdiff Output\n); print qq(\n); print qq(
hdiff output

\n); } print ""; print "
"; print "
"; } sub HtmlFooter { print ""; print ""; print "
"; print "\n
"; print "Legend
\n"; print ""; print ""; print ""; print "
Lines Added 
Lines changed
 Lines Removed
\n"; if ($opt_f) { open(FOOTER,"$opt_f") or die "Can not open $opt_f $!\n"; print