| 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 |  |  |  |  |  |  |  | 
| 5 | 9 |  |  | 9 |  | 374553 | use Moo; | 
|  | 9 |  |  |  |  | 220868 |  | 
|  | 9 |  |  |  |  | 65 |  | 
| 6 | 9 |  |  | 9 |  | 26633 | use utf8; | 
|  | 9 |  |  |  |  | 89 |  | 
|  | 9 |  |  |  |  | 59 |  | 
| 7 | 9 |  |  | 9 |  | 5185 | use Template::Reverse::Part; | 
|  | 9 |  |  |  |  | 33 |  | 
|  | 9 |  |  |  |  | 436 |  | 
| 8 | 9 |  |  | 9 |  | 39368 | use Algorithm::Diff qw(sdiff); | 
|  | 9 |  |  |  |  | 65420 |  | 
|  | 9 |  |  |  |  | 825 |  | 
| 9 | 9 |  |  | 9 |  | 91 | use Scalar::Util qw(blessed); | 
|  | 9 |  |  |  |  | 19 |  | 
|  | 9 |  |  |  |  | 7669 |  | 
| 10 |  |  |  |  |  |  | our $VERSION = '0.143'; # VERSION | 
| 11 |  |  |  |  |  |  |  | 
| 12 |  |  |  |  |  |  |  | 
| 13 |  |  |  |  |  |  | has 'sidelen' => ( | 
| 14 |  |  |  |  |  |  | is=>'rw', | 
| 15 |  |  |  |  |  |  | default => sub{return 10;} | 
| 16 |  |  |  |  |  |  | ); | 
| 17 |  |  |  |  |  |  |  | 
| 18 |  |  |  |  |  |  |  | 
| 19 |  |  |  |  |  |  | my $_WILDCARD = bless [], 'WILDCARD'; | 
| 20 | 52 |  |  | 52 | 1 | 179 | sub WILDCARD{return $_WILDCARD}; | 
| 21 |  |  |  |  |  |  | sub _isWILDCARD{ | 
| 22 | 387 |  |  | 387 |  | 2047 | return ref $_[0] eq 'WILDCARD'; | 
| 23 |  |  |  |  |  |  | } | 
| 24 |  |  |  |  |  |  |  | 
| 25 |  |  |  |  |  |  |  | 
| 26 |  |  |  |  |  |  | sub detect{ | 
| 27 | 4 |  |  | 4 | 1 | 5150 | my $self = shift; | 
| 28 | 4 |  |  |  |  | 11 | my @strs = @_; | 
| 29 | 4 |  |  |  |  | 18 | my $diff = _diff($strs[0],$strs[1]); | 
| 30 | 4 |  |  |  |  | 44 | my $pattern = _detect($diff,$self->sidelen()); | 
| 31 | 4 |  |  |  |  | 19 | return $pattern; | 
| 32 |  |  |  |  |  |  | } | 
| 33 |  |  |  |  |  |  |  | 
| 34 |  |  |  |  |  |  |  | 
| 35 |  |  |  |  |  |  | ### internal functions | 
| 36 |  |  |  |  |  |  | sub _detect{ | 
| 37 | 29 |  |  | 29 |  | 28758 | my $diff = shift; | 
| 38 | 29 |  |  |  |  | 50 | my $sidelen = shift; | 
| 39 | 29 | 100 |  |  |  | 98 | $sidelen = 0 unless $sidelen; | 
| 40 | 29 |  |  |  |  | 44 | my @d = @{$diff}; | 
|  | 29 |  |  |  |  | 157 |  | 
| 41 | 29 |  |  |  |  | 46 | my $lastStar = 0; | 
| 42 | 29 |  |  |  |  | 42 | my @res; | 
| 43 | 29 |  |  |  |  | 97 | for(my $i=0; $i<@d; $i++) | 
| 44 |  |  |  |  |  |  | { | 
| 45 | 230 | 100 |  |  |  | 439 | if( _isWILDCARD($d[$i] ) ) | 
| 46 |  |  |  |  |  |  | { | 
| 47 | 45 |  |  |  |  | 67 | my $from = $lastStar; | 
| 48 | 45 |  |  |  |  | 122 | my $to = $i-1; | 
| 49 | 45 | 100 |  |  |  | 101 | if( $sidelen ){ | 
| 50 | 19 | 100 |  |  |  | 66 | $from = $to-$sidelen+1 if $to-$from+1 > $sidelen; | 
| 51 |  |  |  |  |  |  | } | 
| 52 | 45 |  |  |  |  | 147 | my @pre = @d[$from..$to]; | 
| 53 |  |  |  |  |  |  |  | 
| 54 | 45 |  |  |  |  | 105 | my $j = @d; | 
| 55 | 45 | 100 |  |  |  | 109 | if( $i+1 < @d ){ | 
| 56 | 37 |  |  |  |  | 118 | for( $j=$i+1; $j<@d; $j++) | 
| 57 |  |  |  |  |  |  | { | 
| 58 | 131 | 100 |  |  |  | 310 | if( _isWILDCARD( $d[$j] ) ){ | 
| 59 | 19 |  |  |  |  | 36 | last; | 
| 60 |  |  |  |  |  |  | } | 
| 61 |  |  |  |  |  |  | } | 
| 62 |  |  |  |  |  |  | } | 
| 63 | 45 |  |  |  |  | 72 | $from = $i+1; | 
| 64 | 45 |  |  |  |  | 61 | $to = $j-1; | 
| 65 | 45 | 100 |  |  |  | 93 | if( $sidelen ){ | 
| 66 | 19 | 100 |  |  |  | 59 | $to = $from + $sidelen-1 if $to-$from+1 > $sidelen; | 
| 67 |  |  |  |  |  |  | } | 
| 68 | 45 |  |  |  |  | 112 | my @post = @d[$from..$to]; | 
| 69 | 45 |  |  |  |  | 1234 | my $part = Template::Reverse::Part->new(pre=>\@pre, post=>\@post); | 
| 70 | 45 |  |  |  |  | 8868 | push(@res,$part); | 
| 71 | 45 |  |  |  |  | 197 | $lastStar = $i+1; | 
| 72 |  |  |  |  |  |  | } | 
| 73 |  |  |  |  |  |  | } | 
| 74 | 29 |  |  |  |  | 129 | return \@res; | 
| 75 |  |  |  |  |  |  | } | 
| 76 |  |  |  |  |  |  |  | 
| 77 |  |  |  |  |  |  |  | 
| 78 |  |  |  |  |  |  | sub _diff{ | 
| 79 | 16 |  |  | 16 |  | 9130 | my ($a,$b) = @_; | 
| 80 | 16 |  |  |  |  | 28 | my ($org_a,$org_b) = @_; | 
| 81 |  |  |  |  |  |  |  | 
| 82 | 16 | 50 |  |  |  | 25 | $a = [map{blessed($_)?$_->as_string:$_}@{$a}]; | 
|  | 79 |  |  |  |  | 267 |  | 
|  | 16 |  |  |  |  | 31 |  | 
| 83 | 16 | 50 |  |  |  | 29 | $b = [map{blessed($_)?$_->as_string:$_}@{$b}]; | 
|  | 77 |  |  |  |  | 183 |  | 
|  | 16 |  |  |  |  | 25 |  | 
| 84 |  |  |  |  |  |  |  | 
| 85 | 16 |  |  |  |  | 73 | my @d = sdiff($a,$b); | 
| 86 | 16 |  |  |  |  | 3289 | my @rr; | 
| 87 | 16 |  |  |  |  | 28 | my $before=''; | 
| 88 | 16 |  |  |  |  | 22 | my $idx = 0; | 
| 89 | 16 |  |  |  |  | 32 | for my $r (@d){ | 
| 90 | 90 | 100 |  |  |  | 267 | if( $r->[0] eq 'u' ){ | 
| 91 | 64 |  |  |  |  | 113 | push(@rr,$org_a->[$idx]); | 
| 92 | 64 |  |  |  |  | 78 | $before = ''; | 
| 93 |  |  |  |  |  |  | } | 
| 94 |  |  |  |  |  |  | else{ | 
| 95 | 26 | 100 |  |  |  | 52 | push(@rr,WILDCARD) unless _isWILDCARD($before); | 
| 96 | 26 |  |  |  |  | 53 | $before = WILDCARD; | 
| 97 |  |  |  |  |  |  | } | 
| 98 | 90 | 100 |  |  |  | 227 | $idx++ if $r->[0] ne '+'; | 
| 99 |  |  |  |  |  |  |  | 
| 100 |  |  |  |  |  |  | } | 
| 101 | 16 |  |  |  |  | 90 | return \@rr; | 
| 102 |  |  |  |  |  |  | } | 
| 103 |  |  |  |  |  |  |  | 
| 104 |  |  |  |  |  |  |  | 
| 105 |  |  |  |  |  |  |  | 
| 106 |  |  |  |  |  |  | 1; | 
| 107 |  |  |  |  |  |  |  | 
| 108 |  |  |  |  |  |  | __END__ |