File Coverage

blib/lib/Text/Metaphone/Amharic.pm
Criterion Covered Total %
statement 91 135 67.4
branch 17 48 35.4
condition n/a
subroutine 12 17 70.5
pod 0 9 0.0
total 120 209 57.4


line stmt bran cond sub pod time code
1             package Text::Metaphone::Amharic;
2              
3             # If either of these next two lines are inside
4             # the BEGIN block the package will break.
5             #
6 1     1   344957 use utf8;
  1         3  
  1         8  
7 1     1   814 use Regexp::Ethiopic::Amharic qw(:forms overload setForm);
  1         8311  
  1         10  
8              
9             BEGIN
10             {
11 1     1   474 use strict;
  1         2  
  1         33  
12 1     1   6 use warnings;
  1         3  
  1         68  
13 1     1   6 use vars qw( $VERSION %IMExpected %IMError %plosives $GRANULARITY $STYLE );
  1         2  
  1         344  
14              
15 1     1   6 $VERSION = "0.14";
16              
17 1         7 %plosives = (
18             ቅ => 'k',
19             ጥ => 't',
20             ጭ => 'ʧ',
21             ጵ => 'p',
22             ጽ => 's'
23             );
24 1         13 %IMExpected =(
25             ስ => "s",
26             ጽ => "s'",
27             ቅ => "k'",
28             ቕ => "q",
29             ት => "t",
30             ጥ => "t'",
31             ች => "ʧ",
32             ጭ => "ʧ",
33             ን => "n",
34             ኝ => "n",
35             ክ => "k",
36             ዝ => "z",
37             ዥ => "ʒ",
38             ጵ => "p'",
39             ፕ => "p"
40             );
41 1         6 %IMError =(
42             ስ => "ጽ",
43             ጽ => "ስ",
44             ቅ => "ቕ",
45             ቕ => "ቅ",
46             ት => "ጥ",
47             ጥ => "ት",
48             ች => "ጭ",
49             ጭ => "ች",
50             ን => "ኝ",
51             ኝ => "ን",
52             ክ => "ኽ",
53             ዝ => "ዥ",
54             ዥ => "ዝ",
55             ጵ => "ፕ",
56             ፕ => "ጵ"
57             );
58 1         2 $GRANULARITY = "low";
59 1         315 $STYLE = "ethio";
60             }
61              
62              
63             sub import
64             {
65 0     0   0 my ( $pkg, %args ) = @_;
66              
67 0 0       0 $STYLE = lc($args{style}) if ( $args{style} );
68 0 0       0 $GRANULARITY = lc($args{granularity}) if ( $args{granularity} );
69             }
70              
71              
72             sub new
73             {
74 1     1 0 1319 my $class = shift;
75 1         5 my $self = { _style => $STYLE, _granularity => $GRANULARITY };
76              
77 1         3 my $blessing = bless ( $self, $class );
78              
79 1         3 %_ = @_;
80              
81 1 50       5 $self->{_style} = lc($_{style}) if ( $_{style} );
82 1 50       3 $self->{_granularity} = lc($_{granularity}) if ( $_{granularity} );
83              
84 1         4 $blessing;
85             }
86              
87              
88             sub _formatStyle
89             {
90 0     0   0 my ($self, $keys) = @_;
91              
92 0 0       0 if ( $self->{_style} eq "ipa" ) {
    0          
93 0         0 foreach my $i ( 0..$#{$keys} ) {
  0         0  
94 0         0 $keys->[$i] =~ s/([ቅጥጭጵጽ])/$plosives{$1}'/og;
95 0         0 $keys->[$i] =~ tr/ህልምርስሽቕብትችንኝእክውይድዽጅዝዥግጝፍፕ/hlmrsʃqbtʧnɲakwjdɗʤzʒgɲfp/;
96             }
97             }
98             elsif ( $self->{_style} eq "sera" ) {
99 0         0 foreach my $i ( 0..$#{$keys} ) {
  0         0  
100 0         0 $keys->[$i] =~ tr/ህልምርስሽቅቕብትችንኝእክውይድዽጅዝዥግጝጥጭጵጽፍፕ/hlmrsxqQbtcnNakwydDjzZgGTCPSfp/;
101             }
102             }
103              
104             }
105              
106              
107             sub metaphone
108             {
109 9     9 0 5695 my $self = shift;
110              
111 9         27 $_ = $self->simplify($_[0]);
112 9         29 my ($re, @keys) = $self->glyphs ( $_ );
113 9         22 ($re, @keys) = $self->phono ( $re, @keys );
114 9         25 ($re, @keys) = $self->im ( $re, @keys );
115              
116 9 50       21 if ( @keys ) {
117 9         157 push ( @keys, qr/$re/ );
118             }
119              
120 9 50       34 $self->_formatStyle ( \@keys ) if ( $self->{_style} ne "ethio" );
121              
122 9 100       49 (wantarray) ? @keys : $keys[0];
123             }
124              
125              
126             sub simplify
127             {
128 9     9 0 14 my $self = shift;
129              
130 9         24 $_ = $_[0];
131              
132             #
133             # strip out all but first vowel:
134             #
135 9         45 s/^[=#አ#=]/አ/o;
136 9         37 s/[=#ሀ#=]/ሀ/og;
137              
138 9         33 s/(.)[=#አ#=]/$1/g;
139              
140 9 50       33 if ( $self->{_granularity} eq "low" ) {
141 9         27 s/(.)[#ወ#]/$1/og;
142 9         28 s/(.)[#የ#]/$1/og;
143             }
144             else {
145 0         0 s/([#11#])/setForm($1,$ሳድስ)."ዋ"/eg;
  0         0  
146             }
147 9         21 s/[=#ሰ#=]/ሰ/og;
148 9         24 s/[=#ጸ#=]/ጸ/og;
149 9         19 s/[#ቨ#]/በ/og;
150              
151             #
152             # now strip vowels, this simplies later code:
153             #
154 9 50       42 s/(\p{Ethiopic})/ ($1 eq 'ኘ') ? $1 : setForm($1,$ሳድስ)/eg;
  24         349  
155              
156              
157 9         144 $_;
158             }
159              
160              
161             sub glyphs
162             {
163 9     9 0 16 my $self = shift;
164              
165              
166 9         46 my @keys = ( $_[0] );
167 9         17 my $re = $_[0];
168              
169             #
170             # Confusion with ዽ
171             #
172 9 50       31 if ( $keys[0] =~ /ዽ/ ) {
173 0         0 $keys[2] = $keys[1] = $keys[0];
174 0         0 $keys[0] =~ s/ዽ/ድ/o; # caps problem
175             # $keys[1] literal
176 0         0 $keys[2] =~ s/ዽ/ጵ/o; # mistaken glyph
177 0         0 $re =~ s/ዽ/([ድዽጵ])/og;
178             }
179             #
180             # Confusion with ኘ
181             #
182 9 50       23 if ( $keys[0] =~ /ኘ/ ) {
183 0         0 my (@newKeysA, @newKeysB);
184 0         0 for (my $i=0; $i < @keys; $i++) {
185 0         0 $newKeysA[$i] = $newKeysB[$i] = $keys[$i]; # copy old keys
186             # $keys[$i] literal
187 0         0 $newKeysA[$i] =~ s/ኘ/ን/o; # caps problem
188 0         0 $newKeysB[$i] =~ s/ኘ/ፕ/o; # mistaken glyph
189             }
190 0         0 push (@keys,@newKeysA); # add new keys to old keys
191 0         0 push (@keys,@newKeysB); # add new keys to old keys
192 0         0 $re =~ s/ኘ/[ንኝፕ]/og;
193             }
194              
195 9         33 ($re, @keys);
196             }
197              
198              
199             sub phono
200             {
201 9     9 0 24 my ( $self, $re, @keys ) = @_;
202              
203              
204              
205 9 100       28 if ( $keys[0] =~ /ም[ብፍ]/ ) {
206 1         2 my @newKeys;
207 1         5 for (my $i=0; $i < @keys; $i++) {
208 1         2 $newKeys[$i] = $keys[$i]; # copy old keys
209 1         5 $newKeys[$i] =~ s/ምብ/ንብ/o; # update old keys for primary mapping
210 1         4 $newKeys[$i] =~ s/ምፍ/ንፍ/o; # update old keys for primary mapping
211             }
212 1         3 push (@keys,@newKeys); # add new keys to old keys
213 1         4 $re =~ s/ምብ/[ምን]ብ/og;
214 1         3 $re =~ s/ምፍ/[ምን]ፍ/og;
215             }
216              
217 9         27 ($re, @keys);
218             }
219              
220              
221             sub im
222             {
223 9     9 0 20 my ( $self, $re, @keys ) = @_;
224              
225 9         16 my $first = 1;
226             #
227             # Handle IM problems
228             # try to keep least probable keys last:
229             #
230 9         17 $_ = $keys[0]; # bidi folding # upper-to-lower
231 9 50       51 my $keyboard = ( $self->{_granularity} eq "high" ) ? qr/([ስቅቕትችንኝክዝዥጥጭጽጵፕ])/ : qr/([ቕኝዥጥጭጽጵ])/ ;
232              
233 9         73 while ( /$keyboard/ ) {
234 3         9 my $a = $1;
235 3         6 my @newKeys;
236 3 50       8 if ( $self->{_granularity} eq "low" ) {
237 3         55 s/$a/$IMExpected{$a}/g;
238             }
239             else {
240 0         0 s/$a/$IMExpected{$a}/;
241             }
242              
243 3         13 for (my $i=0; $i < @keys; $i++) {
244 3         11 $newKeys[$i] = $keys[$i]; # copy old keys
245             }
246              
247 3 50       9 if ( $first ) {
248             # update new keys for alternative
249 3 50       67 $keys[0] =~ s/^$a/ሀ$a/ if ( $self->{_style} ne "ipa" );
250 3 50       11 if ( $self->{_granularity} eq "low" ) {
251 3         112 $newKeys[0] =~ s/$a/ሀ$IMError{$a}/g;
252             }
253             else {
254 0         0 $newKeys[0] =~ s/$a/ሀ$IMError{$a}/;
255             }
256             }
257              
258 3         16 for (my $i=$first; $i < @newKeys; $i++) {
259             # update new keys for alternative
260 0 0       0 if ( $self->{_granularity} eq "low" ) {
261 0         0 $newKeys[$i] =~ s/([^ሀ])$a/$1ሀ$IMError{$a}/g;
262             }
263             else {
264 0         0 $newKeys[$i] =~ s/([^ሀ])$a/$1ሀ$IMError{$a}/;
265             }
266             }
267              
268 3         25 $first = 0;
269 3         9 push (@keys,@newKeys); # add new keys to old keys
270              
271             #
272             # this still needs work:
273             #
274             # $re =~ s/$a(?!\w+?\])/[$a$IMError{$a}]/g;
275 3         239 $re =~ s/(?
276             }
277              
278             #
279             # convert symbols that were missed in low granularity mode:
280             #
281 9         36 foreach my $i (0..$#keys) {
282 13         43 $keys[$i] =~ s/ሀ//og;
283 13         27 $keys[$i] =~ s/ኘ/ኝ/og;
284             }
285              
286 9         64 ($re, @keys);
287             }
288              
289              
290             sub reverse
291             {
292 0     0 0   my $self = shift;
293              
294 0           $_ = $_[0];
295            
296 0 0         if ( $self->{_style} eq "ipa" ) {
    0          
297 0           s/([stʧkp])'/$plosives{$1}/g;
298 0           tr/hlmrsʃqbtʧnɲakwjdɗʤzʒgɲfp/ህልምርስሽቕብትችንኝእክውይድዽጅዝዥግጝፍፕ/;
299             }
300             elsif ( $self->{_style} eq "sera" ) {
301 0           tr/hlmrsxqQbtcnNakwydDjzZgTCPSGfp/ህልምርስሽቅቕብትችንኝእክውይድዽጅዝዥግጝጥጭጵጽፍፕ/;
302             }
303              
304 0           $_;
305             }
306              
307              
308             sub style
309             {
310 0     0 0   my $self = shift;
311              
312 0 0         $self->{_style} = lc($_[0]) if (@_);
313              
314 0           $self->{_style};
315             }
316              
317              
318             sub granularity
319             {
320 0     0 0   my $self = shift;
321              
322 0 0         $self->{_granularity} = lc($_[0]) if (@_);
323              
324 0           $self->{_granularity};
325             }
326              
327              
328              
329             #########################################################
330             # Do not change this, Do not put anything below this.
331             # File must return "true" value at termination
332             1;
333             ##########################################################
334              
335             __END__