diffpp.in - enscript - GNU Enscript
 (HTM) git clone git://thinkerwim.org/enscript.git
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
       diffpp.in (4545B)
       ---
            1 #!@PERLPROG@
            2 # -*- perl -*-
            3 #
            4 # Pretty-print diff outputs with GNU enscript.
            5 # Copyright (c) 1996-1998 Markku Rossi
            6 #
            7 # Author: Markku Rossi <mtr@iki.fi>
            8 #
            9 
           10 #
           11 # This file is part of GNU Enscript.
           12 #
           13 # Enscript is free software: you can redistribute it and/or modify
           14 # it under the terms of the GNU General Public License as published by
           15 # the Free Software Foundation, either version 3 of the License, or
           16 # (at your option) any later version.
           17 #
           18 # Enscript is distributed in the hope that it will be useful,
           19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
           20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
           21 # GNU General Public License for more details.
           22 #
           23 # You should have received a copy of the GNU General Public License
           24 # along with Enscript.  If not, see <http://www.gnu.org/licenses/>.
           25 #
           26 
           27 #
           28 # Original idea by Trent Fisher <trent@informix.com>
           29 # Thanks to:
           30 #  - Tero Kivinen <kivinen@iki.fi> for the first prototype
           31 #  - Tait Cyrus <tait.cyrus@mci.com> for fixes and cleanups
           32 #
           33 
           34 $file = shift(@ARGV);
           35 $add_gray = ".80";
           36 $del_gray = ".60";
           37 
           38 $program = $0;
           39 $program =~ s/.*\///g;
           40 
           41 sub usage {
           42     warn "Usage: $program ORIGINAL_FILE < DIFF\n\n";
           43     warn "Program reads a diff file from its standard input and annotates
           44 ORIGINAL_FILE to show the changes made to the file.  The easiest way to use
           45 this program is to use it as an input filter for GNU enscript:
           46 
           47   \$ enscript -G2re --filter='rcsdiff %s | diffpp %s' *.c *.h
           48   \$ enscript -G2re --filter='diff %s~ %s | diffpp %s' *.c *.h
           49 
           50 ";
           51 }
           52 
           53 if (!defined($file) || defined($ARGV[0])) {
           54     &usage;
           55     exit 1;
           56 }
           57 
           58 if ($file eq "--help") {
           59     &usage;
           60     exit 0;
           61 }
           62 
           63 if ($file eq "--version") {
           64     warn "diffpp 1.0\n";
           65     exit 0;
           66 }
           67 
           68 # Read in original file into internal array.
           69 open(FP, $file) || die "$program: couldn't open file `$file' for input: $!\n";
           70 @orig_file = <FP>;
           71 close(FP);
           72 $[ = 1;
           73 $orig_line_num = 1;
           74 $orig_num_lines = @orig_file;
           75 
           76 # Now read in file of diffs into internal array.
           77 @diffs = <STDIN>;
           78 $diff_line_num = 1;
           79 $diff_num_lines = @diffs;
           80 
           81 while ($diff_line_num <= $diff_num_lines) {
           82     $_ = $diffs[$diff_line_num];
           83     if (/a/) {
           84         do_add($_);
           85     } elsif (/d/) {
           86         do_delete($_);
           87     } elsif (/c/) {
           88         do_change($_);
           89     }
           90 }
           91 
           92 while ($orig_line_num <= $orig_num_lines) {
           93     print $orig_file[$orig_line_num++];
           94 }
           95 
           96 # Handle new/added lines
           97 #
           98 # Formats used:
           99 #        #a#
          100 #        #a#,#
          101 sub do_add {
          102     ($line) = @_;
          103     if ($line =~ /(\d+)a(\d+),(\d+)/) {
          104         $insert_at_line = $1;
          105         $num_new_lines = $3 - $2 + 1;
          106     } elsif ($line =~ /(\d+)a(\d+)/) {
          107         $insert_at_line = $1;
          108         $num_new_lines = 1;
          109     }
          110     &skip_to_line($insert_at_line);
          111     printf("\000shade{$add_gray}");
          112     &mark_to_line($num_new_lines, "+");
          113     printf("\000shade{1.0}");
          114 }
          115 
          116 # Handle deleted/removed lines
          117 #
          118 # Formats used:
          119 #        #d#
          120 #        #,#d#
          121 sub do_delete {
          122     ($line) = @_;
          123     if ($line =~ /(\d+),(\d+)d(\d+)/) {
          124         $num_del_lines = $2 - $1 + 1;
          125     } elsif ($line =~ /(\d+)d(\d+)/) {
          126         $num_del_lines = 1;
          127     }
          128     $del_from = $1;
          129     &skip_to_line($del_from - 1);
          130     printf("\000shade{$del_gray}");
          131     &mark_to_line($num_del_lines, "-");
          132     printf("\000shade{1.0}");
          133     $orig_line_num += $num_del_lines;
          134 }
          135 
          136 # Handle changed/modified lines
          137 #
          138 # Formats used:
          139 #        #,#c#,#
          140 #        #,#c#
          141 #        #c#,#
          142 #        #c#
          143 sub do_change {
          144     ($line) = @_;
          145     if ($line =~ /(\d+),(\d+)c(\d+),(\d+)/) {
          146         $num_old_lines = $2 - $1 + 1;
          147         $num_new_lines = $4 - $3 + 1;
          148         $change_at_line = $1;
          149     } elsif ($line =~ /(\d+),(\d+)c(\d+)/) {
          150         $num_old_lines = $2 - $1 + 1;
          151         $num_new_lines = 1;
          152         $change_at_line = $1;
          153     } elsif ($line =~ /(\d+)c(\d+),(\d+)/) {
          154         $num_old_lines = 1;
          155         $num_new_lines = $3 - $2 + 1;
          156         $change_at_line = $1;
          157     } elsif ($line =~ /(\d+)c(\d+)/) {
          158         $num_old_lines = 1;
          159         $num_new_lines = 1;
          160         $change_at_line = $1;
          161     }
          162     # Mark old lines
          163     &skip_to_line($change_at_line - 1);
          164     $orig_line_num += $num_old_lines;        # skip over changed lines
          165     printf("\000shade{$del_gray}");
          166     &mark_to_line($num_old_lines, "-");
          167     printf("\000shade{1.0}");
          168     # Mark new lines
          169     printf("\000shade{$add_gray}");
          170     &mark_to_line($num_new_lines, "+");
          171     printf("\000shade{1.0}");
          172 }
          173 
          174 sub skip_to_line {
          175     ($line) = @_;
          176 
          177     while ($orig_line_num <= $line) {
          178         print $orig_file[$orig_line_num];
          179         $orig_line_num++;
          180     }
          181 }
          182 
          183 sub mark_to_line {
          184     ($num_lines, $marker) = @_;
          185 
          186     $diff_line_num++;                # skip over diff command
          187     while ($num_lines > 0) {
          188         $diff_line = substr($diffs[$diff_line_num++],3);
          189         print "\000ps{gsave -5 0 rmoveto ($marker) show grestore}";
          190         print $diff_line;
          191         $num_lines--;
          192     }
          193 }