File Coverage

blib/lib/Lingua/Zompist/Verdurian.pm
Criterion Covered Total %
statement 203 214 94.8
branch 172 188 91.4
condition 338 345 97.9
subroutine 13 13 100.0
pod 10 10 100.0
total 736 770 95.5


line stmt bran cond sub pod time code
1             package Lingua::Zompist::Verdurian;
2             # vim:set tw=72 sw=2:
3              
4 14     14   376749 use 5.005;
  14         63  
  14         634  
5 14     14   102 use strict;
  14         52  
  14         741  
6              
7             require Exporter;
8 14     14   74 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS $keep_accents);
  14         30  
  14         109702  
9             @ISA = qw(Exporter);
10              
11             # Items to export into callers namespace by default. Note: do not export
12             # names by default without a very good reason. Use EXPORT_OK instead.
13             # Do not simply export all your public functions/methods/constants.
14              
15             # This allows declaration use Lingua::Zompist::Verdurian ':all';
16             # If you do not need this, moving things directly into @EXPORT or @EXPORT_OK
17             # will save memory.
18             %EXPORT_TAGS = ( 'all' => [ qw(
19             demeric
20             scrifel
21             izhcrifel
22             ctanec
23             epesec
24             befel
25             classimp
26             part
27             noun
28             adj
29             ) ] );
30              
31             @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
32              
33             @EXPORT = qw(
34            
35             );
36             $VERSION = '0.91';
37              
38             # Keep accents on words by default, even if the accented syllable would
39             # be stressed anyway due to its position?
40             $keep_accents = 1;
41              
42             my %verb = (demeric => \&demeric,
43             scrifel => \&scrifel,
44             izhcrifel => \&izhcrifel,
45             ctanec => \&ctanec,
46             epesec => \&epesec,
47             befel => \&befel,
48             classimp => \&classimp,
49             );
50              
51             my @persons = qw(se le il ta mu ca);
52              
53             my @cases = qw(nom gen acc dat);
54              
55             my @numbers = qw(sing pl);
56              
57             my %endings = (
58             N => [ qw( ai ei e am o u ) ],
59             R => [ qw( u eu e um o ü ) ],
60             C => [ qw( ao eo e om o u ) ],
61             );
62              
63             # Some handy things for -i- insertion and moving stress
64             my $cons = qr/(?:[szcdr]h|[pbtdcgkfvszmnlr])/;
65             my $vow = qr/[aeiouAEIOU]/; # plain vowels only
66             my %acc = (
67             'a' => 'á',
68             'e' => 'é',
69             'i' => 'í',
70             'o' => 'ó',
71             'u' => 'ú',
72             'A' => 'Á',
73             'E' => 'É',
74             'I' => 'Í',
75             'O' => 'Ó',
76             'U' => 'Ú',
77             );
78              
79             my %unacc = (
80             'á' => 'a',
81             'é' => 'e',
82             'í' => 'i',
83             'ó' => 'o',
84             'ú' => 'u',
85             'Á' => 'A',
86             'É' => 'E',
87             'Í' => 'I',
88             'Ó' => 'O',
89             'Ú' => 'U',
90             );
91              
92              
93             my %demeric = (
94             esan => [ qw( ai ei e am eo eu ) ],
95             fassec => [ qw( fassao fasseo fas fassom fasso fassu ) ],
96             kies => [ qw( kiai kiei kiet kaiam kaio kaiu ) ],
97             'lübec' => [ qw( lübao lüo lü lübom lübo lübu ) ],
98             mizec => [ qw( mizao mizeo mis mizom mizo mizu ) ],
99             shrifec => [ qw( shrifao shris shri shrifom shrifo shrifu ) ],
100             zhanen => [ qw( zhai zhes zhe zhanam zhano zhanu ) ],
101             zhusir => [ qw( zhui zhus zhu zhusum zhuso zhusü ) ],
102             );
103              
104             sub demeric {
105 17     17 1 48 my $verb = shift;
106 17         26 my $stem = $verb;
107 17         22 my $table;
108              
109 17 100       107 if($stem =~ s/^(\S+)(fassec|mizec|shrifec|zhanen|zhusir)$/$1/) {
110 2         3 return [ map "$stem$_", @{$demeric{$2}} ];
  2         33  
111             }
112              
113 15 100       105 return $demeric{$verb} if exists $demeric{$verb};
114              
115 7 100       50 if($stem =~ s/[ea]n$//) {
    100          
    50          
116 3         5 $table = [ map "$stem$_", @{$endings{N}} ];
  3         28  
117             } elsif($stem =~ s/[ie]r$//) {
118 2         5 $table = [ map "$stem$_", @{$endings{R}} ];
  2         19  
119             } elsif($stem =~ s/ec$//) {
120 2         4 $table = [ map "$stem$_", @{$endings{C}} ];
  2         16  
121             } else {
122 0         0 return;
123             }
124              
125 7         20 for(@$table) {
126 42         3026 s/zh(?=[aou][iom]?$)/g/;
127             }
128              
129 7         218 return $table;
130             }
131              
132             my %scrifel = (
133             esan => [ qw( fuai fuei fue/esne fuam fuo fueu/esnu ) ],
134             fassec => [ map "fashsh$_", @{$endings{C}} ],
135             dan => [ map "don$_", @{$endings{N}} ],
136             kies => [ map "kaiv$_", @{$endings{N}} ],
137             shushchan => [ map "shushd$_", @{$endings{N}} ],
138             );
139              
140             sub scrifel {
141 83     83 1 209 my $verb = shift;
142 83         152 my $stem = $verb;
143 83         139 my $table;
144 83         125 my $add = 0; # did we have to add an -i-?
145              
146 83 100       400 return $scrifel{$verb} if exists $scrifel{$verb};
147              
148 78 100       1062 if($stem =~ s/($cons[lr])([ea]n|[ie]r|ec)$/$1i$2/) {
149 52         96 $add = 1;
150             }
151              
152 78 100 100     3077 if($stem =~ s/c[ea]n$/sn/ ||
    100 100        
    50 100        
      100        
      100        
      100        
      100        
      100        
      100        
      100        
      100        
      100        
      66        
153             $stem =~ s/ch[ea]n$/dn/ ||
154             $stem =~ s/d[ea]n$/zn/ ||
155             $stem =~ s/g[ea]n$/zhn/ ||
156             $stem =~ s/[ea]n$/n/) {
157 29         39 $table = [ map "$stem$_", @{$endings{N}} ];
  29         265  
158             } elsif($stem =~ s/ch[ie]r$/dr/ ||
159             $stem =~ s/m[ie]r$/mbr/ ||
160             $stem =~ s/n[ie]r$/ndr/ ||
161             $stem =~ s/z[ie]r$/dr/ ||
162             $stem =~ s/[ie]r$/r/) {
163 29         47 $table = [ map "$stem$_", @{$endings{R}} ];
  29         281  
164             } elsif($stem =~ s/cec$/sc/ ||
165             $stem =~ s/chec$/shc/ ||
166             $stem =~ s/mec$/nc/ ||
167             $stem =~ s/sec$/sh/ ||
168             $stem =~ s/zec$/zh/ ||
169             $stem =~ s/ec$/c/) {
170 20         29 $table = [ map "$stem$_", @{$endings{C}} ];
  20         275  
171             } else {
172 0         0 return;
173             }
174              
175 78 100       276 if($add) {
176 52         105 for(@$table) {
177             # replace -VC+[lr]i[nrc]VC* with -V'C+[lr]i[nrc]VC*
178 312         2439 s{
179             ($vow) # a vowel, which we'll accent (to $1)
180             ( # begin capturing to $2
181             (?:$cons)+ # one or more consonants
182             # (never zero, since otherwise we wouldn't have had
183             # to insert the -i-)
184             [lr] # one of 'l' or 'r'
185             i # the epenthetic -i- which must not receive the stress
186             [nrc] # endings are either -n-, -r-, or -c-
187             $vow # followed by only one (unstressed) vowel
188             m? # and possibly an -m (for the -am -um -om endings
189             # of the Ist person plural)
190             $ # and finally end-of-string
191             ) # end of $2
192             }{$acc{$1}$2}ox;
193             }
194             }
195              
196 78         604 return $table;
197             }
198              
199             my %izhcrifel = (
200             fassec => [ map "fashsher$_", @{$endings{C}} ],
201             dan => [ map "doner$_", @{$endings{N}} ],
202             kies => [ map "kaiver$_", @{$endings{N}} ],
203             shushchan => [ map "shushder$_", @{$endings{N}} ],
204             );
205              
206             sub izhcrifel {
207 82     82 1 231 my $verb = shift;
208 82         146 my $stem = $verb;
209 82         127 my $table;
210 82         131 my $add = 0;
211              
212 82 100       331 return $izhcrifel{$verb} if exists $izhcrifel{$verb};
213              
214 78 100       1036 if($stem =~ s/($cons[lr])([ea]n|[ie]r|ec)$/$1i$2/) {
215 52         102 $add = 1;
216             }
217              
218 78 100 100     2814 if($stem =~ s/c[ea]n$/sner/ ||
    100 100        
    50 100        
      100        
      100        
      100        
      100        
      100        
      100        
      100        
      100        
      100        
      66        
219             $stem =~ s/ch[ea]n$/dner/ ||
220             $stem =~ s/d[ea]n$/zner/ ||
221             $stem =~ s/g[ea]n$/zhner/ ||
222             $stem =~ s/[ea]n$/ner/) {
223 29         42 $table = [ map "$stem$_", @{$endings{N}} ];
  29         261  
224             } elsif($stem =~ s/ch[ie]r$/dre/ ||
225             $stem =~ s/m[ie]r$/mbre/ ||
226             $stem =~ s/n[ie]r$/ndre/ ||
227             $stem =~ s/z[ie]r$/dre/ ||
228             $stem =~ s/[ie]r$/re/) {
229 29         50 $table = [ map "$stem$_", @{$endings{R}} ];
  29         275  
230             } elsif($stem =~ s/cec$/scer/ ||
231             $stem =~ s/chec$/shcer/ ||
232             $stem =~ s/mec$/ncer/ ||
233             $stem =~ s/sec$/sher/ ||
234             $stem =~ s/zec$/zher/ ||
235             $stem =~ s/ec$/cer/) {
236 20         38 $table = [ map "$stem$_", @{$endings{C}} ];
  20         192  
237             } else {
238 0         0 return;
239             }
240              
241             # Don't need to shift stress since the ending will always have at least
242             # two vowels
243              
244 78         645 return $table;
245             }
246              
247             my %ctanec = (
248             fassec => [ map "fasst$_", @{$endings{C}} ],
249             dan => [ map "dom$_", @{$endings{N}} ],
250             kies => [ map "kaim$_", @{$endings{N}} ],
251             shushchan => [ map "shushm$_", @{$endings{N}} ],
252             );
253              
254             sub ctanec {
255 21     21 1 63 my $verb = shift;
256 21         33 my $stem = $verb;
257 21         36 my $table;
258 21         29 my $add = 0;
259              
260 21 100       111 return $ctanec{$verb} if exists $ctanec{$verb};
261              
262 17 100       226 if($stem =~ s/($cons[lr])([ea]n|[ie]r|ec)$/$1i$2/) {
263 1         2 $add = 1;
264             }
265              
266 17 100 100     873 if($stem =~ s/ch[ea]n$/dm/ ||
    100 100        
    50 100        
      100        
      100        
      100        
267             $stem =~ s/g[ea]n$/zhm/ ||
268             $stem =~ s/[ea]n$/m/) {
269 7         18 $table = [ map "$stem$_", @{$endings{N}} ];
  7         78  
270             } elsif($stem =~ s/ch[ie]r$/tret/ ||
271             $stem =~ s/m[ie]r$/mbret/ ||
272             $stem =~ s/n[ie]r$/ndret/ ||
273             $stem =~ s/z[ie]r$/dret/ ||
274             $stem =~ s/[ie]r$/ret/) {
275 8         15 $table = [ map "$stem$_", @{$endings{R}} ];
  8         79  
276             } elsif($stem =~ s/ec$/t/) {
277 2         4 $table = [ map "$stem$_", @{$endings{C}} ];
  2         21  
278             } else {
279 0         0 return;
280             }
281              
282 17 100       86 if($add) {
283 1         3 for(@$table) {
284             # replace -VC+[lr]i[mt]VC* with -V'C+[lr]i[nrc]VC*
285 6         104 s{
286             ($vow) # a vowel, which we'll accent (to $1)
287             ( # begin capturing to $2
288             (?:$cons)+ # one or more consonants
289             # (never zero, since otherwise we wouldn't have had
290             # to insert the -i-)
291             [lr] # one of 'l' or 'r'
292             i # the epenthetic -i- which must not receive the stress
293             [mt] # endings are either -m- or -t-
294             # (-ret- already has an extra vowel)
295             $vow # followed by only one (unstressed) vowel
296             m? # and possibly an -m (for the -am -um -om endings
297             # of the Ist person plural)
298             $ # and finally end-of-string
299             ) # end of $2
300             }{$acc{$1}$2}ox;
301             }
302             }
303              
304 17         140 return $table;
305             }
306              
307              
308             my %epesec = (
309             dan => [ map "doncel$_", @{$endings{N}} ],
310             fassec => [ map "fashshel$_", @{$endings{C}} ],
311             kies => [ map "keshel$_", @{$endings{N}} ],
312             );
313              
314             sub epesec {
315 22     22 1 60 my $verb = shift;
316 22         34 my $stem = $verb;
317 22         31 my $table;
318 22         26 my $add = 0;
319              
320 22 100       100 return $epesec{$verb} if exists $epesec{$verb};
321              
322 19 50       223 if($stem =~ s/($cons$cons)([ea]n|[ie]r|ec)$/$1i$2/) {
323 0         0 $add = 1;
324             }
325              
326 19 100 100     616 if($stem =~ s/c[ea]n$/scel/ ||
    100 100        
    50 100        
      100        
      100        
      100        
      100        
      100        
      100        
      100        
      100        
      100        
      100        
      100        
      66        
327             $stem =~ s/ch[ea]n$/shcel/ ||
328             $stem =~ s/m[ea]n$/ncel/ ||
329             $stem =~ s/s[ea]n$/shel/ ||
330             $stem =~ s/z[ea]n$/zhel/ ||
331             $stem =~ s/[ea]n$/cel/) {
332 7         9 $table = [ map "$stem$_", @{$endings{N}} ];
  7         59  
333             } elsif($stem =~ s/c[ie]r$/scel/ ||
334             $stem =~ s/ch[ie]r$/shcel/ ||
335             $stem =~ s/m[ie]r$/ncel/ ||
336             $stem =~ s/s[ie]r$/shel/ ||
337             $stem =~ s/z[ie]r$/zhel/ ||
338             $stem =~ s/[ie]r$/cel/) {
339 6         8 $table = [ map "$stem$_", @{$endings{R}} ];
  6         621  
340             } elsif($stem =~ s/cec$/scel/ ||
341             $stem =~ s/chec$/shcel/ ||
342             $stem =~ s/mec$/ncel/ ||
343             $stem =~ s/sec$/shel/ ||
344             $stem =~ s/zec$/zhel/ ||
345             $stem =~ s/ec$/cel/) {
346 6         12 $table = [ map "$stem$_", @{$endings{C}} ];
  6         59  
347             } else {
348 0         0 return;
349             }
350              
351             # Don't need to shift stress since the ending will always have at least
352             # two vowels
353              
354 19         169 return $table;
355             }
356              
357             sub befel {
358 12     12 1 40 my $verb = shift;
359 12         20 my $stem = $verb;
360              
361 12 100       37 return if $verb eq 'kies'; # has no imperative, according to Mark
362              
363 11 100       69 if($stem =~ m/[ea]n$/) {
    100          
    50          
364 5         8 return [ map "$stem$_", @{$endings{N}} ];
  5         68  
365             } elsif($stem =~ m/[ie]r$/) {
366 3         6 return [ map "$stem$_", @{$endings{R}} ];
  3         599  
367             } elsif($stem =~ m/ec$/) {
368 3         5 return [ map "$stem$_", @{$endings{C}} ];
  3         43  
369             } else {
370 0         0 return;
371             }
372             }
373              
374              
375             # Form the so-called "classical imperative"
376             sub classimp {
377 12     12 1 32 my $verb = shift;
378 12         16 my $stem = $verb;
379              
380 12 100       36 return if $verb eq 'kies'; # has no imperative, according to Mark
381              
382 11 100       106 if($stem =~ s/[ea]n$//) {
    100          
    50          
383 5         42 return [ undef, $stem . 'i', undef, undef, $stem . 'il', undef ];
384             } elsif($stem =~ s/[ie]r$//) {
385 3         25 return [ undef, $stem . 'u', undef, undef, $stem . 'ul', undef ];
386             } elsif($stem =~ s/ec$//) {
387 3         24 return [ undef, $stem . 'e', undef, undef, $stem . 'el', undef ];
388             } else {
389 0         0 return;
390             }
391             }
392              
393              
394             my %part = (
395             dan => [ qw(donec donul donäm ) ],
396             kies => [ qw(kaivec kaivul kaiväm) ],
397             );
398              
399              
400             # Participles
401             sub part {
402 24     24 1 58 my $verb = shift;
403              
404 24         28 my($present, $past, $gerund);
405              
406 24 100       64 if(exists $part{$verb}) {
407 4         8 ($present, $past, $gerund) = @{ $part{$verb} };
  4         18  
408             } else {
409 20 50       87 return unless $verb =~ /(?:ec|[ea]n|[ie]r)$/;
410              
411 20         47 ($present, $past, $gerund) = ($verb) x 3;
412              
413 20         38 for($present) {
414 20 100       124 s/ec$/ë/ || s/(?:[ie]r|[ea]n)$/ec/;
415             }
416              
417 20         34 for($past) {
418 20         80 s/(?:ec|[ea]n|[ie]r)$/ul/;
419             }
420              
421 20         61 for($gerund) {
422 20         76 s/(?:ec|[ea]n|[ie]r)$/äm/;
423             }
424             }
425              
426 24 100       188 return wantarray ? ($present, $past, $gerund) : [ $present, $past, $gerund ];
427             }
428              
429              
430              
431              
432             my %masc = (
433             creza => 1,
434             'Ervëa' => 1,
435             esta => 1,
436             hezhiosa => 1,
437             rhena => 1,
438             didha => 1,
439             vyozha => 1,
440             );
441              
442             sub noun {
443 146     146 1 1239 my $noun = shift;
444 146         245 my $stem = $noun;
445 146         216 my $type = 'fem';
446 146         187 my $table;
447              
448 146 100       561 $type = 'masc' if exists $masc{$noun};
449              
450             # is it the article?
451 146 50       369 return [ qw( so soei so soán soî soië soi soin ) ] if $noun eq 'so';
452 146 50       361 return [ qw( soa soe soa soan soî soië soem soen ) ] if $noun eq 'soa';
453              
454             # is it a personal pronoun?
455 146 100       450 return [ qw( se esë et sen ta taë tam tan ) ] if $noun eq 'se';
456 145 100       325 return [ qw( le lë erh len mu muë mü mun ) ] if $noun eq 'le';
457 144 100       380 return [ qw( ilu lië ilet ilun ca caë cam can ) ] if $noun eq 'ilu';
458 143 100       477 return [ qw( ila liue ilat ilan ca caë cam can ) ] if $noun eq 'ila';
459 142 100       295 return [ qw( il lië iler ilon ca caë cam can ) ] if $noun eq 'il';
460 141 100       337 return [ qw( ze zië zet zen za zaë zam zan ) ] if $noun eq 'ze';
461 140 100       402 return [ qw( tu tuë tu/tü tun ), (undef) x 4 ] if $noun eq 'tu';
462 139 100       283 return [ qw( ta taë tam tan ), (undef) x 4 ] if $noun eq 'ta';
463 138 100       831 return [ qw( mu muë mü mun ), (undef) x 4 ] if $noun eq 'mu';
464 137 100       273 return [ qw( ca caë cam can ), (undef) x 4 ] if $noun eq 'ca';
465 136 100       264 return [ qw( za zaë zam zan ), (undef) x 4 ] if $noun eq 'za';
466              
467             # relative or interrogative pronoun?
468 135 100       1479 if($stem =~ s/^((?:if|nib|ti)?k)e$/$1/) {
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
469 3         55 return [ map "$stem$_", qw( e ë et en aë aëne aëm aën ) ];
470             } elsif($stem =~ s/^((?:if|nib|ti)?ki)o$/$1/) {
471 3         40 return [ ( map "$stem$_", qw( o ei om on ) ), (undef) x 4 ];
472             } elsif($stem =~ s/^((?:nëc|nik|sh|e)t)o$/$1/) {
473 4         84 return [ ( map "$stem$_", qw( o ë o on ) ), (undef) x 4 ];
474             } elsif($noun eq 'tot') {
475 1         9 return [ qw( tot totë tot totán ), (undef) x 4 ];
476             } elsif($noun eq 'fsya') {
477 1         9 return [ qw( fsya fsye fsya fsyan ), (undef) x 4 ];
478             } elsif($stem =~ s/^((?:if|nib|ti)c|kt|fs)ë$/$1/) {
479 5         56 return [ ( map "$stem$_", qw( ë ëi ë ën ) ), (undef) x 4 ];
480             } elsif($noun eq 'zdesy') {
481 1         9 return [ qw( zdesy zdesii zdesy zdesín ), (undef) x 4 ];
482             } elsif($noun eq 'cechel') {
483 1         9 return [ qw( cechel cechelei cechel cechelán ), (undef) x 4 ];
484             } elsif($noun eq 'nish') {
485 1         8 return [ qw( nish nishei nish nishán ), (undef) x 4 ];
486             }
487              
488             # else treat it as a noun.
489              
490             # apparently, -consonant and -a are the most common, so put those
491             # first, followed by the other masculine and then the feminine
492             # declensions
493             # must, however, put '-ia' before '-a' or we'll get confused.
494 115 100 100     1747 if($stem =~ m/[pbtdhcgkfvszmnlr]$/) {
    100 100        
    100 66        
    100 66        
    100 33        
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    50          
    100          
    50          
495 48         436 $table = [ map "$stem$_", '', 'ei', '', 'án', 'î', 'ië', 'i', 'in' ];
496             } elsif($type eq 'fem' && $stem =~ s/ia$//) {
497 5         46 $table = [ map "$stem$_", qw( ia ë iam ian iî ië em en ) ];
498             } elsif($type eq 'fem' && $stem =~ s/a$//) {
499 14         138 $table = [ map "$stem$_", qw( a e a an î ië em en ) ];
500             } elsif($stem =~ s/o$//) {
501 2         17 $table = [ map "$stem$_", qw( o ei am on oi oë om oin ) ];
502             } elsif($stem =~ s/u$//) {
503 2         19 $table = [ map "$stem$_", qw( u ui um un î uë om uin ) ];
504             } elsif($stem =~ s/iy$//) {
505 2         21 $table = [ map "$stem$_", qw( iy ii iim iín iî ië iom iuin ) ];
506             } elsif($stem =~ s/íy$//) {
507 4 100       47 $table = [ map "$stem$_", $keep_accents
508             ? qw( íy íi íim iín íî íë íom íuin )
509             : qw( íy ii iim iín iî íë iom íuin ) ];
510             } elsif($stem =~ s/y$//) {
511 2         16 $table = [ map "$stem$_", qw( y ii im ín î uë om uin ) ];
512             } elsif($type eq 'masc' && $stem =~ s/a$//) {
513 8         70 $table = [ map "$stem$_", qw( a ei a an ai aë am ain ) ];
514             } elsif($stem =~ s/i$//) {
515 2         21 $table = [ map "$stem$_", qw( i ë a in î ië em in ) ];
516             } elsif($stem =~ s/e$//) {
517 2         20 $table = [ map "$stem$_", qw( e ei a en î ië em en ) ];
518             } elsif($stem =~ s/ë$//) {
519 2         21 $table = [ map "$stem$_", qw( ë ëi ä en î ië em en ) ];
520             } elsif($type eq 'fem' && $stem =~ s/á$//) {
521 2         16 $table = [ map "$stem$_", qw( á é á án í ië ém én ) ];
522             } elsif($stem =~ s/ó$//) {
523 8 100       100 $table = [ map "$stem$_", $keep_accents
524             ? qw( ó éi ám ón ói oë óm óin )
525             : qw( ó ei ám ón oi oë óm oin ) ];
526             } elsif($stem =~ s/ú$//) {
527 4 100       67 $table = [ map "$stem$_", $keep_accents
528             ? qw( ú úi úm ún í uë óm úin )
529             : qw( ú ui úm ún í uë óm uin ) ];
530             } elsif($type eq 'masc' && $stem =~ s/á$//) {
531 0 0       0 $table = [ map "$stem$_", $keep_accents
532             ? qw( á éi á án ái aë ám áin )
533             : qw( á ei á án ai aë ám ain ) ];
534             } elsif($stem =~ s/í$//) {
535 1         10 $table = [ map "$stem$_", qw( í ë á ín í ië ém ín ) ];
536             } elsif($stem =~ s/é$//) {
537 7 100       81 $table = [ map "$stem$_", $keep_accents
538             ? qw( é éi á én í ië ém én )
539             : qw( é ei á én í ië ém én ) ];
540             } else {
541 0         0 return;
542             }
543              
544             # remove accents for words ending in án or ín
545             # and put in irregular plurals
546 115         339 for(@$table) {
547 920 100       2329 if(/[áí]n$/) {
548             # remove all accents
549 60         207 tr/áéíóúÁÉÍÓÚ/aeiouAEIOU/;
550             # and put the last one back on
551 60         212 s/an$/án/;
552 60         198 s/in$/ín/;
553             }
554              
555             # c, ca -> s; d -> z; g, ga -> zh; t -> dh or ch or s
556 920         5808 my $c = qr/c(?=(?:î|i[ën]?)$)/;
557 920         2156 my $ca = qr/c(?=(?:î|ië|e[mn])$)/;
558 920         1847 my $d = qr/d(?=(?:î|i[ën]?)$)/;
559 920         2200 my $g = qr/g(?=(?:î|i[ën]?)$)/;
560 920         2380 my $ga = qr/g(?=(?:î|ië|e[mn])$)/;
561 920         1989 my $k = qr/k(?=(?:î|i[ën]?)$)/;
562 920         2044 my $t = qr/t(?=(?:î|i[ën]?)$)/;
563              
564 920 100 100     95049 s/^aklogî$/aklozhi/ ||
      100        
      100        
      100        
      100        
      100        
      100        
      100        
      100        
      100        
      100        
      100        
      100        
      100        
      100        
      100        
      100        
      100        
      100        
      100        
      100        
      100        
      100        
      100        
      100        
      100        
      100        
      100        
      100        
      100        
      100        
      100        
      100        
      100        
      100        
      100        
      100        
      100        
      100        
      100        
      100        
      100        
      100        
      100        
      100        
      100        
      100        
      100        
      100        
      100        
      100        
      100        
      100        
      100        
      100        
      100        
      100        
      100        
      100        
      100        
      100        
565             s/^aklo$g/aklozh/o ||
566             s/^ánselcu$d/ánselcuz/o ||
567             s/^barsú$c/barsús/o ||
568             s/^bela$c/belas/o ||
569             s/^bo$c/bos/o ||
570             s/^brö$ca/brös/o ||
571             s/^bü$t/büs/o ||
572             s/^chedesnagî$/chedesnazhi/ ||
573             s/^chedesna$ga/chedesnazh/o ||
574             s/^chu$ca/chus/o ||
575             s/^dosi$c/dosis/o ||
576             s/^dra$c/dras/o ||
577             s/^dushi$c/dushis/o ||
578             s/^dha$c/dhas/o ||
579             s/^dhie$c/dhies/o ||
580             s/^ecelógî$/ecelózhi/ ||
581             s/^eceló$g/ecelózh/o ||
582             s/^etalógî$/etalózhi/ ||
583             s/^etaló$g/etalózh/o ||
584             s/^feri$ca/feris/o ||
585             s/^fifachi$c/fifachis/o ||
586             s/^formi$ca/formis/o ||
587             s/^glä$ca/gläs/o ||
588             s/^goratî$/goradhi/ ||
589             s/^gora$t/goradh/o ||
590             s/^gra$k/grah/o ||
591             s/^gutî$/gudhi/ ||
592             s/^gu$t/gudh/o ||
593             s/^hu$ca/hus/o ||
594             s/^ktëlogî$/ktëlozhi/ ||
595             s/^ktëlo$g/ktëlozh/o ||
596             s/^ku$d/kuz/o ||
597             s/^lertlogî$/lertlozhi/ ||
598             s/^lertlo$g/lertlozh/o ||
599             s/^logî$/lozhi/ ||
600             s/^lo$g/lozh/o ||
601             s/^mati$ca/matis/o ||
602             s/^me$ca/mes/o ||
603             s/^mevlogî$/mevlozhi/ ||
604             s/^mevlo$g/mevlozh/o ||
605             s/^morutî$/morudhi/ ||
606             s/^moru$t/morudh/o ||
607             s/^nagî$/nazhi/ ||
608             s/^na$ga/nazh/o ||
609             s/^ni$d/niz/o ||
610             s/^pagî$/pazhi/ ||
611             s/^pa$g/pazh/o ||
612             s/^prologî$/prolozhi/ ||
613             s/^prolo$g/prolozh/o ||
614             s/^ra$k/rah/o ||
615             s/^rogî$/rozhi/ ||
616             s/^ro$g/rozh/o ||
617             s/^rhitî$/rhichi/ ||
618             s/^rhi$t/rhich/o ||
619             s/^sfi$ca/sfis/o ||
620             s/^shan$k/shanh/o ||
621             s/^smeri$c/smeris/o ||
622             s/^veratî$/veradhi/ ||
623             s/^vera$t/veradh/o ||
624             s/^yagî$/yazhi/ ||
625             s/^ya$g/yazh/o ||
626             1;
627              
628 920 100       4965 if(! $keep_accents) {
629             # remove unnecessary accents: if the accented vowel is
630             # the penultimate vowel and the last vowel is not umlauted
631 80         462 s/([áéíóúÁÉÍÓÚ])(?=[pbtdhcgkfvszmnlr]*[aeiouî][pbtdhcgkfvszmnlr]*$)/$unacc{$1}/;
632             }
633             }
634              
635 115         1068 return $table;
636             }
637              
638              
639             sub adj {
640 9     9 1 40 my $adj = shift;
641 9         22 my $stem = $adj;
642 9         16 my $table;
643              
644 9 100 100     707 if($stem =~ m/[pbtdhcgkfvszmnlr]$/ || $stem eq 'so') {
    100          
    100          
    50          
645 2         43 $table = [ [ map "$stem$_", '', 'ei', '', 'án', 'î', 'ië', 'i', 'in' ],
646             [ map "$stem$_", qw( a e a an î ië em en ) ] ];
647             } elsif($stem =~ s/e$//) {
648 1         16 $table = [ [ map "$stem$_", qw( e ei em en î eë em ein ) ],
649             [ map "$stem$_", qw( ë ëi ä en î ië em en ) ] ];
650             } elsif($stem =~ s/y$//) {
651 1         17 $table = [ [ map "$stem$_", qw( y ii im ín î uë om uin ) ],
652             [ map "$stem$_", qw( y ye ya yan î yië yem yen ) ] ];
653             } elsif($stem =~ s/ë$//) {
654 5         117 $table = [ [ map "$stem$_", qw( ë ëi ä én ëi ëë óm ëin ) ],
655             [ map "$stem$_", qw( a e a an î ië em en ) ] ];
656             } else {
657 0         0 return;
658             }
659              
660             # remove accents for words ending in án or ín or én or óm
661 9         41 for(@$table) {
662 18         219 for(@$_) {
663 144 100 100     940 if(/[áíé]n$/ || /óm$/) {
664             # remove all accents
665 13         68 tr/áéíóú/aeiou/;
666             # and put the last one back on
667 13         31 s/an$/án/;
668 13         21 s/in$/ín/;
669 13         38 s/en$/én/;
670 13         31 s/om$/óm/;
671             }
672              
673 144 100       5605 if(! $keep_accents) {
674             # remove unnecessary accents: if the accented vowel is
675             # the penultimate vowel and the last vowel is not umlauted
676 16         77 s/([áéíóúÁÉÍÓÚ])(?=[pbtdhcgkfvszmnlr]*[aeiouî][pbtdhcgkfvszmnlr]*$)/$unacc{$1}/;
677             }
678             }
679             }
680              
681 9         136 return $table;
682             }
683              
684              
685             1;
686             __END__