File Coverage

blib/lib/Lingua/Boolean/Tiny.pm
Criterion Covered Total %
statement 154 199 77.3
branch 27 34 79.4
condition 1 3 33.3
subroutine 82 110 74.5
pod 5 5 100.0
total 269 351 76.6


line stmt bran cond sub pod time code
1 1     1   68404 use 5.006002;
  1         4  
2 1     1   5 use strict;
  1         2  
  1         23  
3 1     1   5 use warnings;
  1         2  
  1         28  
4 1     1   630 use utf8;
  1         14  
  1         6  
5 1     1   35 no warnings qw( void once uninitialized );
  1         3  
  1         489  
6              
7             {
8             package Lingua::Boolean::Tiny;
9            
10             require Exporter;
11             our @ISA = 'Exporter';
12            
13             our $AUTHORITY = 'cpan:TOBYINK';
14             our $VERSION = '0.008';
15             our @EXPORT = qw( boolean );
16             our (%LANG, @LANG);
17             our @BASELANG = qw( zh en es hi ru ar pt bn fr ms de ja );
18            
19             sub new
20             {
21 106     106 1 792 require Carp;
22 106         176 my $class = shift;
23 106 50       225 my $self = $class->new_strict(@_)
24             or Carp::carp("Language not available, using English instead");
25 106 50       272 $self || "Lingua::Boolean::Tiny"->new_strict("en");
26             }
27            
28             sub new_strict
29             {
30 648     648 1 964 shift;
31 648         1062 my ($lang) = @_;
32 648 100       1398 return "Lingua::Boolean::Tiny::Union"->new(@$lang) if ref($lang);
33 577 50       1050 return "Lingua::Boolean::Tiny::Union"->new(@BASELANG) if !defined $lang;
34             my $class = $LANG{ lc $lang }
35 577   33     1332 || do { require Lingua::Boolean::Tiny::More; $LANG{ lc $lang } };
36 577 50       12928 return $class->new if $class;
37 0         0 return;
38             }
39            
40             sub boolean
41             {
42 105     105 1 22379 my $text = shift;
43 105 100       351 my $lang = __PACKAGE__->new(@_ ? $_[0] : \@LANG);
44 105         284 $lang->boolean($text);
45             }
46            
47             sub langs
48             {
49 0     0 1 0 @LANG;
50             }
51            
52             sub languages
53             {
54 0     0 1 0 map __PACKAGE__->new($_)->languages, @LANG;
55             }
56             }
57              
58             {
59             package Lingua::Boolean::Tiny::BASE;
60            
61             our $AUTHORITY = 'cpan:TOBYINK';
62             our $VERSION = '0.008';
63            
64             # Versions of ~~ and fc for legacy Perls...
65 1     1   706 use if $] >= 5.016, feature => 'fc';
  1         14  
  1         7  
66 1 50   1   263 BEGIN { eval q[fc("1")] or eval q[sub fc($) { lc $_[0] }] };
67            
68             eval q
69 1     1   416 {
  0     1   0  
  0     1   0  
  1     348   22  
  1         6  
  1         10  
  1         3  
  1         72  
  348         2080  
70             use match::simple qw(match);
71             1;
72             }
73             or eval q
74             {
75             use v5.10.1;
76             no warnings;
77             sub match { $_[0] ~~ $_[1] };
78             1;
79             }
80             or eval q
81             {
82             sub match
83             {
84             my ($a, $b) = @_;
85             if (ref($b) eq 'ARRAY')
86             {
87             for my $b2 (@$b)
88             {
89             return 1 if match($a, $b2);
90             }
91             }
92             ref($b) eq 'Regexp' and return $a =~ $b;
93             ref($b) eq 'CODE' and return $b->($a);
94             return $a eq $b;
95             }
96             };
97            
98             sub boolean
99             {
100 210     210   297 my $self = shift;
101 210         371 my ($text) = @_;
102            
103 210         569 $text =~ s/(?:^\s+)|(?:\s+$)//gs;
104            
105 210 100       4291 return 1 if fc $text eq fc $self->yes;
106 198 100       3832 return 0 if fc $text eq fc $self->no;
107 180 100       3432 return 1 if match($text, $self->yes_expr);
108 168 100       3362 return 0 if match($text, $self->no_expr);
109 138 100       341 return 1 if $text eq 1;
110 135 100       247 return 0 if $text eq 0;
111 129         236 return undef;
112             }
113            
114             sub yesno
115             {
116 2 100   2   61 $_[1] ? $_[0]->yes : $_[0]->no
117             }
118            
119             sub make_classes
120             {
121 1     1   5 my $base = shift;
122 1     1   9 no strict 'refs';
  1         2  
  1         165  
123 1         14 for (@_)
124             {
125 12         51 my ($lang, $codes, $yes, $no, $yes_expr, $no_expr) = @$_;
126 12 50       45 $yes_expr = $yes unless defined $yes_expr;
127 12 50       63 $no_expr = $no unless defined $no_expr;
128 12         53 my $class = "Lingua::Boolean::Tiny::$lang";
129 12         31 ${"$class\::AUTHORITY"} = $AUTHORITY;
  12         135  
130 12         33 ${"$class\::VERSION"} = $VERSION;
  12         84  
131 12         30 @{"$class\::ISA"} = ($base);
  12         407  
132 1     1   8 no warnings qw( closure );
  1         2  
  1         683  
133             eval qq
134 12     0   3406 {
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     40   0  
  0     105   0  
  0     40   0  
  0     40   0  
  0     40   0  
  0     40   0  
  0     40   0  
  0     72   0  
  0     40   0  
  0     40   0  
  0     40   0  
  0     40   0  
  0     10   0  
  40     40   89  
  40     10   165  
  105     10   244  
  105     10   460  
  40     69   95  
  40     10   165  
  40     18   89  
  40     4   174  
  40     10   87  
  40     4   165  
  40     4   87  
  40     10   160  
  40     10   89  
  40     10   337  
  72     4   153  
  72     4   363  
  40     4   88  
  40     8   171  
  40     35   95  
  40     10   205  
  40     10   96  
  40     10   194  
  40     53   93  
  40     10   167  
  10     4   114  
  40     24   140  
  10     10   36  
  10     10   46  
  10     10   34  
  69     10   222  
  10     4   32  
  18     40   65  
  4     75   13  
  10     10   32  
  4     4   13  
  4     40   13  
  10     10   198  
  10     10   188  
  10     4   187  
  4     4   74  
  4     10   75  
  4     10   86  
  8     10   150  
  35     4   709  
  10     11   202  
  10     57   183  
  10     10   186  
  53         1020  
  10         35  
  4         15  
  24         81  
  10         36  
  10         37  
  10         46  
  10         55  
  4         13  
  40         171  
  75         254  
  10         40  
  4         13  
  40         803  
  10         185  
  10         185  
  4         74  
  4         74  
  10         218  
  10         186  
  10         235  
  4         76  
  11         204  
  57         1071  
  10         199  
135             package $class;
136             sub new { my \$k = shift; bless qr{$lang}, \$k };
137             sub yes { \$yes };
138             sub no { \$no };
139             sub yes_expr { \$yes_expr };
140             sub no_expr { \$no_expr };
141             sub languages { \$lang };
142             sub langs { \@{ \$codes } };
143             };
144 12         93 for my $lang (@$codes)
145             {
146 28         115 $Lingua::Boolean::Tiny::LANG{$lang} = $class;
147             }
148 12         59 push @Lingua::Boolean::Tiny::LANG, $codes->[0];
149             }
150            
151 1         67 return 1;
152             }
153             }
154              
155             {
156             package Lingua::Boolean::Tiny::Union;
157            
158             our $AUTHORITY = 'cpan:TOBYINK';
159             our $VERSION = '0.008';
160            
161             sub new
162             {
163 71     71   124 my $class = shift;
164 71         183 bless [ grep defined, map "Lingua::Boolean::Tiny"->new_strict($_), @_ ] => $class;
165             }
166            
167             sub boolean
168             {
169 71     71   114 my $self = shift;
170 71         138 for (@$self)
171             {
172 176         408 my $r = $_->boolean(@_);
173 176 100       711 return $r if defined $r;
174             }
175 8         46 return undef;
176             }
177            
178             sub langs
179             {
180 0     0     my $self = shift;
181 0           map $_->langs, @$self;
182             }
183            
184             sub languages
185             {
186 0     0     my $self = shift;
187 0           map $_->languages, @$self;
188             }
189             }
190              
191             "Lingua::Boolean::Tiny::BASE"->make_classes(
192             [
193             Chinese => [qw( zh zho chi )],
194             q/是/ => q/不是/,
195             [qr{^[yY是]}, qw( 是 對 是 对 ), qr{^[ds]h[ìi]$}i],
196             [qr{^[nN不否]}, qw( 不是 不對 不是 不对 ), qr{^b[úu]\s*[ds]h[ìi]$}i],
197             ],
198             [
199             English => [qw( en eng )],
200             qw( yes no ),
201             [qr{^y(?:es)?$}i, qr{^on$}i, qr{^ok$}i, qr{^true$}i],
202             [qr{^no?$}i, qr{^off$}i, qr{not ?ok$}i, qr{^false$}i],
203             ],
204             [
205             Spanish => [qw( es spa )],
206             qw( sí no ),
207             qr{^[sSyY]},
208             qr{^[nN]$},
209             ],
210             [
211             Hindi => [qw( hi hin )],
212             q/हाँ/ => q/नहीं/,
213 1     1   7 ["हाँ", qr{^h[aā]̃$}i, "जी", qr{^j[īi]$}i, "जी हाँ", qr{^j[īi]\s*h[aā]̃$}i, qr{^ji\s*ha$}i, qr{^[yY]}],
  1         9  
  1         11  
214             ["नहीं", qr{^nahī̃$}i, "जी नहीं", qr{^jī nahī̃$}i, qr{^ji\s*nahi$}i, qr{^[nN]}],
215             ],
216             [
217             Russian => [qw( ru rus )],
218             qw( да нет ),
219             [qr{^[ДдYy]}, qr{^да$}i, qr{^da$}i],
220             [qr{^[НнNn]}, qr{^нет$}i, qr{^n[iy]?et$}i],
221             ],
222             [
223             Arabic => [qw( ar ara )],
224             q/نعم/ => q/ﻻ/,
225             qr{^[نyY].*},
226             qr{^[لnN].*},
227             ],
228             [
229             Portuguese => [qw( pt por )],
230             qw( sim não ),
231             [qr{^[SsyY].*}, qr{^sim$}i],
232             [qr{^[nN].*}, qr{^n[aã]o$}i],
233             ],
234             [
235             Bengali => [qw( bn ben )],
236             q/হ্যাঁ/ => q/না/,
237             [qr{^[হ্যাঁyY]}, q/জি/, q/হ্যাঁ/, qr{^ji$}i, qr{^h[eê][nñ]$}i],
238             [qr{^[নাnN]}, q/না/, qr{^n[aā]$}i],
239             ],
240             [
241             French => [qw( fr fre fra )],
242             qw( oui non ),
243             [qr{^[oOjJyYsS1].*}, qr{^oui$}i, qr{^ok$}i, qr{^vraie?$}i],
244             [qr{^[nN0].*}, qr{^n(?:on?)?$}i, qr{^faux$}i],
245             ],
246             [
247             Malay => [qw( ms may msa )],
248             qw( ya tidak ),
249             [qr{^[Yy]}, qr{^ya$}i, qr{^ha'?ah$}i],
250             [qr{^[Tt]}, qr{^tidak$}i, qr{^tak$}i],
251             ],
252             [
253             German => [qw( de deu ger )],
254             qw( ja nein ),
255             [qr{^[jJyY].*}, qr{^ja?$}i, qr{^wahr$}i],
256             [qr{^[nN].*}, qr{^n(?:ein)?$}i, qr{^falsche$}i],
257             ],
258             [
259             Japanese => [qw( ja jpn )],
260             q/はい/ => q/いいえ/,
261             [qr{^([yYyY]|はい|ハイ)}, q/はい/, q/ええ/, q/うん/, qr{^hai$}i, qr{^[eē]$}i, qr{^un$}i, qr{^n̄$}i],
262             [qr{^([nNnN]|いいえ|イイエ)}, q/いいえ/, q/いえ/, q/ううん/, q/違う/, qr{^[íi]?ie$}i, qr{^uun$}i, qr{^[n̄n]n$}i, qr{^chigau$}i],
263             ],
264             );
265              
266             __END__