File Coverage

blib/lib/Template/Reverse.pm
Criterion Covered Total %
statement 54 54 100.0
branch 6 6 100.0
condition 1 3 33.3
subroutine 10 10 100.0
pod 1 1 100.0
total 72 74 97.3


line stmt bran cond sub pod time code
1             package Template::Reverse;
2              
3             # ABSTRACT: A template generator getting different parts between pair of text
4 8     8   147894 use Moo;
  8         99584  
  8         52  
5 8     8   17308 use utf8;
  8         125  
  8         59  
6 8     8   7210 use Template::Reverse::Util;
  8         2228  
  8         1757  
7 8     8   3877 use constant::Atom qw(WILDCARD BOF EOF);
  8         25664  
  8         40  
8 8     8   7048 use Algorithm::Diff qw(sdiff);
  8         43528  
  8         726  
9 8     8   86 use List::Util qw(max min);
  8         23  
  8         4503  
10             require Exporter;
11             our @ISA = 'Exporter';
12             our @EXPORT = qw(WILDCARD BOF EOF);
13              
14             our $VERSION = '0.202'; # VERSION
15              
16              
17             has 'sidelen' => (
18             is=>'rw',
19             default => sub{return 10;}
20             );
21              
22              
23             sub detect{
24 4     4 1 4777 my ($self,$arr1,$arr2,$sidelen) = @_;
25 4   33     45 $sidelen ||= $self->sidelen();
26 4         6 $arr1 = [BOF, @{$arr1}, EOF];
  4         14  
27 4         9 $arr2 = [BOF, @{$arr2}, EOF];
  4         9  
28 4         14 my $diff = _diff($arr1,$arr2);
29 4         11 my $pattern = _detect($diff, $sidelen);
30 4         15 return $pattern;
31             }
32              
33             ### internal functions
34              
35             sub _detect{
36 29     29   36731 my ($diff, $sidelen) = @_;
37 29     261   129 my @parts = partition_by(sub{$_[0]==WILDCARD}, @{$diff});
  261         658  
  29         132  
38 29         139 my @each_parts = partition(3, 2, @parts);
39              
40 29         54 my @res;
41 29         60 foreach my $part (@each_parts){
42 45         71 my($pre, $wc, $post) = @{$part};
  45         90  
43 45         66 my @pre = @{$pre};
  45         89  
44 45         74 my @post = @{$post};
  45         102  
45 45         200 @pre = splice(@pre, max(0-@pre,-$sidelen));
46 45         146 @post = splice(@post, 0, min(0+@post,$sidelen));
47 45         161 push(@res, {pre=>\@pre, post=>\@post});
48             }
49 29         126 return \@res;
50             }
51              
52             sub _diff{
53 16     16   13189 my ($a,$b) = @_;
54 16         68 my @d = sdiff($a,$b);
55 16         4253 my @rr;
56 16         36 my $idx = 0;
57 16         39 for my $r (@d){
58 98 100       225 if( $r->[0] eq 'u' ){
59 72         144 push(@rr,$a->[$idx]);
60             }
61             else{
62 26 100       124 push(@rr,WILDCARD) unless WILDCARD == $rr[-1];
63             }
64 98 100       421 $idx++ if $r->[0] ne '+';
65             }
66 16         70 return \@rr;
67             }
68              
69              
70              
71             1;
72              
73             __END__