File Coverage

blib/lib/App/Greple/subst/Dict.pm
Criterion Covered Total %
statement 58 164 35.3
branch 0 34 0.0
condition 0 9 0.0
subroutine 20 36 55.5
pod 0 11 0.0
total 78 254 30.7


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 1     1   16 use v5.14;
  1         3  
12 1     1   5 use warnings;
  1         2  
  1         33  
13 1     1   23 use utf8;
  1         3  
  1         5  
14 1     1   29 use open IO => ':utf8', ':std';
  1         2  
  1         6  
15 1     1   131 use Encode qw(encode decode);
  1         2  
  1         78  
16 1     1   5 use Data::Dumper;
  1         2  
  1         45  
17              
18 1     1   506 use Mo qw(default build); {
  1         461  
  1         5  
19             has VERSION => ;
20             has NAME => ;
21             has FILE => ;
22             has DATA => ;
23             has LIST => default => [] ;
24             has CONFIG => default => {} ;
25             sub BUILD {
26 0     0 0   my($obj, $args) = @_;
27 0 0         if (my $file = $obj->FILE) {
    0          
28 0           $obj->read_file($file);
29             }
30             elsif (my $data = $obj->DATA) {
31 0           $obj->read_data($data);
32             }
33             }
34 1     1   1710 } no Mo;
  1         2  
  1         328  
35              
36             sub words {
37 0     0 0   my $obj = shift;
38 0           @{$obj->LIST};
  0            
39             }
40              
41             sub add {
42 0     0 0   my $obj = shift;
43 0           push @{$obj->LIST}, App::Greple::subst::Dict::Ent->new(@_);
  0            
44 0           $obj;
45             }
46              
47             sub add_comment {
48 0     0 0   my $obj = shift;
49 0           push @{$obj->LIST}, App::Greple::subst::Dict::Ent->new_comment(@_);
  0            
50 0           $obj;
51             }
52              
53             sub read_data {
54 0 0   0 0   my $obj = shift or die;
55 0           my $data = shift;
56 0           $obj->NAME("DATA");
57 0 0         if (utf8::is_utf8 $data) {
58 0           $data = encode 'utf8', $data;
59             }
60 0           open my $fh, "<", \$data;
61 0           $obj->read_fh($fh);
62 0           $obj;
63             }
64              
65             sub read_file {
66 0 0   0 0   my $obj = shift or die;
67 0           my $file = shift;
68 0           $obj->FILE($file);
69 0           $obj->NAME($file =~ s[.*/][]r);
70 0 0         say $file if $obj->CONFIG->{dictname};
71 0 0         open my $fh, "<", $file or die "$file: $!\n";
72 0           $obj->read_fh($fh);
73 0           $obj;
74             }
75              
76 1     1   7 use App::Greple::Pattern;
  1         2  
  1         281  
77              
78             sub read_fh {
79 0 0   0 0   my $obj = shift or die;
80 0           my $conf = $obj->CONFIG;
81 0           my $fh = shift;
82 0           local $_;
83 0           my $flag = FLAG_REGEX;
84 0 0         $flag |= FLAG_COOK if $conf->{linefold};
85 0           while (<$fh>) {
86 0           chomp;
87 0 0         say if $conf->{printdict};
88 0 0         if (not /^\s*[^#]/) {
89 0           $obj->add_comment($_);
90 0           next;
91             }
92 0           my @param = grep { not m{^//+$} } split ' ';
  0            
93 0           splice @param, 0, -2; # leave last one or two
94 0           my($pattern, $correct) = @param;
95 0           $obj->add($pattern, $correct, flag => $flag);
96             }
97 0           $obj;
98             }
99              
100 1     1   430 use Text::VisualWidth::PP;
  1         2748  
  1         57  
101 1     1   440 use Text::VisualPrintf qw(vprintf vsprintf);
  1         45202  
  1         156  
102              
103             sub vwidth {
104 0 0 0 0 0   if (not defined $_[0] or length $_[0] == 0) {
105 0           return 0;
106             }
107 0           Text::VisualWidth::PP::width $_[0];
108             }
109              
110             sub print {
111 1     1   44 use List::Util qw(max);
  1         4  
  1         410  
112 0     0 0   my $obj = shift;
113 0           my @words = $obj->words;
114 0           my $max = max map { vwidth $_->string } grep { defined } @words;
  0            
  0            
115 0           for my $p (@words) {
116 0 0         if ($p->is_comment) {
117 0           say $p->comment;
118             } else {
119 0   0       my($from_re, $to) = ($p->string, $p->correct // '');
120 0   0       vprintf "%-*s // %s", $max, $from_re // '', $to // '';
      0        
121 0           CORE::print "\n";
122             }
123             }
124             }
125              
126             sub to_text {
127 0     0 0   my $obj = shift;
128 0           my $text;
129 0 0         open my $fh, ">:encoding(utf8)", \$text or die;
130 0           select do {
131 0           my $old = select $fh;
132 0           $obj->print;
133 0           close $fh;
134 0           $old;
135             };
136 0           decode 'utf8', $text;
137             }
138              
139             sub select {
140 0     0 0   my $obj = shift;
141 0           my $select = shift;
142 0           my $max = @$obj;
143 1     1   508 use Getopt::EX::Numbers;
  1         6531  
  1         227  
144 0           my $numbers = Getopt::EX::Numbers->new(max => $max);
145 0           my @select = do {
146 0           map { $_ - 1 }
147 0           sort { $a <=> $b }
148 0           grep { $_ <= $max }
149 0           map { $numbers->parse($_)->sequence }
  0            
150             split /,/, $select;
151             };
152 0           @$obj = do {
153 0           my @tmp = (undef) x $max;
154 0           @tmp[@select] = @{$obj}[@select];
  0            
155 0           @tmp;
156             };
157 0           $obj;
158             }
159              
160             }
161              
162             package App::Greple::subst::Dict::Ent {
163              
164 1     1   14 use v5.14;
  1         16  
165 1     1   11 use warnings;
  1         2  
  1         30  
166              
167 1     1   9 use Exporter 'import';
  1         7  
  1         58  
168             our @EXPORT_OK = qw(print_dict);
169              
170 1     1   7 use Carp;
  1         2  
  1         56  
171 1     1   7 use Getopt::EX::Module;
  1         3  
  1         83  
172 1     1   8 use App::Greple::Common;
  1         4  
  1         114  
173 1     1   8 use App::Greple::Pattern;
  1         2  
  1         392  
174              
175             our @ISA = 'App::Greple::Pattern';
176              
177             sub new {
178 0     0     my $class = shift;
179 0 0         if (@_ < 2) {
180 0           return bless {}, $class;
181             }
182 0           my($pattern, $correct) = splice @_, 0, 2;
183 0           my $obj = $class->SUPER::new($pattern, @_);
184 0           $obj->correct($correct);
185 0           $obj;
186             }
187              
188             sub correct {
189 0     0     my $obj = shift;
190 0 0         @_ ? $obj->{CORRECT} = shift : $obj->{CORRECT};
191             }
192              
193             sub new_comment {
194 0     0     my $class = shift;
195 0           my $comment = shift;
196 0           my $obj = $class->SUPER::new();
197 0           $obj->comment($comment);
198 0           $obj;
199             }
200              
201             sub comment {
202 0     0     my $obj = shift;
203 0 0         @_ ? $obj->{COMMENT} = shift : $obj->{COMMENT};
204             }
205              
206             sub is_comment {
207 0     0     my $obj = shift;
208 0           defined $obj->{COMMENT};
209             }
210              
211             }
212              
213             1;