File Coverage

bin/untemplate
Criterion Covered Total %
statement 125 142 88.0
branch 41 48 85.4
condition 16 17 94.1
subroutine 17 19 89.4
pod n/a
total 199 226 88.0


'; '; ';
line stmt bran cond sub pod time code
1             #!/usr/bin/env perl
2             # ABSTRACT: analyze several HTML documents based on the same template
3             # PODNAME: untemplate
4 30     30   2148 use 5.010;
  30         93  
  30         2976  
5 30     30   193 use strict;
  30         47  
  30         1042  
6 30     30   38734 use utf8::all;
  30         2737575  
  30         237  
7 30     30   196999 use warnings qw(all);
  30         83  
  30         1080  
8              
9 30     30   145 use Carp qw(croak);
  30         66  
  30         1963  
10 30     30   180 use File::Basename;
  30         59  
  30         3090  
11 30     30   57117 use File::Temp;
  30         1057111  
  30         2822  
12 30     30   53156 use Getopt::Long;
  30         440414  
  30         222  
13 30     30   34101 use HTML::Linear;
  30         170  
  30         525  
14 30     30   47681 use IO::Interactive qw(is_interactive);
  30         191129  
  30         207  
15 30     30   40844 use Class::Load qw(try_load_class);
  30         1220717  
  30         2393  
16 30     30   41882 use Pod::Usage;
  30         1666859  
  30         6000  
17 30     30   384 use Term::ANSIColor qw(:constants);
  30         73  
  30         14304  
18 30     30   42689 use Tie::IxHash;
  30         176788  
  30         191171  
19              
20             ## no critic (ProhibitDeepNests, ProhibitPackageVars)
21              
22 30         123 our $VERSION = '0.019'; # VERSION
23              
24              
25 30 100       371 GetOptions(
26             q(help) => \my $help,
27             q(color!) => \my $color,
28             q(16) => \my $sixteen,
29             q(html!) => \my $html,
30             q(encoding=s) => \my $encoding,
31             q(partial!) => \my $partial,
32             q(shrink!) => \my $shrink,
33             q(strict!) => \my $strict,
34             q(unmangle=s) => \my @unmangle,
35             ) or pod2usage(q(-verbose) => 1);
36 29 100 100     30684 pod2usage(q(-verbose) => 1)
37             if $help or $#ARGV < 1;
38              
39 27   66     179 $color //= is_interactive(*STDOUT);
40              
41 27 100       356 if ($html) {
    100          
42 9         17 (%HTML::Linear::Path::xpath_wrap) = (%{$HTML::Linear::Path::Colors::scheme{html}});
  9         146  
43 9         33 $color = 0;
44 9         544 print $HTML::Linear::Path::Colors::html[0];
45             } elsif ($color) {
46 9 100 100     19 (%HTML::Linear::Path::xpath_wrap) = (%{$HTML::Linear::Path::Colors::scheme{($sixteen // 0) ? q(terminal) : q(terminal256)}});
  9         192  
47 9         34 $html = 0;
48             }
49              
50 27 50       650 try_load_class('YADA')
51             and fetch_documents();
52              
53 27         39579 tie my %elem, 'Tie::IxHash';
54 27         524 parse_files(\%elem);
55              
56 26         276 tie my %xpath, 'Tie::IxHash';
57 26         561 build_xpath(\%elem, \%xpath);
58              
59 26         199 for my $xpath (keys %xpath) {
60 3119         28807 dump_diffs($xpath, \%xpath);
61             }
62              
63 26 100       17916 print $HTML::Linear::Path::Colors::html[1]
64             if $html;
65              
66             sub fetch_documents {
67 0     0   0 my (@local, @remote);
68 0         0 for (@ARGV) {
69 0 0       0 if (m{^https?://}x) {
70 0         0 push @remote, $_;
71             } else {
72 0         0 push @local, $_;
73             }
74             }
75 0 0       0 return unless @remote;
76              
77             ## no critic (RequireLocalizedPunctuationVars)
78 0         0 @ARGV = @local;
79              
80 0         0 my $q = YADA->new;
81 0         0 for (@remote) {
82 0         0 my $tmp = File::Temp->new(
83             SUFFIX => '.html',
84             TEMPLATE => 'doc-XXXX',
85             TMPDIR => 1,
86             );
87             $q->append(sub {
88             YADA::Worker->new({
89             initial_url => $_,
90             on_init => sub {
91 0         0 $_[0]->setopt(writedata => $tmp);
92             },
93             on_finish => sub {
94 0         0 $tmp->flush;
95 0 0       0 push @ARGV, $tmp unless $_[0]->has_error;
96             },
97             })
98 0     0   0 });
  0         0  
99             }
100 0         0 $q->wait;
101 0         0 return;
102             }
103              
104             sub parse_files {
105 27     27   558 my ($elem) = @_;
106 27         91 for my $file (@ARGV) {
107 53         9688 my $hl = HTML::Linear->new;
108              
109 53 100 100     3711 $hl->set_shrink
110             if $shrink // 1;
111              
112 53 100 100     10369 $hl->set_strict
113             if $strict // 0;
114              
115 53 100       13501 open(my $fh, '<:' . ($encoding ? "encoding($encoding)" : 'utf8' ), $file)
    100          
116             or croak "Can't open $file: $!";
117 52         959 $hl->parse_file($fh);
118 52         33742 close $fh;
119              
120 4781         381648 push @{$elem->{$_}}, [ $_ => basename($file) ]
121 52         663 for $hl->as_list;
122             }
123 26         8760 return;
124             }
125              
126             sub build_xpath {
127 26     26   85 my ($elem, $xpath) = @_;
128 26         437 while (my ($key, $list) = each %$elem) {
129 4781         184608 for (@{$list}) {
  4781         18641  
130 4781         6835 my ($el, $file) = @{$_};
  4781         13207  
131              
132 4781 100       14754 if (@unmangle) {
133 191         230 for my $path (@{$el->path}) {
  191         640  
134 1318         1528 for my $attr (keys %{$path->attributes}) {
  1318         6052  
135             ## no critic (ProtectPrivateSubs)
136 2276 100       12254 next unless HTML::Linear::Path::_isgroup($el->path->[-1], $attr);
137 126         281 for my $unmangle (@unmangle) {
138 126         997 $path->attributes->{$attr} =~ s/$unmangle//x;
139             }
140             }
141             }
142             }
143              
144 4781         16198 my $hash = $el->as_hash;
145 4781         62582 ++$xpath->{$_}->{$hash->{$_}}{$file}
146 4781         6715 for keys %{$hash};
147             }
148             }
149 26         8568 return;
150             }
151              
152             sub dump_diffs {
153 3119     3119   4660 my ($xpath, $xpath_ref) = @_;
154              
155 3119         3582 my %file;
156 3119         3435 my $m = 0;
157 3119         8008 my $n = 0;
158 3119         3181 for my $p (keys %{$xpath_ref->{$xpath}}) {
  3119         15266  
159 3369         51785 for my $q (keys %{$xpath_ref->{$xpath}->{$p}}) {
  3369         13914  
160 6187         53258 push @{$file{$q}}, $p;
  6187         17603  
161 6187         17603 ++$m;
162             }
163 3369         9526 ++$n;
164             }
165              
166 3119         7557 my $flag = 0;
167 3119 100       8412 $flag = 1
168             if $n == $m / scalar @ARGV;
169 3119 100 100     13198 $flag = 1
      100        
170             if
171             not ($partial // 0)
172             and scalar keys %file != scalar @ARGV;
173 3119 100       14960 return if $flag;
174              
175 274 100       708 if (1 < scalar keys %file) {
176 250 100       598 if ($html) {
177 90         470 say '
' . HTML::Linear::Path::Colors::wrap_xpath($xpath) . '
178             } else {
179 160         3560 say $xpath;
180             }
181              
182 250         1428 for my $file (sort keys %file) {
183 500         632 for (@{$file{$file}}) {
  500         1372  
184 500 100       928 if ($html) {
185 180         764 say '
' . $file . ''
186             . HTML::Linear::Path::Colors::wrap_content($_, 1)
187             . '
188             } else {
189 320 100       520 if ($color) {
190 160         4200 print GREEN . $file . RESET;
191 160         9326 $_ = HTML::Linear::Path::Colors::wrap_content($_);
192             } else {
193 160         639 print $file;
194             }
195 320         1801 say "\t${_}";
196             }
197             }
198             }
199              
200 250 100       627 if ($html) {
201 90         214 say '
202             } else {
203 160         298 say '';
204             }
205             }
206              
207 274         1165 return;
208             }
209              
210             __END__