File Coverage

blib/lib/Lingua/LO/NLP/Romanize/IPA.pm
Criterion Covered Total %
statement 41 41 100.0
branch 4 4 100.0
condition n/a
subroutine 14 14 100.0
pod 2 2 100.0
total 61 61 100.0


line stmt bran cond sub pod time code
1             package Lingua::LO::NLP::Romanize::IPA;
2 1     1   7 use strict;
  1         4  
  1         42  
3 1     1   7 use warnings;
  1         3  
  1         32  
4 1     1   21 use 5.012000;
  1         4  
5 1     1   8 use utf8;
  1         3  
  1         7  
6 1     1   45 use feature qw/ unicode_strings say /;
  1         3  
  1         117  
7 1     1   9 use charnames qw/ :full lao /;
  1         2  
  1         8  
8 1     1   546 use version 0.77; our $VERSION = version->declare('v1.0.1');
  1         19  
  1         6  
9 1     1   82 use Carp;
  1         2  
  1         48  
10 1     1   299 use Lingua::LO::NLP::Analyze;
  1         3  
  1         6  
11 1     1   43 use parent 'Lingua::LO::NLP::Romanize::PCGN';
  1         2  
  1         4  
12              
13             =encoding utf8
14              
15             =head1 NAME
16              
17             Lingua::LO::NLP::Romanize::IPA - Convert Lao syllables to the International Phonetic Alphabet
18              
19             =head1 FUNCTION
20              
21             This class is not supposed to be used directly. Rather use
22             L as a factory:
23              
24             my $o = Lingua::LO::NLP::Romanize->new(variant => 'IPA');
25              
26             =cut
27              
28             my %CONSONANTS = (
29             'ກ' => 'k', # TODO: split /g/+/k/ here?
30             'ຂ' => [qw/ kʰ k /],
31             'ຄ' => [qw/ kʰ k /],
32             'ງ' => 'ŋ',
33             'ຈ' => [qw/ tɕ t /],
34             'ສ' => [qw/ s t /],
35             'ຊ' => [qw/ s t /],
36             'ຍ' => 'ɲ',
37             'ດ' => [qw/ d t /],
38             'ຕ' => 't',
39             'ຖ' => [qw/ tʰ t /],
40             'ທ' => [qw/ tʰ t /],
41             'ນ' => 'n',
42             'ບ' => [qw/ b p /],
43             'ປ' => 'p',
44             'ຜ' => 'pʰ',
45             'ຝ' => [qw/ f p /],
46             'ພ' => [qw/ pʰ p /],
47             'ຟ' => [qw/ f p /],
48             'ມ' => 'm',
49             'ຢ' => 'j',
50             'ລ' => 'l',
51             "\N{LAO SEMIVOWEL SIGN LO}" => 'l',
52             'ວ' => [qw/ ʋ w /],
53             'ຫ' => 'h',
54             'ອ' => 'ʔ',
55             'ຮ' => 'h',
56             'ຣ' => 'r', # TODO l?
57             'ໜ' => 'n',
58             'ໝ' => 'm',
59             'ຫຼ' => 'l',
60             'ຫຍ' => 'ɲ',
61             'ຫນ' => 'n',
62             'ຫມ' => 'm',
63             'ຫຣ' => 'r', # TODO l?
64             'ຫລ' => 'l',
65             'ຫວ' => 'w', # TODO ʋ?
66             );
67              
68             my %VOWELS = (
69             ### Monophthongs
70             'Xະ' => 'aʔ',
71             'Xັ' => 'a',
72             'Xາ' => 'aː',
73             'Xາວ' => 'aːo',
74              
75             'Xິ' => 'i',
76             'Xີ' => 'iː',
77             'Xິວ' => 'iu', # TODO correct?
78             'Xີວ' => 'iːu', # TODO correct?
79              
80             'Xຶ' => 'ɯ',
81             'Xື' => 'ɯː',
82              
83             'Xຸ' => 'u',
84             'Xູ' => 'uː',
85              
86             'ເXະ' => 'eʔ',
87             'ເXັ' => 'e',
88             'ເX' => 'eː',
89              
90             'ແXະ' => 'ɛʔ',
91             'ແXັ' => 'ɛ',
92             'ແX' => 'ɛː',
93             'ແXວ' => 'ɛːo',
94              
95             'ໂXະ' => 'oʔ',
96             'Xົ' => 'o',
97             'ໂX' => 'oː',
98             'ໂXຍ' => 'oːi', # TODO correct?
99             'Xອຍ' => 'oːi',
100              
101             'ເXາະ' => 'ɔʔ',
102             'Xັອ' => 'ɔ',
103             'Xໍ' => 'ɔː',
104             'Xອ' => 'ɔː',
105              
106             'ເXິ' => 'ɤ',
107             'ເXີ' => 'ɤː',
108             'ເXື' => 'ɯːə', # TODO correct?
109              
110             'ເXັຍ' => 'iə',
111             'Xັຽ' => 'iə',
112             'ເXຍ' => 'iːə',
113             'Xຽ' => 'iːə',
114             'Xຽວ' => 'iːəo', # TODO correct?
115              
116             'ເXີຍ' => 'ɤːi',
117             'ເXິຍ' => 'ɤi',
118              
119             'ເXຶອ' => 'ɯə',
120             'ເXືອ' => 'ɯːə',
121             'ເXືອຍ' => 'ɯːəi',
122              
123             'Xົວະ' => 'uəʔ',
124             'Xົວ' => 'uːə',
125             'Xວ' => 'uːə',
126             'Xວຍ' => 'uːəi',
127              
128             'ໄX' => 'aj',
129             'ໃX' => 'aj',
130             'Xາຍ' => 'aːj',
131             'Xັຍ' => 'aj',
132              
133             'ເXົາ' => 'aw',
134             'Xຳ' => 'am', # composed U+0EB3
135             'Xໍາ' => 'am',
136             );
137             {
138             # Replace "X" in %VOWELS keys with DOTTED CIRCLE. Makes code easier to edit.
139             my %v;
140             foreach my $v (keys %VOWELS) {
141             (my $w = $v) =~ s/X/\N{DOTTED CIRCLE}/;
142             $v{$w} = $VOWELS{$v};
143             }
144             %VOWELS = %v;
145             }
146              
147             my %TONE_DIACRITICS = (
148             LOW => "\N{COMBINING GRAVE ACCENT}",
149             MID => "\N{COMBINING MACRON}", MID_STOP => "\N{COMBINING MACRON}",
150             HIGH => "\N{COMBINING ACUTE ACCENT}", HIGH_STOP => "\N{COMBINING ACUTE ACCENT}",
151             RISING => "\N{COMBINING CARON}",
152             HIGH_FALLING => "\N{COMBINING CIRCUMFLEX ACCENT}",
153             MID_FALLING => "\N{COMBINING CIRCUMFLEX ACCENT BELOW}",
154             );
155              
156             =head2 new
157              
158             You don't call this constructor directly but via L.
159             It adds the following attribute:
160              
161             =over 4
162              
163             =item C: boolean indicating whether to add dicacritics for tone
164              
165             =back
166              
167             =cut
168              
169             sub new {
170 2     2 1 5 my ($class, %args) = @_;
171 2         4 my $self = bless {}, $class;
172 2 100       12 $self->{romanize_vowel} = $args{tone} ? \&_vowel_with_tone : \&_vowel_without_tone;
173 2         6 return $self;
174             }
175              
176             sub _vowel_with_tone {
177 14     14   52 my ($lao_vowel, $tone) = @_;
178 14         19 my $vowel = $VOWELS{ $lao_vowel };
179             # Insert tone diacritic after first character
180 14         48 substr($vowel, 1, 0) = $TONE_DIACRITICS{ $tone };
181 14         32 return $vowel;
182             }
183              
184 14     14   61 sub _vowel_without_tone { return $VOWELS{ $_[0] } }
185              
186             =head2 romanize_consonant
187              
188             Overrides L to access
189             module-local data.
190              
191             =cut
192              
193             sub romanize_consonant {
194 36     36 1 57 my (undef, $cons, $position) = @_;
195 36         59 my $consdata = $CONSONANTS{ $cons };
196 36 100       91 return ref $consdata ? $consdata->[$position] : $consdata;
197             }
198              
199             1;
200