File Coverage

blib/lib/App/Greple/subst/Dict.pm
Criterion Covered Total %
statement 136 176 77.2
branch 24 44 54.5
condition 0 9 0.0
subroutine 33 37 89.1
pod 0 12 0.0
total 193 278 69.4


line stmt bran cond sub pod time code
1             =encoding utf8
2              
3             =head1 NAME
4              
5             subst::Dict - Dictionary object for App::Greple::subst
6              
7             =cut
8              
9             package App::Greple::subst::Dict {
10              
11 22     22   364 use v5.14;
  22         84  
12 22     22   283 use warnings;
  22         168  
  22         1449  
13 22     22   232 use utf8;
  22         67  
  22         140  
14 22     22   1040 use open IO => ':utf8', ':std';
  22         43  
  22         158  
15 22     22   3085 use Encode qw(encode decode);
  22         86  
  22         1535  
16 22     22   177 use Data::Dumper;
  22         62  
  22         1320  
17              
18 22     22   11381 use Mo qw(default build); {
  22         16114  
  22         127  
19             has VERSION => ;
20             has NAME => ;
21             has FILE => ;
22             has DATA => ;
23             has LIST => default => [] ;
24             has CONFIG => default => {} ;
25             sub BUILD {
26 21     21 0 1357 my($obj, $args) = @_;
27 21 100       102 if (my $file = $obj->FILE) {
    50          
28 17         254 $obj->read_file($file);
29             }
30             elsif (my $data = $obj->DATA) {
31 4         112 $obj->read_data($data);
32             }
33             }
34 22     22   47924 } no Mo;
  22         50  
  22         12748  
35              
36             sub words {
37 26     26 0 58 my $obj = shift;
38 26         70 @{$obj->LIST};
  26         122  
39             }
40              
41             sub add {
42 164     164 0 259 my $obj = shift;
43 164         212 push @{$obj->LIST}, App::Greple::subst::Dict::Ent->new(@_);
  164         384  
44 164         1135 $obj;
45             }
46              
47             sub add_comment {
48 33     33 0 58 my $obj = shift;
49 33         48 push @{$obj->LIST}, App::Greple::subst::Dict::Ent->new_comment(@_);
  33         103  
50 33         68 $obj;
51             }
52              
53             sub read_data {
54 4 50   4 0 33 my $obj = shift or die;
55 4         10 my $data = shift;
56 4 100       36 if (ref $data eq 'ARRAY') {
57 2         10 $obj->NAME("PAIRS");
58 2 50       18 $obj->load_pairs(@$data) if @$data;
59             } else {
60 2         13 $obj->NAME("DATA");
61 2 50       21 if (utf8::is_utf8 $data) {
62 2         54 $data = encode 'utf8', $data;
63             }
64 2         102 open my $fh, "<", \$data;
65 2         13 $obj->read_fh($fh);
66             }
67 4         17 $obj;
68             }
69              
70             sub read_file {
71 17 50   17 0 68 my $obj = shift or die;
72 17         35 my $file = shift;
73 17         60 $obj->FILE($file);
74 17         248 $obj->NAME($file =~ s[.*/][]r);
75 17 50       136 say $file if $obj->CONFIG->{dictname};
76 17 50       1105 open my $fh, "<", $file or die "$file: $!\n";
77 17         149 $obj->read_fh($fh);
78 17         317 $obj;
79             }
80              
81 22     22   184 use App::Greple::Pattern;
  22         41  
  22         16831  
82              
83             sub read_fh {
84 19 50   19 0 95 my $obj = shift or die;
85 19         77 my $conf = $obj->CONFIG;
86 19         169 my $fh = shift;
87 19         61 local $_;
88 19         59 my $flag = FLAG_REGEX;
89 19 50       78 $flag |= FLAG_COOK if $conf->{linefold};
90 19         1793 while (<$fh>) {
91 194         1231 s/\R\z//;
92 194 50       490 say if $conf->{printdict};
93 194 100       629 if (not /^\s*[^#]/) {
94 33         104 $obj->add_comment($_);
95 33         138 next;
96             }
97 161         231 my @param;
98 161 100       747 if ((@param = split(m{\h+//\h+}, $_, 2)) == 2) {
99 51         119 $param[0] =~ s/^\h+//;
100             } else {
101 110         334 @param = split ' ';
102             }
103 161         341 splice @param, 0, -2; # leave last one or two
104 161         334 my($pattern, $correct) = @param;
105 161         459 $obj->add($pattern, $correct, flag => $flag);
106             }
107 19         95 $obj;
108             }
109              
110             sub load_pairs {
111 2 50   2 0 6 my $obj = shift or die;
112 2         10 my $conf = $obj->CONFIG;
113 2         18 my $flag = FLAG_REGEX;
114 2 50       8 $flag |= FLAG_COOK if $conf->{linefold};
115 2         8 while (my($pattern, $correct) = splice @_, 0, 2) {
116 3         11 $obj->add($pattern, $correct, flag => $flag);
117             }
118 2         4 $obj;
119             }
120              
121 22     22   12691 use Text::VisualWidth::PP;
  22         95516  
  22         1792  
122 22     22   11049 use Text::VisualPrintf qw(vprintf vsprintf);
  22         1292819  
  22         4239  
123              
124             sub vwidth {
125 0 0 0 0 0 0 if (not defined $_[0] or length $_[0] == 0) {
126 0         0 return 0;
127             }
128 0         0 Text::VisualWidth::PP::width $_[0];
129             }
130              
131             sub print {
132 22     22   254 use List::Util qw(max);
  22         48  
  22         8748  
133 0     0 0 0 my $obj = shift;
134 0         0 my @words = $obj->words;
135 0         0 my $max = max map { vwidth $_->string } grep { defined } @words;
  0         0  
  0         0  
136 0         0 for my $p (@words) {
137 0 0       0 if ($p->is_comment) {
138 0         0 say $p->comment;
139             } else {
140 0   0     0 my($from_re, $to) = ($p->string, $p->correct // '');
141 0   0     0 vprintf "%-*s // %s", $max, $from_re // '', $to // '';
      0        
142 0         0 CORE::print "\n";
143             }
144             }
145             }
146              
147             sub to_text {
148 0     0 0 0 my $obj = shift;
149 0         0 my $text;
150 0 0       0 open my $fh, ">:encoding(utf8)", \$text or die;
151 0         0 select do {
152 0         0 my $old = select $fh;
153 0         0 $obj->print;
154 0         0 close $fh;
155 0         0 $old;
156             };
157 0         0 decode 'utf8', $text;
158             }
159              
160             sub select {
161 0     0 0 0 my $obj = shift;
162 0         0 my $select = shift;
163 0         0 my $max = @$obj;
164 22     22   894 use Getopt::EX::Numbers;
  22         7014  
  22         6906  
165 0         0 my $numbers = Getopt::EX::Numbers->new(max => $max);
166 0         0 my @select = do {
167 0         0 map { $_ - 1 }
168 0         0 sort { $a <=> $b }
169 0         0 grep { $_ <= $max }
170 0         0 map { $numbers->parse($_)->sequence }
  0         0  
171             split /,/, $select;
172             };
173 0         0 @$obj = do {
174 0         0 my @tmp = (undef) x $max;
175 0         0 @tmp[@select] = @{$obj}[@select];
  0         0  
176 0         0 @tmp;
177             };
178 0         0 $obj;
179             }
180              
181             }
182              
183             package App::Greple::subst::Dict::Ent {
184              
185 22     22   331 use v5.14;
  22         112  
186 22     22   155 use warnings;
  22         42  
  22         1866  
187              
188 22     22   182 use Exporter 'import';
  22         53  
  22         1347  
189             our @EXPORT_OK = qw(print_dict);
190              
191 22     22   158 use Carp;
  22         50  
  22         1724  
192 22     22   133 use Getopt::EX::Module;
  22         56  
  22         969  
193 22     22   120 use App::Greple::Common;
  22         42  
  22         1168  
194 22     22   187 use App::Greple::Pattern;
  22         63  
  22         8276  
195              
196             our @ISA = 'App::Greple::Pattern';
197              
198             sub new {
199 164     164   1269 my $class = shift;
200 164 50       405 if (@_ < 2) {
201 0         0 return bless {}, $class;
202             }
203 164         348 my($pattern, $correct) = splice @_, 0, 2;
204 164         533 my $obj = $class->SUPER::new($pattern, @_);
205 164         22745 $obj->correct($correct);
206 164         383 $obj;
207             }
208              
209             sub correct {
210 388     388   2685 my $obj = shift;
211 388 100       1731 @_ ? $obj->{CORRECT} = shift : $obj->{CORRECT};
212             }
213              
214             sub new_comment {
215 33     33   392 my $class = shift;
216 33         64 my $comment = shift;
217 33         182 my $obj = $class->SUPER::new();
218 33         454 $obj->comment($comment);
219 33         69 $obj;
220             }
221              
222             sub comment {
223 33     33   56 my $obj = shift;
224 33 50       209 @_ ? $obj->{COMMENT} = shift : $obj->{COMMENT};
225             }
226              
227             sub is_comment {
228 266     266   460 my $obj = shift;
229 266         1039 defined $obj->{COMMENT};
230             }
231              
232             }
233              
234             1;