#!/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;
$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 "
Lines Added
";
print "
Lines changed
";
print "
Lines Removed
";
print "
\n";
if ($opt_f) {
open(FOOTER,"$opt_f") or die "Can not open $opt_f $!\n";
print