Text-WordDiff

 view release on metacpan or  search on metacpan

lib/Text/WordDiff.pm  view on Meta::CPAN

        # Append to the scalar reference.
        my $out_ref = $out_handler;
        $out_handler = sub { $$out_ref .= shift };
    }
    elsif ( $type eq 'ARRAY' ) {
        # Push each item onto the array.
        my $out_ref = $out_handler;
        $out_handler = sub { push @$out_ref, shift };
    }
    elsif ( $type eq 'GLOB' || UNIVERSAL::isa( $out_handler, 'IO::Handle' )) {
        # print to the file handle.
        my $output_handle = $out_handler;
        $out_handler = sub { print $output_handle shift };
    }
    else {
        # D'oh!
        croak "Unrecognized output type: $type";
    }

    # Instantiate the diff object, along with any options.
    my $diff = Algorithm::Diff->new(@seqs, delete $opts->{DIFF_OPTS});

    # Load the style class and instantiate an instance.
    my $style  = delete $opts->{STYLE} || 'ANSIColor';
    $style     = __PACKAGE__ . "::$style" if exists $styles{$style};
    eval "require $style" or die $@ unless $style->can('new');
    $style     = $style->new($opts) if !ref $style;

    # Run the diff.
    my $hunks = 0;
    $out_handler->($style->file_header());
    while ($diff->Next) {
        $hunks++;
        $out_handler->( $style->hunk_header() );

        # Output unchanged items.
        if (my @same = $diff->Same) {
            $out_handler->( $style->same_items(@same) );
        }

        # Output deleted and inserted items.
        else {
            if (my @del = $diff->Items(1)) {
                $out_handler->( $style->delete_items(@del) );
            }
            if (my @ins = $diff->Items(2)) {
                $out_handler->( $style->insert_items(@ins) );
            }
        }
        $out_handler->( $style->hunk_footer() );
    }
    $out_handler->( $style->file_footer() );

    return defined $output ? $output : $hunks;
}

package Text::WordDiff::Base;

sub new {
    my ($class, $opts) = @_;
    return bless { %{$opts} } => $class;
}


sub file_header  {
    my $self = shift;
    my $fn1 = $self->filename_a;
    my $fn2 = $self->filename_b;
    return '' unless defined $fn1 && defined $fn2;

    my $p1 = $self->filename_prefix_a;
    my $t1 = $self->mtime_a;
    my $p2 = $self->filename_prefix_b;
    my $t2 = $self->mtime_b;

    return "$p1 $fn1" . (defined $t1 ? "\t" . localtime $t1 : '') . "\n"
         . "$p2 $fn2" . (defined $t2 ? "\t" . localtime $t2 : '') . "\n"
         ;
}

sub hunk_header         { return '' }
sub same_items          { return '' }
sub insert_items        { return '' }
sub delete_items        { return '' }
sub hunk_footer         { return '' }
sub file_footer         { return '' }
sub filename_a          { return shift->{FILENAME_A} }
sub filename_b          { return shift->{FILENAME_B} }
sub mtime_a             { return shift->{MTIME_A}    }
sub mtime_b             { return shift->{MTIME_B}    }
sub filename_prefix_a   { return shift->{FILENAME_PREFIX_A} }
sub filename_prefix_b   { return shift->{FILENAME_PREFIX_B} }

1;
__END__

##############################################################################

=head1 Name

Text::WordDiff - Track changes between documents

=head1 Synopsis

    use Text::WordDiff;

    my $diff = word_diff 'file1.txt', 'file2.txt', { STYLE => 'HTML' };
    my $diff = word_diff \$string1,   \$string2,   { STYLE => 'ANSIColor' };
    my $diff = word_diff \*FH1,       \*FH2;       \%options;
    my $diff = word_diff \&reader1,   \&reader2;
    my $diff = word_diff \@records1,  \@records2;

    # May also mix input types:
    my $diff = word_diff \@records1,  'file_B.txt';

=head1 Description

This module is a variation on the lovely L<Text::Diff|Text::Diff> module.
Rather than generating traditional line-oriented diffs, however, it generates
word-oriented diffs. This can be useful for tracking changes in narrative
documents or documents with very long lines. To diff source code, one is still

 view all matches for this distribution
 view release on metacpan -  search on metacpan

( run in 2.823 seconds using v1.00-cache-2.02-grep-82fe00e-cpan-d29e8ade9f55 )