Ticket #15: XimbiotPluginDiff.pm

File XimbiotPluginDiff.pm, 3.0 KB (added by dom, 5 years ago)

As referred to in original report

Line 
1package XimbiotPluginDiff;
2
3use strict;
4
5use vars qw($VERSION @ISA);
6
7use CGI::Wiki::Plugin::Diff;
8use Params::Validate::Dummy ();
9use Module::Optional qw(Params::Validate
10        validate validate_pos SCALAR SCALARREF ARRAYREF HASHREF UNDEF);
11
12@ISA = qw(CGI::Wiki::Plugin::Diff);
13$VERSION = 0.01;
14
15=head1 NAME
16
17XimbiotPluginDiff - Implementation of CGI::Wiki::Plugin::Diff which caches
18the retrieved node data for use by the caller.
19
20=head1 REQUIRES
21
22Subclasses CGI::Wiki::Plugin::Diff
23
24=head1 SYNOPSIS
25
26See CGI::Wiki::Plugin::Diff
27
28=head1 METHODS
29
30=over 4
31
32=item B<differences>
33
34Like the parent method of the same name, except if either left_version or
35right_version is found to be a reference, it is assumed to be cached
36revision information as returned by the CGI::Wiki::Database::retrieve_node
37method.  Also, two extra fields will be present in the output hash,
38left_revision & right_revision, which will contain references to the hashes
39returned by retrieve node for each version (the same ones passed into the
40function, when such is passed).
41
42=cut
43
44sub differences
45{
46    my $self = shift;
47    my %args = validate (@_, {node          => {type => SCALAR},
48                              left_version  => {type => SCALAR | HASHREF},
49                              right_version => {type => SCALAR | HASHREF},
50                              meta_include  => {type => ARRAYREF,
51                                                optional => 1},
52                              meta_exclude  => {type => ARRAYREF,
53                                                optional => 1}});
54
55    my ($node, $v1, $v2)  = @args{qw(node left_version right_version)};
56    my $store = $self->datastore;
57    my $fmt = $self->formatter;
58
59    $v1 = {$store->retrieve_node (name => $node, version => $v1)}
60        unless ref $v1;
61    $v2 = {$store->retrieve_node (name => $node, version => $v2)}
62        unless ref $v2;
63
64    my $verstring1 = "Version " . $v1->{version};
65    my $verstring2 = "Version " . $v2->{version};
66
67    my $el1 = VCS::Lite->new
68        ($verstring1, undef,
69         $self->content_escape ($v1->{content})
70         . $self->{metadata_separator}
71         . $self->serialise_metadata ($v1->{metadata},
72                                      @args{qw(meta_include meta_exclude)}));
73    my $el2 = VCS::Lite->new
74        ($verstring2, undef,
75         $self->content_escape ($v2->{content})
76         . $self->{metadata_separator}
77         . $self->serialise_metadata ($v2->{metadata},
78                                    @args{qw(meta_include meta_exclude)}));
79
80    my %pag;
81    $pag{left_version} = $verstring1;
82    $pag{right_version} = $verstring2;
83    $pag{left_revision} = $v1;
84    $pag{right_revision} = $v2;
85    $pag{content} = $fmt->format ($v1->{content});
86    my $dlt = $el1->delta ($el2)
87        or return %pag;
88
89    my @out;
90   
91    for ($dlt->hunks)
92    {
93        my ($lin1, $lin2, $out1, $out2);
94        for (@$_)
95        {
96            my ($ind, $line, $text) = @$_;
97            if ($ind ne '+')
98            {
99                $lin1 ||= $line;
100                $out1 .= $text;
101            }
102            if ($ind ne '-')
103            {
104                $lin2 ||= $line;
105                $out2 .= $text;
106            }
107        }
108        push @out, {left => $self->line_number ($lin1), 
109                    right => $self->line_number ($lin2)};
110        my ($text1,$text2) = $self->intradiff ($out1, $out2);
111        push @out, {left => $text1, right => $text2};
112    }
113
114    $pag{diff} = \@out;
115    return %pag;
116}