File Coverage

blib/lib/Lingua/ZH/CCDICT/Romanization/Pinyin.pm
Criterion Covered Total %
statement 43 43 100.0
branch 18 20 90.0
condition 6 6 100.0
subroutine 8 8 100.0
pod 2 3 66.6
total 77 80 96.2


line stmt bran cond sub pod time code
1             package Lingua::ZH::CCDICT::Romanization::Pinyin;
2              
3 1     1   5 use strict;
  1         2  
  1         31  
4 1     1   5 use warnings;
  1         1  
  1         25  
5              
6 1     1   5 use base 'Lingua::ZH::CCDICT::Romanization';
  1         1  
  1         1205  
7              
8             my $umlaut_u = chr(252);
9              
10             my %PinyinUnicode =
11             ( a1 => chr(257),
12             e1 => chr(275),
13             i1 => chr(299),
14             o1 => chr(333),
15             u1 => chr(363),
16             "${umlaut_u}1" => chr(470),
17              
18             a2 => chr(225),
19             e2 => chr(233),
20             i2 => chr(237),
21             o2 => chr(243),
22             u2 => chr(250),
23             "${umlaut_u}2" => chr(472),
24              
25             a3 => chr(462),
26             e3 => chr(283),
27             i3 => chr(464),
28             o3 => chr(466),
29             u3 => chr(468),
30             "${umlaut_u}3" => chr(474),
31              
32             a4 => chr(224),
33             e4 => chr(232),
34             i4 => chr(236),
35             o4 => chr(242),
36             u4 => chr(249),
37             "${umlaut_u}4" => chr(476),
38             );
39              
40              
41             sub new
42             {
43 47737     47737 0 217122 my $self = shift->SUPER::new(@_);
44              
45             # handle errors found in parent class
46 47737 100       130526 return unless defined $self->{syllable};
47              
48             # there are a bunch of lX, mX, and nX, as well as one ng3
49 47734 100       135235 return if $self->{syllable} =~ /^(?:l|m|n|ng)\d$/;
50              
51 47615         89856 $self->{ascii} = $self->{syllable};
52 47615         85629 $self->{syllable} =~ s/uu/$umlaut_u/g;
53              
54 47615         117510 $self->_make_unicode_version();
55              
56 47615         110617 return $self;
57             }
58              
59 2     2 1 12 sub as_ascii { $_[0]->{ascii} }
60              
61             sub _make_unicode_version
62             {
63 47615     47615   55539 my $self = shift;
64              
65 47615         210573 my @syls = split /(?<=\d)/, $self->{syllable};
66              
67 47673         91521 $self->{pinyin_unicode} =
68 47615         107652 join '', map { $self->_pinyin_as_unicode($_) } @syls;
69              
70 47615         87235 return $self;
71             }
72              
73             sub _pinyin_as_unicode
74             {
75 47673     47673   54124 my $self = shift;
76 47673         62946 my $syl = shift;
77              
78 47673         87702 my $num = chop $syl;
79              
80 47673 100       167537 unless ( $num =~ /[12345]/ )
81             {
82 1 50       6 warn "Bad pinyin (tone): $self->{syllable}\n" if $ENV{DEBUG_CCDICT_SOURCE};
83 1         4 return;
84             }
85              
86             # no tone marking
87 47672 100       146224 return $syl if $num == 5;
88              
89 47539         133160 my @letters = split //, $syl;
90              
91 47539         60017 my $vowel_to_change;
92 47539         118871 for ( my $x = 0; $x <= $#letters; $x++ )
93             {
94 100879 100       509143 if ( $letters[$x] =~ /[aeiou$umlaut_u]/ )
95             {
96 47538         65954 $vowel_to_change = $x;
97 47538         75383 last;
98             }
99             }
100              
101 47539 100       95455 unless ( defined $vowel_to_change )
102             {
103 1 50       5 warn "Bad pinyin (no vowel to mark): $self->{syllable}\n" if $ENV{DEBUG_CCDICT_SOURCE};
104 1         5 return;
105             }
106              
107 47538 100 100     282151 if ( $letters[$vowel_to_change + 1] &&
108             $letters[$vowel_to_change + 1] =~ /[aeiou$umlaut_u]/ )
109             {
110             # handle multiple vowels properly
111 18939 100 100     89572 $vowel_to_change++
112             unless ( $letters[$vowel_to_change + 1] eq 'u' ||
113             $letters[$vowel_to_change + 1] eq 'o' );
114             }
115              
116 47538         134373 $letters[$vowel_to_change] = $PinyinUnicode{ $letters[$vowel_to_change] . $num };
117              
118 47538         262424 return join '', @letters;
119             }
120              
121 3     3 1 17 sub as_unicode { $_[0]->{pinyin_unicode} }
122              
123              
124             1;
125              
126             __END__