File Coverage

blib/lib/MojoMojo/WordDiff.pm
Criterion Covered Total %
statement 41 42 97.6
branch 7 10 70.0
condition n/a
subroutine 7 7 100.0
pod 1 1 100.0
total 56 60 93.3


line stmt bran cond sub pod time code
1             package MojoMojo::WordDiff;
2              
3             # based on Text::WordDiff, but with many differences.
4              
5 41     41   68324 use strict;
  41         93  
  41         1168  
6 41     41   1801 use HTML::Entities;
  41         18525  
  41         2252  
7 41     41   388 use base qw(Exporter);
  41         108  
  41         3098  
8 41     41   807 use Algorithm::Diff;
  41         3933  
  41         6510  
9              
10             our @EXPORT = qw(word_diff);
11              
12             sub _split_html_str {
13 10     10   16 my $str = shift;
14 10         14 my @array;
15 10         99 my @tags = split qr/(?:(?<=>)|(?=<))/msx, $str;
16 10         25 foreach(@tags) {
17 18 50       44 if(length($_) == 0) {
18 0         0 next;
19             }
20 18 100       43 if($_ =~ /^</) {
21 8         15 push @array, $_;
22             } else {
23 10         60 my $tmp_str = decode_entities($_);
24 10     1   133 my @tmp_arr = split qr/(?:(?<!\p{IsWord})(?=\p{IsWord})|(?<!\p{IsSpace})(?=\p{IsSpace})|(?<!\p{IsPunct})(?=\p{IsPunct}))/msx, $tmp_str;
  1         500  
  1         13  
  1         12  
25 10         23 @tmp_arr = map {$_ = encode_entities($_)} @tmp_arr;
  98         1079  
26 10         187 push @array, @tmp_arr;
27             }
28             }
29 10         46 return @array;
30             }
31              
32             sub word_diff {
33 5     5 1 2391 my @args = map {my @a = _split_html_str($_); \@a;} @_;
  10         23  
  10         27  
34 5         20 my $diff = Algorithm::Diff->new(@args);
35 5         2076 my $out = "";
36 5         16 while ($diff->Next) {
37 13 100       278 if (my @same = $diff->Same) {
38 8         208 $out .= (join '', @same);
39             }
40             else {
41 5 50       56 if (my @del = $diff->Items(1)) {
42 5         96 $out .= '<del>' . (join '', @del) . '</del>';
43             }
44 5 50       14 if (my @ins = $diff->Items(2)) {
45 5         90 $out .= '<ins>' . (join '', @ins) . '</ins>';
46             }
47             }
48             }
49 5         121 return $out;
50             }
51              
52             =head1 NAME
53              
54             MojoMojo::WordDiff - generate inline word-based HTML diffs
55              
56             =head1 DESCRIPTION
57              
58             Creates a word by word line diff for lines that are changed.
59              
60             =head1 METHODS
61              
62             =head2 word_diff
63              
64             Takes two conflicting lines, and returns a line with the diff in HTML.
65              
66             =head2
67              
68             =cut
69              
70             1;