This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
636b8a878d1f742be22290af8d296550d54afee0
[perl5.git] / cpan / Unicode-Collate / Collate / Locale.pm
1 package Unicode::Collate::Locale;
2
3 use strict;
4 use Carp;
5 use base qw(Unicode::Collate);
6
7 our $VERSION = '0.93';
8
9 my $PL_EXT  = '.pl';
10
11 my %LocaleFile = map { ($_, $_) } qw(
12    af ar as az be bg bn ca cs cy da eo es et fa fi fil fo fr
13    gu ha haw hi hr hu hy ig is ja kk kl kn ko kok ln lt lv
14    mk ml mr mt nb nn nso om or pa pl ro ru sa se si sk sl sq
15    sr sv ta te th tn to tr uk ur vi wae wo yo zh
16 );
17    $LocaleFile{'default'} = '';
18 # aliases
19    $LocaleFile{'bs'}      = 'hr';
20    $LocaleFile{'sr_Latn'} = 'hr';
21 # short file names
22    $LocaleFile{'de__phonebook'}   = 'de_phone';
23    $LocaleFile{'es__traditional'} = 'es_trad';
24    $LocaleFile{'fi__phonebook'}   = 'fi_phone';
25    $LocaleFile{'si__dictionary'}  = 'si_dict';
26    $LocaleFile{'sv__reformed'}    = 'sv_refo';
27    $LocaleFile{'zh__big5han'}     = 'zh_big5';
28    $LocaleFile{'zh__gb2312han'}   = 'zh_gb';
29    $LocaleFile{'zh__pinyin'}      = 'zh_pin';
30    $LocaleFile{'zh__stroke'}      = 'zh_strk';
31
32 my %TypeAlias = qw(
33     phone     phonebook
34     phonebk   phonebook
35     dict      dictionary
36     reform    reformed
37     trad      traditional
38     big5      big5han
39     gb2312    gb2312han
40 );
41
42 sub _locale {
43     my $locale = shift;
44     if ($locale) {
45         $locale = lc $locale;
46         $locale =~ tr/\-\ \./_/;
47         $locale =~ s/_([0-9a-z]+)\z/$TypeAlias{$1} ?
48                                   "_$TypeAlias{$1}" : "_$1"/e;
49         $LocaleFile{$locale} and return $locale;
50
51         my @code = split /_/, $locale;
52         my $lan = shift @code;
53         my $scr = @code && length $code[0] == 4 ? ucfirst shift @code : '';
54         my $reg = @code && length $code[0] <  4 ? uc      shift @code : '';
55         my $var = @code                         ?         shift @code : '';
56
57         my @list;
58         push @list, (
59             "${lan}_${scr}_${reg}_$var",
60             "${lan}_${scr}__$var", # empty $scr should not be ${lan}__$var.
61             "${lan}_${reg}_$var",  # empty $reg may be ${lan}__$var.
62             "${lan}__$var",
63         ) if $var ne '';
64         push @list, (
65             "${lan}_${scr}_${reg}",
66             "${lan}_${scr}",
67             "${lan}_${reg}",
68              ${lan},
69         );
70         for my $loc (@list) {
71             $LocaleFile{$loc} and return $loc;
72         }
73     }
74     return 'default';
75 }
76
77 sub getlocale {
78     return shift->{accepted_locale};
79 }
80
81 sub locale_version {
82     return shift->{locale_version};
83 }
84
85 sub _fetchpl {
86     my $accepted = shift;
87     my $f = $LocaleFile{$accepted};
88     return if !$f;
89     $f .= $PL_EXT;
90
91     # allow to search @INC
92 #   use File::Spec;
93 #   my $path = File::Spec->catfile('Unicode', 'Collate', 'Locale', $f);
94     my $path = "Unicode/Collate/Locale/$f";
95     my $h = do $path;
96     croak "Unicode/Collate/Locale/$f can't be found" if !$h;
97     return $h;
98 }
99
100 sub new {
101     my $class = shift;
102     my %hash = @_;
103     $hash{accepted_locale} = _locale($hash{locale});
104
105     if (exists $hash{table}) {
106         croak "your table can't be used with Unicode::Collate::Locale";
107     }
108
109     my $href = _fetchpl($hash{accepted_locale});
110     while (my($k,$v) = each %$href) {
111         if (exists $hash{$k}) {
112             croak "$k is reserved by $hash{locale}, can't be overwritten";
113         }
114         $hash{$k} = $v;
115     }
116     return $class->SUPER::new(%hash);
117 }
118
119 1;
120 __END__
121
122 MEMORANDA for developing
123
124 locale          based CLDR
125 ----------------------------------------------------------------------------
126 af              2.0 = 1.8.1
127 ar              2.0
128 as              2.0 = 1.8.1
129 az              2.0 = 1.8.1 (type="standard")
130 be              2.0
131 bg              2.0
132 bn              2.0.1 (type="standard")
133 bs              2.0 (alias source="hr")
134 ca              2.0 = 1.8.1 (alt="proposed" type="standard")
135 cs              2.0 = 1.8.1 (type="standard")
136 cy              2.0 = 1.8.1
137 da              2.0 = 1.8.1 (type="standard") [modify aA to pass CLDR tests]
138 de__phonebook   2.0 (type="phonebook")
139 eo              2.0 = 1.8.1
140 es              2.0 (type="standard")
141 es__traditional 2.0 = 1.8.1 (type="traditional")
142 et              2.0 = 1.8.1
143 fa              2.0 = 1.8.1
144 fi              2.0 = 1.8.1 (type="standard" alt="proposed")
145 fi__phonebook   2.0 = 1.8.1 (type="phonebook")
146 fil             2.0 (type="standard") = 1.8.1
147 fo              2.0 = 1.8.1 (alt="proposed" type="standard")
148 fr              2.0 (fr_CA, backwards="on")
149 gu              2.0 (type="standard")
150 ha              2.0
151 haw             2.0 = 1.8.1
152 hi              2.0 (type="standard")
153 hr              2.0 (type="standard")
154 hu              2.0 = 1.8.1 (alt="proposed" type="standard")
155 hy              2.0 = 1.8.1
156 ig              2.0 = 1.8.1
157 is              2.0 = 1.8.1 (type="standard")
158 ja              2.0 = 1.8.1 (type="standard")
159 kk              2.0
160 kl              2.0 = 1.8.1 (type="standard")
161 kn              2.0 (type="standard")
162 ko              2.0 = 1.8.1 (type="standard")
163 kok             2.0 = 1.8.1
164 ln              2.0 (type="standard") = 1.8.1
165 lt              2.0
166 lv              2.0 (type="standard") = 1.8.1
167 mk              2.0
168 ml              2.0
169 mr              2.0 = 1.8.1
170 mt              2.0
171 nb              2.0 (type="standard")
172 nn              2.0 (type="standard")
173 nso             2.0 = 1.8.1
174 om              2.0 = 1.8.1
175 or              2.0
176 pa              2.0 = 1.8.1
177 pl              2.0 = 1.8.1
178 ro              2.0 (type="standard")
179 ru              2.0
180 sa              1.8.1 (type="standard" alt="proposed") [currently in /seed]
181 se              2.0 = 1.8.1 (type="standard")
182 si              2.0 (type="standard")
183 si__dictionary  2.0 (type="dictionary")
184 sk              2.0 (type="standard")
185 sl              2.0 = 1.8.1 (type="standard" alt="proposed")
186 sq              2.0 = 1.8.1 (alt="proposed" type="standard")
187 sr              2.0 (type="standard")
188 sr_Latn         2.0 = 1.8.1 (alias source="hr")
189 sv              2.0 (type="standard")
190 sv__reformed    2.0 = 1.8.1 (type="reformed")
191 ta              2.0
192 te              2.0
193 th              2.0 (type="standard")
194 tn              2.0 = 1.8.1
195 to              2.0 = 1.8.1 (type="standard" alt="proposed")
196 tr              2.0 = 1.8.1 (type="standard")
197 uk              2.0
198 ur              2.0
199 vi              2.0 = 1.8.1
200 wae             2.0
201 wo              1.8.1 [currently in /seed]
202 yo              2.0 = 1.8.1
203 zh              2.0 = 1.8.1 (type="standard")
204 zh__big5han     2.0 = 1.8.1 (type="big5han")
205 zh__gb2312han   2.0 = 1.8.1 (type="gb2312han")
206 zh__pinyin      2.0 (type='pinyin' alt='short')
207 zh__stroke      2.0 = 1.9.1 (type='stroke' alt='short')
208 ----------------------------------------------------------------------------
209
210 =head1 NAME
211
212 Unicode::Collate::Locale - Linguistic tailoring for DUCET via Unicode::Collate
213
214 =head1 SYNOPSIS
215
216   use Unicode::Collate::Locale;
217
218   #construct
219   $Collator = Unicode::Collate::Locale->
220       new(locale => $locale_name, %tailoring);
221
222   #sort
223   @sorted = $Collator->sort(@not_sorted);
224
225   #compare
226   $result = $Collator->cmp($a, $b); # returns 1, 0, or -1.
227
228 B<Note:> Strings in C<@not_sorted>, C<$a> and C<$b> are interpreted
229 according to Perl's Unicode support. See L<perlunicode>,
230 L<perluniintro>, L<perlunitut>, L<perlunifaq>, L<utf8>.
231 Otherwise you can use C<preprocess> (cf. C<Unicode::Collate>)
232 or should decode them before.
233
234 =head1 DESCRIPTION
235
236 This module provides linguistic tailoring for it
237 taking advantage of C<Unicode::Collate>.
238
239 =head2 Constructor
240
241 The C<new> method returns a collator object.
242
243 A parameter list for the constructor is a hash, which can include
244 a special key C<locale> and its value (case-insensitive) standing
245 for a Unicode base language code (two or three-letter).
246 For example, C<Unicode::Collate::Locale-E<gt>new(locale =E<gt> 'FR')>
247 returns a collator tailored for French.
248
249 C<$locale_name> may be suffixed with a Unicode script code (four-letter),
250 a Unicode region code, a Unicode language variant code. These codes are
251 case-insensitive, and separated with C<'_'> or C<'-'>.
252 E.g. C<en_US> for English in USA,
253 C<az_Cyrl> for Azerbaijani in the Cyrillic script,
254 C<es_ES_traditional> for Spanish in Spain (Traditional).
255
256 If C<$locale_name> is not available,
257 fallback is selected in the following order:
258
259     1. language with a variant code
260     2. language with a script code
261     3. language with a region code
262     4. language
263     5. default
264
265 Tailoring tags provided by C<Unicode::Collate> are allowed as long as
266 they are not used for C<locale> support.  Esp. the C<table> tag
267 is always untailorable, since it is reserved for DUCET.
268
269 E.g. a collator for French, which ignores diacritics and case difference
270 (i.e. level 1), with reversed case ordering and no normalization.
271
272     Unicode::Collate::Locale->new(
273         level => 1,
274         locale => 'fr',
275         upper_before_lower => 1,
276         normalization => undef
277     )
278
279 Overriding a behavior already tailored by C<locale> is disallowed
280 if such a tailoring is passed to C<new()>.
281
282     Unicode::Collate::Locale->new(
283         locale => 'da',
284         upper_before_lower => 0, # causes error as reserved by 'da'
285     )
286
287 However C<change()> inherited from C<Unicode::Collate> allows
288 such a tailoring that is reserved by C<locale>. Examples:
289
290     new(locale => 'ca')->change(backwards => undef)
291     new(locale => 'da')->change(upper_before_lower => 0)
292     new(locale => 'ja')->change(overrideCJK => undef)
293
294 =head2 Methods
295
296 C<Unicode::Collate::Locale> is a subclass of C<Unicode::Collate>
297 and methods other than C<new> are inherited from C<Unicode::Collate>.
298
299 Here is a list of additional methods:
300
301 =over 4
302
303 =item C<$Collator-E<gt>getlocale>
304
305 Returns a language code accepted and used actually on collation.
306 If linguistic tailoring is not provided for a language code you passed
307 (intensionally for some languages, or due to the incomplete implementation),
308 this method returns a string C<'default'> meaning no special tailoring.
309
310 =item C<$Collator-E<gt>locale_version>
311
312 (Since Unicode::Collate::Locale 0.87)
313 Returns the version number (perhaps C</\d\.\d\d/>) of the locale, as that
314 of F<Locale/*.pl>.
315
316 B<Note:> F<Locale/*.pl> that a collator uses should be identified by
317 a combination of return values from C<getlocale> and C<locale_version>.
318
319 =back
320
321 =head2 A list of tailorable locales
322
323       locale name       description
324     --------------------------------------------------------------
325       af                Afrikaans
326       ar                Arabic
327       as                Assamese
328       az                Azerbaijani (Azeri)
329       be                Belarusian
330       bg                Bulgarian
331       bn                Bengali
332       bs                Bosnian
333       ca                Catalan
334       cs                Czech
335       cy                Welsh
336       da                Danish
337       de__phonebook     German (umlaut as 'ae', 'oe', 'ue')
338       eo                Esperanto
339       es                Spanish
340       es__traditional   Spanish ('ch' and 'll' as a grapheme)
341       et                Estonian
342       fa                Persian
343       fi                Finnish (v and w are primary equal)
344       fi__phonebook     Finnish (v and w as separate characters)
345       fil               Filipino
346       fo                Faroese
347       fr                French
348       gu                Gujarati
349       ha                Hausa
350       haw               Hawaiian
351       hi                Hindi
352       hr                Croatian
353       hu                Hungarian
354       hy                Armenian
355       ig                Igbo
356       is                Icelandic
357       ja                Japanese [1]
358       kk                Kazakh
359       kl                Kalaallisut
360       kn                Kannada
361       ko                Korean [2]
362       kok               Konkani
363       ln                Lingala
364       lt                Lithuanian
365       lv                Latvian
366       mk                Macedonian
367       ml                Malayalam
368       mr                Marathi
369       mt                Maltese
370       nb                Norwegian Bokmal
371       nn                Norwegian Nynorsk
372       nso               Northern Sotho
373       om                Oromo
374       or                Oriya
375       pa                Punjabi
376       pl                Polish
377       ro                Romanian
378       ru                Russian
379       sa                Sanskrit
380       se                Northern Sami
381       si                Sinhala
382       si__dictionary    Sinhala (U+0DA5 = U+0DA2,0DCA,0DA4)
383       sk                Slovak
384       sl                Slovenian
385       sq                Albanian
386       sr                Serbian
387       sr_Latn           Serbian in Latin (tailored as Croatian)
388       sv                Swedish (v and w are primary equal)
389       sv__reformed      Swedish (v and w as separate characters)
390       ta                Tamil
391       te                Telugu
392       th                Thai
393       tn                Tswana
394       to                Tonga
395       tr                Turkish
396       uk                Ukrainian
397       ur                Urdu
398       vi                Vietnamese
399       wae               Walser
400       wo                Wolof
401       yo                Yoruba
402       zh                Chinese
403       zh__big5han       Chinese (ideographs: big5 order)
404       zh__gb2312han     Chinese (ideographs: GB-2312 order)
405       zh__pinyin        Chinese (ideographs: pinyin order) [3]
406       zh__stroke        Chinese (ideographs: stroke order) [3]
407     --------------------------------------------------------------
408
409 Locales according to the default UCA rules include
410 chr (Cherokee),
411 de (German),
412 en (English),
413 ga (Irish),
414 id (Indonesian),
415 it (Italian),
416 ka (Georgian),
417 ms (Malay),
418 nl (Dutch),
419 pt (Portuguese),
420 st (Southern Sotho),
421 sw (Swahili),
422 xh (Xhosa),
423 zu (Zulu).
424
425 B<Note>
426
427 [1] ja: Ideographs are sorted in JIS X 0208 order.
428 Fullwidth and halfwidth forms are identical to their normal form.
429 The difference between hiragana and katakana is at the 4th level,
430 the comparison also requires C<(variable =E<gt> 'Non-ignorable')>,
431 and then C<katakana_before_hiragana> has no effect.
432
433 [2] ko: Plenty of ideographs are sorted by their reading. Such
434 an ideograph is primary (level 1) equal to, and secondary (level 2)
435 greater than, the corresponding hangul syllable.
436
437 [3] zh__pinyin and zh__stroke: implemented alt='short', where
438 a smaller number of ideographs are tailored.
439
440 =head1 INSTALL
441
442 Installation of C<Unicode::Collate::Locale> requires F<Collate/Locale.pm>,
443 F<Collate/Locale/*.pm>, F<Collate/CJK/*.pm> and F<Collate/allkeys.txt>.
444 On building, C<Unicode::Collate::Locale> doesn't require any of F<data/*.txt>,
445 F<gendata/*>, and F<mklocale>.
446 Tests for C<Unicode::Collate::Locale> are named F<t/loc_*.t>.
447
448 =head1 CAVEAT
449
450 =over 4
451
452 =item tailoring is not maximum
453
454 Even if a certain letter is tailored, its equivalent would not always
455 tailored as well as it. For example, even though W is tailored,
456 fullwidth W (C<U+FF37>), W with acute (C<U+1E82>), etc. are not
457 tailored. The result may depend on whether source strings are
458 normalized or not, and whether decomposed or composed.
459 Thus C<(normalization =E<gt> undef)> is less preferred.
460
461 =back
462
463 =head1 AUTHOR
464
465 The Unicode::Collate::Locale module for perl was written
466 by SADAHIRO Tomoyuki, <SADAHIRO@cpan.org>.
467 This module is Copyright(C) 2004-2012, SADAHIRO Tomoyuki. Japan.
468 All rights reserved.
469
470 This module is free software; you can redistribute it and/or
471 modify it under the same terms as Perl itself.
472
473 =head1 SEE ALSO
474
475 =over 4
476
477 =item Unicode Collation Algorithm - UTS #10
478
479 L<http://www.unicode.org/reports/tr10/>
480
481 =item The Default Unicode Collation Element Table (DUCET)
482
483 L<http://www.unicode.org/Public/UCA/latest/allkeys.txt>
484
485 =item Unicode Locale Data Markup Language (LDML) - UTS #35
486
487 L<http://www.unicode.org/reports/tr35/>
488
489 =item CLDR - Unicode Common Locale Data Repository
490
491 L<http://cldr.unicode.org/>
492
493 =item L<Unicode::Collate>
494
495 =item L<Unicode::Normalize>
496
497 =back
498
499 =cut