File Coverage

blib/lib/Lingua/IT/Ita2heb/LettersSeq/IT/ToHeb.pm
Criterion Covered Total %
statement 16 18 88.8
branch n/a
condition n/a
subroutine 6 6 100.0
pod n/a
total 22 24 91.6


line stmt bran cond sub pod time code
1             package Lingua::IT::Ita2heb::LettersSeq::IT::ToHeb;
2              
3 1     1   27 use 5.010;
  1         4  
  1         45  
4 1     1   7 use strict;
  1         1  
  1         36  
5 1     1   6 use warnings;
  1         2  
  1         37  
6              
7 1     1   6 use Carp;
  1         2  
  1         85  
8 1     1   6 use Readonly;
  1         2  
  1         49  
9              
10 1     1   626 use Moose;
  0            
  0            
11              
12             extends(
13             'Lingua::IT::Ita2heb::LettersSeq::IT'
14             );
15              
16             with( 'Lingua::IT::Ita2heb::Role::Constants::Hebrew' );
17              
18             has total_text =>
19             (
20             is => 'ro',
21             isa => 'Str',
22             traits => ['String'],
23             default => q{},
24             handles =>
25             {
26             main_add => 'append',
27             },
28             );
29              
30             has next_letter_error_code =>
31             (
32             is => 'ro',
33             isa => 'Str',
34             default => 'NEXT_LETTER',
35             );
36              
37             has all_hebrew_vowels =>
38             (
39             is => 'ro',
40             isa => 'ArrayRef[Str]',
41             lazy_build => 1,
42             );
43              
44             has disable_rafe => (
45             is => 'ro',
46             isa => 'Bool',
47             );
48              
49             has ascii_geresh => (
50             is => 'ro',
51             isa => 'Bool',
52             );
53              
54             has ascii_maqaf => (
55             is => 'ro',
56             isa => 'Bool',
57             );
58              
59             has disable_dagesh => (
60             is => 'ro',
61             isa => 'Bool',
62             traits => ['Bool'],
63             handles => {
64             dagesh_enabled => 'not',
65             },
66             );
67              
68             has '_simple_trs' => (
69             is => 'ro',
70             isa => 'HashRef[Str]',
71             lazy_build => 1,
72             );
73              
74             sub _build__simple_trs {
75             my $seq = shift;
76              
77             return +{
78             'b' => $seq->heb('BET'),
79             'd' => $seq->heb('DALET'),
80             (map { $_ => $seq->heb('SEGOL') } @{$seq->types_of_e}),
81             'k' => $seq->heb('QOF'),
82             'l' => $seq->heb('LAMED'),
83             (map { $_ => $seq->heb('HOLAM_MALE') } @{$seq->types_of_o}),
84             'p' => $seq->heb('PE'),
85             'r' => $seq->heb('RESH'),
86             't' => $seq->heb('TET'),
87             'x' => $seq->heb('SHIN'), # This isn't right, of course
88             };
89             }
90              
91             has special_words => (
92             is => 'ro',
93             isa => 'HashRef[Str]',
94             );
95              
96             sub _build_special_words {
97             my ($seq) = @_;
98              
99             return {
100             Roma => $seq->heb('RESH,VAV,HOLAM,MEM,QAMATS,ALEF'),
101             };
102             }
103              
104             has _geresh => (
105             is => 'ro',
106             isa => 'Str',
107             lazy_build => 1,
108             );
109              
110             sub _build__geresh {
111             my ($seq) = @_;
112              
113             return $seq->ascii_geresh ? q{'} : $seq->heb('TRUE_GERESH');
114             }
115              
116             has handled_letters => (
117             isa => 'HashRef[Str]',
118             is => 'ro',
119             lazy_build => 1,
120             );
121              
122             sub _build_handled_letters {
123             my $seq = shift;
124              
125             return +{ (map { $_ => "_handle_letter_$_" } qw(c f g h m n q s v z)),
126             (map { $_ => "_handle_letter_a" } @{$seq->types_of_a}),
127             (map { $_ => "_handle_letter_i" } @{$seq->types_of_i}),
128             (map { $_ => "_handle_letter_u" } @{$seq->types_of_u}),
129             (map { $_ => "_handle_simple_tr_letter" }
130             keys(%{$seq->_simple_trs})
131             ),
132             };
133             }
134              
135             sub _build_all_hebrew_vowels {
136             my ($self) = @_;
137             return [ $self->list_heb( qw( QAMATS HATAF_QAMATS PATAH HATAF_PATAH
138             TSERE SEGOL HATAF_SEGOL HIRIQ HIRIQ_MALE HOLAM HOLAM_MALE QUBUTS SHURUK)
139             ) ];
140             }
141              
142             sub add_heb_final {
143             my ($seq, @args) = @_;
144              
145             return $seq->add_final(map { $seq->heb($_) } @args);
146             }
147              
148             sub add_heb {
149             my ($seq, $latinized_spec) = @_;
150              
151             return $seq->add( $seq->heb( $latinized_spec ) );
152             }
153              
154             sub _main_add_heb {
155             my ($seq, $latinized_spec) = @_;
156              
157             return $seq->main_add( $seq->heb( $latinized_spec ) );
158             }
159              
160             sub handle_letter {
161             my ($seq, $letter) = @_;
162              
163             my $meth = $seq->handled_letters->{$letter};
164              
165             return $seq->$meth($letter);
166             }
167              
168             sub _handle_simple_tr_letter {
169             my ($seq, $letter) = @_;
170              
171             $seq->add( $seq->_simple_trs->{$letter} );
172              
173             return;
174             }
175              
176             sub _handle_letter_a {
177             my ($seq) = @_;
178              
179             $seq->add_heb($seq->closed_syllable ? 'PATAH' : 'QAMATS');
180              
181             return;
182             }
183              
184             sub _handle_letter_c {
185             my ($seq) = @_;
186              
187             if (
188             not( $seq->match_before([['s']])
189             and $seq->match_cg_mod_after([]))
190             )
191             {
192             $seq->add_heb(
193             $seq->set_optional_cg_geresh([['c']]) ? 'TSADI' : 'QOF'
194             );
195             }
196            
197             return;
198             }
199              
200             sub _handle_letter_f {
201             my ($seq) = @_;
202              
203             if (! $seq->add_heb_final('PE', 'FINAL_PE')) {
204             if ($seq->at_start and not $seq->disable_rafe)
205             {
206             $seq->add_heb('RAFE');
207             }
208             }
209              
210             return;
211             }
212              
213             sub _handle_letter_g {
214             my ($seq) = @_;
215              
216             $seq->set_optional_cg_geresh([['g']]);
217              
218             if ($seq->match_after([['n']]))
219             {
220             $seq->add_heb('NUN,SHEVA,YOD');
221             }
222             elsif (
223             not(
224             $seq->after_start
225             and $seq->match_after([['l']])
226             )
227             )
228             {
229             $seq->add_heb('GIMEL');
230             }
231              
232             return;
233             }
234              
235             sub _handle_letter_h {
236             return; # Niente.
237             }
238              
239             sub _handle_letter_i {
240             my ($seq) = @_;
241              
242             if ( # No [i] in sci, except end of word
243             not(
244             $seq->before_end
245             and $seq->match_before([['s'],['c']])
246             )
247             )
248             {
249             if ($seq->should_add_geresh) {
250             if (not $seq->match_vowel_after )
251             {
252             $seq->add_heb('HIRIQ')
253             }
254             }
255             elsif ($seq->match_vowel_after)
256             {
257             if ( $seq->at_start
258             or $seq->match_vowel_before) {
259             $seq->add_heb('YOD')
260             }
261             else {
262             $seq->add_heb('SHEVA,YOD')
263             }
264             }
265             else {
266             $seq->add_heb('HIRIQ_MALE')
267             }
268             }
269              
270             return;
271             }
272              
273             sub _handle_letter_n {
274             my ($seq) = @_;
275              
276             if ( $seq->match_before([['g']]) )
277             {
278             return $seq->next_letter_error_code;
279             }
280              
281             $seq->add_heb_final('NUN', 'FINAL_NUN');
282              
283             return;
284             }
285              
286             sub _handle_letter_m {
287             my ($seq) = @_;
288              
289             $seq->add_heb_final('MEM', 'FINAL_MEM');
290              
291             return;
292             }
293              
294             sub _handle_letter_q {
295             my ($seq) = @_;
296              
297             if ( $seq->match_before([['c']]) )
298             {
299             if ($seq->dagesh_enabled) {
300             $seq->add_heb('DAGESH');
301             }
302             }
303             else {
304             $seq->add_heb('QOF');
305             }
306              
307             $seq->add_heb('SHEVA,VAV');
308              
309             return;
310             }
311              
312             sub _handle_letter_s {
313             my ($seq) = @_;
314              
315             if ( $seq->match_vowel_before
316             and $seq->match_vowel_after
317             )
318             {
319             $seq->add_heb('ZAYIN');
320             }
321             elsif ($seq->match_cg_mod_after([['c']]))
322             {
323             $seq->add_heb('SHIN');
324             }
325             else {
326             $seq->add_heb('SAMEKH');
327             }
328              
329             return;
330             }
331              
332             sub _handle_letter_u {
333             my ($seq) = @_;
334              
335             if ($seq->match_before([['q']]))
336             {
337             return $seq->next_letter_error_code;
338             }
339             else {
340             $seq->add_heb('SHURUK');
341             }
342              
343             return;
344             }
345              
346             sub _handle_letter_v {
347             my ($seq) = @_;
348              
349             $seq->add_heb($seq->does_v_require_bet ? 'BET' : 'VAV');
350              
351             return;
352             }
353              
354             sub _handle_letter_z {
355             my ($seq) = @_;
356              
357             if ($seq->at_start) {
358             $seq->add_heb('DALET,DAGESH,SHEVA,ZAYIN');
359             }
360             else {
361             $seq->add_heb_final('TSADI', 'FINAL_TSADI');
362             }
363              
364             return;
365             }
366              
367             {
368             my %map = (map { $_ => 1 } qw(b p));
369              
370             sub requires_dagesh_phonetic {
371             my ($seq) = @_;
372              
373             return exists($map{$seq->current});
374             }
375             }
376              
377             sub _to_add_in {
378             my ($seq, $letters_aref) = @_;
379              
380             return ($seq->text_to_add ~~ $letters_aref);
381             }
382              
383             {
384             # Dagesh qal.
385             # BET and PE must not change according to these rules in transliterated
386             # Italian and KAF and TAV are not needed in Italian at all.
387             # Dagesh qal in GIMEL and DALET is totally artificial, but it's part
388             # of the standard...
389              
390             my @REQUIRES_DAGESH_LENE = __PACKAGE__->list_heb( qw(GIMEL DALET) );
391              
392             sub text_to_add_requires_dagesh_lene {
393             return shift->_to_add_in(\@REQUIRES_DAGESH_LENE);
394             }
395             }
396              
397             sub should_add_dagesh {
398             my ($seq) = @_;
399              
400             return
401             (
402             $seq->requires_dagesh_phonetic
403             or
404             ($seq->geminated and $seq->dagesh_enabled) # Dagesh geminating
405             or
406             (
407             (not $seq->match_vowel_before)
408             and $seq->text_to_add_requires_dagesh_lene
409             and (not $seq->requires_dagesh_phonetic)
410             )
411             );
412             }
413              
414             sub add_dagesh_if_needed {
415             my ($seq) = @_;
416              
417             if ( $seq->should_add_dagesh )
418             {
419             if (! $seq->_to_add_in([$seq->heb('RESH')])) {
420             $seq->add_heb('DAGESH');
421             }
422              
423             $seq->unset_geminated;
424             }
425              
426             return;
427             }
428              
429             sub _add_geresh_cond {
430             my ($seq, $letters_aref) = @_;
431              
432             return ($seq->should_add_geresh and $seq->_to_add_in($letters_aref));
433             }
434              
435             sub perform_switch {
436             my ($seq) = @_;
437              
438             my $letter = $seq->current;
439              
440             if ( exists($seq->handled_letters->{$letter}) ) {
441             if (defined ( my $error_code = $seq->handle_letter($letter) ) ) {
442             return $error_code;
443             }
444             }
445             else {
446             $seq->add(q{?});
447             carp('Unknown letter ' . $seq->current . ' in the source.');
448             }
449              
450             return;
451             }
452              
453             sub _add_geresh_to_text {
454             my ($seq) = @_;
455              
456             $seq->main_add( $seq->_geresh );
457              
458             return;
459             }
460              
461             sub _before_geresh_helper {
462             my ($seq) = @_;
463              
464             if ($seq->_to_add_in([$seq->heb('HIRIQ')])) {
465             $seq->_main_add_heb( 'YOD' );
466             }
467              
468             return;
469             }
470              
471              
472             sub _on_geresh {
473             my ($seq, $letters_aref, $callback) = @_;
474              
475             if ($seq->_add_geresh_cond($letters_aref)) {
476             $seq->_add_geresh_to_text;
477             $seq->unset_add_geresh;
478              
479             $seq->$callback();
480             }
481              
482             return;
483             }
484              
485             {
486             my @VOWEL_AFTER_GERESH = __PACKAGE__->list_heb( qw(HOLAM_MALE SHURUK) );
487              
488             my @VOWEL_BEFORE_GERESH = __PACKAGE__->list_heb(
489             qw(QAMATS PATAH TSERE SEGOL HIRIQ)
490             );
491              
492             sub after_switch {
493             my ($seq) = @_;
494              
495             $seq->add_dagesh_if_needed;
496              
497             $seq->_on_geresh(\@VOWEL_AFTER_GERESH, sub { return; },);
498              
499             $seq->main_add( $seq->text_to_add );
500              
501             if ($seq->should_add_sheva)
502             {
503             $seq->_main_add_heb( 'SHEVA' );
504             }
505              
506             $seq->_on_geresh(\@VOWEL_BEFORE_GERESH, '_before_geresh_helper');
507              
508             if ($seq->at_end) {
509             if ($seq->_to_add_in([ $seq->list_heb(qw(QAMATS SEGOL))])) {
510             $seq->_main_add_heb( 'HE' );
511             }
512             }
513              
514             if ($seq->_to_add_in($seq->all_hebrew_vowels)) {
515             $seq->set_wrote_vowel;
516             }
517              
518             return;
519             }
520             }
521              
522             sub before_switch {
523             my ($seq) = @_;
524              
525             if ($seq->should_add_alef)
526             {
527             $seq->_main_add_heb( 'ALEF' );
528             }
529              
530             if ($seq->try_geminated)
531             {
532             return $seq->next_letter_error_code;
533             }
534              
535             $seq->unset_wrote_vowel;
536              
537             return;
538             }
539              
540             sub main_loop {
541             my ($seq) = @_;
542            
543             ITA_LETTER:
544             while (defined($seq->next_index)) {
545             foreach my $method (qw(before_switch perform_switch after_switch)) {
546             if (defined ( my $error_code = $seq->$method() ) ) {
547             if ($error_code eq $seq->next_letter_error_code()) {
548             next ITA_LETTER;
549             }
550             }
551             }
552             }
553              
554             return;
555             }
556              
557             sub maqaf {
558             my ($seq) = @_;
559              
560             return $seq->ascii_maqaf ? q{-} : $seq->heb('TRUE_MAQAF');
561             }
562              
563             1; # End of Lingua::IT::Ita2heb::LettersSeq::IT::ToHeb
564              
565             __END__
566              
567             =head1 NAME
568              
569             Lingua::IT::Ita2heb::LettersSeq::IT::ToHeb - Italian-to-Hebrew specific
570             subclass of Lingua::IT::Ita2heb::LettersSeq::IT
571              
572             =head1 DESCRIPTION
573              
574             A converter of letters from Italian to Hebrew.
575              
576             =head1 VERSION
577              
578             Version 0.01
579              
580             =head1 SYNOPSIS
581              
582             use Lingua::IT::Ita2heb::LettersSeq::IT::ToHeb;
583              
584             my $seq = Lingua::IT::Ita2heb::LettersSeq::IT::ToHeb->new(
585             {
586             ita_letters => \@ita_letters,
587             disable_rafe => ($option{disable_rafe} ? 1 : 0),
588             disable_dagesh => ($option{disable_dagesh} ? 1 : 0),
589             }
590             );
591              
592             =head1 METHODS
593              
594             =head2 $seq->all_hebrew_vowels()
595              
596             Returns an array ref of all Hebrew vowels.
597              
598              
599             =head2 $seq->add_heb_final($non_final, $final)
600              
601             Adds the Hebrew as given by $non_final and $final by first calling
602             C<< ->heb() >> on them.
603              
604             =head2 $seq->add_heb($latinized_spec)
605              
606             Adds the Hebrew Latinized spec $latinized_spec after converting it to the
607             Hebrew glyphs.
608              
609             =head2 $seq->dagesh_enabled
610              
611             The opposite of $seq->disable_dagesh .
612              
613             =head2 $seq->handled_letters()
614              
615             Returns a lookup table of the letters that the object can handle.
616              
617             =head2 $seq->handle_letter($letter)
618              
619             Handles the Latin letter $letter.
620              
621             =head2 $seq->requires_dagesh_phonetic()
622              
623             Whether the current letter requires a dagesh phonetic (b or p).
624              
625             =head2 $seq->text_to_add_requires_dagesh_lene()
626              
627             =head2 $seq->should_add_dagesh()
628              
629             This predicate determines if a dagesh is needed to be added after the current
630             letter.
631              
632             =head2 $seq->add_dagesh_if_needed()
633              
634             determines if a dagesh is needed and if so adds it.
635              
636             =head2 $seq->before_switch()
637              
638             do all the relevant operations before the given/when on the $ita_letter .
639              
640             =head2 $seq->perform_switch()
641              
642             Perform the switch itself.
643              
644             =head2 $seq->after_switch()
645              
646             Do all the relevant operations after the given/when on the $ita_letter .
647              
648             =head2 $seq->main_loop()
649              
650             Loop over the letters and process them.
651              
652             =head2 $seq->maqaf()
653              
654             Returns the Maqaf that should be used according to the options.
655              
656             =head1 SUPPORT
657              
658             You can find documentation for this module with the perldoc command.
659              
660             perldoc Lingua::IT::Ita2heb::LettersSeq::IT
661              
662             You can also look for information at:
663              
664             =over
665              
666             =item * RT: CPAN's request tracker
667              
668             L<http://rt.cpan.org/NoAuth/Bugs.html?Dist=Lingua-IT-Ita2heb>
669              
670             =item * AnnoCPAN: Annotated CPAN documentation
671              
672             L<http://annocpan.org/dist/Lingua-IT-Ita2heb>
673              
674             =item * CPAN Ratings
675              
676             L<http://cpanratings.perl.org/d/Lingua-IT-Ita2heb>
677              
678             =item * Search CPAN
679              
680             L<http://search.cpan.org/dist/Lingua-IT-Ita2heb/>
681              
682             =back
683              
684             =head1 LICENSE AND COPYRIGHT
685              
686             Copyright 2011 Amir E. Aharoni.
687              
688             This program is free software; you can redistribute it and
689             modify it under the terms of either:
690              
691             =over
692              
693             =item * the GNU General Public License version 3 as published
694             by the Free Software Foundation.
695              
696             =item * or the Artistic License version 2.0.
697              
698             =back
699              
700             See http://dev.perl.org/licenses/ for more information.
701              
702             =head1 AUTHOR
703              
704             Amir E. Aharoni, C<< <amir.aharoni at mail.huji.ac.il> >>
705             and Shlomi Fish ( L<http://www.shlomifish.org/> ).
706              
707             =cut