line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Locale::CLDR; |
2
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
=encoding utf8 |
4
|
|
|
|
|
|
|
|
5
|
|
|
|
|
|
|
=head1 NAME |
6
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
Locale::CLDR - A Module to create locale objects with localisation data from the CLDR |
8
|
|
|
|
|
|
|
|
9
|
|
|
|
|
|
|
=head1 VERSION |
10
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
Version 0.34 |
12
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
=head1 SYNOPSIS |
14
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
This module provides a locale object you can use to localise your output. |
16
|
|
|
|
|
|
|
The localisation data comes from the Unicode Common Locale Data Repository. |
17
|
|
|
|
|
|
|
Most of this code can be used with Perl version 5.10.1 or above. There are a |
18
|
|
|
|
|
|
|
few parts of the code that require version 5.18 or above. |
19
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
=head1 USAGE |
21
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
my $locale = Locale::CLDR->new('en_US'); |
23
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
or |
25
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
my $locale = Locale::CLDR->new(language_id => 'en', region_id => 'us'); |
27
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
A full locale identifier is |
29
|
|
|
|
|
|
|
|
30
|
|
|
|
|
|
|
C<language>_C<script>_C<region>_C<variant>_u_C<extension name>_C<extension value> |
31
|
|
|
|
|
|
|
|
32
|
|
|
|
|
|
|
my $locale = Locale::CLDR->new('en_latn_US_SCOUSE_u_nu_traditional'); |
33
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
or |
35
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
my $locale = Locale::CLDR->new(language_id => 'en', script_id => 'latn', region_id => 'US', variant => 'SCOUSE', extensions => { nu => 'traditional' } ); |
37
|
|
|
|
|
|
|
|
38
|
|
|
|
|
|
|
=cut |
39
|
|
|
|
|
|
|
|
40
|
21
|
|
|
21
|
|
2169781
|
use v5.10.1; |
|
21
|
|
|
|
|
271
|
|
41
|
21
|
|
|
21
|
|
8811
|
use version; |
|
21
|
|
|
|
|
39554
|
|
|
21
|
|
|
|
|
172
|
|
42
|
|
|
|
|
|
|
our $VERSION = version->declare('v0.34'); |
43
|
|
|
|
|
|
|
|
44
|
21
|
|
|
21
|
|
11960
|
use open ':encoding(utf8)'; |
|
21
|
|
|
|
|
24616
|
|
|
21
|
|
|
|
|
115
|
|
45
|
21
|
|
|
21
|
|
253676
|
use utf8; |
|
21
|
|
|
|
|
61
|
|
|
21
|
|
|
|
|
132
|
|
46
|
21
|
|
|
21
|
|
1382
|
use if $^V ge v5.12.0, feature => 'unicode_strings'; |
|
21
|
|
|
|
|
56
|
|
|
21
|
|
|
|
|
912
|
|
47
|
21
|
|
|
21
|
|
2879
|
use if $^V le v5.16, charnames => 'full'; |
|
21
|
|
|
|
|
46
|
|
|
21
|
|
|
|
|
198
|
|
48
|
|
|
|
|
|
|
|
49
|
21
|
|
|
21
|
|
11803
|
use Moo; |
|
21
|
|
|
|
|
238315
|
|
|
21
|
|
|
|
|
105
|
|
50
|
21
|
|
|
21
|
|
40095
|
use MooX::ClassAttribute; |
|
21
|
|
|
|
|
414092
|
|
|
21
|
|
|
|
|
141
|
|
51
|
21
|
|
|
21
|
|
15141
|
use Types::Standard qw( Str Int Maybe ArrayRef HashRef Object Bool InstanceOf ); |
|
21
|
|
|
|
|
1509251
|
|
|
21
|
|
|
|
|
304
|
|
52
|
|
|
|
|
|
|
|
53
|
|
|
|
|
|
|
with 'Locale::CLDR::ValidCodes', 'Locale::CLDR::EraBoundries', 'Locale::CLDR::WeekData', |
54
|
|
|
|
|
|
|
'Locale::CLDR::MeasurementSystem', 'Locale::CLDR::LikelySubtags', 'Locale::CLDR::NumberingSystems', |
55
|
|
|
|
|
|
|
'Locale::CLDR::NumberFormatter', 'Locale::CLDR::RegionContainment', 'Locale::CLDR::CalendarPreferences', |
56
|
|
|
|
|
|
|
'Locale::CLDR::Currencies', 'Locale::CLDR::Plurals'; |
57
|
|
|
|
|
|
|
|
58
|
21
|
|
|
21
|
|
45788
|
use Class::Load; |
|
21
|
|
|
|
|
319598
|
|
|
21
|
|
|
|
|
1064
|
|
59
|
21
|
|
|
21
|
|
9738
|
use namespace::autoclean; |
|
21
|
|
|
|
|
166166
|
|
|
21
|
|
|
|
|
93
|
|
60
|
21
|
|
|
21
|
|
1958
|
use List::Util qw(first); |
|
21
|
|
|
|
|
48
|
|
|
21
|
|
|
|
|
1122
|
|
61
|
21
|
|
|
21
|
|
10795
|
use DateTime::Locale; |
|
21
|
|
|
|
|
4003474
|
|
|
21
|
|
|
|
|
837
|
|
62
|
21
|
|
|
21
|
|
13595
|
use Unicode::Normalize(); |
|
21
|
|
|
|
|
45369
|
|
|
21
|
|
|
|
|
675
|
|
63
|
21
|
|
|
21
|
|
9920
|
use Locale::CLDR::Collator(); |
|
21
|
|
|
|
|
93
|
|
|
21
|
|
|
|
|
707
|
|
64
|
21
|
|
|
21
|
|
181
|
use File::Spec(); |
|
21
|
|
|
|
|
46
|
|
|
21
|
|
|
|
|
433
|
|
65
|
21
|
|
|
21
|
|
109
|
use Scalar::Util qw(blessed); |
|
21
|
|
|
|
|
51
|
|
|
21
|
|
|
|
|
1167
|
|
66
|
21
|
|
|
21
|
|
11785
|
use Unicode::Regex::Set(); |
|
21
|
|
|
|
|
36579
|
|
|
21
|
|
|
|
|
2894
|
|
67
|
|
|
|
|
|
|
|
68
|
|
|
|
|
|
|
# Backwards compatibility |
69
|
|
|
|
|
|
|
BEGIN { |
70
|
21
|
50
|
|
21
|
|
135
|
if (defined &CORE::fc) { #v5.16 |
71
|
21
|
|
|
|
|
45710
|
*fc = \&CORE::fc; |
72
|
|
|
|
|
|
|
} |
73
|
|
|
|
|
|
|
else { |
74
|
|
|
|
|
|
|
# We only use fc() with code that expects Perl v5.18 or above |
75
|
0
|
|
|
|
|
0
|
*fc = sub {}; |
76
|
|
|
|
|
|
|
} |
77
|
|
|
|
|
|
|
} |
78
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
=head1 ATTRIBUTES |
80
|
|
|
|
|
|
|
|
81
|
|
|
|
|
|
|
These can be passed into the constructor and all are optional. |
82
|
|
|
|
|
|
|
|
83
|
|
|
|
|
|
|
=over 4 |
84
|
|
|
|
|
|
|
|
85
|
|
|
|
|
|
|
=item language_id |
86
|
|
|
|
|
|
|
|
87
|
|
|
|
|
|
|
A valid language or language alias id, such as C<en> |
88
|
|
|
|
|
|
|
|
89
|
|
|
|
|
|
|
=cut |
90
|
|
|
|
|
|
|
|
91
|
|
|
|
|
|
|
has 'language_id' => ( |
92
|
|
|
|
|
|
|
is => 'ro', |
93
|
|
|
|
|
|
|
isa => Str, |
94
|
|
|
|
|
|
|
required => 1, |
95
|
|
|
|
|
|
|
); |
96
|
|
|
|
|
|
|
|
97
|
|
|
|
|
|
|
# language aliases |
98
|
|
|
|
|
|
|
around 'language_id' => sub { |
99
|
|
|
|
|
|
|
my ($orig, $self) = @_; |
100
|
|
|
|
|
|
|
my $value = $self->$orig; |
101
|
|
|
|
|
|
|
return $self->language_aliases->{$value} // $value; |
102
|
|
|
|
|
|
|
}; |
103
|
|
|
|
|
|
|
|
104
|
|
|
|
|
|
|
=item script_id |
105
|
|
|
|
|
|
|
|
106
|
|
|
|
|
|
|
A valid script id, such as C<latn> or C<Ctcl>. The code will pick a likely script |
107
|
|
|
|
|
|
|
depending on the given language if non is provided. |
108
|
|
|
|
|
|
|
|
109
|
|
|
|
|
|
|
=cut |
110
|
|
|
|
|
|
|
|
111
|
|
|
|
|
|
|
has 'script_id' => ( |
112
|
|
|
|
|
|
|
is => 'ro', |
113
|
|
|
|
|
|
|
isa => Str, |
114
|
|
|
|
|
|
|
default => '', |
115
|
|
|
|
|
|
|
predicate => 'has_script', |
116
|
|
|
|
|
|
|
); |
117
|
|
|
|
|
|
|
|
118
|
|
|
|
|
|
|
=item region_id |
119
|
|
|
|
|
|
|
|
120
|
|
|
|
|
|
|
A valid region id or region alias such as C<GB> |
121
|
|
|
|
|
|
|
|
122
|
|
|
|
|
|
|
=cut |
123
|
|
|
|
|
|
|
|
124
|
|
|
|
|
|
|
has 'region_id' => ( |
125
|
|
|
|
|
|
|
is => 'ro', |
126
|
|
|
|
|
|
|
isa => Str, |
127
|
|
|
|
|
|
|
default => '', |
128
|
|
|
|
|
|
|
predicate => 'has_region', |
129
|
|
|
|
|
|
|
); |
130
|
|
|
|
|
|
|
|
131
|
|
|
|
|
|
|
# region aliases |
132
|
|
|
|
|
|
|
around 'region_id' => sub { |
133
|
|
|
|
|
|
|
my ($orig, $self) = @_; |
134
|
|
|
|
|
|
|
my $value = $self->$orig; |
135
|
|
|
|
|
|
|
my $alias = $self->region_aliases->{$value}; |
136
|
|
|
|
|
|
|
return $value if ! defined $alias; |
137
|
|
|
|
|
|
|
return (split /\s+/, $alias)[0]; |
138
|
|
|
|
|
|
|
}; |
139
|
|
|
|
|
|
|
|
140
|
|
|
|
|
|
|
=item variant_id |
141
|
|
|
|
|
|
|
|
142
|
|
|
|
|
|
|
A valid variant id. The code currently ignores this |
143
|
|
|
|
|
|
|
|
144
|
|
|
|
|
|
|
=cut |
145
|
|
|
|
|
|
|
|
146
|
|
|
|
|
|
|
has 'variant_id' => ( |
147
|
|
|
|
|
|
|
is => 'ro', |
148
|
|
|
|
|
|
|
isa => Str, |
149
|
|
|
|
|
|
|
default => '', |
150
|
|
|
|
|
|
|
predicate => 'has_variant', |
151
|
|
|
|
|
|
|
); |
152
|
|
|
|
|
|
|
|
153
|
|
|
|
|
|
|
=item extensions |
154
|
|
|
|
|
|
|
|
155
|
|
|
|
|
|
|
A Hashref of extension names and values. You can use this to override |
156
|
|
|
|
|
|
|
the locales number formatting and calendar by passing in the Unicode |
157
|
|
|
|
|
|
|
extension names or aliases as keys and the extension value as the hash |
158
|
|
|
|
|
|
|
value. |
159
|
|
|
|
|
|
|
|
160
|
|
|
|
|
|
|
Currently supported extensions are |
161
|
|
|
|
|
|
|
|
162
|
|
|
|
|
|
|
=over 8 |
163
|
|
|
|
|
|
|
|
164
|
|
|
|
|
|
|
=item ca |
165
|
|
|
|
|
|
|
|
166
|
|
|
|
|
|
|
=item calendar |
167
|
|
|
|
|
|
|
|
168
|
|
|
|
|
|
|
You can use this to override a locales default calendar. Valid values are |
169
|
|
|
|
|
|
|
|
170
|
|
|
|
|
|
|
=over 12 |
171
|
|
|
|
|
|
|
|
172
|
|
|
|
|
|
|
=item buddhist |
173
|
|
|
|
|
|
|
|
174
|
|
|
|
|
|
|
Thai Buddhist calendar |
175
|
|
|
|
|
|
|
|
176
|
|
|
|
|
|
|
=item chinese |
177
|
|
|
|
|
|
|
|
178
|
|
|
|
|
|
|
Traditional Chinese calendar |
179
|
|
|
|
|
|
|
|
180
|
|
|
|
|
|
|
=item coptic |
181
|
|
|
|
|
|
|
|
182
|
|
|
|
|
|
|
Coptic calendar |
183
|
|
|
|
|
|
|
|
184
|
|
|
|
|
|
|
=item dangi |
185
|
|
|
|
|
|
|
|
186
|
|
|
|
|
|
|
Traditional Korean calendar |
187
|
|
|
|
|
|
|
|
188
|
|
|
|
|
|
|
=item ethioaa |
189
|
|
|
|
|
|
|
|
190
|
|
|
|
|
|
|
=item ethiopic-amete-alem |
191
|
|
|
|
|
|
|
|
192
|
|
|
|
|
|
|
Ethiopic calendar, Amete Alem (epoch approx. 5493 B.C.E) |
193
|
|
|
|
|
|
|
|
194
|
|
|
|
|
|
|
=item ethiopic |
195
|
|
|
|
|
|
|
|
196
|
|
|
|
|
|
|
Ethiopic calendar, Amete Mihret (epoch approx, 8 C.E.) |
197
|
|
|
|
|
|
|
|
198
|
|
|
|
|
|
|
=item gregory |
199
|
|
|
|
|
|
|
|
200
|
|
|
|
|
|
|
=item gregorian |
201
|
|
|
|
|
|
|
|
202
|
|
|
|
|
|
|
Gregorian calendar |
203
|
|
|
|
|
|
|
|
204
|
|
|
|
|
|
|
=item hebrew |
205
|
|
|
|
|
|
|
|
206
|
|
|
|
|
|
|
Hebrew Calendar |
207
|
|
|
|
|
|
|
|
208
|
|
|
|
|
|
|
=item indian |
209
|
|
|
|
|
|
|
|
210
|
|
|
|
|
|
|
Indian National Calendar |
211
|
|
|
|
|
|
|
|
212
|
|
|
|
|
|
|
=item islamic |
213
|
|
|
|
|
|
|
|
214
|
|
|
|
|
|
|
Islamic Calendar |
215
|
|
|
|
|
|
|
|
216
|
|
|
|
|
|
|
=item islamic-civil |
217
|
|
|
|
|
|
|
|
218
|
|
|
|
|
|
|
Islamic Calendar (tabular, civil epoch) |
219
|
|
|
|
|
|
|
|
220
|
|
|
|
|
|
|
=item islamic-rgsa |
221
|
|
|
|
|
|
|
|
222
|
|
|
|
|
|
|
Islamic Calendar (Saudi Arabia, sighting) |
223
|
|
|
|
|
|
|
|
224
|
|
|
|
|
|
|
=item islamic-tbla |
225
|
|
|
|
|
|
|
|
226
|
|
|
|
|
|
|
Islamic Calendar (tabular, astronomical epoch) |
227
|
|
|
|
|
|
|
|
228
|
|
|
|
|
|
|
=item islamic-umalqura |
229
|
|
|
|
|
|
|
|
230
|
|
|
|
|
|
|
Islamic Calendar (Umm al-Qura) |
231
|
|
|
|
|
|
|
|
232
|
|
|
|
|
|
|
=item iso8601 |
233
|
|
|
|
|
|
|
|
234
|
|
|
|
|
|
|
ISO-8601 Calendar |
235
|
|
|
|
|
|
|
|
236
|
|
|
|
|
|
|
=item japanese |
237
|
|
|
|
|
|
|
|
238
|
|
|
|
|
|
|
Japanese Calendar |
239
|
|
|
|
|
|
|
|
240
|
|
|
|
|
|
|
=item persian |
241
|
|
|
|
|
|
|
|
242
|
|
|
|
|
|
|
Persian Calendar |
243
|
|
|
|
|
|
|
|
244
|
|
|
|
|
|
|
=item roc |
245
|
|
|
|
|
|
|
|
246
|
|
|
|
|
|
|
Minguo Calendar |
247
|
|
|
|
|
|
|
|
248
|
|
|
|
|
|
|
=back |
249
|
|
|
|
|
|
|
|
250
|
|
|
|
|
|
|
=item nu |
251
|
|
|
|
|
|
|
|
252
|
|
|
|
|
|
|
=item numbers |
253
|
|
|
|
|
|
|
|
254
|
|
|
|
|
|
|
The number type can be one of |
255
|
|
|
|
|
|
|
|
256
|
|
|
|
|
|
|
=over 12 |
257
|
|
|
|
|
|
|
|
258
|
|
|
|
|
|
|
=item arab |
259
|
|
|
|
|
|
|
|
260
|
|
|
|
|
|
|
Arabic-Indic Digits |
261
|
|
|
|
|
|
|
|
262
|
|
|
|
|
|
|
=item arabext |
263
|
|
|
|
|
|
|
|
264
|
|
|
|
|
|
|
Extended Arabic-Indic Digits |
265
|
|
|
|
|
|
|
|
266
|
|
|
|
|
|
|
=item armn |
267
|
|
|
|
|
|
|
|
268
|
|
|
|
|
|
|
Armenian Numerals |
269
|
|
|
|
|
|
|
|
270
|
|
|
|
|
|
|
=item armnlow |
271
|
|
|
|
|
|
|
|
272
|
|
|
|
|
|
|
Armenian Lowercase Numerals |
273
|
|
|
|
|
|
|
|
274
|
|
|
|
|
|
|
=item bali |
275
|
|
|
|
|
|
|
|
276
|
|
|
|
|
|
|
Balinese Digits |
277
|
|
|
|
|
|
|
|
278
|
|
|
|
|
|
|
=item beng |
279
|
|
|
|
|
|
|
|
280
|
|
|
|
|
|
|
Bengali Digits |
281
|
|
|
|
|
|
|
|
282
|
|
|
|
|
|
|
=item brah |
283
|
|
|
|
|
|
|
|
284
|
|
|
|
|
|
|
Brahmi Digits |
285
|
|
|
|
|
|
|
|
286
|
|
|
|
|
|
|
=item cakm |
287
|
|
|
|
|
|
|
|
288
|
|
|
|
|
|
|
Chakma Digits |
289
|
|
|
|
|
|
|
|
290
|
|
|
|
|
|
|
=item cham |
291
|
|
|
|
|
|
|
|
292
|
|
|
|
|
|
|
Cham Digits |
293
|
|
|
|
|
|
|
|
294
|
|
|
|
|
|
|
=item deva |
295
|
|
|
|
|
|
|
|
296
|
|
|
|
|
|
|
Devanagari Digits |
297
|
|
|
|
|
|
|
|
298
|
|
|
|
|
|
|
=item ethi |
299
|
|
|
|
|
|
|
|
300
|
|
|
|
|
|
|
Ethiopic Numerals |
301
|
|
|
|
|
|
|
|
302
|
|
|
|
|
|
|
=item finance |
303
|
|
|
|
|
|
|
|
304
|
|
|
|
|
|
|
Financial Numerals |
305
|
|
|
|
|
|
|
|
306
|
|
|
|
|
|
|
=item fullwide |
307
|
|
|
|
|
|
|
|
308
|
|
|
|
|
|
|
Full Width Digits |
309
|
|
|
|
|
|
|
|
310
|
|
|
|
|
|
|
=item geor |
311
|
|
|
|
|
|
|
|
312
|
|
|
|
|
|
|
Georgian Numerals |
313
|
|
|
|
|
|
|
|
314
|
|
|
|
|
|
|
=item grek |
315
|
|
|
|
|
|
|
|
316
|
|
|
|
|
|
|
Greek Numerals |
317
|
|
|
|
|
|
|
|
318
|
|
|
|
|
|
|
=item greklow |
319
|
|
|
|
|
|
|
|
320
|
|
|
|
|
|
|
Greek Lowercase Numerals |
321
|
|
|
|
|
|
|
|
322
|
|
|
|
|
|
|
=item gujr |
323
|
|
|
|
|
|
|
|
324
|
|
|
|
|
|
|
Gujarati Digits |
325
|
|
|
|
|
|
|
|
326
|
|
|
|
|
|
|
=item guru |
327
|
|
|
|
|
|
|
|
328
|
|
|
|
|
|
|
Gurmukhi Digits |
329
|
|
|
|
|
|
|
|
330
|
|
|
|
|
|
|
=item hanidays |
331
|
|
|
|
|
|
|
|
332
|
|
|
|
|
|
|
Chinese Calendar Day-of-Month Numerals |
333
|
|
|
|
|
|
|
|
334
|
|
|
|
|
|
|
=item hanidec |
335
|
|
|
|
|
|
|
|
336
|
|
|
|
|
|
|
Chinese Decimal Numerals |
337
|
|
|
|
|
|
|
|
338
|
|
|
|
|
|
|
=item hans |
339
|
|
|
|
|
|
|
|
340
|
|
|
|
|
|
|
Simplified Chinese Numerals |
341
|
|
|
|
|
|
|
|
342
|
|
|
|
|
|
|
=item hansfin |
343
|
|
|
|
|
|
|
|
344
|
|
|
|
|
|
|
Simplified Chinese Financial Numerals |
345
|
|
|
|
|
|
|
|
346
|
|
|
|
|
|
|
=item hant |
347
|
|
|
|
|
|
|
|
348
|
|
|
|
|
|
|
Traditional Chinese Numerals |
349
|
|
|
|
|
|
|
|
350
|
|
|
|
|
|
|
=item hantfin |
351
|
|
|
|
|
|
|
|
352
|
|
|
|
|
|
|
Traditional Chinese Financial Numerals |
353
|
|
|
|
|
|
|
|
354
|
|
|
|
|
|
|
=item hebr |
355
|
|
|
|
|
|
|
|
356
|
|
|
|
|
|
|
Hebrew Numerals |
357
|
|
|
|
|
|
|
|
358
|
|
|
|
|
|
|
=item java |
359
|
|
|
|
|
|
|
|
360
|
|
|
|
|
|
|
Javanese Digits |
361
|
|
|
|
|
|
|
|
362
|
|
|
|
|
|
|
=item jpan |
363
|
|
|
|
|
|
|
|
364
|
|
|
|
|
|
|
Japanese Numerals |
365
|
|
|
|
|
|
|
|
366
|
|
|
|
|
|
|
=item jpanfin |
367
|
|
|
|
|
|
|
|
368
|
|
|
|
|
|
|
Japanese Financial Numerals |
369
|
|
|
|
|
|
|
|
370
|
|
|
|
|
|
|
=item kali |
371
|
|
|
|
|
|
|
|
372
|
|
|
|
|
|
|
Kayah Li Digits |
373
|
|
|
|
|
|
|
|
374
|
|
|
|
|
|
|
=item khmr |
375
|
|
|
|
|
|
|
|
376
|
|
|
|
|
|
|
Khmer Digits |
377
|
|
|
|
|
|
|
|
378
|
|
|
|
|
|
|
=item knda |
379
|
|
|
|
|
|
|
|
380
|
|
|
|
|
|
|
Kannada Digits |
381
|
|
|
|
|
|
|
|
382
|
|
|
|
|
|
|
=item lana |
383
|
|
|
|
|
|
|
|
384
|
|
|
|
|
|
|
Tai Tham Hora Digits |
385
|
|
|
|
|
|
|
|
386
|
|
|
|
|
|
|
=item lanatham |
387
|
|
|
|
|
|
|
|
388
|
|
|
|
|
|
|
Tai Tham Tham Digits |
389
|
|
|
|
|
|
|
|
390
|
|
|
|
|
|
|
=item laoo |
391
|
|
|
|
|
|
|
|
392
|
|
|
|
|
|
|
Lao Digits |
393
|
|
|
|
|
|
|
|
394
|
|
|
|
|
|
|
=item latn |
395
|
|
|
|
|
|
|
|
396
|
|
|
|
|
|
|
Western Digits |
397
|
|
|
|
|
|
|
|
398
|
|
|
|
|
|
|
=item lepc |
399
|
|
|
|
|
|
|
|
400
|
|
|
|
|
|
|
Lepcha Digits |
401
|
|
|
|
|
|
|
|
402
|
|
|
|
|
|
|
=item limb |
403
|
|
|
|
|
|
|
|
404
|
|
|
|
|
|
|
Limbu Digits |
405
|
|
|
|
|
|
|
|
406
|
|
|
|
|
|
|
=item mlym |
407
|
|
|
|
|
|
|
|
408
|
|
|
|
|
|
|
Malayalam Digits |
409
|
|
|
|
|
|
|
|
410
|
|
|
|
|
|
|
=item mong |
411
|
|
|
|
|
|
|
|
412
|
|
|
|
|
|
|
Mongolian Digits |
413
|
|
|
|
|
|
|
|
414
|
|
|
|
|
|
|
=item mtei |
415
|
|
|
|
|
|
|
|
416
|
|
|
|
|
|
|
Meetei Mayek Digits |
417
|
|
|
|
|
|
|
|
418
|
|
|
|
|
|
|
=item mymr |
419
|
|
|
|
|
|
|
|
420
|
|
|
|
|
|
|
Myanmar Digits |
421
|
|
|
|
|
|
|
|
422
|
|
|
|
|
|
|
=item mymrshan |
423
|
|
|
|
|
|
|
|
424
|
|
|
|
|
|
|
Myanmar Shan Digits |
425
|
|
|
|
|
|
|
|
426
|
|
|
|
|
|
|
=item native |
427
|
|
|
|
|
|
|
|
428
|
|
|
|
|
|
|
Native Digits |
429
|
|
|
|
|
|
|
|
430
|
|
|
|
|
|
|
=item nkoo |
431
|
|
|
|
|
|
|
|
432
|
|
|
|
|
|
|
N'Ko Digits |
433
|
|
|
|
|
|
|
|
434
|
|
|
|
|
|
|
=item olck |
435
|
|
|
|
|
|
|
|
436
|
|
|
|
|
|
|
Ol Chiki Digits |
437
|
|
|
|
|
|
|
|
438
|
|
|
|
|
|
|
=item orya |
439
|
|
|
|
|
|
|
|
440
|
|
|
|
|
|
|
Oriya Digits |
441
|
|
|
|
|
|
|
|
442
|
|
|
|
|
|
|
=item osma |
443
|
|
|
|
|
|
|
|
444
|
|
|
|
|
|
|
Osmanya Digits |
445
|
|
|
|
|
|
|
|
446
|
|
|
|
|
|
|
=item roman |
447
|
|
|
|
|
|
|
|
448
|
|
|
|
|
|
|
Roman Numerals |
449
|
|
|
|
|
|
|
|
450
|
|
|
|
|
|
|
=item romanlow |
451
|
|
|
|
|
|
|
|
452
|
|
|
|
|
|
|
Roman Lowercase Numerals |
453
|
|
|
|
|
|
|
|
454
|
|
|
|
|
|
|
=item saur |
455
|
|
|
|
|
|
|
|
456
|
|
|
|
|
|
|
Saurashtra Digits |
457
|
|
|
|
|
|
|
|
458
|
|
|
|
|
|
|
=item shrd |
459
|
|
|
|
|
|
|
|
460
|
|
|
|
|
|
|
Sharada Digits |
461
|
|
|
|
|
|
|
|
462
|
|
|
|
|
|
|
=item sora |
463
|
|
|
|
|
|
|
|
464
|
|
|
|
|
|
|
Sora Sompeng Digits |
465
|
|
|
|
|
|
|
|
466
|
|
|
|
|
|
|
=item sund |
467
|
|
|
|
|
|
|
|
468
|
|
|
|
|
|
|
Sundanese Digits |
469
|
|
|
|
|
|
|
|
470
|
|
|
|
|
|
|
=item takr |
471
|
|
|
|
|
|
|
|
472
|
|
|
|
|
|
|
Takri Digits |
473
|
|
|
|
|
|
|
|
474
|
|
|
|
|
|
|
=item talu |
475
|
|
|
|
|
|
|
|
476
|
|
|
|
|
|
|
New Tai Lue Digits |
477
|
|
|
|
|
|
|
|
478
|
|
|
|
|
|
|
=item taml |
479
|
|
|
|
|
|
|
|
480
|
|
|
|
|
|
|
Traditional Tamil Numerals |
481
|
|
|
|
|
|
|
|
482
|
|
|
|
|
|
|
=item tamldec |
483
|
|
|
|
|
|
|
|
484
|
|
|
|
|
|
|
Tamil Digits |
485
|
|
|
|
|
|
|
|
486
|
|
|
|
|
|
|
=item telu |
487
|
|
|
|
|
|
|
|
488
|
|
|
|
|
|
|
Telugu Digits |
489
|
|
|
|
|
|
|
|
490
|
|
|
|
|
|
|
=item thai |
491
|
|
|
|
|
|
|
|
492
|
|
|
|
|
|
|
Thai Digits |
493
|
|
|
|
|
|
|
|
494
|
|
|
|
|
|
|
=item tibt |
495
|
|
|
|
|
|
|
|
496
|
|
|
|
|
|
|
Tibetan Digits |
497
|
|
|
|
|
|
|
|
498
|
|
|
|
|
|
|
=item traditional |
499
|
|
|
|
|
|
|
|
500
|
|
|
|
|
|
|
Traditional Numerals |
501
|
|
|
|
|
|
|
|
502
|
|
|
|
|
|
|
=item vaii |
503
|
|
|
|
|
|
|
|
504
|
|
|
|
|
|
|
Vai Digits |
505
|
|
|
|
|
|
|
|
506
|
|
|
|
|
|
|
=back |
507
|
|
|
|
|
|
|
|
508
|
|
|
|
|
|
|
=item cu |
509
|
|
|
|
|
|
|
|
510
|
|
|
|
|
|
|
=item currency |
511
|
|
|
|
|
|
|
|
512
|
|
|
|
|
|
|
This extention overrides the default currency symbol for the locale. |
513
|
|
|
|
|
|
|
It's value is any valid currency identifyer. |
514
|
|
|
|
|
|
|
|
515
|
|
|
|
|
|
|
=item cf |
516
|
|
|
|
|
|
|
|
517
|
|
|
|
|
|
|
This overrides the default currency format. It can be set to one of |
518
|
|
|
|
|
|
|
C<standard> or C<account> |
519
|
|
|
|
|
|
|
|
520
|
|
|
|
|
|
|
=item fw |
521
|
|
|
|
|
|
|
|
522
|
|
|
|
|
|
|
This extention overrides the first day of the week. It can be set to |
523
|
|
|
|
|
|
|
one of |
524
|
|
|
|
|
|
|
|
525
|
|
|
|
|
|
|
=over 12 |
526
|
|
|
|
|
|
|
|
527
|
|
|
|
|
|
|
=item mon |
528
|
|
|
|
|
|
|
|
529
|
|
|
|
|
|
|
=item tue |
530
|
|
|
|
|
|
|
|
531
|
|
|
|
|
|
|
=item wed |
532
|
|
|
|
|
|
|
|
533
|
|
|
|
|
|
|
=item thu |
534
|
|
|
|
|
|
|
|
535
|
|
|
|
|
|
|
=item fri |
536
|
|
|
|
|
|
|
|
537
|
|
|
|
|
|
|
=item sat |
538
|
|
|
|
|
|
|
|
539
|
|
|
|
|
|
|
=item sun |
540
|
|
|
|
|
|
|
|
541
|
|
|
|
|
|
|
=back |
542
|
|
|
|
|
|
|
|
543
|
|
|
|
|
|
|
=back |
544
|
|
|
|
|
|
|
|
545
|
|
|
|
|
|
|
=cut |
546
|
|
|
|
|
|
|
|
547
|
|
|
|
|
|
|
has 'extensions' => ( |
548
|
|
|
|
|
|
|
is => 'ro', |
549
|
|
|
|
|
|
|
isa => Maybe[HashRef], |
550
|
|
|
|
|
|
|
default => undef, |
551
|
|
|
|
|
|
|
writer => '_set_extensions', |
552
|
|
|
|
|
|
|
); |
553
|
|
|
|
|
|
|
|
554
|
|
|
|
|
|
|
=back |
555
|
|
|
|
|
|
|
|
556
|
|
|
|
|
|
|
=head1 Methods |
557
|
|
|
|
|
|
|
|
558
|
|
|
|
|
|
|
The following methods can be called on the locale object |
559
|
|
|
|
|
|
|
|
560
|
|
|
|
|
|
|
=over 4 |
561
|
|
|
|
|
|
|
|
562
|
|
|
|
|
|
|
=item id() |
563
|
|
|
|
|
|
|
|
564
|
|
|
|
|
|
|
The local identifier. This is what you get if you attempt to |
565
|
|
|
|
|
|
|
stringify a locale object. |
566
|
|
|
|
|
|
|
|
567
|
|
|
|
|
|
|
=item has_region() |
568
|
|
|
|
|
|
|
|
569
|
|
|
|
|
|
|
True if a region id was passed into the constructor |
570
|
|
|
|
|
|
|
|
571
|
|
|
|
|
|
|
=item has_script() |
572
|
|
|
|
|
|
|
|
573
|
|
|
|
|
|
|
True if a script id was passed into the constructor |
574
|
|
|
|
|
|
|
|
575
|
|
|
|
|
|
|
=item has_variant() |
576
|
|
|
|
|
|
|
|
577
|
|
|
|
|
|
|
True if a variant id was passed into the constructor |
578
|
|
|
|
|
|
|
|
579
|
|
|
|
|
|
|
=item likely_language() |
580
|
|
|
|
|
|
|
|
581
|
|
|
|
|
|
|
Given a locale with no language passed in or with the explicit language |
582
|
|
|
|
|
|
|
code of C<und>, this method attempts to use the script and region |
583
|
|
|
|
|
|
|
data to guess the locale's language. |
584
|
|
|
|
|
|
|
|
585
|
|
|
|
|
|
|
=cut |
586
|
|
|
|
|
|
|
|
587
|
|
|
|
|
|
|
has 'likely_language' => ( |
588
|
|
|
|
|
|
|
is => 'ro', |
589
|
|
|
|
|
|
|
isa => Str, |
590
|
|
|
|
|
|
|
init_arg => undef, |
591
|
|
|
|
|
|
|
lazy => 1, |
592
|
|
|
|
|
|
|
builder => '_build_likely_language', |
593
|
|
|
|
|
|
|
); |
594
|
|
|
|
|
|
|
|
595
|
|
|
|
|
|
|
sub _build_likely_language { |
596
|
0
|
|
|
0
|
|
0
|
my $self = shift; |
597
|
|
|
|
|
|
|
|
598
|
0
|
|
|
|
|
0
|
my $language = $self->language_id(); |
599
|
|
|
|
|
|
|
|
600
|
0
|
0
|
|
|
|
0
|
return $self->language unless $language eq 'und'; |
601
|
|
|
|
|
|
|
|
602
|
0
|
|
|
|
|
0
|
return $self->likely_subtag->language; |
603
|
|
|
|
|
|
|
} |
604
|
|
|
|
|
|
|
|
605
|
|
|
|
|
|
|
=item likely_script() |
606
|
|
|
|
|
|
|
|
607
|
|
|
|
|
|
|
Given a locale with no script passed in this method attempts to use the |
608
|
|
|
|
|
|
|
language and region data to guess the locale's script. |
609
|
|
|
|
|
|
|
|
610
|
|
|
|
|
|
|
=cut |
611
|
|
|
|
|
|
|
|
612
|
|
|
|
|
|
|
has 'likely_script' => ( |
613
|
|
|
|
|
|
|
is => 'ro', |
614
|
|
|
|
|
|
|
isa => Str, |
615
|
|
|
|
|
|
|
init_arg => undef, |
616
|
|
|
|
|
|
|
lazy => 1, |
617
|
|
|
|
|
|
|
builder => '_build_likely_script', |
618
|
|
|
|
|
|
|
); |
619
|
|
|
|
|
|
|
|
620
|
|
|
|
|
|
|
sub _build_likely_script { |
621
|
0
|
|
|
0
|
|
0
|
my $self = shift; |
622
|
|
|
|
|
|
|
|
623
|
0
|
|
|
|
|
0
|
my $script = $self->script(); |
624
|
|
|
|
|
|
|
|
625
|
0
|
0
|
|
|
|
0
|
return $script if $script; |
626
|
|
|
|
|
|
|
|
627
|
0
|
|
0
|
|
|
0
|
return $self->likely_subtag->script || ''; |
628
|
|
|
|
|
|
|
} |
629
|
|
|
|
|
|
|
|
630
|
|
|
|
|
|
|
=item likely_region() |
631
|
|
|
|
|
|
|
|
632
|
|
|
|
|
|
|
Given a locale with no region passed in this method attempts to use the |
633
|
|
|
|
|
|
|
language and script data to guess the locale's region. |
634
|
|
|
|
|
|
|
|
635
|
|
|
|
|
|
|
=back |
636
|
|
|
|
|
|
|
|
637
|
|
|
|
|
|
|
=cut |
638
|
|
|
|
|
|
|
|
639
|
|
|
|
|
|
|
has 'likely_region' => ( |
640
|
|
|
|
|
|
|
is => 'ro', |
641
|
|
|
|
|
|
|
isa => Str, |
642
|
|
|
|
|
|
|
init_arg => undef, |
643
|
|
|
|
|
|
|
lazy => 1, |
644
|
|
|
|
|
|
|
builder => '_build_likely_region', |
645
|
|
|
|
|
|
|
); |
646
|
|
|
|
|
|
|
|
647
|
|
|
|
|
|
|
sub _build_likely_region { |
648
|
0
|
|
|
0
|
|
0
|
my $self = shift; |
649
|
|
|
|
|
|
|
|
650
|
0
|
|
|
|
|
0
|
my $region = $self->region(); |
651
|
|
|
|
|
|
|
|
652
|
0
|
0
|
|
|
|
0
|
return $region if $region; |
653
|
|
|
|
|
|
|
|
654
|
0
|
|
0
|
|
|
0
|
return $self->likely_subtag->region || ''; |
655
|
|
|
|
|
|
|
} |
656
|
|
|
|
|
|
|
|
657
|
|
|
|
|
|
|
has 'module' => ( |
658
|
|
|
|
|
|
|
is => 'ro', |
659
|
|
|
|
|
|
|
isa => Object, |
660
|
|
|
|
|
|
|
init_arg => undef, |
661
|
|
|
|
|
|
|
lazy => 1, |
662
|
|
|
|
|
|
|
builder => '_build_module', |
663
|
|
|
|
|
|
|
); |
664
|
|
|
|
|
|
|
|
665
|
|
|
|
|
|
|
sub _build_module { |
666
|
|
|
|
|
|
|
# Create the new path |
667
|
116
|
|
|
116
|
|
542
|
my $self = shift; |
668
|
|
|
|
|
|
|
|
669
|
348
|
|
|
|
|
1090
|
my @path = map { ucfirst lc } |
670
|
116
|
100
|
|
|
|
3042
|
map { $_ ? $_ : 'Any' } ( |
|
348
|
|
|
|
|
1160
|
|
671
|
|
|
|
|
|
|
$self->language_id, |
672
|
|
|
|
|
|
|
$self->script_id, |
673
|
|
|
|
|
|
|
$self->region_id, |
674
|
|
|
|
|
|
|
); |
675
|
|
|
|
|
|
|
|
676
|
|
|
|
|
|
|
my @likely_path = |
677
|
116
|
100
|
|
|
|
1291
|
map { ucfirst lc } ( |
|
348
|
100
|
|
|
|
802
|
|
|
|
100
|
|
|
|
|
|
678
|
|
|
|
|
|
|
$self->_has_likely_subtag ? $self->likely_subtag->language_id : 'Any', |
679
|
|
|
|
|
|
|
$self->_has_likely_subtag ? $self->likely_subtag->script_id : 'Any', |
680
|
|
|
|
|
|
|
$self->_has_likely_subtag ? $self->likely_subtag->region_id : 'Any', |
681
|
|
|
|
|
|
|
); |
682
|
|
|
|
|
|
|
|
683
|
116
|
|
|
|
|
571
|
for (my $i = 0; $i < @path; $i++) { |
684
|
348
|
100
|
66
|
|
|
1863
|
$likely_path[$i] = $path[$i] unless $path[$i] eq 'und' or $path[$i] eq 'Any'; |
685
|
|
|
|
|
|
|
} |
686
|
|
|
|
|
|
|
|
687
|
|
|
|
|
|
|
# Note the order we push these onto the stack is important |
688
|
116
|
|
|
|
|
712
|
@path = join '::', @likely_path; |
689
|
116
|
|
|
|
|
562
|
push @path, join '::', $likely_path[0], 'Any', $likely_path[2]; |
690
|
116
|
|
|
|
|
531
|
push @path, join '::', @likely_path[0 .. 1]; |
691
|
116
|
|
|
|
|
394
|
push @path, join '::', $likely_path[0]; |
692
|
|
|
|
|
|
|
|
693
|
|
|
|
|
|
|
# Strip out all paths that end in ::Any |
694
|
116
|
|
|
|
|
319
|
@path = grep { ! /::Any$/ } @path; |
|
464
|
|
|
|
|
1364
|
|
695
|
|
|
|
|
|
|
|
696
|
|
|
|
|
|
|
# Now we go through the path loading each module |
697
|
|
|
|
|
|
|
# And calling new on it. |
698
|
116
|
|
|
|
|
438
|
my $module; |
699
|
|
|
|
|
|
|
my $errors; |
700
|
116
|
|
|
|
|
0
|
my $module_name; |
701
|
116
|
|
|
|
|
407
|
foreach my $name (@path) { |
702
|
231
|
|
|
|
|
613
|
$module_name = "Locale::CLDR::Locales::$name"; |
703
|
231
|
|
|
|
|
1500
|
my ($canload, $error) = Class::Load::try_load_class($module_name, { -version => $VERSION}); |
704
|
230
|
100
|
|
|
|
80310
|
if ($canload) { |
705
|
95
|
|
|
|
|
637
|
Class::Load::load_class($module_name, { -version => $VERSION}); |
706
|
95
|
|
|
|
|
25679
|
$errors = 0; |
707
|
95
|
|
|
|
|
300
|
last; |
708
|
|
|
|
|
|
|
} |
709
|
|
|
|
|
|
|
else { |
710
|
135
|
|
|
|
|
435
|
$errors = 1; |
711
|
|
|
|
|
|
|
} |
712
|
|
|
|
|
|
|
} |
713
|
|
|
|
|
|
|
|
714
|
115
|
100
|
|
|
|
474
|
if ($errors) { |
715
|
20
|
|
|
|
|
102
|
Class::Load::load_class('Locale::CLDR::Locales::Root'); |
716
|
20
|
|
|
|
|
1676
|
$module_name = 'Locale::CLDR::Locales::Root'; |
717
|
|
|
|
|
|
|
} |
718
|
|
|
|
|
|
|
|
719
|
115
|
|
|
|
|
2808
|
$module = $module_name->new; |
720
|
|
|
|
|
|
|
|
721
|
|
|
|
|
|
|
# If we only have the root module then we have a problem as |
722
|
|
|
|
|
|
|
# none of the language specific data is in the root. So we |
723
|
|
|
|
|
|
|
# fall back to the en module |
724
|
|
|
|
|
|
|
|
725
|
115
|
100
|
|
|
|
4892
|
if ( ref $module eq 'Locale::CLDR::Locales::Root') { |
726
|
20
|
|
|
|
|
121
|
Class::Load::load_class('Locale::CLDR::Locales::En'); |
727
|
20
|
|
|
|
|
2437
|
$module = Locale::CLDR::Locales::En->new |
728
|
|
|
|
|
|
|
} |
729
|
|
|
|
|
|
|
|
730
|
115
|
|
|
|
|
38895
|
return $module; |
731
|
|
|
|
|
|
|
} |
732
|
|
|
|
|
|
|
|
733
|
|
|
|
|
|
|
class_has 'method_cache' => ( |
734
|
|
|
|
|
|
|
is => 'rw', |
735
|
|
|
|
|
|
|
isa => HashRef[HashRef[ArrayRef[Object]]], |
736
|
|
|
|
|
|
|
init_arg => undef, |
737
|
|
|
|
|
|
|
default => sub { return {}}, |
738
|
|
|
|
|
|
|
); |
739
|
|
|
|
|
|
|
|
740
|
|
|
|
|
|
|
has 'break_grapheme_cluster' => ( |
741
|
|
|
|
|
|
|
is => 'ro', |
742
|
|
|
|
|
|
|
isa => ArrayRef, |
743
|
|
|
|
|
|
|
init_arg => undef(), |
744
|
|
|
|
|
|
|
lazy => 1, |
745
|
|
|
|
|
|
|
default => sub {shift->_build_break('GraphemeClusterBreak')}, |
746
|
|
|
|
|
|
|
); |
747
|
|
|
|
|
|
|
|
748
|
|
|
|
|
|
|
has 'break_word' => ( |
749
|
|
|
|
|
|
|
is => 'ro', |
750
|
|
|
|
|
|
|
isa => ArrayRef, |
751
|
|
|
|
|
|
|
init_arg => undef(), |
752
|
|
|
|
|
|
|
lazy => 1, |
753
|
|
|
|
|
|
|
default => sub {shift->_build_break('WordBreak')}, |
754
|
|
|
|
|
|
|
); |
755
|
|
|
|
|
|
|
|
756
|
|
|
|
|
|
|
has 'break_line' => ( |
757
|
|
|
|
|
|
|
is => 'ro', |
758
|
|
|
|
|
|
|
isa => ArrayRef, |
759
|
|
|
|
|
|
|
init_arg => undef(), |
760
|
|
|
|
|
|
|
lazy => 1, |
761
|
|
|
|
|
|
|
default => sub {shift->_build_break('LineBreak')}, |
762
|
|
|
|
|
|
|
); |
763
|
|
|
|
|
|
|
|
764
|
|
|
|
|
|
|
has 'break_sentence' => ( |
765
|
|
|
|
|
|
|
is => 'ro', |
766
|
|
|
|
|
|
|
isa => ArrayRef, |
767
|
|
|
|
|
|
|
init_arg => undef(), |
768
|
|
|
|
|
|
|
lazy => 1, |
769
|
|
|
|
|
|
|
default => sub {shift->_build_break('SentenceBreak')}, |
770
|
|
|
|
|
|
|
); |
771
|
|
|
|
|
|
|
|
772
|
|
|
|
|
|
|
=head2 Meta Data |
773
|
|
|
|
|
|
|
|
774
|
|
|
|
|
|
|
The following methods return, in English, the names if the various |
775
|
|
|
|
|
|
|
id's passed into the locales constructor. I.e. if you passed |
776
|
|
|
|
|
|
|
C<language =E<gt> 'fr'> to the constructor you would get back C<French> |
777
|
|
|
|
|
|
|
for the language. |
778
|
|
|
|
|
|
|
|
779
|
|
|
|
|
|
|
=over 4 |
780
|
|
|
|
|
|
|
|
781
|
|
|
|
|
|
|
=item name |
782
|
|
|
|
|
|
|
|
783
|
|
|
|
|
|
|
The locale's name. This is usually built up out of the language, |
784
|
|
|
|
|
|
|
script, region and variant of the locale |
785
|
|
|
|
|
|
|
|
786
|
|
|
|
|
|
|
=item language |
787
|
|
|
|
|
|
|
|
788
|
|
|
|
|
|
|
The name of the locale's language |
789
|
|
|
|
|
|
|
|
790
|
|
|
|
|
|
|
=item script |
791
|
|
|
|
|
|
|
|
792
|
|
|
|
|
|
|
The name of the locale's script |
793
|
|
|
|
|
|
|
|
794
|
|
|
|
|
|
|
=item region |
795
|
|
|
|
|
|
|
|
796
|
|
|
|
|
|
|
The name of the locale's region |
797
|
|
|
|
|
|
|
|
798
|
|
|
|
|
|
|
=item variant |
799
|
|
|
|
|
|
|
|
800
|
|
|
|
|
|
|
The name of the locale's variant |
801
|
|
|
|
|
|
|
|
802
|
|
|
|
|
|
|
=back |
803
|
|
|
|
|
|
|
|
804
|
|
|
|
|
|
|
=head2 Native Meta Data |
805
|
|
|
|
|
|
|
|
806
|
|
|
|
|
|
|
Like Meta Data above this provides the names of the various id's |
807
|
|
|
|
|
|
|
passed into the locale's constructor. However in this case the |
808
|
|
|
|
|
|
|
names are formatted to match the locale. I.e. if you passed |
809
|
|
|
|
|
|
|
C<language =E<gt> 'fr'> to the constructor you would get back |
810
|
|
|
|
|
|
|
C<français> for the language. |
811
|
|
|
|
|
|
|
|
812
|
|
|
|
|
|
|
=over 4 |
813
|
|
|
|
|
|
|
|
814
|
|
|
|
|
|
|
=item native_name |
815
|
|
|
|
|
|
|
|
816
|
|
|
|
|
|
|
The locale's name. This is usually built up out of the language, |
817
|
|
|
|
|
|
|
script, region and variant of the locale. Returned in the locale's |
818
|
|
|
|
|
|
|
language and script |
819
|
|
|
|
|
|
|
|
820
|
|
|
|
|
|
|
=item native_language |
821
|
|
|
|
|
|
|
|
822
|
|
|
|
|
|
|
The name of the locale's language in the locale's language and script. |
823
|
|
|
|
|
|
|
|
824
|
|
|
|
|
|
|
=item native_script |
825
|
|
|
|
|
|
|
|
826
|
|
|
|
|
|
|
The name of the locale's script in the locale's language and script. |
827
|
|
|
|
|
|
|
|
828
|
|
|
|
|
|
|
=item native_region |
829
|
|
|
|
|
|
|
|
830
|
|
|
|
|
|
|
The name of the locale's region in the locale's language and script. |
831
|
|
|
|
|
|
|
|
832
|
|
|
|
|
|
|
=item native_variant |
833
|
|
|
|
|
|
|
|
834
|
|
|
|
|
|
|
The name of the locale's variant in the locale's language and script. |
835
|
|
|
|
|
|
|
|
836
|
|
|
|
|
|
|
=back |
837
|
|
|
|
|
|
|
|
838
|
|
|
|
|
|
|
=cut |
839
|
|
|
|
|
|
|
|
840
|
|
|
|
|
|
|
foreach my $property (qw( name language script region variant)) { |
841
|
|
|
|
|
|
|
has $property => ( |
842
|
|
|
|
|
|
|
is => 'ro', |
843
|
|
|
|
|
|
|
isa => Str, |
844
|
|
|
|
|
|
|
init_arg => undef, |
845
|
|
|
|
|
|
|
lazy => 1, |
846
|
|
|
|
|
|
|
builder => "_build_$property", |
847
|
|
|
|
|
|
|
); |
848
|
|
|
|
|
|
|
|
849
|
21
|
|
|
21
|
|
210
|
no strict 'refs'; |
|
21
|
|
|
|
|
50
|
|
|
21
|
|
|
|
|
19132
|
|
850
|
|
|
|
|
|
|
*{"native_$property"} = sub { |
851
|
0
|
|
|
0
|
|
0
|
my ($self, $for) = @_; |
852
|
|
|
|
|
|
|
|
853
|
0
|
|
0
|
|
|
0
|
$for //= $self; |
854
|
0
|
|
|
|
|
0
|
my $build = "_build_native_$property"; |
855
|
0
|
|
|
|
|
0
|
return $self->$build($for); |
856
|
|
|
|
|
|
|
}; |
857
|
|
|
|
|
|
|
} |
858
|
|
|
|
|
|
|
|
859
|
|
|
|
|
|
|
=head2 Calenders |
860
|
|
|
|
|
|
|
|
861
|
|
|
|
|
|
|
The Calendar data is built to hook into L<DateTime::Locale> so that |
862
|
|
|
|
|
|
|
all Locale::CLDR objects can be used as replacements for DateTime::Locale's |
863
|
|
|
|
|
|
|
locale data. To use, say, the French data do |
864
|
|
|
|
|
|
|
|
865
|
|
|
|
|
|
|
my $french_locale = Locale::CLDR->new('fr_FR'); |
866
|
|
|
|
|
|
|
my $french_dt = DateTime->now(locale => $french_locale); |
867
|
|
|
|
|
|
|
say "French month : ", $french_dt->month_name; # prints out the current month in French |
868
|
|
|
|
|
|
|
|
869
|
|
|
|
|
|
|
=over 4 |
870
|
|
|
|
|
|
|
|
871
|
|
|
|
|
|
|
=item month_format_wide |
872
|
|
|
|
|
|
|
|
873
|
|
|
|
|
|
|
=item month_format_abbreviated |
874
|
|
|
|
|
|
|
|
875
|
|
|
|
|
|
|
=item month_format_narrow |
876
|
|
|
|
|
|
|
|
877
|
|
|
|
|
|
|
=item month_stand_alone_wide |
878
|
|
|
|
|
|
|
|
879
|
|
|
|
|
|
|
=item month_stand_alone_abbreviated |
880
|
|
|
|
|
|
|
|
881
|
|
|
|
|
|
|
=item month_stand_alone_narrow |
882
|
|
|
|
|
|
|
|
883
|
|
|
|
|
|
|
All the above return an arrayref of month names in the requested style. |
884
|
|
|
|
|
|
|
|
885
|
|
|
|
|
|
|
=item day_format_wide |
886
|
|
|
|
|
|
|
|
887
|
|
|
|
|
|
|
=item day_format_abbreviated |
888
|
|
|
|
|
|
|
|
889
|
|
|
|
|
|
|
=item day_format_narrow |
890
|
|
|
|
|
|
|
|
891
|
|
|
|
|
|
|
=item day_stand_alone_wide |
892
|
|
|
|
|
|
|
|
893
|
|
|
|
|
|
|
=item day_stand_alone_abbreviated |
894
|
|
|
|
|
|
|
|
895
|
|
|
|
|
|
|
=item day_stand_alone_narrow |
896
|
|
|
|
|
|
|
|
897
|
|
|
|
|
|
|
All the above return an array ref of day names in the requested style. |
898
|
|
|
|
|
|
|
|
899
|
|
|
|
|
|
|
=item quarter_format_wide |
900
|
|
|
|
|
|
|
|
901
|
|
|
|
|
|
|
=item quarter_format_abbreviated |
902
|
|
|
|
|
|
|
|
903
|
|
|
|
|
|
|
=item quarter_format_narrow |
904
|
|
|
|
|
|
|
|
905
|
|
|
|
|
|
|
=item quarter_stand_alone_wide |
906
|
|
|
|
|
|
|
|
907
|
|
|
|
|
|
|
=item quarter_stand_alone_abbreviated |
908
|
|
|
|
|
|
|
|
909
|
|
|
|
|
|
|
=item quarter_stand_alone_narrow |
910
|
|
|
|
|
|
|
|
911
|
|
|
|
|
|
|
All the above return an arrayref of quarter names in the requested style. |
912
|
|
|
|
|
|
|
|
913
|
|
|
|
|
|
|
=item am_pm_wide |
914
|
|
|
|
|
|
|
|
915
|
|
|
|
|
|
|
=item am_pm_abbreviated |
916
|
|
|
|
|
|
|
|
917
|
|
|
|
|
|
|
=item am_pm_narrow |
918
|
|
|
|
|
|
|
|
919
|
|
|
|
|
|
|
All the above return the date period name for AM and PM |
920
|
|
|
|
|
|
|
in the requested style |
921
|
|
|
|
|
|
|
|
922
|
|
|
|
|
|
|
=item era_wide |
923
|
|
|
|
|
|
|
|
924
|
|
|
|
|
|
|
=item era_abbreviated |
925
|
|
|
|
|
|
|
|
926
|
|
|
|
|
|
|
=item era_narrow |
927
|
|
|
|
|
|
|
|
928
|
|
|
|
|
|
|
All the above return an array ref of era names. Note that these |
929
|
|
|
|
|
|
|
return the first two eras which is what you normally want for |
930
|
|
|
|
|
|
|
BC and AD etc. but won't work correctly for Japanese calendars. |
931
|
|
|
|
|
|
|
|
932
|
|
|
|
|
|
|
=back |
933
|
|
|
|
|
|
|
|
934
|
|
|
|
|
|
|
=cut |
935
|
|
|
|
|
|
|
|
936
|
|
|
|
|
|
|
foreach my $property (qw( |
937
|
|
|
|
|
|
|
month_format_wide month_format_abbreviated month_format_narrow |
938
|
|
|
|
|
|
|
month_stand_alone_wide month_stand_alone_abbreviated month_stand_alone_narrow |
939
|
|
|
|
|
|
|
day_format_wide day_format_abbreviated day_format_narrow |
940
|
|
|
|
|
|
|
day_stand_alone_wide day_stand_alone_abbreviated day_stand_alone_narrow |
941
|
|
|
|
|
|
|
quarter_format_wide quarter_format_abbreviated quarter_format_narrow |
942
|
|
|
|
|
|
|
quarter_stand_alone_wide quarter_stand_alone_abbreviated quarter_stand_alone_narrow |
943
|
|
|
|
|
|
|
am_pm_wide am_pm_abbreviated am_pm_narrow |
944
|
|
|
|
|
|
|
era_wide era_abbreviated era_narrow |
945
|
|
|
|
|
|
|
era_format_wide era_format_abbreviated era_format_narrow |
946
|
|
|
|
|
|
|
era_stand_alone_wide era_stand_alone_abbreviated era_stand_alone_narrow |
947
|
|
|
|
|
|
|
)) { |
948
|
|
|
|
|
|
|
has $property => ( |
949
|
|
|
|
|
|
|
is => 'ro', |
950
|
|
|
|
|
|
|
isa => ArrayRef, |
951
|
|
|
|
|
|
|
init_arg => undef, |
952
|
|
|
|
|
|
|
lazy => 1, |
953
|
|
|
|
|
|
|
builder => "_build_$property", |
954
|
|
|
|
|
|
|
clearer => "_clear_$property", |
955
|
|
|
|
|
|
|
); |
956
|
|
|
|
|
|
|
} |
957
|
|
|
|
|
|
|
|
958
|
|
|
|
|
|
|
=pod |
959
|
|
|
|
|
|
|
|
960
|
|
|
|
|
|
|
The next set of methods are not used by DateTime::Locale but CLDR provide |
961
|
|
|
|
|
|
|
the data and you might want it |
962
|
|
|
|
|
|
|
|
963
|
|
|
|
|
|
|
=over 4 |
964
|
|
|
|
|
|
|
|
965
|
|
|
|
|
|
|
=item am_pm_format_wide |
966
|
|
|
|
|
|
|
|
967
|
|
|
|
|
|
|
=item am_pm_format_abbreviated |
968
|
|
|
|
|
|
|
|
969
|
|
|
|
|
|
|
=item am_pm_format_narrow |
970
|
|
|
|
|
|
|
|
971
|
|
|
|
|
|
|
=item am_pm_stand_alone_wide |
972
|
|
|
|
|
|
|
|
973
|
|
|
|
|
|
|
=item am_pm_stand_alone_abbreviated |
974
|
|
|
|
|
|
|
|
975
|
|
|
|
|
|
|
=item am_pm_stand_alone_narrow |
976
|
|
|
|
|
|
|
|
977
|
|
|
|
|
|
|
All the above return a hashref keyed on date period |
978
|
|
|
|
|
|
|
with the value being the value for that date period |
979
|
|
|
|
|
|
|
|
980
|
|
|
|
|
|
|
=item era_format_wide |
981
|
|
|
|
|
|
|
|
982
|
|
|
|
|
|
|
=item era_format_abbreviated |
983
|
|
|
|
|
|
|
|
984
|
|
|
|
|
|
|
=item era_format_narrow |
985
|
|
|
|
|
|
|
|
986
|
|
|
|
|
|
|
=item era_stand_alone_wide |
987
|
|
|
|
|
|
|
|
988
|
|
|
|
|
|
|
=item era_stand_alone_abbreviated |
989
|
|
|
|
|
|
|
|
990
|
|
|
|
|
|
|
=item era_stand_alone_narrow |
991
|
|
|
|
|
|
|
|
992
|
|
|
|
|
|
|
All the above return an array ref with I<all> the era data for the |
993
|
|
|
|
|
|
|
locale formatted to the requested width |
994
|
|
|
|
|
|
|
|
995
|
|
|
|
|
|
|
=cut |
996
|
|
|
|
|
|
|
|
997
|
|
|
|
|
|
|
foreach my $property (qw( |
998
|
|
|
|
|
|
|
am_pm_format_wide am_pm_format_abbreviated am_pm_format_narrow |
999
|
|
|
|
|
|
|
am_pm_stand_alone_wide am_pm_stand_alone_abbreviated am_pm_stand_alone_narrow |
1000
|
|
|
|
|
|
|
)) { |
1001
|
|
|
|
|
|
|
has $property => ( |
1002
|
|
|
|
|
|
|
is => 'ro', |
1003
|
|
|
|
|
|
|
isa => HashRef, |
1004
|
|
|
|
|
|
|
init_arg => undef, |
1005
|
|
|
|
|
|
|
lazy => 1, |
1006
|
|
|
|
|
|
|
builder => "_build_$property", |
1007
|
|
|
|
|
|
|
clearer => "_clear_$property", |
1008
|
|
|
|
|
|
|
); |
1009
|
|
|
|
|
|
|
} |
1010
|
|
|
|
|
|
|
|
1011
|
|
|
|
|
|
|
=item date_format_full |
1012
|
|
|
|
|
|
|
|
1013
|
|
|
|
|
|
|
=item date_format_long |
1014
|
|
|
|
|
|
|
|
1015
|
|
|
|
|
|
|
=item date_format_medium |
1016
|
|
|
|
|
|
|
|
1017
|
|
|
|
|
|
|
=item date_format_short |
1018
|
|
|
|
|
|
|
|
1019
|
|
|
|
|
|
|
=item time_format_full |
1020
|
|
|
|
|
|
|
|
1021
|
|
|
|
|
|
|
=item time_format_long |
1022
|
|
|
|
|
|
|
|
1023
|
|
|
|
|
|
|
=item time_format_medium |
1024
|
|
|
|
|
|
|
|
1025
|
|
|
|
|
|
|
=item time_format_short |
1026
|
|
|
|
|
|
|
|
1027
|
|
|
|
|
|
|
=item datetime_format_full |
1028
|
|
|
|
|
|
|
|
1029
|
|
|
|
|
|
|
=item datetime_format_long |
1030
|
|
|
|
|
|
|
|
1031
|
|
|
|
|
|
|
=item datetime_format_medium |
1032
|
|
|
|
|
|
|
|
1033
|
|
|
|
|
|
|
=item datetime_format_short |
1034
|
|
|
|
|
|
|
|
1035
|
|
|
|
|
|
|
All the above return the CLDR I<date format pattern> for the given |
1036
|
|
|
|
|
|
|
element and width |
1037
|
|
|
|
|
|
|
|
1038
|
|
|
|
|
|
|
=cut |
1039
|
|
|
|
|
|
|
|
1040
|
|
|
|
|
|
|
foreach my $property (qw( |
1041
|
|
|
|
|
|
|
id |
1042
|
|
|
|
|
|
|
date_format_full date_format_long |
1043
|
|
|
|
|
|
|
date_format_medium date_format_short |
1044
|
|
|
|
|
|
|
time_format_full time_format_long |
1045
|
|
|
|
|
|
|
time_format_medium time_format_short |
1046
|
|
|
|
|
|
|
datetime_format_full datetime_format_long |
1047
|
|
|
|
|
|
|
datetime_format_medium datetime_format_short |
1048
|
|
|
|
|
|
|
)) { |
1049
|
|
|
|
|
|
|
has $property => ( |
1050
|
|
|
|
|
|
|
is => 'ro', |
1051
|
|
|
|
|
|
|
isa => Str, |
1052
|
|
|
|
|
|
|
init_arg => undef, |
1053
|
|
|
|
|
|
|
lazy => 1, |
1054
|
|
|
|
|
|
|
builder => "_build_$property", |
1055
|
|
|
|
|
|
|
clearer => "_clear_$property", |
1056
|
|
|
|
|
|
|
); |
1057
|
|
|
|
|
|
|
} |
1058
|
|
|
|
|
|
|
|
1059
|
|
|
|
|
|
|
has 'available_formats' => ( |
1060
|
|
|
|
|
|
|
is => 'ro', |
1061
|
|
|
|
|
|
|
isa => ArrayRef, |
1062
|
|
|
|
|
|
|
init_arg => undef, |
1063
|
|
|
|
|
|
|
lazy => 1, |
1064
|
|
|
|
|
|
|
builder => "_build_available_formats", |
1065
|
|
|
|
|
|
|
clearer => "_clear_available_formats", |
1066
|
|
|
|
|
|
|
); |
1067
|
|
|
|
|
|
|
|
1068
|
|
|
|
|
|
|
around available_formats => sub { |
1069
|
|
|
|
|
|
|
my ($orig, $self) = @_; |
1070
|
|
|
|
|
|
|
my $formats = $self->$orig; |
1071
|
|
|
|
|
|
|
|
1072
|
|
|
|
|
|
|
return @{$formats}; |
1073
|
|
|
|
|
|
|
}; |
1074
|
|
|
|
|
|
|
|
1075
|
|
|
|
|
|
|
has 'format_data' => ( |
1076
|
|
|
|
|
|
|
is => 'ro', |
1077
|
|
|
|
|
|
|
isa => HashRef, |
1078
|
|
|
|
|
|
|
init_arg => undef, |
1079
|
|
|
|
|
|
|
lazy => 1, |
1080
|
|
|
|
|
|
|
builder => "_build_format_data", |
1081
|
|
|
|
|
|
|
clearer => "_clear_format_data", |
1082
|
|
|
|
|
|
|
); |
1083
|
|
|
|
|
|
|
|
1084
|
|
|
|
|
|
|
# default_calendar |
1085
|
|
|
|
|
|
|
foreach my $property (qw( |
1086
|
|
|
|
|
|
|
default_date_format_length default_time_format_length |
1087
|
|
|
|
|
|
|
)) { |
1088
|
|
|
|
|
|
|
has $property => ( |
1089
|
|
|
|
|
|
|
is => 'ro', |
1090
|
|
|
|
|
|
|
isa => Str, |
1091
|
|
|
|
|
|
|
init_arg => undef, |
1092
|
|
|
|
|
|
|
lazy => 1, |
1093
|
|
|
|
|
|
|
builder => "_build_$property", |
1094
|
|
|
|
|
|
|
writer => "set_$property" |
1095
|
|
|
|
|
|
|
); |
1096
|
|
|
|
|
|
|
} |
1097
|
|
|
|
|
|
|
|
1098
|
|
|
|
|
|
|
=item prefers_24_hour_time() |
1099
|
|
|
|
|
|
|
|
1100
|
|
|
|
|
|
|
Returns a boolean value, true if the locale has a preference |
1101
|
|
|
|
|
|
|
for 24 hour time over 12 hour |
1102
|
|
|
|
|
|
|
|
1103
|
|
|
|
|
|
|
=cut |
1104
|
|
|
|
|
|
|
|
1105
|
|
|
|
|
|
|
has 'prefers_24_hour_time' => ( |
1106
|
|
|
|
|
|
|
is => 'ro', |
1107
|
|
|
|
|
|
|
isa => Bool, |
1108
|
|
|
|
|
|
|
init_arg => undef, |
1109
|
|
|
|
|
|
|
lazy => 1, |
1110
|
|
|
|
|
|
|
builder => "_build_prefers_24_hour_time", |
1111
|
|
|
|
|
|
|
); |
1112
|
|
|
|
|
|
|
|
1113
|
|
|
|
|
|
|
=item first_day_of_week() |
1114
|
|
|
|
|
|
|
|
1115
|
|
|
|
|
|
|
Returns the numeric representation of the first day of the week |
1116
|
|
|
|
|
|
|
With 0 = Saturday |
1117
|
|
|
|
|
|
|
|
1118
|
|
|
|
|
|
|
=item get_day_period($time, $type = 'default') |
1119
|
|
|
|
|
|
|
|
1120
|
|
|
|
|
|
|
This method will calculate the correct |
1121
|
|
|
|
|
|
|
period for a given time and return the period name in |
1122
|
|
|
|
|
|
|
the locale's language and script |
1123
|
|
|
|
|
|
|
|
1124
|
|
|
|
|
|
|
=item format_for($date_time_format) |
1125
|
|
|
|
|
|
|
|
1126
|
|
|
|
|
|
|
This method takes a CLDR date time format and returns |
1127
|
|
|
|
|
|
|
the localised version of the format. |
1128
|
|
|
|
|
|
|
|
1129
|
|
|
|
|
|
|
=cut |
1130
|
|
|
|
|
|
|
|
1131
|
|
|
|
|
|
|
has 'first_day_of_week' => ( |
1132
|
|
|
|
|
|
|
is => 'ro', |
1133
|
|
|
|
|
|
|
isa => Int, |
1134
|
|
|
|
|
|
|
init_arg => undef, |
1135
|
|
|
|
|
|
|
lazy => 1, |
1136
|
|
|
|
|
|
|
builder => "_build_first_day_of_week", |
1137
|
|
|
|
|
|
|
); |
1138
|
|
|
|
|
|
|
|
1139
|
|
|
|
|
|
|
has 'likely_subtag' => ( |
1140
|
|
|
|
|
|
|
is => 'ro', |
1141
|
|
|
|
|
|
|
isa => InstanceOf['Locale::CLDR'], |
1142
|
|
|
|
|
|
|
init_arg => undef, |
1143
|
|
|
|
|
|
|
writer => '_set_likely_subtag', |
1144
|
|
|
|
|
|
|
predicate => '_has_likely_subtag', |
1145
|
|
|
|
|
|
|
); |
1146
|
|
|
|
|
|
|
|
1147
|
|
|
|
|
|
|
sub _build_break { |
1148
|
4
|
|
|
4
|
|
24
|
my ($self, $what) = @_; |
1149
|
|
|
|
|
|
|
|
1150
|
4
|
|
|
|
|
22
|
my $vars = $self->_build_break_vars($what); |
1151
|
4
|
|
|
|
|
27
|
my $rules = $self->_build_break_rules($vars, $what); |
1152
|
4
|
|
|
|
|
202
|
return $rules; |
1153
|
|
|
|
|
|
|
} |
1154
|
|
|
|
|
|
|
|
1155
|
|
|
|
|
|
|
sub _build_break_vars { |
1156
|
4
|
|
|
4
|
|
15
|
my ($self, $what) = @_; |
1157
|
|
|
|
|
|
|
|
1158
|
4
|
|
|
|
|
17
|
my $name = "${what}_variables"; |
1159
|
4
|
|
|
|
|
27
|
my @bundles = $self->_find_bundle($name); |
1160
|
4
|
|
|
|
|
37
|
my @vars; |
1161
|
4
|
|
|
|
|
15
|
foreach my $bundle (reverse @bundles) { |
1162
|
4
|
|
|
|
|
9
|
push @vars, @{$bundle->$name}; |
|
4
|
|
|
|
|
84
|
|
1163
|
|
|
|
|
|
|
} |
1164
|
|
|
|
|
|
|
|
1165
|
4
|
|
|
|
|
14
|
my %vars = (); |
1166
|
4
|
|
|
|
|
28
|
while (my ($name, $value) = (shift @vars, shift @vars)) { |
1167
|
174
|
100
|
|
|
|
299
|
last unless defined $name; |
1168
|
170
|
50
|
|
|
|
275
|
if (! defined $value) { |
1169
|
0
|
|
|
|
|
0
|
delete $vars{$name}; |
1170
|
0
|
|
|
|
|
0
|
next; |
1171
|
|
|
|
|
|
|
} |
1172
|
|
|
|
|
|
|
|
1173
|
170
|
|
|
|
|
356
|
$value =~ s{ ( \$ \p{ID_START} \p{ID_CONTINUE}* ) }{$vars{$1}}msxeg; |
|
185
|
|
|
|
|
542
|
|
1174
|
170
|
|
|
|
|
556
|
$vars{$name} = $value; |
1175
|
|
|
|
|
|
|
} |
1176
|
|
|
|
|
|
|
|
1177
|
4
|
|
|
|
|
20
|
return \%vars; |
1178
|
|
|
|
|
|
|
} |
1179
|
|
|
|
|
|
|
|
1180
|
|
|
|
|
|
|
sub IsCLDREmpty { |
1181
|
460
|
|
|
460
|
0
|
198021
|
return ''; |
1182
|
|
|
|
|
|
|
} |
1183
|
|
|
|
|
|
|
|
1184
|
|
|
|
|
|
|
# Test for missing Unicode properties |
1185
|
|
|
|
|
|
|
my $has_emoji = eval '1 !~ /\p{emoji}/'; |
1186
|
|
|
|
|
|
|
my $has_Grapheme_Cluster_Break_ZWJ = eval '1 !~ /\p{Grapheme_Cluster_Break=ZWJ}/'; |
1187
|
|
|
|
|
|
|
my $has_Grapheme_Cluster_Break_E_Base = eval '1 !~ /\p{Grapheme_Cluster_Break=E_Base}/'; |
1188
|
|
|
|
|
|
|
my $has_Grapheme_Cluster_Break_E_Base_GAZ = eval '1 !~ /\p{Grapheme_Cluster_Break=E_Base_GAZ}/'; |
1189
|
|
|
|
|
|
|
my $has_Grapheme_Cluster_Break_E_Modifier = eval '1 !~ /\p{Grapheme_Cluster_Break=E_Modifier}/'; |
1190
|
|
|
|
|
|
|
my $has_Word_Break_ZWJ = eval '1 !~ /\p{Word_Break=ZWJ}/'; |
1191
|
|
|
|
|
|
|
my $has_Word_Break_E_Base = eval '1 !~ /\p{Word_Break=E_Base}/'; |
1192
|
|
|
|
|
|
|
my $has_Word_Break_E_Base_GAZ = eval '1 !~ /\p{Word_Break=E_Base_GAZ}/'; |
1193
|
|
|
|
|
|
|
my $has_Word_Break_E_Modifier = eval '1 !~ /\p{Word_Break=E_Modifier}/'; |
1194
|
|
|
|
|
|
|
my $has_Word_Break_Hebrew_Letter = eval '1 !~ \p{Word_Break=Hebrew_Letter}/'; |
1195
|
|
|
|
|
|
|
my $has_Word_Break_Single_Quote = eval '1 !~ \p{Word_Break=Single_Quote}/'; |
1196
|
|
|
|
|
|
|
my $has_Line_Break_ZWJ = eval '1 !~ /\p{Line_Break=ZWJ}/'; |
1197
|
|
|
|
|
|
|
my $has_Line_Break_E_Base = eval '1 !~ /\p{Line_Break=E_Base}/'; |
1198
|
|
|
|
|
|
|
my $has_Line_Break_E_Base_GAZ = eval '1 !~ /\p{Line_Break=E_Base_GAZ}/'; |
1199
|
|
|
|
|
|
|
my $has_Line_Break_E_Modifier = eval '1 !~ /\p{Line_Break=E_Modifier}/'; |
1200
|
|
|
|
|
|
|
my $has_Extended_Pictographic = eval '1 !~ /\p{Extended_Pictographic}/'; |
1201
|
|
|
|
|
|
|
my $has_Word_Break_WSegSpace = eval '1 !~ /\p{Word_Break=WSegSpace}/'; |
1202
|
|
|
|
|
|
|
|
1203
|
|
|
|
|
|
|
sub _fix_missing_unicode_properties { |
1204
|
341
|
|
|
341
|
|
558
|
my $regex = shift; |
1205
|
|
|
|
|
|
|
|
1206
|
341
|
100
|
|
|
|
692
|
return '' unless defined $regex; |
1207
|
|
|
|
|
|
|
|
1208
|
340
|
50
|
|
|
|
1225
|
$regex =~ s/\\(p)\{emoji\}/\\${1}{IsCLDREmpty}/ig |
1209
|
|
|
|
|
|
|
unless $has_emoji; |
1210
|
|
|
|
|
|
|
|
1211
|
340
|
50
|
|
|
|
658
|
$regex =~ s/\\(p)\{Grapheme_Cluster_Break=ZWJ\}/\\${1}{IsCLDREmpty}/ig |
1212
|
|
|
|
|
|
|
unless $has_Grapheme_Cluster_Break_ZWJ; |
1213
|
|
|
|
|
|
|
|
1214
|
340
|
50
|
|
|
|
634
|
$regex =~ s/\\(p)\{Grapheme_Cluster_Break=E_Base\}/\\${1}{IsCLDREmpty}/ig |
1215
|
|
|
|
|
|
|
unless $has_Grapheme_Cluster_Break_E_Base; |
1216
|
|
|
|
|
|
|
|
1217
|
340
|
50
|
|
|
|
629
|
$regex =~ s/\\(p)\{Grapheme_Cluster_Break=E_Base_GAZ\}/\\${1}{IsCLDREmpty}/ig |
1218
|
|
|
|
|
|
|
unless $has_Grapheme_Cluster_Break_E_Base_GAZ; |
1219
|
|
|
|
|
|
|
|
1220
|
340
|
50
|
|
|
|
583
|
$regex =~ s/\\(p)\{Grapheme_Cluster_Break=E_Modifier\}/\\${1}{IsCLDREmpty}/ig |
1221
|
|
|
|
|
|
|
unless $has_Grapheme_Cluster_Break_E_Modifier; |
1222
|
|
|
|
|
|
|
|
1223
|
340
|
50
|
|
|
|
615
|
$regex =~ s/\\(p)\{Word_Break=ZWJ\}/\\${1}{IsCLDREmpty}/ig |
1224
|
|
|
|
|
|
|
unless $has_Word_Break_ZWJ; |
1225
|
|
|
|
|
|
|
|
1226
|
340
|
50
|
|
|
|
629
|
$regex =~ s/\\(p)\{Word_Break=E_Base\}/\\${1}{IsCLDREmpty}/ig |
1227
|
|
|
|
|
|
|
unless $has_Word_Break_E_Base; |
1228
|
|
|
|
|
|
|
|
1229
|
340
|
50
|
|
|
|
626
|
$regex =~ s/\\(p)\{Word_Break=E_Base_GAZ\}/\\${1}{IsCLDREmpty}/ig |
1230
|
|
|
|
|
|
|
unless $has_Word_Break_E_Base_GAZ; |
1231
|
|
|
|
|
|
|
|
1232
|
340
|
50
|
|
|
|
572
|
$regex =~ s/\\(p)\{Word_Break=E_Modifier\}/\\${1}{IsCLDREmpty}/ig |
1233
|
|
|
|
|
|
|
unless $has_Word_Break_E_Modifier; |
1234
|
|
|
|
|
|
|
|
1235
|
340
|
50
|
|
|
|
950
|
$regex =~ s/\\(p)\{Word_Break=Hebrew_Letter\}/\\${1}{IsCLDREmpty}/ig |
1236
|
|
|
|
|
|
|
unless $has_Word_Break_Hebrew_Letter; |
1237
|
|
|
|
|
|
|
|
1238
|
340
|
50
|
|
|
|
886
|
$regex =~ s/\\(p)\{Word_Break=Single_Quote\}/\\${1}{IsCLDREmpty}/ig |
1239
|
|
|
|
|
|
|
unless $has_Word_Break_Single_Quote; |
1240
|
|
|
|
|
|
|
|
1241
|
340
|
50
|
|
|
|
638
|
$regex =~ s/\\(p)\{Line_Break=ZWJ\}/\\${1}{IsCLDREmpty}/ig |
1242
|
|
|
|
|
|
|
unless $has_Line_Break_ZWJ; |
1243
|
|
|
|
|
|
|
|
1244
|
340
|
50
|
|
|
|
609
|
$regex =~ s/\\(p)\{Line_Break=E_Base\}/\\${1}{IsCLDREmpty}/ig |
1245
|
|
|
|
|
|
|
unless $has_Line_Break_E_Base; |
1246
|
|
|
|
|
|
|
|
1247
|
340
|
50
|
|
|
|
833
|
$regex =~ s/\\(p)\{Line_Break=E_Base_GAZ\}/\\${1}{IsCLDREmpty}/ig |
1248
|
|
|
|
|
|
|
unless $has_Line_Break_E_Base_GAZ; |
1249
|
|
|
|
|
|
|
|
1250
|
340
|
50
|
|
|
|
658
|
$regex =~ s/\\(p)\{Line_Break=E_Modifier\}/\\${1}{IsCLDREmpty}/ig |
1251
|
|
|
|
|
|
|
unless $has_Line_Break_E_Modifier; |
1252
|
|
|
|
|
|
|
|
1253
|
340
|
50
|
|
|
|
906
|
$regex =~ s/\\(p)\{Extended_Pictographic\}/\\${1}{IsCLDREmpty}/ig |
1254
|
|
|
|
|
|
|
unless $has_Extended_Pictographic; |
1255
|
|
|
|
|
|
|
|
1256
|
340
|
50
|
|
|
|
903
|
$regex =~ s/\\(p)\{Word_Break=WSegSpace\}/\\${1}{IsCLDREmpty}/ig |
1257
|
|
|
|
|
|
|
unless $has_Word_Break_WSegSpace; |
1258
|
|
|
|
|
|
|
|
1259
|
340
|
|
|
|
|
1336
|
return $regex; |
1260
|
|
|
|
|
|
|
} |
1261
|
|
|
|
|
|
|
|
1262
|
|
|
|
|
|
|
sub _build_break_rules { |
1263
|
4
|
|
|
4
|
|
15
|
my ($self, $vars, $what) = @_; |
1264
|
|
|
|
|
|
|
|
1265
|
4
|
|
|
|
|
15
|
my $name = "${what}_rules"; |
1266
|
4
|
|
|
|
|
16
|
my @bundles = $self->_find_bundle($name); |
1267
|
|
|
|
|
|
|
|
1268
|
4
|
|
|
|
|
40
|
my %rules; |
1269
|
4
|
|
|
|
|
13
|
foreach my $bundle (reverse @bundles) { |
1270
|
4
|
|
|
|
|
12
|
%rules = (%rules, %{$bundle->$name}); |
|
4
|
|
|
|
|
142
|
|
1271
|
|
|
|
|
|
|
} |
1272
|
|
|
|
|
|
|
|
1273
|
4
|
|
|
|
|
14
|
my @rules; |
1274
|
4
|
|
|
|
|
47
|
foreach my $rule_number ( sort { $a <=> $b } keys %rules ) { |
|
457
|
|
|
|
|
618
|
|
1275
|
|
|
|
|
|
|
# Test for deleted rules |
1276
|
112
|
50
|
|
|
|
807
|
next unless defined $rules{$rule_number}; |
1277
|
|
|
|
|
|
|
|
1278
|
112
|
|
|
|
|
852
|
$rules{$rule_number} =~ s{ ( \$ \p{ID_START} \p{ID_CONTINUE}* ) }{ _fix_missing_unicode_properties($vars->{$1}) }msxeg; |
|
337
|
|
|
|
|
1068
|
|
1279
|
112
|
|
|
|
|
1241
|
my ($first, $opp, $second) = split /(Ã|÷)/, $rules{$rule_number}; |
1280
|
|
|
|
|
|
|
|
1281
|
112
|
|
|
|
|
270
|
foreach my $operand ($first, $second) { |
1282
|
224
|
100
|
|
|
|
99346
|
if ($operand =~ m{ \S }msx) { |
1283
|
189
|
|
|
|
|
4633
|
$operand = _unicode_to_perl($operand); |
1284
|
|
|
|
|
|
|
} |
1285
|
|
|
|
|
|
|
else { |
1286
|
35
|
|
|
|
|
81
|
$operand = '.'; |
1287
|
|
|
|
|
|
|
} |
1288
|
|
|
|
|
|
|
} |
1289
|
|
|
|
|
|
|
|
1290
|
21
|
|
|
21
|
|
64965
|
no warnings 'deprecated'; |
|
21
|
|
|
|
|
54
|
|
|
21
|
|
|
|
|
48909
|
|
1291
|
112
|
100
|
|
|
|
98714
|
push @rules, [qr{$first}msx, qr{$second}msx, ($opp eq 'Ã' ? 1 : 0)]; |
1292
|
|
|
|
|
|
|
} |
1293
|
|
|
|
|
|
|
|
1294
|
4
|
|
|
|
|
42
|
push @rules, [ '.', '.', 0 ]; |
1295
|
|
|
|
|
|
|
|
1296
|
4
|
|
|
|
|
92
|
return \@rules; |
1297
|
|
|
|
|
|
|
} |
1298
|
|
|
|
|
|
|
|
1299
|
|
|
|
|
|
|
sub BUILDARGS { |
1300
|
106
|
|
|
106
|
0
|
638040
|
my $self = shift; |
1301
|
106
|
|
|
|
|
370
|
my %args; |
1302
|
|
|
|
|
|
|
|
1303
|
|
|
|
|
|
|
# Used for arguments when we call new from our own code |
1304
|
106
|
|
|
|
|
333
|
my %internal_args = (); |
1305
|
106
|
50
|
66
|
|
|
808
|
if (@_ > 1 && ref $_[-1] eq 'HASH') { |
1306
|
0
|
|
|
|
|
0
|
%internal_args = %{pop @_}; |
|
0
|
|
|
|
|
0
|
|
1307
|
|
|
|
|
|
|
} |
1308
|
|
|
|
|
|
|
|
1309
|
106
|
100
|
66
|
|
|
875
|
if (1 == @_ && ! ref $_[0]) { |
1310
|
85
|
|
|
|
|
1045
|
my ($language, $script, $region, $variant, $extensions) |
1311
|
|
|
|
|
|
|
= $_[0]=~/^ |
1312
|
|
|
|
|
|
|
([a-zA-Z]+) |
1313
|
|
|
|
|
|
|
(?:[-_]([a-zA-Z]{4}))? |
1314
|
|
|
|
|
|
|
(?:[-_]([a-zA-Z]{2,3}))? |
1315
|
|
|
|
|
|
|
(?:[-_]([a-zA-Z0-9]+))? |
1316
|
|
|
|
|
|
|
(?:[-_]u[_-](.+))? |
1317
|
|
|
|
|
|
|
$/x; |
1318
|
|
|
|
|
|
|
|
1319
|
85
|
100
|
100
|
|
|
588
|
if (! defined $script && length $language == 4) { |
1320
|
1
|
|
|
|
|
3
|
$script = $language; |
1321
|
1
|
|
|
|
|
2
|
$language = undef; |
1322
|
|
|
|
|
|
|
} |
1323
|
|
|
|
|
|
|
|
1324
|
85
|
|
|
|
|
345
|
foreach ($language, $script, $region, $variant) { |
1325
|
340
|
100
|
|
|
|
874
|
$_ = '' unless defined $_; |
1326
|
|
|
|
|
|
|
} |
1327
|
|
|
|
|
|
|
|
1328
|
|
|
|
|
|
|
%args = ( |
1329
|
85
|
|
|
|
|
729
|
language_id => $language, |
1330
|
|
|
|
|
|
|
script_id => $script, |
1331
|
|
|
|
|
|
|
region_id => $region, |
1332
|
|
|
|
|
|
|
variant_id => $variant, |
1333
|
|
|
|
|
|
|
extensions => $extensions, |
1334
|
|
|
|
|
|
|
); |
1335
|
|
|
|
|
|
|
} |
1336
|
|
|
|
|
|
|
|
1337
|
106
|
100
|
|
|
|
537
|
if (! keys %args ) { |
1338
|
|
|
|
|
|
|
%args = ref $_[0] |
1339
|
21
|
50
|
|
|
|
128
|
? %{$_[0]} |
|
0
|
|
|
|
|
0
|
|
1340
|
|
|
|
|
|
|
: @_ |
1341
|
|
|
|
|
|
|
} |
1342
|
|
|
|
|
|
|
|
1343
|
|
|
|
|
|
|
# Split up the extensions |
1344
|
106
|
100
|
66
|
|
|
585
|
if ( defined $args{extensions} && ! ref $args{extensions} ) { |
1345
|
|
|
|
|
|
|
$args{extensions} = { |
1346
|
16
|
|
|
|
|
62
|
map {lc} |
1347
|
|
|
|
|
|
|
split /[_-]/, $args{extensions} |
1348
|
6
|
|
|
|
|
43
|
}; |
1349
|
|
|
|
|
|
|
} |
1350
|
|
|
|
|
|
|
|
1351
|
|
|
|
|
|
|
# Fix casing of args |
1352
|
106
|
100
|
|
|
|
693
|
$args{language_id} = lc $args{language_id} if defined $args{language_id}; |
1353
|
106
|
100
|
|
|
|
691
|
$args{script_id} = ucfirst lc $args{script_id} if defined $args{script_id}; |
1354
|
106
|
100
|
|
|
|
561
|
$args{region_id} = uc $args{region_id} if defined $args{region_id}; |
1355
|
106
|
100
|
|
|
|
512
|
$args{variant_id} = uc $args{variant_id} if defined $args{variant_id}; |
1356
|
|
|
|
|
|
|
|
1357
|
|
|
|
|
|
|
# Set up undefined language |
1358
|
106
|
|
100
|
|
|
455
|
$args{language_id} ||= 'und'; |
1359
|
|
|
|
|
|
|
|
1360
|
106
|
|
|
|
|
1015
|
$self->SUPER::BUILDARGS(%args, %internal_args); |
1361
|
|
|
|
|
|
|
} |
1362
|
|
|
|
|
|
|
|
1363
|
|
|
|
|
|
|
sub BUILD { |
1364
|
|
|
|
|
|
|
my ($self, $args) = @_; |
1365
|
|
|
|
|
|
|
|
1366
|
|
|
|
|
|
|
# Check that the args are valid |
1367
|
|
|
|
|
|
|
# also check for aliases |
1368
|
|
|
|
|
|
|
$args->{language_id} = $self->language_aliases->{$args->{language_id}} |
1369
|
|
|
|
|
|
|
// $args->{language_id}; |
1370
|
|
|
|
|
|
|
|
1371
|
|
|
|
|
|
|
die "Invalid language" if $args->{language_id} |
1372
|
|
|
|
|
|
|
&& ! first { $args->{language_id} eq $_ } $self->valid_languages; |
1373
|
|
|
|
|
|
|
|
1374
|
|
|
|
|
|
|
die "Invalid script" if $args->{script_id} |
1375
|
|
|
|
|
|
|
&& ! first { ucfirst lc $args->{script_id} eq ucfirst lc $_ } $self->valid_scripts; |
1376
|
|
|
|
|
|
|
|
1377
|
|
|
|
|
|
|
die "Invalid region" if $args->{region_id} |
1378
|
|
|
|
|
|
|
&& ( ! ( first { uc $args->{region_id} eq uc $_ } $self->valid_regions ) |
1379
|
|
|
|
|
|
|
&& ( ! $self->region_aliases->{$self->{region_id}} ) |
1380
|
|
|
|
|
|
|
); |
1381
|
|
|
|
|
|
|
|
1382
|
|
|
|
|
|
|
die "Invalid variant" if $args->{variant_id} |
1383
|
|
|
|
|
|
|
&& ( ! ( first { uc $args->{variant_id} eq uc $_ } $self->valid_variants ) |
1384
|
|
|
|
|
|
|
&& ( ! $self->variant_aliases->{lc $self->{variant_id}} ) |
1385
|
|
|
|
|
|
|
); |
1386
|
|
|
|
|
|
|
|
1387
|
|
|
|
|
|
|
if ($args->{extensions}) { |
1388
|
|
|
|
|
|
|
my %valid_keys = $self->valid_keys; |
1389
|
|
|
|
|
|
|
my %key_aliases = $self->key_names; |
1390
|
|
|
|
|
|
|
my @keys = keys %{$args->{extensions}}; |
1391
|
|
|
|
|
|
|
|
1392
|
|
|
|
|
|
|
foreach my $key ( @keys ) { |
1393
|
|
|
|
|
|
|
my $canonical_key = exists $key_aliases{$key} ? $key_aliases{$key} : undef; |
1394
|
|
|
|
|
|
|
$canonical_key //= $key; |
1395
|
|
|
|
|
|
|
if ($canonical_key ne $key) { |
1396
|
|
|
|
|
|
|
$args->{extensions}{$canonical_key} = delete $args->{extensions}{$key}; |
1397
|
|
|
|
|
|
|
} |
1398
|
|
|
|
|
|
|
|
1399
|
|
|
|
|
|
|
$key = $canonical_key; |
1400
|
|
|
|
|
|
|
die "Invalid extension name" unless exists $valid_keys{$key}; |
1401
|
|
|
|
|
|
|
die "Invalid extension value" unless |
1402
|
|
|
|
|
|
|
first { $_ eq $args->{extensions}{$key} } @{$valid_keys{$key}}; |
1403
|
|
|
|
|
|
|
} |
1404
|
|
|
|
|
|
|
|
1405
|
|
|
|
|
|
|
$self->_set_extensions($args->{extensions}); |
1406
|
|
|
|
|
|
|
} |
1407
|
|
|
|
|
|
|
|
1408
|
|
|
|
|
|
|
# Check for variant aliases |
1409
|
|
|
|
|
|
|
if ($args->{variant_id} && (my $variant_alias = $self->variant_aliases->{lc $self->variant_id})) { |
1410
|
|
|
|
|
|
|
delete $args->{variant_id}; |
1411
|
|
|
|
|
|
|
my ($what) = keys %{$variant_alias}; |
1412
|
|
|
|
|
|
|
my ($value) = values %{$variant_alias}; |
1413
|
|
|
|
|
|
|
$args->{$what} = $value; |
1414
|
|
|
|
|
|
|
} |
1415
|
|
|
|
|
|
|
|
1416
|
|
|
|
|
|
|
# Now set up the module |
1417
|
|
|
|
|
|
|
$self->_build_module; |
1418
|
|
|
|
|
|
|
} |
1419
|
|
|
|
|
|
|
|
1420
|
|
|
|
|
|
|
after 'BUILD' => sub { |
1421
|
|
|
|
|
|
|
|
1422
|
|
|
|
|
|
|
my $self = shift; |
1423
|
|
|
|
|
|
|
|
1424
|
|
|
|
|
|
|
# Fix up likely sub tags |
1425
|
|
|
|
|
|
|
|
1426
|
|
|
|
|
|
|
my $likely_subtags = $self->likely_subtags; |
1427
|
|
|
|
|
|
|
my $likely_subtag; |
1428
|
|
|
|
|
|
|
my ($language_id, $script_id, $region_id) = ($self->language_id, $self->script_id, $self->region_id); |
1429
|
|
|
|
|
|
|
|
1430
|
|
|
|
|
|
|
unless ($language_id ne 'und' && $script_id && $region_id ) { |
1431
|
|
|
|
|
|
|
$likely_subtag = $likely_subtags->{join '_', grep { length() } ($language_id, $script_id, $region_id)}; |
1432
|
|
|
|
|
|
|
|
1433
|
|
|
|
|
|
|
if (! $likely_subtag ) { |
1434
|
|
|
|
|
|
|
$likely_subtag = $likely_subtags->{join '_', $language_id, $region_id}; |
1435
|
|
|
|
|
|
|
} |
1436
|
|
|
|
|
|
|
|
1437
|
|
|
|
|
|
|
if (! $likely_subtag ) { |
1438
|
|
|
|
|
|
|
$likely_subtag = $likely_subtags->{join '_', $language_id, $script_id}; |
1439
|
|
|
|
|
|
|
} |
1440
|
|
|
|
|
|
|
|
1441
|
|
|
|
|
|
|
if (! $likely_subtag ) { |
1442
|
|
|
|
|
|
|
$likely_subtag = $likely_subtags->{$language_id}; |
1443
|
|
|
|
|
|
|
} |
1444
|
|
|
|
|
|
|
|
1445
|
|
|
|
|
|
|
if (! $likely_subtag ) { |
1446
|
|
|
|
|
|
|
$likely_subtag = $likely_subtags->{join '_', 'und', $script_id}; |
1447
|
|
|
|
|
|
|
} |
1448
|
|
|
|
|
|
|
} |
1449
|
|
|
|
|
|
|
|
1450
|
|
|
|
|
|
|
my ($likely_language_id, $likely_script_id, $likely_region_id); |
1451
|
|
|
|
|
|
|
if ($likely_subtag) { |
1452
|
|
|
|
|
|
|
($likely_language_id, $likely_script_id, $likely_region_id) = split /_/, $likely_subtag; |
1453
|
|
|
|
|
|
|
$likely_language_id = $language_id unless $language_id eq 'und'; |
1454
|
|
|
|
|
|
|
$likely_script_id = $script_id if length $script_id; |
1455
|
|
|
|
|
|
|
$likely_region_id = $region_id if length $region_id; |
1456
|
|
|
|
|
|
|
$self->_set_likely_subtag(__PACKAGE__->new(join '_',$likely_language_id, $likely_script_id, $likely_region_id)); |
1457
|
|
|
|
|
|
|
} |
1458
|
|
|
|
|
|
|
|
1459
|
|
|
|
|
|
|
# Fix up extension overrides |
1460
|
|
|
|
|
|
|
my $extensions = $self->extensions; |
1461
|
|
|
|
|
|
|
|
1462
|
|
|
|
|
|
|
foreach my $extention ( qw( ca cf co cu em fw hc lb lw ms nu rg sd ss tz va ) ) { |
1463
|
|
|
|
|
|
|
if (exists $extensions->{$extention}) { |
1464
|
|
|
|
|
|
|
my $default = "_set_default_$extention"; |
1465
|
|
|
|
|
|
|
$self->$default($extensions->{$extention}); |
1466
|
|
|
|
|
|
|
} |
1467
|
|
|
|
|
|
|
} |
1468
|
|
|
|
|
|
|
}; |
1469
|
|
|
|
|
|
|
|
1470
|
|
|
|
|
|
|
# Defaults get set by the -u- extension |
1471
|
|
|
|
|
|
|
# Calendar, currency format, collation order, etc. |
1472
|
|
|
|
|
|
|
# but not nu as that is done in the Numbering systems role |
1473
|
|
|
|
|
|
|
foreach my $default (qw( ca cf co cu em fw hc lb lw ms rg sd ss tz va)) { |
1474
|
|
|
|
|
|
|
has "_default_$default" => ( |
1475
|
|
|
|
|
|
|
is => 'ro', |
1476
|
|
|
|
|
|
|
isa => Str, |
1477
|
|
|
|
|
|
|
init_arg => undef, |
1478
|
|
|
|
|
|
|
default => '', |
1479
|
|
|
|
|
|
|
writer => "_set_default_$default", |
1480
|
|
|
|
|
|
|
); |
1481
|
|
|
|
|
|
|
|
1482
|
21
|
|
|
21
|
|
229
|
no strict 'refs'; |
|
21
|
|
|
|
|
50
|
|
|
21
|
|
|
|
|
10154
|
|
1483
|
|
|
|
|
|
|
*{"_test_default_$default"} = sub { |
1484
|
108
|
|
|
108
|
|
186
|
my $self = shift; |
1485
|
108
|
|
|
|
|
287
|
my $method = "_default_$default"; |
1486
|
108
|
|
|
|
|
600
|
return length $self->$method; |
1487
|
|
|
|
|
|
|
}; |
1488
|
|
|
|
|
|
|
} |
1489
|
|
|
|
|
|
|
|
1490
|
|
|
|
|
|
|
sub default_calendar { |
1491
|
68
|
|
|
68
|
1
|
142
|
my ($self, $region) = @_; |
1492
|
|
|
|
|
|
|
|
1493
|
68
|
|
|
|
|
120
|
my $default = ''; |
1494
|
68
|
100
|
|
|
|
199
|
if ($self->_test_default_ca) { |
1495
|
66
|
|
|
|
|
145
|
$default = $self->_default_ca(); |
1496
|
|
|
|
|
|
|
} |
1497
|
|
|
|
|
|
|
else { |
1498
|
2
|
|
|
|
|
10
|
my $calendar_preferences = $self->calendar_preferences(); |
1499
|
2
|
|
33
|
|
|
46
|
$region //= ( $self->region_id() || $self->likely_subtag->region_id ); |
|
|
|
33
|
|
|
|
|
1500
|
2
|
|
|
|
|
5
|
my $current_region = $region; |
1501
|
|
|
|
|
|
|
|
1502
|
2
|
|
|
|
|
8
|
while (! $default) { |
1503
|
10
|
|
|
|
|
20
|
$default = $calendar_preferences->{$current_region}; |
1504
|
10
|
100
|
|
|
|
19
|
if ($default) { |
1505
|
2
|
|
|
|
|
9
|
$default = $default->[0]; |
1506
|
|
|
|
|
|
|
} |
1507
|
|
|
|
|
|
|
else { |
1508
|
8
|
|
|
|
|
28
|
$current_region = $self->region_contained_by()->{$current_region} |
1509
|
|
|
|
|
|
|
} |
1510
|
|
|
|
|
|
|
} |
1511
|
2
|
|
|
|
|
43
|
$self->_set_default_ca($default); |
1512
|
|
|
|
|
|
|
} |
1513
|
68
|
|
|
|
|
220
|
return $default; |
1514
|
|
|
|
|
|
|
} |
1515
|
|
|
|
|
|
|
|
1516
|
|
|
|
|
|
|
sub default_currency_format { |
1517
|
20
|
|
|
20
|
1
|
45
|
my $self = shift; |
1518
|
|
|
|
|
|
|
|
1519
|
20
|
|
|
|
|
41
|
my $default = 'standard'; |
1520
|
20
|
50
|
|
|
|
82
|
if ($self->_test_default_cf) { |
1521
|
20
|
|
|
|
|
49
|
$default = $self->_default_cf(); |
1522
|
|
|
|
|
|
|
} |
1523
|
|
|
|
|
|
|
else { |
1524
|
0
|
|
|
|
|
0
|
$self->_set_default_cf($default); |
1525
|
|
|
|
|
|
|
} |
1526
|
|
|
|
|
|
|
|
1527
|
20
|
|
|
|
|
82
|
return $default; |
1528
|
|
|
|
|
|
|
} |
1529
|
|
|
|
|
|
|
|
1530
|
|
|
|
|
|
|
use overload |
1531
|
40
|
|
|
40
|
|
156
|
'bool' => sub { 1 }, |
1532
|
21
|
|
|
21
|
|
183
|
'""' => sub {shift->id}; |
|
21
|
|
|
3
|
|
48
|
|
|
21
|
|
|
|
|
299
|
|
|
3
|
|
|
|
|
1421
|
|
1533
|
|
|
|
|
|
|
|
1534
|
|
|
|
|
|
|
sub _build_id { |
1535
|
36
|
|
|
36
|
|
64963
|
my $self = shift; |
1536
|
36
|
|
|
|
|
1452
|
my $string = lc $self->language_id; |
1537
|
|
|
|
|
|
|
|
1538
|
36
|
100
|
|
|
|
215
|
if ($self->script_id) { |
1539
|
28
|
|
|
|
|
246
|
$string.= '_' . ucfirst lc $self->script_id; |
1540
|
|
|
|
|
|
|
} |
1541
|
|
|
|
|
|
|
|
1542
|
36
|
100
|
|
|
|
824
|
if ($self->region_id) { |
1543
|
28
|
|
|
|
|
551
|
$string.= '_' . uc $self->region_id; |
1544
|
|
|
|
|
|
|
} |
1545
|
|
|
|
|
|
|
|
1546
|
36
|
100
|
|
|
|
574
|
if ($self->variant_id) { |
1547
|
3
|
|
|
|
|
15
|
$string.= '_' . uc $self->variant_id; |
1548
|
|
|
|
|
|
|
} |
1549
|
|
|
|
|
|
|
|
1550
|
36
|
50
|
|
|
|
352
|
if (defined $self->extensions) { |
1551
|
0
|
|
|
|
|
0
|
$string.= '_u'; |
1552
|
0
|
|
|
|
|
0
|
foreach my $key (sort keys %{$self->extensions}) { |
|
0
|
|
|
|
|
0
|
|
1553
|
0
|
|
|
|
|
0
|
my $value = $self->extensions->{$key}; |
1554
|
0
|
|
|
|
|
0
|
$string .= "_${key}_$value"; |
1555
|
|
|
|
|
|
|
} |
1556
|
0
|
|
|
|
|
0
|
$string =~ s/_u$//; |
1557
|
|
|
|
|
|
|
} |
1558
|
|
|
|
|
|
|
|
1559
|
36
|
|
|
|
|
683
|
return $string; |
1560
|
|
|
|
|
|
|
} |
1561
|
|
|
|
|
|
|
|
1562
|
|
|
|
|
|
|
sub _get_english { |
1563
|
0
|
|
|
0
|
|
0
|
my $self = shift; |
1564
|
0
|
|
|
|
|
0
|
my $english; |
1565
|
0
|
0
|
|
|
|
0
|
if ($self->language_id eq 'en') { |
1566
|
0
|
|
|
|
|
0
|
$english = $self; |
1567
|
|
|
|
|
|
|
} |
1568
|
|
|
|
|
|
|
else { |
1569
|
0
|
|
|
|
|
0
|
$english = Locale::CLDR->new('en_Latn_US'); |
1570
|
|
|
|
|
|
|
} |
1571
|
|
|
|
|
|
|
|
1572
|
0
|
|
|
|
|
0
|
return $english; |
1573
|
|
|
|
|
|
|
} |
1574
|
|
|
|
|
|
|
|
1575
|
|
|
|
|
|
|
sub _build_name { |
1576
|
0
|
|
|
0
|
|
0
|
my $self = shift; |
1577
|
|
|
|
|
|
|
|
1578
|
0
|
|
|
|
|
0
|
return $self->_get_english->native_name($self); |
1579
|
|
|
|
|
|
|
} |
1580
|
|
|
|
|
|
|
|
1581
|
|
|
|
|
|
|
sub _build_native_name { |
1582
|
0
|
|
|
0
|
|
0
|
my ($self, $for) = @_; |
1583
|
|
|
|
|
|
|
|
1584
|
0
|
|
|
|
|
0
|
return $self->locale_name($for); |
1585
|
|
|
|
|
|
|
} |
1586
|
|
|
|
|
|
|
|
1587
|
|
|
|
|
|
|
sub _build_language { |
1588
|
0
|
|
|
0
|
|
0
|
my $self = shift; |
1589
|
|
|
|
|
|
|
|
1590
|
0
|
|
|
|
|
0
|
return $self->_get_english->native_language($self); |
1591
|
|
|
|
|
|
|
} |
1592
|
|
|
|
|
|
|
|
1593
|
|
|
|
|
|
|
sub _build_native_language { |
1594
|
0
|
|
|
0
|
|
0
|
my ($self, $for) = @_; |
1595
|
|
|
|
|
|
|
|
1596
|
0
|
|
0
|
|
|
0
|
return $self->language_name($for) // ''; |
1597
|
|
|
|
|
|
|
} |
1598
|
|
|
|
|
|
|
|
1599
|
|
|
|
|
|
|
sub _build_script { |
1600
|
0
|
|
|
0
|
|
0
|
my $self = shift; |
1601
|
|
|
|
|
|
|
|
1602
|
0
|
|
|
|
|
0
|
return $self->_get_english->native_script($self); |
1603
|
|
|
|
|
|
|
} |
1604
|
|
|
|
|
|
|
|
1605
|
|
|
|
|
|
|
sub _build_native_script { |
1606
|
0
|
|
|
0
|
|
0
|
my ($self, $for) = @_; |
1607
|
|
|
|
|
|
|
|
1608
|
0
|
|
|
|
|
0
|
return $self->script_name($for); |
1609
|
|
|
|
|
|
|
} |
1610
|
|
|
|
|
|
|
|
1611
|
|
|
|
|
|
|
sub _build_region { |
1612
|
0
|
|
|
0
|
|
0
|
my $self = shift; |
1613
|
|
|
|
|
|
|
|
1614
|
0
|
|
|
|
|
0
|
return $self->_get_english->native_region($self); |
1615
|
|
|
|
|
|
|
} |
1616
|
|
|
|
|
|
|
|
1617
|
|
|
|
|
|
|
sub _build_native_region { |
1618
|
0
|
|
|
0
|
|
0
|
my ($self, $for) = @_; |
1619
|
|
|
|
|
|
|
|
1620
|
0
|
|
|
|
|
0
|
return $self->region_name($for); |
1621
|
|
|
|
|
|
|
} |
1622
|
|
|
|
|
|
|
|
1623
|
|
|
|
|
|
|
sub _build_variant { |
1624
|
0
|
|
|
0
|
|
0
|
my $self = shift; |
1625
|
|
|
|
|
|
|
|
1626
|
0
|
|
|
|
|
0
|
return $self->_get_english->native_variant($self); |
1627
|
|
|
|
|
|
|
} |
1628
|
|
|
|
|
|
|
|
1629
|
|
|
|
|
|
|
sub _build_native_variant { |
1630
|
0
|
|
|
0
|
|
0
|
my ($self, $for) = @_; |
1631
|
|
|
|
|
|
|
|
1632
|
0
|
|
|
|
|
0
|
return $self->variant_name($for); |
1633
|
|
|
|
|
|
|
} |
1634
|
|
|
|
|
|
|
|
1635
|
|
|
|
|
|
|
# Method to locate the resource bundle with the required data |
1636
|
|
|
|
|
|
|
sub _find_bundle { |
1637
|
3363
|
|
|
3363
|
|
6910
|
my ($self, $method_name) = @_; |
1638
|
3363
|
50
|
|
|
|
72084
|
my $id = $self->_has_likely_subtag() |
1639
|
|
|
|
|
|
|
? $self->likely_subtag()->id() |
1640
|
|
|
|
|
|
|
: $self->id(); |
1641
|
|
|
|
|
|
|
|
1642
|
|
|
|
|
|
|
|
1643
|
3363
|
100
|
|
|
|
73577
|
if ($self->method_cache->{$id}{$method_name}) { |
1644
|
|
|
|
|
|
|
return wantarray |
1645
|
2451
|
|
|
|
|
36382
|
? @{$self->method_cache->{$id}{$method_name}} |
1646
|
3230
|
100
|
|
|
|
34199
|
: $self->method_cache->{$id}{$method_name}[0]; |
1647
|
|
|
|
|
|
|
} |
1648
|
|
|
|
|
|
|
|
1649
|
133
|
|
|
|
|
1872
|
foreach my $module (@{mro::get_linear_isa( ref ($self->module ))}) { |
|
133
|
|
|
|
|
2503
|
|
1650
|
665
|
100
|
|
|
|
8141
|
last if $module eq 'Moo::Object'; |
1651
|
532
|
100
|
|
|
|
788
|
if (defined &{"${module}::${method_name}"}) { |
|
532
|
|
|
|
|
3706
|
|
1652
|
123
|
|
|
|
|
277
|
push @{$self->method_cache->{$id}{$method_name}}, $module->new; |
|
123
|
|
|
|
|
2375
|
|
1653
|
|
|
|
|
|
|
} |
1654
|
|
|
|
|
|
|
} |
1655
|
|
|
|
|
|
|
|
1656
|
133
|
100
|
|
|
|
2642
|
return unless $self->method_cache->{$id}{$method_name}; |
1657
|
|
|
|
|
|
|
return wantarray |
1658
|
66
|
|
|
|
|
1114
|
? @{$self->method_cache->{$id}{$method_name}} |
1659
|
81
|
100
|
|
|
|
1340
|
: $self->method_cache->{$id}{$method_name}[0]; |
1660
|
|
|
|
|
|
|
} |
1661
|
|
|
|
|
|
|
|
1662
|
|
|
|
|
|
|
=back |
1663
|
|
|
|
|
|
|
|
1664
|
|
|
|
|
|
|
=head2 Names |
1665
|
|
|
|
|
|
|
|
1666
|
|
|
|
|
|
|
These methods allow you to pass in a locale, either by C<id> or as a |
1667
|
|
|
|
|
|
|
Locale::CLDR object and return an name formatted in the locale of $self. |
1668
|
|
|
|
|
|
|
If you don't pass in a locale then it will use $self. |
1669
|
|
|
|
|
|
|
|
1670
|
|
|
|
|
|
|
=over 4 |
1671
|
|
|
|
|
|
|
|
1672
|
|
|
|
|
|
|
=item locale_name($name) |
1673
|
|
|
|
|
|
|
|
1674
|
|
|
|
|
|
|
Returns the given locale name in the current locale's format. The name can be |
1675
|
|
|
|
|
|
|
a locale id or a locale object or non existent. If a name is not passed in |
1676
|
|
|
|
|
|
|
then the name of the current locale is returned. |
1677
|
|
|
|
|
|
|
|
1678
|
|
|
|
|
|
|
=cut |
1679
|
|
|
|
|
|
|
|
1680
|
|
|
|
|
|
|
sub locale_name { |
1681
|
6
|
|
|
6
|
1
|
2522
|
my ($self, $name) = @_; |
1682
|
6
|
|
66
|
|
|
42
|
$name //= $self; |
1683
|
|
|
|
|
|
|
|
1684
|
6
|
50
|
|
|
|
54
|
my $code = ref $name |
|
|
100
|
|
|
|
|
|
1685
|
|
|
|
|
|
|
? join ( '_', $name->language_id, $name->region_id ? $name->region_id : () ) |
1686
|
|
|
|
|
|
|
: $name; |
1687
|
|
|
|
|
|
|
|
1688
|
6
|
|
|
|
|
30
|
my @bundles = $self->_find_bundle('display_name_language'); |
1689
|
|
|
|
|
|
|
|
1690
|
6
|
|
|
|
|
62
|
foreach my $bundle (@bundles) { |
1691
|
6
|
|
|
|
|
54
|
my $display_name = $bundle->display_name_language->($code); |
1692
|
6
|
100
|
|
|
|
56
|
return $display_name if defined $display_name; |
1693
|
|
|
|
|
|
|
} |
1694
|
|
|
|
|
|
|
|
1695
|
|
|
|
|
|
|
# $name can be a string or a Locale::CLDR::Locales::* |
1696
|
2
|
50
|
|
|
|
10
|
if (! ref $name) { |
1697
|
|
|
|
|
|
|
# Wrap in an eval to stop it dieing on unknown locales |
1698
|
2
|
|
|
|
|
4
|
$name = eval { Locale::CLDR->new($name) }; |
|
2
|
|
|
|
|
60
|
|
1699
|
|
|
|
|
|
|
} |
1700
|
|
|
|
|
|
|
|
1701
|
|
|
|
|
|
|
# Now we have to process each individual element |
1702
|
|
|
|
|
|
|
# to pass to the display name pattern |
1703
|
2
|
|
|
|
|
2561
|
my $language = $self->language_name($name); |
1704
|
2
|
|
|
|
|
13
|
my $script = $self->script_name($name); |
1705
|
2
|
|
|
|
|
10
|
my $region = $self->region_name($name); |
1706
|
2
|
|
|
|
|
11
|
my $variant = $self->variant_name($name); |
1707
|
|
|
|
|
|
|
|
1708
|
2
|
|
|
|
|
7
|
my $bundle = $self->_find_bundle('display_name_pattern'); |
1709
|
2
|
|
|
|
|
28
|
return $bundle |
1710
|
|
|
|
|
|
|
->display_name_pattern($language, $region, $script, $variant); |
1711
|
|
|
|
|
|
|
} |
1712
|
|
|
|
|
|
|
|
1713
|
|
|
|
|
|
|
=item language_name($language) |
1714
|
|
|
|
|
|
|
|
1715
|
|
|
|
|
|
|
Returns the language name in the current locale's format. The name can be |
1716
|
|
|
|
|
|
|
a locale language id or a locale object or non existent. If a name is not |
1717
|
|
|
|
|
|
|
passed in then the language name of the current locale is returned. |
1718
|
|
|
|
|
|
|
|
1719
|
|
|
|
|
|
|
=cut |
1720
|
|
|
|
|
|
|
|
1721
|
|
|
|
|
|
|
sub language_name { |
1722
|
8
|
|
|
8
|
1
|
31
|
my ($self, $name) = @_; |
1723
|
|
|
|
|
|
|
|
1724
|
8
|
|
66
|
|
|
49
|
$name //= $self; |
1725
|
|
|
|
|
|
|
|
1726
|
8
|
100
|
|
|
|
160
|
my $code = ref $name ? $name->language_id : eval { Locale::CLDR->new(language_id => $name)->language_id }; |
|
3
|
|
|
|
|
96
|
|
1727
|
|
|
|
|
|
|
|
1728
|
8
|
|
|
|
|
9447
|
my $language = undef; |
1729
|
8
|
|
|
|
|
59
|
my @bundles = $self->_find_bundle('display_name_language'); |
1730
|
8
|
100
|
|
|
|
94
|
if ($code) { |
1731
|
7
|
|
|
|
|
23
|
foreach my $bundle (@bundles) { |
1732
|
7
|
|
|
|
|
58
|
my $display_name = $bundle->display_name_language->($code); |
1733
|
7
|
50
|
|
|
|
38
|
if (defined $display_name) { |
1734
|
7
|
|
|
|
|
22
|
$language = $display_name; |
1735
|
7
|
|
|
|
|
25
|
last; |
1736
|
|
|
|
|
|
|
} |
1737
|
|
|
|
|
|
|
} |
1738
|
|
|
|
|
|
|
} |
1739
|
|
|
|
|
|
|
# If we don't have a display name for the language we try again |
1740
|
|
|
|
|
|
|
# with the und tag |
1741
|
8
|
100
|
|
|
|
34
|
if (! defined $language ) { |
1742
|
1
|
|
|
|
|
5
|
foreach my $bundle (@bundles) { |
1743
|
1
|
|
|
|
|
9
|
my $display_name = $bundle->display_name_language->('und'); |
1744
|
1
|
50
|
|
|
|
6
|
if (defined $display_name) { |
1745
|
1
|
|
|
|
|
4
|
$language = $display_name; |
1746
|
1
|
|
|
|
|
3
|
last; |
1747
|
|
|
|
|
|
|
} |
1748
|
|
|
|
|
|
|
} |
1749
|
|
|
|
|
|
|
} |
1750
|
|
|
|
|
|
|
|
1751
|
8
|
|
|
|
|
59
|
return $language; |
1752
|
|
|
|
|
|
|
} |
1753
|
|
|
|
|
|
|
|
1754
|
|
|
|
|
|
|
=item all_languages() |
1755
|
|
|
|
|
|
|
|
1756
|
|
|
|
|
|
|
Returns a hash ref keyed on language id of all the languages the system |
1757
|
|
|
|
|
|
|
knows about. The values are the language names for the corresponding id's |
1758
|
|
|
|
|
|
|
|
1759
|
|
|
|
|
|
|
=cut |
1760
|
|
|
|
|
|
|
|
1761
|
|
|
|
|
|
|
sub all_languages { |
1762
|
1
|
|
|
1
|
1
|
2
|
my $self = shift; |
1763
|
|
|
|
|
|
|
|
1764
|
1
|
|
|
|
|
4
|
my @bundles = $self->_find_bundle('display_name_language'); |
1765
|
1
|
|
|
|
|
8
|
my %languages; |
1766
|
1
|
|
|
|
|
4
|
foreach my $bundle (@bundles) { |
1767
|
1
|
|
|
|
|
6
|
my $languages = $bundle->display_name_language->(); |
1768
|
|
|
|
|
|
|
|
1769
|
|
|
|
|
|
|
# Remove existing languages |
1770
|
1
|
|
|
|
|
3
|
delete @{$languages}{keys %languages}; |
|
1
|
|
|
|
|
3
|
|
1771
|
|
|
|
|
|
|
|
1772
|
|
|
|
|
|
|
# Assign new ones to the hash |
1773
|
1
|
|
|
|
|
300
|
@languages{keys %$languages} = values %$languages; |
1774
|
|
|
|
|
|
|
} |
1775
|
|
|
|
|
|
|
|
1776
|
1
|
|
|
|
|
11
|
return \%languages; |
1777
|
|
|
|
|
|
|
} |
1778
|
|
|
|
|
|
|
|
1779
|
|
|
|
|
|
|
=item script_name($script) |
1780
|
|
|
|
|
|
|
|
1781
|
|
|
|
|
|
|
Returns the script name in the current locale's format. The script can be |
1782
|
|
|
|
|
|
|
a locale script id or a locale object or non existent. If a script is not |
1783
|
|
|
|
|
|
|
passed in then the script name of the current locale is returned. |
1784
|
|
|
|
|
|
|
|
1785
|
|
|
|
|
|
|
=cut |
1786
|
|
|
|
|
|
|
|
1787
|
|
|
|
|
|
|
sub script_name { |
1788
|
7
|
|
|
7
|
1
|
27
|
my ($self, $name) = @_; |
1789
|
7
|
|
66
|
|
|
37
|
$name //= $self; |
1790
|
|
|
|
|
|
|
|
1791
|
7
|
100
|
|
|
|
32
|
if (! ref $name ) { |
1792
|
3
|
|
|
|
|
8
|
$name = eval {__PACKAGE__->new(script_id => $name)}; |
|
3
|
|
|
|
|
87
|
|
1793
|
|
|
|
|
|
|
} |
1794
|
|
|
|
|
|
|
|
1795
|
7
|
100
|
100
|
|
|
4368
|
if ( ref $name && ! $name->script_id ) { |
1796
|
3
|
|
|
|
|
13
|
return ''; |
1797
|
|
|
|
|
|
|
} |
1798
|
|
|
|
|
|
|
|
1799
|
4
|
|
|
|
|
13
|
my $script = undef; |
1800
|
4
|
|
|
|
|
28
|
my @bundles = $self->_find_bundle('display_name_script'); |
1801
|
4
|
100
|
|
|
|
56
|
if ($name) { |
1802
|
3
|
|
|
|
|
12
|
foreach my $bundle (@bundles) { |
1803
|
3
|
|
|
|
|
36
|
$script = $bundle->display_name_script->($name->script_id); |
1804
|
3
|
50
|
|
|
|
15
|
if (defined $script) { |
1805
|
3
|
|
|
|
|
9
|
last; |
1806
|
|
|
|
|
|
|
} |
1807
|
|
|
|
|
|
|
} |
1808
|
|
|
|
|
|
|
} |
1809
|
|
|
|
|
|
|
|
1810
|
4
|
100
|
|
|
|
30
|
if (! $script) { |
1811
|
1
|
|
|
|
|
4
|
foreach my $bundle (@bundles) { |
1812
|
1
|
|
|
|
|
10
|
$script = $bundle->display_name_script->('Zzzz'); |
1813
|
1
|
50
|
|
|
|
6
|
if (defined $script) { |
1814
|
1
|
|
|
|
|
3
|
last; |
1815
|
|
|
|
|
|
|
} |
1816
|
|
|
|
|
|
|
} |
1817
|
|
|
|
|
|
|
} |
1818
|
|
|
|
|
|
|
|
1819
|
4
|
|
|
|
|
9383
|
return $script; |
1820
|
|
|
|
|
|
|
} |
1821
|
|
|
|
|
|
|
|
1822
|
|
|
|
|
|
|
=item all_scripts() |
1823
|
|
|
|
|
|
|
|
1824
|
|
|
|
|
|
|
Returns a hash ref keyed on script id of all the scripts the system |
1825
|
|
|
|
|
|
|
knows about. The values are the script names for the corresponding id's |
1826
|
|
|
|
|
|
|
|
1827
|
|
|
|
|
|
|
=cut |
1828
|
|
|
|
|
|
|
|
1829
|
|
|
|
|
|
|
sub all_scripts { |
1830
|
1
|
|
|
1
|
1
|
2
|
my $self = shift; |
1831
|
|
|
|
|
|
|
|
1832
|
1
|
|
|
|
|
5
|
my @bundles = $self->_find_bundle('display_name_script'); |
1833
|
1
|
|
|
|
|
8
|
my %scripts; |
1834
|
1
|
|
|
|
|
4
|
foreach my $bundle (@bundles) { |
1835
|
1
|
|
|
|
|
9
|
my $scripts = $bundle->display_name_script->(); |
1836
|
|
|
|
|
|
|
|
1837
|
|
|
|
|
|
|
# Remove existing scripts |
1838
|
1
|
|
|
|
|
4
|
delete @{$scripts}{keys %scripts}; |
|
1
|
|
|
|
|
3
|
|
1839
|
|
|
|
|
|
|
|
1840
|
|
|
|
|
|
|
# Assign new ones to the hash |
1841
|
1
|
|
|
|
|
68
|
@scripts{keys %$scripts} = values %$scripts; |
1842
|
|
|
|
|
|
|
} |
1843
|
|
|
|
|
|
|
|
1844
|
1
|
|
|
|
|
8
|
return \%scripts; |
1845
|
|
|
|
|
|
|
} |
1846
|
|
|
|
|
|
|
|
1847
|
|
|
|
|
|
|
=item region_name($region) |
1848
|
|
|
|
|
|
|
|
1849
|
|
|
|
|
|
|
Returns the region name in the current locale's format. The region can be |
1850
|
|
|
|
|
|
|
a locale region id or a locale object or non existent. If a region is not |
1851
|
|
|
|
|
|
|
passed in then the region name of the current locale is returned. |
1852
|
|
|
|
|
|
|
|
1853
|
|
|
|
|
|
|
=cut |
1854
|
|
|
|
|
|
|
|
1855
|
|
|
|
|
|
|
sub region_name { |
1856
|
9
|
|
|
9
|
1
|
38
|
my ($self, $name) = @_; |
1857
|
9
|
|
66
|
|
|
44
|
$name //= $self; |
1858
|
|
|
|
|
|
|
|
1859
|
9
|
100
|
|
|
|
39
|
if (! ref $name ) { |
1860
|
5
|
|
|
|
|
15
|
$name = eval { __PACKAGE__->new(language_id => 'und', region_id => $name); }; |
|
5
|
|
|
|
|
147
|
|
1861
|
|
|
|
|
|
|
} |
1862
|
|
|
|
|
|
|
|
1863
|
9
|
50
|
66
|
|
|
11914
|
if ( ref $name && ! $name->region_id) { |
1864
|
0
|
|
|
|
|
0
|
return ''; |
1865
|
|
|
|
|
|
|
} |
1866
|
|
|
|
|
|
|
|
1867
|
9
|
|
|
|
|
32
|
my $region = undef; |
1868
|
9
|
|
|
|
|
54
|
my @bundles = $self->_find_bundle('display_name_region'); |
1869
|
9
|
100
|
|
|
|
123
|
if ($name) { |
1870
|
7
|
|
|
|
|
26
|
foreach my $bundle (@bundles) { |
1871
|
7
|
|
|
|
|
200
|
$region = $bundle->display_name_region->{$name->region_id}; |
1872
|
7
|
50
|
|
|
|
37
|
if (defined $region) { |
1873
|
7
|
|
|
|
|
25
|
last; |
1874
|
|
|
|
|
|
|
} |
1875
|
|
|
|
|
|
|
} |
1876
|
|
|
|
|
|
|
} |
1877
|
|
|
|
|
|
|
|
1878
|
9
|
100
|
|
|
|
52
|
if (! defined $region) { |
1879
|
2
|
|
|
|
|
8
|
foreach my $bundle (@bundles) { |
1880
|
2
|
|
|
|
|
13
|
$region = $bundle->display_name_region->{'ZZ'}; |
1881
|
2
|
50
|
|
|
|
9
|
if (defined $region) { |
1882
|
2
|
|
|
|
|
7
|
last; |
1883
|
|
|
|
|
|
|
} |
1884
|
|
|
|
|
|
|
} |
1885
|
|
|
|
|
|
|
} |
1886
|
|
|
|
|
|
|
|
1887
|
9
|
|
|
|
|
16468
|
return $region; |
1888
|
|
|
|
|
|
|
} |
1889
|
|
|
|
|
|
|
|
1890
|
|
|
|
|
|
|
=item all_regions |
1891
|
|
|
|
|
|
|
|
1892
|
|
|
|
|
|
|
Returns a hash ref keyed on region id of all the region the system |
1893
|
|
|
|
|
|
|
knows about. The values are the region names for the corresponding ids |
1894
|
|
|
|
|
|
|
|
1895
|
|
|
|
|
|
|
=cut |
1896
|
|
|
|
|
|
|
|
1897
|
|
|
|
|
|
|
sub all_regions { |
1898
|
1
|
|
|
1
|
1
|
3
|
my $self = shift; |
1899
|
|
|
|
|
|
|
|
1900
|
1
|
|
|
|
|
6
|
my @bundles = $self->_find_bundle('display_name_region'); |
1901
|
1
|
|
|
|
|
9
|
my %regions; |
1902
|
1
|
|
|
|
|
4
|
foreach my $bundle (@bundles) { |
1903
|
1
|
|
|
|
|
5
|
my $regions = $bundle->display_name_region; |
1904
|
|
|
|
|
|
|
|
1905
|
|
|
|
|
|
|
# Remove existing regions |
1906
|
1
|
|
|
|
|
4
|
delete @{$regions}{keys %regions}; |
|
1
|
|
|
|
|
3
|
|
1907
|
|
|
|
|
|
|
|
1908
|
|
|
|
|
|
|
# Assign new ones to the hash |
1909
|
1
|
|
|
|
|
160
|
@regions{keys %$regions} = values %$regions; |
1910
|
|
|
|
|
|
|
} |
1911
|
|
|
|
|
|
|
|
1912
|
1
|
|
|
|
|
9
|
return \%regions; |
1913
|
|
|
|
|
|
|
} |
1914
|
|
|
|
|
|
|
|
1915
|
|
|
|
|
|
|
=item variant_name($variant) |
1916
|
|
|
|
|
|
|
|
1917
|
|
|
|
|
|
|
Returns the variant name in the current locale's format. The variant can be |
1918
|
|
|
|
|
|
|
a locale variant id or a locale object or non existent. If a variant is not |
1919
|
|
|
|
|
|
|
passed in then the variant name of the current locale is returned. |
1920
|
|
|
|
|
|
|
|
1921
|
|
|
|
|
|
|
=cut |
1922
|
|
|
|
|
|
|
|
1923
|
|
|
|
|
|
|
sub variant_name { |
1924
|
7
|
|
|
7
|
1
|
86
|
my ($self, $name) = @_; |
1925
|
7
|
|
66
|
|
|
37
|
$name //= $self; |
1926
|
|
|
|
|
|
|
|
1927
|
7
|
100
|
|
|
|
33
|
if (! ref $name ) { |
1928
|
4
|
|
|
|
|
117
|
$name = __PACKAGE__->new(language_id=> 'und', variant_id => $name); |
1929
|
|
|
|
|
|
|
} |
1930
|
|
|
|
|
|
|
|
1931
|
6
|
100
|
|
|
|
6074
|
return '' unless $name->variant_id; |
1932
|
3
|
|
|
|
|
10
|
my $variant = undef; |
1933
|
3
|
50
|
|
|
|
19
|
if ($name->has_variant) { |
1934
|
3
|
|
|
|
|
22
|
my @bundles = $self->_find_bundle('display_name_variant'); |
1935
|
3
|
|
|
|
|
34
|
foreach my $bundle (@bundles) { |
1936
|
3
|
|
|
|
|
32
|
$variant= $bundle->display_name_variant->{$name->variant_id}; |
1937
|
3
|
100
|
|
|
|
16
|
if (defined $variant) { |
1938
|
2
|
|
|
|
|
9
|
last; |
1939
|
|
|
|
|
|
|
} |
1940
|
|
|
|
|
|
|
} |
1941
|
|
|
|
|
|
|
} |
1942
|
|
|
|
|
|
|
|
1943
|
3
|
|
100
|
|
|
19588
|
return $variant // ''; |
1944
|
|
|
|
|
|
|
} |
1945
|
|
|
|
|
|
|
|
1946
|
|
|
|
|
|
|
=item key_name($key) |
1947
|
|
|
|
|
|
|
|
1948
|
|
|
|
|
|
|
Returns the key name in the current locale's format. The key must be |
1949
|
|
|
|
|
|
|
a locale key id as a string |
1950
|
|
|
|
|
|
|
|
1951
|
|
|
|
|
|
|
=cut |
1952
|
|
|
|
|
|
|
|
1953
|
|
|
|
|
|
|
sub key_name { |
1954
|
3
|
|
|
3
|
1
|
13
|
my ($self, $key) = @_; |
1955
|
|
|
|
|
|
|
|
1956
|
3
|
|
|
|
|
11
|
$key = lc $key; |
1957
|
|
|
|
|
|
|
|
1958
|
3
|
|
|
|
|
98
|
my %key_aliases = $self->key_aliases; |
1959
|
3
|
|
|
|
|
74
|
my %key_names = $self->key_names; |
1960
|
3
|
|
|
|
|
67
|
my %valid_keys = $self->valid_keys; |
1961
|
|
|
|
|
|
|
|
1962
|
3
|
|
100
|
|
|
30
|
my $alias = $key_aliases{$key} // ''; |
1963
|
3
|
|
100
|
|
|
18
|
my $name = $key_names{$key} // ''; |
1964
|
|
|
|
|
|
|
|
1965
|
3
|
50
|
66
|
|
|
27
|
return '' unless exists $valid_keys{$key} || exists $valid_keys{$alias} || exists $valid_keys{$name}; |
|
|
|
33
|
|
|
|
|
1966
|
3
|
|
|
|
|
20
|
my @bundles = $self->_find_bundle('display_name_key'); |
1967
|
3
|
|
|
|
|
29
|
foreach my $bundle (@bundles) { |
1968
|
3
|
|
|
|
|
22
|
my $return = $bundle->display_name_key->{$key}; |
1969
|
3
|
|
66
|
|
|
22
|
$return //= $bundle->display_name_key->{$alias}; |
1970
|
3
|
|
33
|
|
|
10
|
$return //= $bundle->display_name_key->{$name}; |
1971
|
|
|
|
|
|
|
|
1972
|
3
|
50
|
33
|
|
|
103
|
return $return if defined $return && length $return; |
1973
|
|
|
|
|
|
|
} |
1974
|
|
|
|
|
|
|
|
1975
|
0
|
|
0
|
|
|
0
|
return ucfirst ($key_names{$name} || $key_names{$alias} || $key_names{$key} || $key); |
1976
|
|
|
|
|
|
|
} |
1977
|
|
|
|
|
|
|
|
1978
|
|
|
|
|
|
|
=item type_name($key, $type) |
1979
|
|
|
|
|
|
|
|
1980
|
|
|
|
|
|
|
Returns the type name in the current locale's format. The key and type must be |
1981
|
|
|
|
|
|
|
a locale key id and type id as a string |
1982
|
|
|
|
|
|
|
|
1983
|
|
|
|
|
|
|
=cut |
1984
|
|
|
|
|
|
|
|
1985
|
|
|
|
|
|
|
sub type_name { |
1986
|
3
|
|
|
3
|
1
|
15
|
my ($self, $key, $type) = @_; |
1987
|
|
|
|
|
|
|
|
1988
|
3
|
|
|
|
|
15
|
$key = lc $key; |
1989
|
3
|
|
|
|
|
9
|
$type = lc $type; |
1990
|
|
|
|
|
|
|
|
1991
|
3
|
|
|
|
|
118
|
my %key_aliases = $self->key_aliases; |
1992
|
3
|
|
|
|
|
64
|
my %valid_keys = $self->valid_keys; |
1993
|
3
|
|
|
|
|
66
|
my %key_names = $self->key_names; |
1994
|
|
|
|
|
|
|
|
1995
|
3
|
|
100
|
|
|
33
|
my $alias = $key_aliases{$key} // ''; |
1996
|
3
|
|
100
|
|
|
18
|
my $name = $key_names{$key} // ''; |
1997
|
|
|
|
|
|
|
|
1998
|
3
|
50
|
66
|
|
|
33
|
return '' unless exists $valid_keys{$key} || $valid_keys{$alias} || $valid_keys{$name}; |
|
|
|
33
|
|
|
|
|
1999
|
3
|
100
|
|
20
|
|
23
|
return '' unless first { $_ eq $type } @{$valid_keys{$key} || []}, @{$valid_keys{$alias} || []}, @{$valid_keys{$name} || []}; |
|
20
|
50
|
|
|
|
40
|
|
|
3
|
100
|
|
|
|
19
|
|
|
3
|
50
|
|
|
|
23
|
|
|
3
|
|
|
|
|
32
|
|
2000
|
|
|
|
|
|
|
|
2001
|
3
|
|
|
|
|
21
|
my @bundles = $self->_find_bundle('display_name_type'); |
2002
|
3
|
|
|
|
|
31
|
foreach my $bundle (@bundles) { |
2003
|
3
|
|
66
|
|
|
40
|
my $types = $bundle->display_name_type->{$key} // $bundle->display_name_type->{$alias} // $bundle->display_name_type->{$name}; |
|
|
|
33
|
|
|
|
|
2004
|
3
|
|
|
|
|
10
|
my $type = $types->{$type}; |
2005
|
3
|
50
|
|
|
|
138
|
return $type if defined $type; |
2006
|
|
|
|
|
|
|
} |
2007
|
|
|
|
|
|
|
|
2008
|
0
|
|
|
|
|
0
|
return ''; |
2009
|
|
|
|
|
|
|
} |
2010
|
|
|
|
|
|
|
|
2011
|
|
|
|
|
|
|
=item measurement_system_name($measurement_system) |
2012
|
|
|
|
|
|
|
|
2013
|
|
|
|
|
|
|
Returns the measurement system name in the current locale's format. The measurement system must be |
2014
|
|
|
|
|
|
|
a measurement system id as a string |
2015
|
|
|
|
|
|
|
|
2016
|
|
|
|
|
|
|
=cut |
2017
|
|
|
|
|
|
|
|
2018
|
|
|
|
|
|
|
sub measurement_system_name { |
2019
|
6
|
|
|
6
|
1
|
1405
|
my ($self, $name) = @_; |
2020
|
|
|
|
|
|
|
|
2021
|
|
|
|
|
|
|
# Fix case of code |
2022
|
6
|
|
|
|
|
20
|
$name = uc $name; |
2023
|
6
|
100
|
|
|
|
26
|
$name = 'metric' if $name eq 'METRIC'; |
2024
|
|
|
|
|
|
|
|
2025
|
6
|
|
|
|
|
28
|
my @bundles = $self->_find_bundle('display_name_measurement_system'); |
2026
|
6
|
|
|
|
|
52
|
foreach my $bundle (@bundles) { |
2027
|
6
|
|
|
|
|
28
|
my $system = $bundle->display_name_measurement_system->{$name}; |
2028
|
6
|
50
|
|
|
|
47
|
return $system if defined $system; |
2029
|
|
|
|
|
|
|
} |
2030
|
|
|
|
|
|
|
|
2031
|
0
|
|
|
|
|
0
|
return ''; |
2032
|
|
|
|
|
|
|
} |
2033
|
|
|
|
|
|
|
|
2034
|
|
|
|
|
|
|
=item transform_name($name) |
2035
|
|
|
|
|
|
|
|
2036
|
|
|
|
|
|
|
Returns the transform (transliteration) name in the current locale's format. The transform must be |
2037
|
|
|
|
|
|
|
a transform id as a string |
2038
|
|
|
|
|
|
|
|
2039
|
|
|
|
|
|
|
=cut |
2040
|
|
|
|
|
|
|
|
2041
|
|
|
|
|
|
|
sub transform_name { |
2042
|
1
|
|
|
1
|
1
|
4
|
my ($self, $name) = @_; |
2043
|
|
|
|
|
|
|
|
2044
|
1
|
|
|
|
|
5
|
$name = lc $name; |
2045
|
|
|
|
|
|
|
|
2046
|
1
|
|
|
|
|
3
|
my @bundles = $self->_find_bundle('display_name_transform_name'); |
2047
|
1
|
|
|
|
|
8
|
foreach my $bundle (@bundles) { |
2048
|
0
|
|
|
|
|
0
|
my $key = $bundle->display_name_transform_name->{$name}; |
2049
|
0
|
0
|
|
|
|
0
|
return $key if length $key; |
2050
|
|
|
|
|
|
|
} |
2051
|
|
|
|
|
|
|
|
2052
|
1
|
|
|
|
|
5
|
return ''; |
2053
|
|
|
|
|
|
|
} |
2054
|
|
|
|
|
|
|
|
2055
|
|
|
|
|
|
|
=item code_pattern($type, $locale) |
2056
|
|
|
|
|
|
|
|
2057
|
|
|
|
|
|
|
This method formats a language, script or region name, given as C<$type> |
2058
|
|
|
|
|
|
|
from C<$locale> in a way expected by the current locale. If $locale is |
2059
|
|
|
|
|
|
|
not passed in or is undef() the method uses the current locale. |
2060
|
|
|
|
|
|
|
|
2061
|
|
|
|
|
|
|
=cut |
2062
|
|
|
|
|
|
|
|
2063
|
|
|
|
|
|
|
sub code_pattern { |
2064
|
3
|
|
|
3
|
1
|
1412
|
my ($self, $type, $locale) = @_; |
2065
|
3
|
|
|
|
|
15
|
$type = lc $type; |
2066
|
|
|
|
|
|
|
|
2067
|
3
|
50
|
|
|
|
33
|
return '' unless $type =~ m{ \A (?: language | script | region ) \z }x; |
2068
|
|
|
|
|
|
|
|
2069
|
|
|
|
|
|
|
# If locale is not passed in then we are using ourself |
2070
|
3
|
|
33
|
|
|
20
|
$locale //= $self; |
2071
|
|
|
|
|
|
|
|
2072
|
|
|
|
|
|
|
# If locale is not an object then inflate it |
2073
|
3
|
50
|
|
|
|
26
|
$locale = __PACKAGE__->new($locale) unless blessed $locale; |
2074
|
|
|
|
|
|
|
|
2075
|
3
|
|
|
|
|
13
|
my $method = $type . '_name'; |
2076
|
3
|
|
|
|
|
25
|
my $substitute = $self->$method($locale); |
2077
|
|
|
|
|
|
|
|
2078
|
3
|
|
|
|
|
23
|
my @bundles = $self->_find_bundle('display_name_code_patterns'); |
2079
|
3
|
|
|
|
|
34
|
foreach my $bundle (@bundles) { |
2080
|
3
|
|
|
|
|
25
|
my $text = $bundle->display_name_code_patterns->{$type}; |
2081
|
3
|
50
|
|
|
|
15
|
next unless defined $text; |
2082
|
3
|
|
|
|
|
13
|
my $match = qr{ \{ 0 \} }x; |
2083
|
3
|
|
|
|
|
62
|
$text=~ s{ $match }{$substitute}gxms; |
2084
|
3
|
|
|
|
|
41
|
return $text; |
2085
|
|
|
|
|
|
|
} |
2086
|
|
|
|
|
|
|
|
2087
|
0
|
|
|
|
|
0
|
return ''; |
2088
|
|
|
|
|
|
|
} |
2089
|
|
|
|
|
|
|
|
2090
|
|
|
|
|
|
|
=item text_orientation($type) |
2091
|
|
|
|
|
|
|
|
2092
|
|
|
|
|
|
|
Gets the text orientation for the locale. Type must be one of |
2093
|
|
|
|
|
|
|
C<lines> or C<characters> |
2094
|
|
|
|
|
|
|
|
2095
|
|
|
|
|
|
|
=cut |
2096
|
|
|
|
|
|
|
|
2097
|
|
|
|
|
|
|
sub text_orientation { |
2098
|
2
|
|
|
2
|
1
|
1276
|
my $self = shift; |
2099
|
2
|
|
|
|
|
7
|
my $type = shift; |
2100
|
|
|
|
|
|
|
|
2101
|
2
|
|
|
|
|
11
|
my @bundles = $self->_find_bundle('text_orientation'); |
2102
|
2
|
|
|
|
|
19
|
foreach my $bundle (@bundles) { |
2103
|
2
|
|
|
|
|
8
|
my $orientation = $bundle->text_orientation; |
2104
|
2
|
50
|
|
|
|
8
|
next unless defined $orientation; |
2105
|
2
|
|
|
|
|
18
|
return $orientation->{$type}; |
2106
|
|
|
|
|
|
|
} |
2107
|
|
|
|
|
|
|
|
2108
|
0
|
|
|
|
|
0
|
return; |
2109
|
|
|
|
|
|
|
} |
2110
|
|
|
|
|
|
|
|
2111
|
|
|
|
|
|
|
sub _set_casing { |
2112
|
0
|
|
|
0
|
|
0
|
my ($self, $casing, $string) = @_; |
2113
|
|
|
|
|
|
|
|
2114
|
0
|
|
|
|
|
0
|
my @words = $self->split_words($string); |
2115
|
|
|
|
|
|
|
|
2116
|
0
|
0
|
|
|
|
0
|
if ($casing eq 'titlecase-firstword') { |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
2117
|
|
|
|
|
|
|
# Check to see whether $words[0] is white space or not |
2118
|
0
|
|
|
|
|
0
|
my $firstword_location = 0; |
2119
|
0
|
0
|
|
|
|
0
|
if ($words[0] =~ m{ \A \s }x) { |
2120
|
0
|
|
|
|
|
0
|
$firstword_location = 1; |
2121
|
|
|
|
|
|
|
} |
2122
|
|
|
|
|
|
|
|
2123
|
0
|
|
|
|
|
0
|
$words[$firstword_location] = ucfirst $words[$firstword_location]; |
2124
|
|
|
|
|
|
|
} |
2125
|
|
|
|
|
|
|
elsif ($casing eq 'titlecase-words') { |
2126
|
0
|
|
|
|
|
0
|
@words = map{ ucfirst } @words; |
|
0
|
|
|
|
|
0
|
|
2127
|
|
|
|
|
|
|
} |
2128
|
|
|
|
|
|
|
elsif ($casing eq 'lowercase-words') { |
2129
|
0
|
|
|
|
|
0
|
@words = map{ lc } @words; |
|
0
|
|
|
|
|
0
|
|
2130
|
|
|
|
|
|
|
} |
2131
|
|
|
|
|
|
|
|
2132
|
0
|
|
|
|
|
0
|
return join '', @words; |
2133
|
|
|
|
|
|
|
} |
2134
|
|
|
|
|
|
|
|
2135
|
|
|
|
|
|
|
=back |
2136
|
|
|
|
|
|
|
|
2137
|
|
|
|
|
|
|
=head2 Segmentation |
2138
|
|
|
|
|
|
|
|
2139
|
|
|
|
|
|
|
This group of methods allow you to split a string in various ways |
2140
|
|
|
|
|
|
|
Note you need Perl 5.18 or above for this |
2141
|
|
|
|
|
|
|
|
2142
|
|
|
|
|
|
|
=over 4 |
2143
|
|
|
|
|
|
|
|
2144
|
|
|
|
|
|
|
=item split_grapheme_clusters($string) |
2145
|
|
|
|
|
|
|
|
2146
|
|
|
|
|
|
|
Splits a string on grapheme clusters using the locale's segmentation rules. |
2147
|
|
|
|
|
|
|
Returns a list of grapheme clusters. |
2148
|
|
|
|
|
|
|
|
2149
|
|
|
|
|
|
|
=cut |
2150
|
|
|
|
|
|
|
# Need 5.18 and above |
2151
|
|
|
|
|
|
|
sub _new_perl { |
2152
|
11
|
50
|
|
11
|
|
165
|
die "You need Perl 5.18 or later for this functionality\n" |
2153
|
|
|
|
|
|
|
if $^V lt v5.18.0; |
2154
|
|
|
|
|
|
|
} |
2155
|
|
|
|
|
|
|
|
2156
|
|
|
|
|
|
|
sub split_grapheme_clusters { |
2157
|
1
|
|
|
1
|
1
|
1366
|
_new_perl(); |
2158
|
|
|
|
|
|
|
|
2159
|
1
|
|
|
|
|
5
|
my ($self, $string) = @_; |
2160
|
|
|
|
|
|
|
|
2161
|
1
|
|
|
|
|
29
|
my $rules = $self->break_grapheme_cluster; |
2162
|
1
|
|
|
|
|
41
|
my @clusters = $self->_split($rules, $string, 1); |
2163
|
|
|
|
|
|
|
|
2164
|
1
|
|
|
|
|
14
|
return @clusters; |
2165
|
|
|
|
|
|
|
} |
2166
|
|
|
|
|
|
|
|
2167
|
|
|
|
|
|
|
=item split_words($string) |
2168
|
|
|
|
|
|
|
|
2169
|
|
|
|
|
|
|
Splits a string on word boundaries using the locale's segmentation rules. |
2170
|
|
|
|
|
|
|
Returns a list of words. |
2171
|
|
|
|
|
|
|
|
2172
|
|
|
|
|
|
|
=cut |
2173
|
|
|
|
|
|
|
|
2174
|
|
|
|
|
|
|
sub split_words { |
2175
|
1
|
|
|
1
|
1
|
1440
|
_new_perl(); |
2176
|
|
|
|
|
|
|
|
2177
|
1
|
|
|
|
|
6
|
my ($self, $string) = @_; |
2178
|
|
|
|
|
|
|
|
2179
|
1
|
|
|
|
|
48
|
my $rules = $self->break_word; |
2180
|
1
|
|
|
|
|
45
|
my @words = $self->_split($rules, $string); |
2181
|
|
|
|
|
|
|
|
2182
|
1
|
|
|
|
|
10
|
return @words; |
2183
|
|
|
|
|
|
|
} |
2184
|
|
|
|
|
|
|
|
2185
|
|
|
|
|
|
|
=item split_sentences($string) |
2186
|
|
|
|
|
|
|
|
2187
|
|
|
|
|
|
|
Splits a string on on all points where a sentence could |
2188
|
|
|
|
|
|
|
end using the locale's segmentation rules. Returns a list |
2189
|
|
|
|
|
|
|
the end of each list element is the point where a sentence |
2190
|
|
|
|
|
|
|
could end. |
2191
|
|
|
|
|
|
|
|
2192
|
|
|
|
|
|
|
=cut |
2193
|
|
|
|
|
|
|
|
2194
|
|
|
|
|
|
|
sub split_sentences { |
2195
|
1
|
|
|
1
|
1
|
1088
|
_new_perl(); |
2196
|
|
|
|
|
|
|
|
2197
|
1
|
|
|
|
|
7
|
my ($self, $string) = @_; |
2198
|
|
|
|
|
|
|
|
2199
|
1
|
|
|
|
|
48
|
my $rules = $self->break_sentence; |
2200
|
1
|
|
|
|
|
43
|
my @sentences = $self->_split($rules, $string); |
2201
|
|
|
|
|
|
|
|
2202
|
1
|
|
|
|
|
10
|
return @sentences; |
2203
|
|
|
|
|
|
|
} |
2204
|
|
|
|
|
|
|
|
2205
|
|
|
|
|
|
|
=item split_lines($string) |
2206
|
|
|
|
|
|
|
|
2207
|
|
|
|
|
|
|
Splits a string on on all points where a line could |
2208
|
|
|
|
|
|
|
end using the locale's segmentation rules. Returns a list |
2209
|
|
|
|
|
|
|
the end of each list element is the point where a line |
2210
|
|
|
|
|
|
|
could end. |
2211
|
|
|
|
|
|
|
|
2212
|
|
|
|
|
|
|
=cut |
2213
|
|
|
|
|
|
|
|
2214
|
|
|
|
|
|
|
sub split_lines { |
2215
|
1
|
|
|
1
|
1
|
983
|
_new_perl(); |
2216
|
|
|
|
|
|
|
|
2217
|
1
|
|
|
|
|
6
|
my ($self, $string) = @_; |
2218
|
|
|
|
|
|
|
|
2219
|
1
|
|
|
|
|
44
|
my $rules = $self->break_line; |
2220
|
1
|
|
|
|
|
48
|
my @lines = $self->_split($rules, $string); |
2221
|
|
|
|
|
|
|
|
2222
|
1
|
|
|
|
|
8
|
return @lines; |
2223
|
|
|
|
|
|
|
} |
2224
|
|
|
|
|
|
|
|
2225
|
|
|
|
|
|
|
sub _split { |
2226
|
4
|
|
|
4
|
|
21
|
my ($self, $rules, $string, $grapheme_split) = @_; |
2227
|
|
|
|
|
|
|
|
2228
|
4
|
|
|
|
|
36
|
my @split = (scalar @$rules) x (length($string) - 1); |
2229
|
|
|
|
|
|
|
|
2230
|
4
|
|
|
|
|
18
|
pos($string)=0; |
2231
|
|
|
|
|
|
|
# The Unicode Consortium has deprecated LB=Surrogate but the CLDR still |
2232
|
|
|
|
|
|
|
# uses it, at least in this version. |
2233
|
21
|
|
|
21
|
|
111905
|
no warnings 'deprecated'; |
|
21
|
|
|
|
|
67
|
|
|
21
|
|
|
|
|
86322
|
|
2234
|
4
|
|
|
|
|
24
|
while (length($string) -1 != pos $string) { |
2235
|
160
|
|
|
|
|
316
|
my $rule_number = 0; |
2236
|
160
|
|
|
|
|
260
|
my $first; |
2237
|
160
|
|
|
|
|
431
|
foreach my $rule (@$rules) { |
2238
|
2950
|
100
|
|
|
|
58733
|
unless( ($first) = $string =~ m{ |
2239
|
|
|
|
|
|
|
\G |
2240
|
|
|
|
|
|
|
($rule->[0]) |
2241
|
|
|
|
|
|
|
$rule->[1] |
2242
|
|
|
|
|
|
|
}msx) { |
2243
|
2790
|
|
|
|
|
3090299
|
$rule_number++; |
2244
|
2790
|
|
|
|
|
22030
|
next; |
2245
|
|
|
|
|
|
|
} |
2246
|
160
|
|
|
|
|
195354
|
my $location = pos($string) + length($first) -1; |
2247
|
160
|
|
|
|
|
414
|
$split[$location] = $rule_number; |
2248
|
|
|
|
|
|
|
|
2249
|
|
|
|
|
|
|
# If the left hand side was part of a grapheme cluster |
2250
|
|
|
|
|
|
|
# we have to jump past the entire cluster |
2251
|
160
|
|
|
|
|
299
|
my $length = length $first; |
2252
|
160
|
|
|
|
|
685
|
my ($gc) = $string =~ /\G(\X)/; |
2253
|
160
|
100
|
66
|
|
|
1098
|
$length = (! $grapheme_split && length($gc)) > $length ? length($gc) : $length; |
2254
|
160
|
|
|
|
|
567
|
pos($string)+= $length; |
2255
|
160
|
|
|
|
|
847
|
last; |
2256
|
|
|
|
|
|
|
} |
2257
|
|
|
|
|
|
|
} |
2258
|
|
|
|
|
|
|
|
2259
|
4
|
|
|
|
|
22
|
push @$rules,[undef,undef,1]; |
2260
|
4
|
100
|
|
|
|
20
|
@split = map {$rules->[$_][2] ? 1 : 0} @split; |
|
164
|
|
|
|
|
330
|
|
2261
|
4
|
|
|
|
|
14
|
my $count = 0; |
2262
|
4
|
|
|
|
|
17
|
my @sections = ('.'); |
2263
|
4
|
|
|
|
|
13
|
foreach my $split (@split) { |
2264
|
164
|
100
|
|
|
|
272
|
$count++ unless $split; |
2265
|
164
|
|
|
|
|
238
|
$sections[$count] .= '.'; |
2266
|
|
|
|
|
|
|
} |
2267
|
|
|
|
|
|
|
|
2268
|
4
|
|
|
|
|
39
|
my $regex = _fix_missing_unicode_properties('(' . join(')(', @sections) . ')'); |
2269
|
4
|
|
|
|
|
112
|
$regex = qr{ \A $regex \z}msx; |
2270
|
4
|
|
|
|
|
60
|
@split = $string =~ $regex; |
2271
|
|
|
|
|
|
|
|
2272
|
4
|
|
|
|
|
45
|
return @split; |
2273
|
|
|
|
|
|
|
} |
2274
|
|
|
|
|
|
|
|
2275
|
|
|
|
|
|
|
=back |
2276
|
|
|
|
|
|
|
|
2277
|
|
|
|
|
|
|
=head2 Characters |
2278
|
|
|
|
|
|
|
|
2279
|
|
|
|
|
|
|
=over 4 |
2280
|
|
|
|
|
|
|
|
2281
|
|
|
|
|
|
|
=item is_exemplar_character( $type, $character) |
2282
|
|
|
|
|
|
|
|
2283
|
|
|
|
|
|
|
=item is_exemplar_character($character) |
2284
|
|
|
|
|
|
|
|
2285
|
|
|
|
|
|
|
Tests if the given character is used in the locale. There are |
2286
|
|
|
|
|
|
|
three possible types; C<main>, C<auxiliary> and C<punctuation>. |
2287
|
|
|
|
|
|
|
If no type is given C<main> is assumed. Unless the C<index> type |
2288
|
|
|
|
|
|
|
is given you will have to have a Perl version of 5.18 or above |
2289
|
|
|
|
|
|
|
to use this method |
2290
|
|
|
|
|
|
|
|
2291
|
|
|
|
|
|
|
=cut |
2292
|
|
|
|
|
|
|
|
2293
|
|
|
|
|
|
|
sub is_exemplar_character { |
2294
|
7
|
|
|
7
|
1
|
1375
|
my ($self, @parameters) = @_; |
2295
|
7
|
100
|
|
|
|
30
|
unshift @parameters, 'main' if @parameters == 1; |
2296
|
|
|
|
|
|
|
|
2297
|
7
|
50
|
|
|
|
38
|
_new_perl() unless $parameters[0] eq 'index'; |
2298
|
|
|
|
|
|
|
|
2299
|
7
|
|
|
|
|
34
|
my @bundles = $self->_find_bundle('characters'); |
2300
|
7
|
|
|
|
|
57
|
foreach my $bundle (@bundles) { |
2301
|
10
|
|
|
|
|
37
|
my $characters = $bundle->characters->{lc $parameters[0]}; |
2302
|
10
|
100
|
|
|
|
22
|
next unless defined $characters; |
2303
|
8
|
100
|
|
|
|
74
|
return 1 if fc($parameters[1])=~$characters; |
2304
|
|
|
|
|
|
|
} |
2305
|
|
|
|
|
|
|
|
2306
|
3
|
|
|
|
|
20
|
return; |
2307
|
|
|
|
|
|
|
} |
2308
|
|
|
|
|
|
|
|
2309
|
|
|
|
|
|
|
=item index_characters() |
2310
|
|
|
|
|
|
|
|
2311
|
|
|
|
|
|
|
Returns an array ref of characters normally used when creating |
2312
|
|
|
|
|
|
|
an index and ordered appropriately. |
2313
|
|
|
|
|
|
|
|
2314
|
|
|
|
|
|
|
=cut |
2315
|
|
|
|
|
|
|
|
2316
|
|
|
|
|
|
|
sub index_characters { |
2317
|
1
|
|
|
1
|
1
|
1624
|
my $self = shift; |
2318
|
|
|
|
|
|
|
|
2319
|
1
|
|
|
|
|
6
|
my @bundles = $self->_find_bundle('characters'); |
2320
|
1
|
|
|
|
|
11
|
foreach my $bundle (@bundles) { |
2321
|
1
|
|
|
|
|
5
|
my $characters = $bundle->characters->{index}; |
2322
|
1
|
50
|
|
|
|
5
|
next unless defined $characters; |
2323
|
1
|
|
|
|
|
14
|
return $characters; |
2324
|
|
|
|
|
|
|
} |
2325
|
0
|
|
|
|
|
0
|
return []; |
2326
|
|
|
|
|
|
|
} |
2327
|
|
|
|
|
|
|
|
2328
|
|
|
|
|
|
|
sub _truncated { |
2329
|
6
|
|
|
6
|
|
29
|
my ($self, $type, @params) = @_; |
2330
|
|
|
|
|
|
|
|
2331
|
6
|
|
|
|
|
21
|
my @bundles = $self->_find_bundle('ellipsis'); |
2332
|
6
|
|
|
|
|
49
|
foreach my $bundle (@bundles) { |
2333
|
6
|
|
|
|
|
23
|
my $ellipsis = $bundle->ellipsis->{$type}; |
2334
|
6
|
50
|
|
|
|
16
|
next unless defined $ellipsis; |
2335
|
6
|
|
|
|
|
37
|
$ellipsis=~s{ \{ 0 \} }{$params[0]}msx; |
2336
|
6
|
|
|
|
|
18
|
$ellipsis=~s{ \{ 1 \} }{$params[1]}msx; |
2337
|
6
|
|
|
|
|
44
|
return $ellipsis; |
2338
|
|
|
|
|
|
|
} |
2339
|
|
|
|
|
|
|
} |
2340
|
|
|
|
|
|
|
|
2341
|
|
|
|
|
|
|
=back |
2342
|
|
|
|
|
|
|
|
2343
|
|
|
|
|
|
|
=head2 Truncation |
2344
|
|
|
|
|
|
|
|
2345
|
|
|
|
|
|
|
These methods format a string to show where part of the string has been removed |
2346
|
|
|
|
|
|
|
|
2347
|
|
|
|
|
|
|
=over 4 |
2348
|
|
|
|
|
|
|
|
2349
|
|
|
|
|
|
|
=item truncated_beginning($string) |
2350
|
|
|
|
|
|
|
|
2351
|
|
|
|
|
|
|
Adds the locale specific marking to show that the |
2352
|
|
|
|
|
|
|
string has been truncated at the beginning. |
2353
|
|
|
|
|
|
|
|
2354
|
|
|
|
|
|
|
=cut |
2355
|
|
|
|
|
|
|
|
2356
|
|
|
|
|
|
|
sub truncated_beginning { |
2357
|
1
|
|
|
1
|
1
|
1308
|
shift->_truncated(initial => @_); |
2358
|
|
|
|
|
|
|
} |
2359
|
|
|
|
|
|
|
|
2360
|
|
|
|
|
|
|
=item truncated_between($string, $string) |
2361
|
|
|
|
|
|
|
|
2362
|
|
|
|
|
|
|
Adds the locale specific marking to show that something |
2363
|
|
|
|
|
|
|
has been truncated between the two strings. Returns a |
2364
|
|
|
|
|
|
|
string comprising of the concatenation of the first string, |
2365
|
|
|
|
|
|
|
the mark and the second string |
2366
|
|
|
|
|
|
|
|
2367
|
|
|
|
|
|
|
=cut |
2368
|
|
|
|
|
|
|
|
2369
|
|
|
|
|
|
|
sub truncated_between { |
2370
|
1
|
|
|
1
|
1
|
6
|
shift->_truncated(medial => @_); |
2371
|
|
|
|
|
|
|
} |
2372
|
|
|
|
|
|
|
|
2373
|
|
|
|
|
|
|
=item truncated_end($string) |
2374
|
|
|
|
|
|
|
|
2375
|
|
|
|
|
|
|
Adds the locale specific marking to show that the |
2376
|
|
|
|
|
|
|
string has been truncated at the end. |
2377
|
|
|
|
|
|
|
|
2378
|
|
|
|
|
|
|
=cut |
2379
|
|
|
|
|
|
|
|
2380
|
|
|
|
|
|
|
sub truncated_end { |
2381
|
1
|
|
|
1
|
1
|
6
|
shift->_truncated(final => @_); |
2382
|
|
|
|
|
|
|
} |
2383
|
|
|
|
|
|
|
|
2384
|
|
|
|
|
|
|
=item truncated_word_beginning($string) |
2385
|
|
|
|
|
|
|
|
2386
|
|
|
|
|
|
|
Adds the locale specific marking to show that the |
2387
|
|
|
|
|
|
|
string has been truncated at the beginning. This |
2388
|
|
|
|
|
|
|
should be used in preference to C<truncated_beginning> |
2389
|
|
|
|
|
|
|
when the truncation occurs on a word boundary. |
2390
|
|
|
|
|
|
|
|
2391
|
|
|
|
|
|
|
=cut |
2392
|
|
|
|
|
|
|
|
2393
|
|
|
|
|
|
|
sub truncated_word_beginning { |
2394
|
1
|
|
|
1
|
1
|
5
|
shift->_truncated('word-initial' => @_); |
2395
|
|
|
|
|
|
|
} |
2396
|
|
|
|
|
|
|
|
2397
|
|
|
|
|
|
|
=item truncated_word_between($string, $string) |
2398
|
|
|
|
|
|
|
|
2399
|
|
|
|
|
|
|
Adds the locale specific marking to show that something |
2400
|
|
|
|
|
|
|
has been truncated between the two strings. Returns a |
2401
|
|
|
|
|
|
|
string comprising of the concatenation of the first string, |
2402
|
|
|
|
|
|
|
the mark and the second string. This should be used in |
2403
|
|
|
|
|
|
|
preference to C<truncated_between> when the truncation |
2404
|
|
|
|
|
|
|
occurs on a word boundary. |
2405
|
|
|
|
|
|
|
|
2406
|
|
|
|
|
|
|
=cut |
2407
|
|
|
|
|
|
|
|
2408
|
|
|
|
|
|
|
sub truncated_word_between { |
2409
|
1
|
|
|
1
|
1
|
5
|
shift->_truncated('word-medial' => @_); |
2410
|
|
|
|
|
|
|
} |
2411
|
|
|
|
|
|
|
|
2412
|
|
|
|
|
|
|
=item truncated_word_end($string) |
2413
|
|
|
|
|
|
|
|
2414
|
|
|
|
|
|
|
Adds the locale specific marking to show that the |
2415
|
|
|
|
|
|
|
string has been truncated at the end. This should be |
2416
|
|
|
|
|
|
|
used in preference to C<truncated_end> when the |
2417
|
|
|
|
|
|
|
truncation occurs on a word boundary. |
2418
|
|
|
|
|
|
|
|
2419
|
|
|
|
|
|
|
=cut |
2420
|
|
|
|
|
|
|
|
2421
|
|
|
|
|
|
|
sub truncated_word_end { |
2422
|
1
|
|
|
1
|
1
|
7
|
shift->_truncated('word-final' => @_); |
2423
|
|
|
|
|
|
|
} |
2424
|
|
|
|
|
|
|
|
2425
|
|
|
|
|
|
|
=back |
2426
|
|
|
|
|
|
|
|
2427
|
|
|
|
|
|
|
=head2 Quoting |
2428
|
|
|
|
|
|
|
|
2429
|
|
|
|
|
|
|
=over 4 |
2430
|
|
|
|
|
|
|
|
2431
|
|
|
|
|
|
|
=item quote($string) |
2432
|
|
|
|
|
|
|
|
2433
|
|
|
|
|
|
|
Adds the locale's primary quotation marks to the ends of the string. |
2434
|
|
|
|
|
|
|
Also scans the string for paired primary and auxiliary quotation |
2435
|
|
|
|
|
|
|
marks and flips them. |
2436
|
|
|
|
|
|
|
|
2437
|
|
|
|
|
|
|
eg passing C<z âabcâ z> to this method for the C<en_GB> locale |
2438
|
|
|
|
|
|
|
gives C<âz âabcâ zâ> |
2439
|
|
|
|
|
|
|
|
2440
|
|
|
|
|
|
|
=cut |
2441
|
|
|
|
|
|
|
|
2442
|
|
|
|
|
|
|
sub quote { |
2443
|
3
|
|
|
3
|
1
|
2787
|
my ($self, $text) = @_; |
2444
|
|
|
|
|
|
|
|
2445
|
3
|
|
|
|
|
7
|
my %quote; |
2446
|
3
|
|
|
|
|
13
|
my @bundles = $self->_find_bundle('quote_start'); |
2447
|
3
|
|
|
|
|
29
|
foreach my $bundle (@bundles) { |
2448
|
3
|
|
|
|
|
15
|
my $quote = $bundle->quote_start; |
2449
|
3
|
50
|
|
|
|
12
|
next unless defined $quote; |
2450
|
3
|
|
|
|
|
9
|
$quote{start} = $quote; |
2451
|
3
|
|
|
|
|
8
|
last; |
2452
|
|
|
|
|
|
|
} |
2453
|
|
|
|
|
|
|
|
2454
|
3
|
|
|
|
|
10
|
@bundles = $self->_find_bundle('quote_end'); |
2455
|
3
|
|
|
|
|
27
|
foreach my $bundle (@bundles) { |
2456
|
3
|
|
|
|
|
14
|
my $quote = $bundle->quote_end; |
2457
|
3
|
50
|
|
|
|
12
|
next unless defined $quote; |
2458
|
3
|
|
|
|
|
5
|
$quote{end} = $quote; |
2459
|
3
|
|
|
|
|
8
|
last; |
2460
|
|
|
|
|
|
|
} |
2461
|
|
|
|
|
|
|
|
2462
|
3
|
|
|
|
|
10
|
@bundles = $self->_find_bundle('alternate_quote_start'); |
2463
|
3
|
|
|
|
|
25
|
foreach my $bundle (@bundles) { |
2464
|
3
|
|
|
|
|
12
|
my $quote = $bundle->alternate_quote_start; |
2465
|
3
|
50
|
|
|
|
9
|
next unless defined $quote; |
2466
|
3
|
|
|
|
|
8
|
$quote{alternate_start} = $quote; |
2467
|
3
|
|
|
|
|
4
|
last; |
2468
|
|
|
|
|
|
|
} |
2469
|
|
|
|
|
|
|
|
2470
|
3
|
|
|
|
|
13
|
@bundles = $self->_find_bundle('alternate_quote_end'); |
2471
|
3
|
|
|
|
|
25
|
foreach my $bundle (@bundles) { |
2472
|
3
|
|
|
|
|
39
|
my $quote = $bundle->alternate_quote_end; |
2473
|
3
|
50
|
|
|
|
12
|
next unless defined $quote; |
2474
|
3
|
|
|
|
|
7
|
$quote{alternate_end} = $quote; |
2475
|
3
|
|
|
|
|
6
|
last; |
2476
|
|
|
|
|
|
|
} |
2477
|
|
|
|
|
|
|
|
2478
|
|
|
|
|
|
|
# Check to see if we need to switch quotes |
2479
|
3
|
|
|
|
|
9
|
foreach (qw( start end alternate_start alternate_end)) { |
2480
|
12
|
|
50
|
|
|
29
|
$quote{$_} //= ''; |
2481
|
|
|
|
|
|
|
} |
2482
|
|
|
|
|
|
|
|
2483
|
3
|
|
|
|
|
11
|
my $from = join ' | ', map {quotemeta} @quote{qw( start end alternate_start alternate_end)}; |
|
12
|
|
|
|
|
34
|
|
2484
|
3
|
|
|
|
|
9
|
my %to; |
2485
|
|
|
|
|
|
|
@to{@quote{qw( start end alternate_start alternate_end)}} |
2486
|
3
|
|
|
|
|
17
|
= @quote{qw( alternate_start alternate_end start end)}; |
2487
|
|
|
|
|
|
|
|
2488
|
3
|
|
|
|
|
12
|
my $outer = index($text, $quote{start}); |
2489
|
3
|
|
|
|
|
7
|
my $inner = index($text, $quote{alternate_start}); |
2490
|
|
|
|
|
|
|
|
2491
|
3
|
50
|
33
|
|
|
26
|
if ($inner == -1 || ($outer > -1 && $inner > -1 && $outer < $inner)) { |
|
|
|
33
|
|
|
|
|
|
|
|
66
|
|
|
|
|
2492
|
3
|
|
|
|
|
88
|
$text =~ s{ ( $from ) }{ $to{$1} }msxeg; |
|
6
|
|
|
|
|
28
|
|
2493
|
|
|
|
|
|
|
} |
2494
|
|
|
|
|
|
|
|
2495
|
3
|
|
|
|
|
25
|
return "$quote{start}$text$quote{end}"; |
2496
|
|
|
|
|
|
|
} |
2497
|
|
|
|
|
|
|
|
2498
|
|
|
|
|
|
|
=back |
2499
|
|
|
|
|
|
|
|
2500
|
|
|
|
|
|
|
=head2 Miscellaneous |
2501
|
|
|
|
|
|
|
|
2502
|
|
|
|
|
|
|
=over 4 |
2503
|
|
|
|
|
|
|
|
2504
|
|
|
|
|
|
|
=item more_information() |
2505
|
|
|
|
|
|
|
|
2506
|
|
|
|
|
|
|
The more information string is one that can be displayed |
2507
|
|
|
|
|
|
|
in an interface to indicate that more information is |
2508
|
|
|
|
|
|
|
available. |
2509
|
|
|
|
|
|
|
|
2510
|
|
|
|
|
|
|
=cut |
2511
|
|
|
|
|
|
|
|
2512
|
|
|
|
|
|
|
sub more_information { |
2513
|
1
|
|
|
1
|
1
|
3
|
my $self = shift; |
2514
|
|
|
|
|
|
|
|
2515
|
1
|
|
|
|
|
5
|
my @bundles = $self->_find_bundle('more_information'); |
2516
|
1
|
|
|
|
|
10
|
foreach my $bundle (@bundles) { |
2517
|
1
|
|
|
|
|
7
|
my $info = $bundle->more_information; |
2518
|
1
|
50
|
|
|
|
5
|
next unless defined $info; |
2519
|
1
|
|
|
|
|
6
|
return $info; |
2520
|
|
|
|
|
|
|
} |
2521
|
0
|
|
|
|
|
0
|
return ''; |
2522
|
|
|
|
|
|
|
} |
2523
|
|
|
|
|
|
|
|
2524
|
|
|
|
|
|
|
|
2525
|
|
|
|
|
|
|
=item measurement() |
2526
|
|
|
|
|
|
|
|
2527
|
|
|
|
|
|
|
Returns the measurement type for the locale |
2528
|
|
|
|
|
|
|
|
2529
|
|
|
|
|
|
|
=cut |
2530
|
|
|
|
|
|
|
|
2531
|
|
|
|
|
|
|
sub measurement { |
2532
|
1
|
|
|
1
|
1
|
1178
|
my $self = shift; |
2533
|
|
|
|
|
|
|
|
2534
|
1
|
|
|
|
|
5
|
my $measurement_data = $self->measurement_system; |
2535
|
1
|
|
50
|
|
|
28
|
my $region = $self->region_id || '001'; |
2536
|
|
|
|
|
|
|
|
2537
|
1
|
|
|
|
|
4
|
my $data = $measurement_data->{$region}; |
2538
|
|
|
|
|
|
|
|
2539
|
1
|
|
|
|
|
5
|
until (defined $data) { |
2540
|
0
|
|
|
|
|
0
|
$region = $self->region_contained_by->{$region}; |
2541
|
0
|
|
|
|
|
0
|
$data = $measurement_data->{$region}; |
2542
|
|
|
|
|
|
|
} |
2543
|
|
|
|
|
|
|
|
2544
|
1
|
|
|
|
|
14
|
return $data; |
2545
|
|
|
|
|
|
|
} |
2546
|
|
|
|
|
|
|
|
2547
|
|
|
|
|
|
|
=item paper() |
2548
|
|
|
|
|
|
|
|
2549
|
|
|
|
|
|
|
Returns the paper type for the locale |
2550
|
|
|
|
|
|
|
|
2551
|
|
|
|
|
|
|
=cut |
2552
|
|
|
|
|
|
|
|
2553
|
|
|
|
|
|
|
sub paper { |
2554
|
1
|
|
|
1
|
1
|
4
|
my $self = shift; |
2555
|
|
|
|
|
|
|
|
2556
|
1
|
|
|
|
|
4
|
my $paper_size = $self->paper_size; |
2557
|
1
|
|
50
|
|
|
27
|
my $region = $self->region_id || '001'; |
2558
|
|
|
|
|
|
|
|
2559
|
1
|
|
|
|
|
5
|
my $data = $paper_size->{$region}; |
2560
|
|
|
|
|
|
|
|
2561
|
1
|
|
|
|
|
4
|
until (defined $data) { |
2562
|
0
|
|
|
|
|
0
|
$region = $self->region_contained_by->{$region}; |
2563
|
0
|
|
|
|
|
0
|
$data = $paper_size->{$region}; |
2564
|
|
|
|
|
|
|
} |
2565
|
|
|
|
|
|
|
|
2566
|
1
|
|
|
|
|
8
|
return $data; |
2567
|
|
|
|
|
|
|
} |
2568
|
|
|
|
|
|
|
|
2569
|
|
|
|
|
|
|
=back |
2570
|
|
|
|
|
|
|
|
2571
|
|
|
|
|
|
|
=head2 Units |
2572
|
|
|
|
|
|
|
|
2573
|
|
|
|
|
|
|
=over 4 |
2574
|
|
|
|
|
|
|
|
2575
|
|
|
|
|
|
|
=item all_units() |
2576
|
|
|
|
|
|
|
|
2577
|
|
|
|
|
|
|
Returns a list of all the unit identifiers for the locale |
2578
|
|
|
|
|
|
|
|
2579
|
|
|
|
|
|
|
=cut |
2580
|
|
|
|
|
|
|
|
2581
|
|
|
|
|
|
|
sub all_units { |
2582
|
0
|
|
|
0
|
1
|
0
|
my $self = shift; |
2583
|
0
|
|
|
|
|
0
|
my @bundles = $self->_find_bundle('units'); |
2584
|
|
|
|
|
|
|
|
2585
|
0
|
|
|
|
|
0
|
my %units; |
2586
|
0
|
|
|
|
|
0
|
foreach my $bundle (reverse @bundles) { |
2587
|
0
|
|
|
|
|
0
|
%units = %units, $bundle->units; |
2588
|
|
|
|
|
|
|
} |
2589
|
|
|
|
|
|
|
|
2590
|
0
|
|
|
|
|
0
|
return keys %units; |
2591
|
|
|
|
|
|
|
} |
2592
|
|
|
|
|
|
|
|
2593
|
|
|
|
|
|
|
=item unit($number, $unit, $width) |
2594
|
|
|
|
|
|
|
|
2595
|
|
|
|
|
|
|
Returns the localised string for the given number and unit formatted for the |
2596
|
|
|
|
|
|
|
required width. The number must not be the localized version of the number. |
2597
|
|
|
|
|
|
|
The returned string will be in the locale's format, including the number. |
2598
|
|
|
|
|
|
|
|
2599
|
|
|
|
|
|
|
=cut |
2600
|
|
|
|
|
|
|
|
2601
|
|
|
|
|
|
|
sub unit { |
2602
|
738
|
|
|
738
|
1
|
3301
|
my ($self, $number, $what, $type) = @_; |
2603
|
738
|
|
100
|
|
|
2829
|
$type //= 'long'; |
2604
|
|
|
|
|
|
|
|
2605
|
738
|
|
|
|
|
3038
|
my $plural = $self->plural($number); |
2606
|
|
|
|
|
|
|
|
2607
|
738
|
|
|
|
|
1933
|
my @bundles = $self->_find_bundle('units'); |
2608
|
738
|
|
|
|
|
5512
|
my $format; |
2609
|
738
|
|
|
|
|
1462
|
foreach my $bundle (@bundles) { |
2610
|
748
|
100
|
|
|
|
3494
|
if (exists $bundle->units()->{$type}{$what}{$plural}) { |
2611
|
728
|
|
|
|
|
1798
|
$format = $bundle->units()->{$type}{$what}{$plural}; |
2612
|
728
|
|
|
|
|
1218
|
last; |
2613
|
|
|
|
|
|
|
} |
2614
|
|
|
|
|
|
|
|
2615
|
20
|
50
|
|
|
|
52
|
if (exists $bundle->units()->{$type}{$what}{other}) { |
2616
|
0
|
|
|
|
|
0
|
$format = $bundle->units()->{$type}{$what}{other}; |
2617
|
0
|
|
|
|
|
0
|
last; |
2618
|
|
|
|
|
|
|
} |
2619
|
|
|
|
|
|
|
} |
2620
|
|
|
|
|
|
|
|
2621
|
|
|
|
|
|
|
# Check for aliases |
2622
|
738
|
100
|
|
|
|
1545
|
unless ($format) { |
2623
|
10
|
|
|
|
|
19
|
my $original_type = $type; |
2624
|
10
|
|
|
|
|
23
|
my @aliases = $self->_find_bundle('unit_alias'); |
2625
|
10
|
|
|
|
|
71
|
foreach my $alias (@aliases) { |
2626
|
10
|
|
|
|
|
31
|
$type = $alias->unit_alias()->{$original_type}; |
2627
|
10
|
50
|
|
|
|
24
|
next unless $type; |
2628
|
10
|
|
|
|
|
18
|
foreach my $bundle (@bundles) { |
2629
|
16
|
100
|
|
|
|
58
|
if (exists $bundle->units()->{$type}{$what}{$plural}) { |
2630
|
4
|
|
|
|
|
12
|
$format = $bundle->units()->{$type}{$what}{$plural}; |
2631
|
4
|
|
|
|
|
9
|
last; |
2632
|
|
|
|
|
|
|
} |
2633
|
|
|
|
|
|
|
|
2634
|
12
|
50
|
|
|
|
36
|
if (exists $bundle->units()->{$type}{$what}{other}) { |
2635
|
0
|
|
|
|
|
0
|
$format = $bundle->units()->{$type}{$what}{other}; |
2636
|
0
|
|
|
|
|
0
|
last; |
2637
|
|
|
|
|
|
|
} |
2638
|
|
|
|
|
|
|
} |
2639
|
|
|
|
|
|
|
} |
2640
|
10
|
|
|
|
|
20
|
$type = $original_type; |
2641
|
|
|
|
|
|
|
} |
2642
|
|
|
|
|
|
|
|
2643
|
|
|
|
|
|
|
# Check for a compound unit that we don't specifically have |
2644
|
738
|
100
|
66
|
|
|
1914
|
if (! $format && (my ($dividend, $divisor) = $what =~ /^(.+)-per-(.+)$/)) { |
2645
|
6
|
|
|
|
|
20
|
return $self->_unit_compound($number, $dividend, $divisor, $type); |
2646
|
|
|
|
|
|
|
} |
2647
|
|
|
|
|
|
|
|
2648
|
732
|
|
|
|
|
2305
|
$number = $self->format_number($number); |
2649
|
732
|
50
|
|
|
|
1661
|
return $number unless $format; |
2650
|
|
|
|
|
|
|
|
2651
|
732
|
|
|
|
|
2741
|
$format =~ s/\{0\}/$number/g; |
2652
|
|
|
|
|
|
|
|
2653
|
732
|
|
|
|
|
4376
|
return $format; |
2654
|
|
|
|
|
|
|
} |
2655
|
|
|
|
|
|
|
|
2656
|
|
|
|
|
|
|
sub _unit_compound { |
2657
|
6
|
|
|
6
|
|
16
|
my ($self, $number, $dividend_what, $divisor_what, $type) = @_; |
2658
|
|
|
|
|
|
|
|
2659
|
6
|
|
50
|
|
|
27
|
$type //= 'long'; |
2660
|
|
|
|
|
|
|
|
2661
|
6
|
|
|
|
|
25
|
my $dividend = $self->unit($number, $dividend_what, $type); |
2662
|
6
|
|
|
|
|
22
|
my $divisor = $self->_unit_per($divisor_what, $type); |
2663
|
6
|
50
|
|
|
|
16
|
if ($divisor) { |
2664
|
6
|
|
|
|
|
8
|
my $format = $divisor; |
2665
|
6
|
|
|
|
|
18
|
$format =~ s/\{0\}/$dividend/; |
2666
|
6
|
|
|
|
|
38
|
return $format; |
2667
|
|
|
|
|
|
|
} |
2668
|
|
|
|
|
|
|
|
2669
|
0
|
|
|
|
|
0
|
$divisor = $self->unit(1, $divisor_what, $type); |
2670
|
|
|
|
|
|
|
|
2671
|
0
|
|
|
|
|
0
|
my $one = $self->format_number(1); |
2672
|
0
|
|
|
|
|
0
|
$divisor =~ s/\s*$one\s*//; |
2673
|
|
|
|
|
|
|
|
2674
|
0
|
|
|
|
|
0
|
my @bundles = $self->_find_bundle('units'); |
2675
|
0
|
|
|
|
|
0
|
my $format; |
2676
|
0
|
|
|
|
|
0
|
foreach my $bundle (@bundles) { |
2677
|
0
|
0
|
|
|
|
0
|
if (exists $bundle->units()->{$type}{per}{''}) { |
2678
|
0
|
|
|
|
|
0
|
$format = $bundle->units()->{$type}{per}{''}; |
2679
|
0
|
|
|
|
|
0
|
last; |
2680
|
|
|
|
|
|
|
} |
2681
|
|
|
|
|
|
|
} |
2682
|
|
|
|
|
|
|
|
2683
|
|
|
|
|
|
|
# Check for aliases |
2684
|
0
|
0
|
|
|
|
0
|
unless ($format) { |
2685
|
0
|
|
|
|
|
0
|
my $original_type = $type; |
2686
|
0
|
|
|
|
|
0
|
my @aliases = $self->_find_bundle('unit_alias'); |
2687
|
0
|
|
|
|
|
0
|
foreach my $alias (@aliases) { |
2688
|
0
|
|
|
|
|
0
|
$type = $alias->unit_alias()->{$original_type}; |
2689
|
0
|
|
|
|
|
0
|
foreach my $bundle (@bundles) { |
2690
|
0
|
0
|
|
|
|
0
|
if (exists $bundle->units()->{$type}{per}{1}) { |
2691
|
0
|
|
|
|
|
0
|
$format = $bundle->units()->{$type}{per}{1}; |
2692
|
0
|
|
|
|
|
0
|
last; |
2693
|
|
|
|
|
|
|
} |
2694
|
|
|
|
|
|
|
} |
2695
|
|
|
|
|
|
|
} |
2696
|
|
|
|
|
|
|
} |
2697
|
|
|
|
|
|
|
|
2698
|
0
|
|
|
|
|
0
|
$format =~ s/\{0\}/$dividend/g; |
2699
|
0
|
|
|
|
|
0
|
$format =~ s/\{1\}/$divisor/g; |
2700
|
|
|
|
|
|
|
|
2701
|
0
|
|
|
|
|
0
|
return $format; |
2702
|
|
|
|
|
|
|
} |
2703
|
|
|
|
|
|
|
|
2704
|
|
|
|
|
|
|
=item unit_name($unit_identifier) |
2705
|
|
|
|
|
|
|
|
2706
|
|
|
|
|
|
|
This method returns the localised name of the unit |
2707
|
|
|
|
|
|
|
|
2708
|
|
|
|
|
|
|
=cut |
2709
|
|
|
|
|
|
|
|
2710
|
|
|
|
|
|
|
sub unit_name { |
2711
|
0
|
|
|
0
|
1
|
0
|
my ($self, $what) = @_; |
2712
|
|
|
|
|
|
|
|
2713
|
0
|
|
|
|
|
0
|
my @bundles = $self->_find_bundle('units'); |
2714
|
0
|
|
|
|
|
0
|
my $name; |
2715
|
0
|
|
|
|
|
0
|
foreach my $bundle (@bundles) { |
2716
|
0
|
0
|
|
|
|
0
|
if (exists $bundle->units()->{long}{$what}{name}) { |
2717
|
0
|
|
|
|
|
0
|
return $bundle->units()->{long}{$what}{name}; |
2718
|
|
|
|
|
|
|
} |
2719
|
|
|
|
|
|
|
} |
2720
|
|
|
|
|
|
|
|
2721
|
|
|
|
|
|
|
# Check for aliases |
2722
|
0
|
|
|
|
|
0
|
my $type = 'long'; |
2723
|
0
|
|
|
|
|
0
|
my @aliases = $self->_find_bundle('unit_alias'); |
2724
|
0
|
|
|
|
|
0
|
foreach my $alias (@aliases) { |
2725
|
0
|
|
|
|
|
0
|
$type = $alias->unit_alias()->{$type}; |
2726
|
0
|
0
|
|
|
|
0
|
next unless $type; |
2727
|
0
|
|
|
|
|
0
|
foreach my $bundle (@bundles) { |
2728
|
0
|
0
|
|
|
|
0
|
if (exists $bundle->units()->{$type}{$what}{name}) { |
2729
|
0
|
|
|
|
|
0
|
return $bundle->units()->{$type}{$what}{name}; |
2730
|
|
|
|
|
|
|
} |
2731
|
|
|
|
|
|
|
} |
2732
|
|
|
|
|
|
|
} |
2733
|
|
|
|
|
|
|
|
2734
|
0
|
|
|
|
|
0
|
return ''; |
2735
|
|
|
|
|
|
|
} |
2736
|
|
|
|
|
|
|
|
2737
|
|
|
|
|
|
|
sub _unit_per { |
2738
|
6
|
|
|
6
|
|
14
|
my ($self, $what, $type) = @_; |
2739
|
|
|
|
|
|
|
|
2740
|
6
|
|
|
|
|
12
|
my @bundles = $self->_find_bundle('units'); |
2741
|
6
|
|
|
|
|
40
|
my $name; |
2742
|
6
|
|
|
|
|
13
|
foreach my $bundle (@bundles) { |
2743
|
8
|
100
|
|
|
|
37
|
if (exists $bundle->units()->{$type}{$what}{per}) { |
2744
|
4
|
|
|
|
|
15
|
return $bundle->units()->{$type}{$what}{per}; |
2745
|
|
|
|
|
|
|
} |
2746
|
|
|
|
|
|
|
} |
2747
|
|
|
|
|
|
|
|
2748
|
|
|
|
|
|
|
# Check for aliases |
2749
|
2
|
|
|
|
|
4
|
my @aliases = $self->_find_bundle('unit_alias'); |
2750
|
2
|
|
|
|
|
15
|
foreach my $alias (@aliases) { |
2751
|
2
|
|
|
|
|
8
|
$type = $alias->unit_alias()->{$type}; |
2752
|
2
|
50
|
|
|
|
6
|
next unless $type; |
2753
|
2
|
|
|
|
|
4
|
foreach my $bundle (@bundles) { |
2754
|
2
|
50
|
|
|
|
10
|
if (exists $bundle->units()->{$type}{$what}{per}) { |
2755
|
2
|
|
|
|
|
9
|
return $bundle->units()->{$type}{$what}{per}; |
2756
|
|
|
|
|
|
|
} |
2757
|
|
|
|
|
|
|
} |
2758
|
|
|
|
|
|
|
} |
2759
|
|
|
|
|
|
|
|
2760
|
0
|
|
|
|
|
0
|
return ''; |
2761
|
|
|
|
|
|
|
} |
2762
|
|
|
|
|
|
|
|
2763
|
|
|
|
|
|
|
sub _get_time_separator { |
2764
|
12
|
|
|
12
|
|
30
|
my $self = shift; |
2765
|
|
|
|
|
|
|
|
2766
|
12
|
|
|
|
|
35
|
my @number_symbols_bundles = $self->_find_bundle('number_symbols'); |
2767
|
12
|
|
|
|
|
117
|
my $symbols_type = $self->default_numbering_system; |
2768
|
|
|
|
|
|
|
|
2769
|
12
|
|
|
|
|
28
|
foreach my $bundle (@number_symbols_bundles) { |
2770
|
24
|
50
|
|
|
|
93
|
if (exists $bundle->number_symbols()->{$symbols_type}{alias}) { |
2771
|
0
|
|
|
|
|
0
|
$symbols_type = $bundle->number_symbols()->{$symbols_type}{alias}; |
2772
|
0
|
|
|
|
|
0
|
redo; |
2773
|
|
|
|
|
|
|
} |
2774
|
|
|
|
|
|
|
|
2775
|
|
|
|
|
|
|
return $bundle->number_symbols()->{$symbols_type}{timeSeparator} |
2776
|
24
|
100
|
|
|
|
92
|
if exists $bundle->number_symbols()->{$symbols_type}{timeSeparator}; |
2777
|
|
|
|
|
|
|
} |
2778
|
0
|
|
|
|
|
0
|
return ':'; |
2779
|
|
|
|
|
|
|
} |
2780
|
|
|
|
|
|
|
|
2781
|
|
|
|
|
|
|
=item duration_unit($format, @data) |
2782
|
|
|
|
|
|
|
|
2783
|
|
|
|
|
|
|
This method formats a duration. The format must be one of |
2784
|
|
|
|
|
|
|
C<hm>, C<hms> or C<ms> corresponding to C<hour minute>, |
2785
|
|
|
|
|
|
|
C<hour minute second> and C<minute second> respectively. |
2786
|
|
|
|
|
|
|
The data must correspond to the given format. |
2787
|
|
|
|
|
|
|
|
2788
|
|
|
|
|
|
|
=cut |
2789
|
|
|
|
|
|
|
|
2790
|
|
|
|
|
|
|
sub duration_unit { |
2791
|
|
|
|
|
|
|
# data in hh,mm; hh,mm,ss or mm,ss |
2792
|
3
|
|
|
3
|
1
|
10
|
my ($self, $format, @data) = @_; |
2793
|
|
|
|
|
|
|
|
2794
|
3
|
|
|
|
|
9
|
my $bundle = $self->_find_bundle('duration_units'); |
2795
|
3
|
|
|
|
|
27
|
my $parsed = $bundle->duration_units()->{$format}; |
2796
|
|
|
|
|
|
|
|
2797
|
3
|
|
|
|
|
6
|
my $num_format = '#'; |
2798
|
3
|
|
|
|
|
18
|
foreach my $entry ( qr/(hh?)/, qr/(mm?)/, qr/(ss?)/) { |
2799
|
9
|
100
|
|
|
|
67
|
$num_format = '00' if $parsed =~ s/$entry/$self->format_number(shift(@data), $num_format)/e; |
|
7
|
|
|
|
|
31
|
|
2800
|
|
|
|
|
|
|
} |
2801
|
|
|
|
|
|
|
|
2802
|
3
|
|
|
|
|
16
|
my $time_separator = $self->_get_time_separator; |
2803
|
|
|
|
|
|
|
|
2804
|
3
|
|
|
|
|
13
|
$parsed =~ s/:/$time_separator/g; |
2805
|
|
|
|
|
|
|
|
2806
|
3
|
|
|
|
|
19
|
return $parsed; |
2807
|
|
|
|
|
|
|
} |
2808
|
|
|
|
|
|
|
|
2809
|
|
|
|
|
|
|
=back |
2810
|
|
|
|
|
|
|
|
2811
|
|
|
|
|
|
|
=head2 Yes or No? |
2812
|
|
|
|
|
|
|
|
2813
|
|
|
|
|
|
|
=over 4 |
2814
|
|
|
|
|
|
|
|
2815
|
|
|
|
|
|
|
=item is_yes($string) |
2816
|
|
|
|
|
|
|
|
2817
|
|
|
|
|
|
|
Returns true if the passed in string matches the locale's |
2818
|
|
|
|
|
|
|
idea of a string designating yes. Note that under POSIX |
2819
|
|
|
|
|
|
|
rules unless the locale's word for yes starts with C<Y> |
2820
|
|
|
|
|
|
|
(U+0079) then a single 'y' will also be accepted as yes. |
2821
|
|
|
|
|
|
|
The string will be matched case insensitive. |
2822
|
|
|
|
|
|
|
|
2823
|
|
|
|
|
|
|
=cut |
2824
|
|
|
|
|
|
|
|
2825
|
|
|
|
|
|
|
sub is_yes { |
2826
|
2
|
|
|
2
|
1
|
7
|
my ($self, $test_str) = @_; |
2827
|
|
|
|
|
|
|
|
2828
|
2
|
|
|
|
|
8
|
my $bundle = $self->_find_bundle('yesstr'); |
2829
|
2
|
100
|
|
|
|
36
|
return $test_str =~ $bundle->yesstr ? 1 : 0; |
2830
|
|
|
|
|
|
|
} |
2831
|
|
|
|
|
|
|
|
2832
|
|
|
|
|
|
|
=item is_no($string) |
2833
|
|
|
|
|
|
|
|
2834
|
|
|
|
|
|
|
Returns true if the passed in string matches the locale's |
2835
|
|
|
|
|
|
|
idea of a string designating no. Note that under POSIX |
2836
|
|
|
|
|
|
|
rules unless the locale's word for no starts with C<n> |
2837
|
|
|
|
|
|
|
(U+006E) then a single 'n' will also be accepted as no |
2838
|
|
|
|
|
|
|
The string will be matched case insensitive. |
2839
|
|
|
|
|
|
|
|
2840
|
|
|
|
|
|
|
=cut |
2841
|
|
|
|
|
|
|
|
2842
|
|
|
|
|
|
|
sub is_no { |
2843
|
2
|
|
|
2
|
1
|
7
|
my ($self, $test_str) = @_; |
2844
|
|
|
|
|
|
|
|
2845
|
2
|
|
|
|
|
6
|
my $bundle = $self->_find_bundle('nostr'); |
2846
|
2
|
100
|
|
|
|
35
|
return $test_str =~ $bundle->nostr ? 1 : 0; |
2847
|
|
|
|
|
|
|
} |
2848
|
|
|
|
|
|
|
|
2849
|
|
|
|
|
|
|
=back |
2850
|
|
|
|
|
|
|
|
2851
|
|
|
|
|
|
|
=cut |
2852
|
|
|
|
|
|
|
|
2853
|
|
|
|
|
|
|
=head2 Transliteration |
2854
|
|
|
|
|
|
|
|
2855
|
|
|
|
|
|
|
This method requires Perl version 5.18 or above to use and for you to have |
2856
|
|
|
|
|
|
|
installed the optional C<Bundle::CLDR::Transformations> |
2857
|
|
|
|
|
|
|
|
2858
|
|
|
|
|
|
|
=over 4 |
2859
|
|
|
|
|
|
|
|
2860
|
|
|
|
|
|
|
=item transform(from => $from, to => $to, variant => $variant, text => $text) |
2861
|
|
|
|
|
|
|
|
2862
|
|
|
|
|
|
|
This method returns the transliterated string of C<text> from script C<from> |
2863
|
|
|
|
|
|
|
to script C<to> using variant C<variant>. If C<from> is not given then the |
2864
|
|
|
|
|
|
|
current locale's script is used. If C<text> is not given then it defaults to an |
2865
|
|
|
|
|
|
|
empty string. The C<variant> is optional. |
2866
|
|
|
|
|
|
|
|
2867
|
|
|
|
|
|
|
=cut |
2868
|
|
|
|
|
|
|
|
2869
|
|
|
|
|
|
|
sub transform { |
2870
|
0
|
|
|
0
|
1
|
0
|
_new_perl(); |
2871
|
|
|
|
|
|
|
|
2872
|
0
|
|
|
|
|
0
|
my ($self, %params) = @_; |
2873
|
|
|
|
|
|
|
|
2874
|
0
|
|
0
|
|
|
0
|
my $from = $params{from} // $self; |
2875
|
0
|
|
|
|
|
0
|
my $to = $params{to}; |
2876
|
0
|
|
0
|
|
|
0
|
my $variant = $params{variant} // 'Any'; |
2877
|
0
|
|
0
|
|
|
0
|
my $text = $params{text} // ''; |
2878
|
|
|
|
|
|
|
|
2879
|
0
|
0
|
|
|
|
0
|
($from, $to) = map {ref $_ ? $_->likely_subtag->script_id() : $_} ($from, $to); |
|
0
|
|
|
|
|
0
|
|
2880
|
0
|
|
|
|
|
0
|
$_ = ucfirst(lc $_) foreach ($from, $to, $variant); |
2881
|
|
|
|
|
|
|
|
2882
|
0
|
|
|
|
|
0
|
my $package = __PACKAGE__ . "::Transformations::${variant}::${from}::${to}"; |
2883
|
0
|
|
|
|
|
0
|
my ($canload, $error) = Class::Load::try_load_class($package, { -version => $VERSION}); |
2884
|
0
|
0
|
|
|
|
0
|
if ($canload) { |
2885
|
0
|
|
|
|
|
0
|
Class::Load::load_class($package, { -version => $VERSION}); |
2886
|
|
|
|
|
|
|
} |
2887
|
|
|
|
|
|
|
else { |
2888
|
0
|
|
|
|
|
0
|
warn $error; |
2889
|
0
|
|
|
|
|
0
|
return $text; # Can't load transform module so return original text |
2890
|
|
|
|
|
|
|
} |
2891
|
21
|
|
|
21
|
|
231
|
use feature 'state'; |
|
21
|
|
|
|
|
53
|
|
|
21
|
|
|
|
|
245438
|
|
2892
|
0
|
|
|
|
|
0
|
state $transforms; |
2893
|
0
|
|
0
|
|
|
0
|
$transforms->{$variant}{$from}{$to} //= $package->new(); |
2894
|
0
|
|
|
|
|
0
|
my $rules = $transforms->{$variant}{$from}{$to}->transforms(); |
2895
|
|
|
|
|
|
|
|
2896
|
|
|
|
|
|
|
# First get the filter rule |
2897
|
0
|
|
|
|
|
0
|
my $filter = $rules->[0]; |
2898
|
|
|
|
|
|
|
|
2899
|
|
|
|
|
|
|
# Break up the input on the filter |
2900
|
0
|
|
|
|
|
0
|
my @text; |
2901
|
0
|
|
|
|
|
0
|
pos($text) = 0; |
2902
|
0
|
|
|
|
|
0
|
while (pos($text) < length($text)) { |
2903
|
0
|
|
|
|
|
0
|
my $characters = ''; |
2904
|
0
|
|
|
|
|
0
|
while (my ($char) = $text =~ /($filter)/) { |
2905
|
0
|
|
|
|
|
0
|
$characters .= $char; |
2906
|
0
|
|
|
|
|
0
|
pos($text) = pos($text) + length $char; |
2907
|
|
|
|
|
|
|
} |
2908
|
0
|
|
|
|
|
0
|
push @text, $characters; |
2909
|
0
|
0
|
|
|
|
0
|
last unless pos($text) < length $text; |
2910
|
|
|
|
|
|
|
|
2911
|
0
|
|
|
|
|
0
|
$characters = ''; |
2912
|
0
|
|
|
|
|
0
|
while ($text !~ /$filter/) { |
2913
|
0
|
|
|
|
|
0
|
my ($char) = $text =~ /\G(\X)/; |
2914
|
0
|
|
|
|
|
0
|
$characters .= $char; |
2915
|
0
|
|
|
|
|
0
|
pos($text) = pos($text) + length $char; |
2916
|
|
|
|
|
|
|
} |
2917
|
0
|
|
|
|
|
0
|
push @text, $characters; |
2918
|
|
|
|
|
|
|
} |
2919
|
|
|
|
|
|
|
|
2920
|
0
|
|
|
|
|
0
|
my $to_transform = 1; |
2921
|
|
|
|
|
|
|
|
2922
|
0
|
|
|
|
|
0
|
foreach my $characters (@text) { |
2923
|
0
|
0
|
|
|
|
0
|
if ($to_transform) { |
2924
|
0
|
|
|
|
|
0
|
foreach my $rule (@$rules[1 .. @$rules -1 ]) { |
2925
|
0
|
0
|
|
|
|
0
|
if ($rule->{type} eq 'transform') { |
2926
|
0
|
|
|
|
|
0
|
$characters = $self->_transformation_transform($characters, $rule->{data}, $variant); |
2927
|
|
|
|
|
|
|
} |
2928
|
|
|
|
|
|
|
else { |
2929
|
0
|
|
|
|
|
0
|
$characters = $self->_transform_convert($characters, $rule->{data}); |
2930
|
|
|
|
|
|
|
} |
2931
|
|
|
|
|
|
|
} |
2932
|
|
|
|
|
|
|
} |
2933
|
0
|
|
|
|
|
0
|
$to_transform = ! $to_transform; |
2934
|
|
|
|
|
|
|
} |
2935
|
|
|
|
|
|
|
|
2936
|
0
|
|
|
|
|
0
|
return join '', @text; |
2937
|
|
|
|
|
|
|
} |
2938
|
|
|
|
|
|
|
|
2939
|
|
|
|
|
|
|
sub _transformation_transform { |
2940
|
0
|
|
|
0
|
|
0
|
my ($self, $text, $rules, $variant) = @_; |
2941
|
|
|
|
|
|
|
|
2942
|
0
|
|
|
|
|
0
|
foreach my $rule (@$rules) { |
2943
|
0
|
|
|
|
|
0
|
for (lc $rule->{to}) { |
2944
|
0
|
0
|
|
|
|
0
|
if ($_ eq 'nfc') { |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
2945
|
0
|
|
|
|
|
0
|
$text = Unicode::Normalize::NFC($text); |
2946
|
|
|
|
|
|
|
} |
2947
|
|
|
|
|
|
|
elsif($_ eq 'nfd') { |
2948
|
0
|
|
|
|
|
0
|
$text = Unicode::Normalize::NFD($text); |
2949
|
|
|
|
|
|
|
} |
2950
|
|
|
|
|
|
|
elsif($_ eq 'nfkd') { |
2951
|
0
|
|
|
|
|
0
|
$text = Unicode::Normalize::NFKD($text); |
2952
|
|
|
|
|
|
|
} |
2953
|
|
|
|
|
|
|
elsif($_ eq 'nfkc') { |
2954
|
0
|
|
|
|
|
0
|
$text = Unicode::Normalize::NFKC($text); |
2955
|
|
|
|
|
|
|
} |
2956
|
|
|
|
|
|
|
elsif($_ eq 'lower') { |
2957
|
0
|
|
|
|
|
0
|
$text = lc($text); |
2958
|
|
|
|
|
|
|
} |
2959
|
|
|
|
|
|
|
elsif($_ eq 'upper') { |
2960
|
0
|
|
|
|
|
0
|
$text = uc($text); |
2961
|
|
|
|
|
|
|
} |
2962
|
|
|
|
|
|
|
elsif($_ eq 'title') { |
2963
|
0
|
|
|
|
|
0
|
$text =~ s/(\X)/\u$1/g; |
2964
|
|
|
|
|
|
|
} |
2965
|
|
|
|
|
|
|
elsif($_ eq 'null') { |
2966
|
|
|
|
|
|
|
} |
2967
|
|
|
|
|
|
|
elsif($_ eq 'remove') { |
2968
|
0
|
|
|
|
|
0
|
$text = ''; |
2969
|
|
|
|
|
|
|
} |
2970
|
|
|
|
|
|
|
else { |
2971
|
0
|
|
|
|
|
0
|
$text = $self->transform(text => $text, variant => $variant, from => $rule->{from}, to => $rule->{to}); |
2972
|
|
|
|
|
|
|
} |
2973
|
|
|
|
|
|
|
} |
2974
|
|
|
|
|
|
|
} |
2975
|
0
|
|
|
|
|
0
|
return $text; |
2976
|
|
|
|
|
|
|
} |
2977
|
|
|
|
|
|
|
|
2978
|
|
|
|
|
|
|
sub _transform_convert { |
2979
|
0
|
|
|
0
|
|
0
|
my ($self, $text, $rules) = @_; |
2980
|
|
|
|
|
|
|
|
2981
|
0
|
|
|
|
|
0
|
pos($text) = 0; # Make sure we start scanning at the beginning of the text |
2982
|
|
|
|
|
|
|
|
2983
|
0
|
|
|
|
|
0
|
CHARACTER: while (pos($text) < length($text)) { |
2984
|
0
|
|
|
|
|
0
|
foreach my $rule (@$rules) { |
2985
|
0
|
0
|
0
|
|
|
0
|
next if length $rule->{before} && $text !~ /$rule->{before}\G/; |
2986
|
0
|
|
|
|
|
0
|
my $regex = $rule->{replace}; |
2987
|
0
|
0
|
|
|
|
0
|
$regex .= '(' . $rule->{after} . ')' if length $rule->{after}; |
2988
|
0
|
|
|
|
|
0
|
my $result = 'q(' . $rule->{result} . ')'; |
2989
|
0
|
0
|
|
|
|
0
|
$result .= '. $1' if length $rule->{after}; |
2990
|
0
|
0
|
|
|
|
0
|
if ($text =~ s/\G$regex/eval $result/e) { |
|
0
|
|
|
|
|
0
|
|
2991
|
0
|
|
|
|
|
0
|
pos($text) += length($rule->{result}) - $rule->{revisit}; |
2992
|
0
|
|
|
|
|
0
|
next CHARACTER; |
2993
|
|
|
|
|
|
|
} |
2994
|
|
|
|
|
|
|
} |
2995
|
|
|
|
|
|
|
|
2996
|
0
|
|
|
|
|
0
|
pos($text)++; |
2997
|
|
|
|
|
|
|
} |
2998
|
|
|
|
|
|
|
|
2999
|
0
|
|
|
|
|
0
|
return $text; |
3000
|
|
|
|
|
|
|
} |
3001
|
|
|
|
|
|
|
|
3002
|
|
|
|
|
|
|
=back |
3003
|
|
|
|
|
|
|
|
3004
|
|
|
|
|
|
|
=head2 Lists |
3005
|
|
|
|
|
|
|
|
3006
|
|
|
|
|
|
|
=over 4 |
3007
|
|
|
|
|
|
|
|
3008
|
|
|
|
|
|
|
=item list(@data) |
3009
|
|
|
|
|
|
|
|
3010
|
|
|
|
|
|
|
Returns C<data> as a string formatted by the locales idea of producing a list |
3011
|
|
|
|
|
|
|
of elements. What is returned can be effected by the locale and the number |
3012
|
|
|
|
|
|
|
of items in C<data>. Note that C<data> can contain 0 or more items. |
3013
|
|
|
|
|
|
|
|
3014
|
|
|
|
|
|
|
=cut |
3015
|
|
|
|
|
|
|
|
3016
|
|
|
|
|
|
|
sub list { |
3017
|
5
|
|
|
5
|
1
|
1105
|
my ($self, @data) = @_; |
3018
|
|
|
|
|
|
|
|
3019
|
|
|
|
|
|
|
# Short circuit on 0 or 1 entries |
3020
|
5
|
100
|
|
|
|
24
|
return '' unless @data; |
3021
|
4
|
100
|
|
|
|
14
|
return $data[0] if 1 == @data; |
3022
|
|
|
|
|
|
|
|
3023
|
3
|
|
|
|
|
14
|
my @bundles = $self->_find_bundle('listPatterns'); |
3024
|
|
|
|
|
|
|
|
3025
|
3
|
|
|
|
|
22
|
my %list_data; |
3026
|
3
|
|
|
|
|
15
|
foreach my $bundle (reverse @bundles) { |
3027
|
6
|
|
|
|
|
10
|
my %listPatterns = %{$bundle->listPatterns}; |
|
6
|
|
|
|
|
38
|
|
3028
|
6
|
|
|
|
|
24
|
@list_data{keys %listPatterns} = values %listPatterns; |
3029
|
|
|
|
|
|
|
} |
3030
|
|
|
|
|
|
|
|
3031
|
3
|
100
|
|
|
|
11
|
if (my $pattern = $list_data{scalar @data}) { |
3032
|
1
|
|
|
|
|
8
|
$pattern=~s/\{([0-9]+)\}/$data[$1]/eg; |
|
2
|
|
|
|
|
10
|
|
3033
|
1
|
|
|
|
|
12
|
return $pattern; |
3034
|
|
|
|
|
|
|
} |
3035
|
|
|
|
|
|
|
|
3036
|
2
|
|
|
|
|
6
|
my ($start, $middle, $end) = @list_data{qw( start middle end )}; |
3037
|
|
|
|
|
|
|
|
3038
|
|
|
|
|
|
|
# First do the end |
3039
|
2
|
|
|
|
|
4
|
my $pattern = $end; |
3040
|
2
|
|
|
|
|
7
|
$pattern=~s/\{1\}/pop @data/e; |
|
2
|
|
|
|
|
7
|
|
3041
|
2
|
|
|
|
|
7
|
$pattern=~s/\{0\}/pop @data/e; |
|
2
|
|
|
|
|
5
|
|
3042
|
|
|
|
|
|
|
|
3043
|
|
|
|
|
|
|
# If there is any data left do the middle |
3044
|
2
|
|
|
|
|
6
|
while (@data > 1) { |
3045
|
1
|
|
|
|
|
4
|
my $current = $pattern; |
3046
|
1
|
|
|
|
|
2
|
$pattern = $middle; |
3047
|
1
|
|
|
|
|
4
|
$pattern=~s/\{1\}/$current/; |
3048
|
1
|
|
|
|
|
4
|
$pattern=~s/\{0\}/pop @data/e; |
|
1
|
|
|
|
|
3
|
|
3049
|
|
|
|
|
|
|
} |
3050
|
|
|
|
|
|
|
|
3051
|
|
|
|
|
|
|
# Now do the start |
3052
|
2
|
|
|
|
|
4
|
my $current = $pattern; |
3053
|
2
|
|
|
|
|
4
|
$pattern = $start; |
3054
|
2
|
|
|
|
|
6
|
$pattern=~s/\{1\}/$current/; |
3055
|
2
|
|
|
|
|
5
|
$pattern=~s/\{0\}/pop @data/e; |
|
2
|
|
|
|
|
3
|
|
3056
|
|
|
|
|
|
|
|
3057
|
2
|
|
|
|
|
11
|
return $pattern; |
3058
|
|
|
|
|
|
|
} |
3059
|
|
|
|
|
|
|
|
3060
|
|
|
|
|
|
|
=back |
3061
|
|
|
|
|
|
|
|
3062
|
|
|
|
|
|
|
=head2 Pluralisation |
3063
|
|
|
|
|
|
|
|
3064
|
|
|
|
|
|
|
=over 4 |
3065
|
|
|
|
|
|
|
|
3066
|
|
|
|
|
|
|
=item plural($number) |
3067
|
|
|
|
|
|
|
|
3068
|
|
|
|
|
|
|
This method takes a number and uses the locale's pluralisation |
3069
|
|
|
|
|
|
|
rules to calculate the type of pluralisation required for |
3070
|
|
|
|
|
|
|
units, currencies and other data that changes depending on |
3071
|
|
|
|
|
|
|
the plural state of the number |
3072
|
|
|
|
|
|
|
|
3073
|
|
|
|
|
|
|
=item plural_range($start, $end) |
3074
|
|
|
|
|
|
|
|
3075
|
|
|
|
|
|
|
This method returns the plural type for the range $start to $end |
3076
|
|
|
|
|
|
|
$start and $end can either be numbers or one of the plural types |
3077
|
|
|
|
|
|
|
C<zero one two few many other> |
3078
|
|
|
|
|
|
|
|
3079
|
|
|
|
|
|
|
=cut |
3080
|
|
|
|
|
|
|
|
3081
|
|
|
|
|
|
|
sub _clear_calendar_data { |
3082
|
0
|
|
|
0
|
|
0
|
my $self = shift; |
3083
|
|
|
|
|
|
|
|
3084
|
0
|
|
|
|
|
0
|
foreach my $property (qw( |
3085
|
|
|
|
|
|
|
month_format_wide month_format_abbreviated month_format_narrow |
3086
|
|
|
|
|
|
|
month_stand_alone_wide month_stand_alone_abbreviated |
3087
|
|
|
|
|
|
|
month_stand_alone_narrow day_format_wide day_format_abbreviated |
3088
|
|
|
|
|
|
|
day_format_narrow day_stand_alone_wide day_stand_alone_abreviated |
3089
|
|
|
|
|
|
|
day_stand_alone_narrow quater_format_wide quater_format_abbreviated |
3090
|
|
|
|
|
|
|
quater_format_narrow quater_stand_alone_wide |
3091
|
|
|
|
|
|
|
quater_stand_alone_abreviated quater_stand_alone_narrow |
3092
|
|
|
|
|
|
|
am_pm_wide am_pm_abbreviated am_pm_narrow am_pm_format_wide |
3093
|
|
|
|
|
|
|
am_pm_format_abbreviated am_pm_format_narrow am_pm_stand_alone_wide |
3094
|
|
|
|
|
|
|
am_pm_stand_alone_abbreviated am_pm_stand_alone_narrow era_wide |
3095
|
|
|
|
|
|
|
era_abbreviated era_narrow date_format_full date_format_long date_format_medium |
3096
|
|
|
|
|
|
|
date_format_short time_format_full |
3097
|
|
|
|
|
|
|
time_format_long time_format_medium time_format_short |
3098
|
|
|
|
|
|
|
datetime_format_full datetime_format_long |
3099
|
|
|
|
|
|
|
datetime_format_medium datetime_format_short |
3100
|
|
|
|
|
|
|
available_formats format_data |
3101
|
|
|
|
|
|
|
)) { |
3102
|
0
|
|
|
|
|
0
|
my $method = "_clear_$property"; |
3103
|
0
|
|
|
|
|
0
|
$self->$method; |
3104
|
|
|
|
|
|
|
} |
3105
|
|
|
|
|
|
|
} |
3106
|
|
|
|
|
|
|
|
3107
|
|
|
|
|
|
|
sub _build_any_month { |
3108
|
8
|
|
|
8
|
|
22
|
my ($self, $type, $width) = @_; |
3109
|
8
|
|
|
|
|
32
|
my $default_calendar = $self->default_calendar(); |
3110
|
8
|
|
|
|
|
28
|
my @bundles = $self->_find_bundle('calendar_months'); |
3111
|
|
|
|
|
|
|
BUNDLES: { |
3112
|
8
|
|
|
|
|
75
|
foreach my $bundle (@bundles) { |
|
12
|
|
|
|
|
33
|
|
3113
|
16
|
|
|
|
|
47
|
my $months = $bundle->calendar_months; |
3114
|
16
|
50
|
|
|
|
42
|
if (exists $months->{$default_calendar}{alias}) { |
3115
|
0
|
|
|
|
|
0
|
$default_calendar = $months->{$default_calendar}{alias}; |
3116
|
0
|
|
|
|
|
0
|
redo BUNDLES; |
3117
|
|
|
|
|
|
|
} |
3118
|
|
|
|
|
|
|
|
3119
|
16
|
100
|
|
|
|
53
|
if (exists $months->{$default_calendar}{$type}{$width}{alias}) { |
3120
|
4
|
|
|
|
|
9
|
($type, $width) = @{$months->{$default_calendar}{$type}{$width}{alias}}{qw(context type)}; |
|
4
|
|
|
|
|
19
|
|
3121
|
4
|
|
|
|
|
12
|
redo BUNDLES; |
3122
|
|
|
|
|
|
|
} |
3123
|
|
|
|
|
|
|
|
3124
|
12
|
|
|
|
|
23
|
my $result = $months->{$default_calendar}{$type}{$width}{nonleap}; |
3125
|
12
|
100
|
|
|
|
152
|
return $result if defined $result; |
3126
|
|
|
|
|
|
|
} |
3127
|
0
|
0
|
|
|
|
0
|
if ($default_calendar ne 'gregorian') { |
3128
|
0
|
|
|
|
|
0
|
$default_calendar = 'gregorian'; |
3129
|
0
|
|
|
|
|
0
|
redo BUNDLES; |
3130
|
|
|
|
|
|
|
} |
3131
|
|
|
|
|
|
|
} |
3132
|
0
|
|
|
|
|
0
|
return []; |
3133
|
|
|
|
|
|
|
} |
3134
|
|
|
|
|
|
|
|
3135
|
|
|
|
|
|
|
sub _build_month_format_wide { |
3136
|
2
|
|
|
2
|
|
1516
|
my $self = shift; |
3137
|
2
|
|
|
|
|
9
|
my ($type, $width) = (qw(format wide)); |
3138
|
|
|
|
|
|
|
|
3139
|
2
|
|
|
|
|
12
|
return $self->_build_any_month($type, $width); |
3140
|
|
|
|
|
|
|
} |
3141
|
|
|
|
|
|
|
|
3142
|
|
|
|
|
|
|
sub _build_month_format_abbreviated { |
3143
|
1
|
|
|
1
|
|
1061
|
my $self = shift; |
3144
|
1
|
|
|
|
|
4
|
my ($type, $width) = (qw(format abbreviated)); |
3145
|
|
|
|
|
|
|
|
3146
|
1
|
|
|
|
|
6
|
return $self->_build_any_month($type, $width); |
3147
|
|
|
|
|
|
|
} |
3148
|
|
|
|
|
|
|
|
3149
|
|
|
|
|
|
|
sub _build_month_format_narrow { |
3150
|
1
|
|
|
1
|
|
674
|
my $self = shift; |
3151
|
1
|
|
|
|
|
5
|
my ($type, $width) = (qw(format narrow)); |
3152
|
|
|
|
|
|
|
|
3153
|
1
|
|
|
|
|
3
|
return $self->_build_any_month($type, $width); |
3154
|
|
|
|
|
|
|
} |
3155
|
|
|
|
|
|
|
|
3156
|
|
|
|
|
|
|
sub _build_month_stand_alone_wide { |
3157
|
1
|
|
|
1
|
|
614
|
my $self = shift; |
3158
|
1
|
|
|
|
|
3
|
my ($type, $width) = ('stand-alone', 'wide'); |
3159
|
|
|
|
|
|
|
|
3160
|
1
|
|
|
|
|
4
|
return $self->_build_any_month($type, $width); |
3161
|
|
|
|
|
|
|
} |
3162
|
|
|
|
|
|
|
|
3163
|
|
|
|
|
|
|
sub _build_month_stand_alone_abbreviated { |
3164
|
2
|
|
|
2
|
|
624
|
my $self = shift; |
3165
|
2
|
|
|
|
|
8
|
my ($type, $width) = ('stand-alone', 'abbreviated'); |
3166
|
|
|
|
|
|
|
|
3167
|
2
|
|
|
|
|
9
|
return $self->_build_any_month($type, $width); |
3168
|
|
|
|
|
|
|
} |
3169
|
|
|
|
|
|
|
|
3170
|
|
|
|
|
|
|
sub _build_month_stand_alone_narrow { |
3171
|
1
|
|
|
1
|
|
606
|
my $self = shift; |
3172
|
1
|
|
|
|
|
4
|
my ($type, $width) = ('stand-alone', 'narrow'); |
3173
|
|
|
|
|
|
|
|
3174
|
1
|
|
|
|
|
4
|
return $self->_build_any_month($type, $width); |
3175
|
|
|
|
|
|
|
} |
3176
|
|
|
|
|
|
|
|
3177
|
|
|
|
|
|
|
sub _build_any_day { |
3178
|
7
|
|
|
7
|
|
16
|
my ($self, $type, $width) = @_; |
3179
|
|
|
|
|
|
|
|
3180
|
7
|
|
|
|
|
23
|
my $default_calendar = $self->default_calendar(); |
3181
|
|
|
|
|
|
|
|
3182
|
7
|
|
|
|
|
20
|
my @bundles = $self->_find_bundle('calendar_days'); |
3183
|
|
|
|
|
|
|
BUNDLES: { |
3184
|
7
|
|
|
|
|
48
|
foreach my $bundle (@bundles) { |
|
10
|
|
|
|
|
19
|
|
3185
|
13
|
|
|
|
|
37
|
my $days= $bundle->calendar_days; |
3186
|
|
|
|
|
|
|
|
3187
|
13
|
50
|
|
|
|
33
|
if (exists $days->{$default_calendar}{alias}) { |
3188
|
0
|
|
|
|
|
0
|
$default_calendar = $days->{$default_calendar}{alias}; |
3189
|
0
|
|
|
|
|
0
|
redo BUNDLES; |
3190
|
|
|
|
|
|
|
} |
3191
|
|
|
|
|
|
|
|
3192
|
13
|
100
|
|
|
|
45
|
if (exists $days->{$default_calendar}{$type}{$width}{alias}) { |
3193
|
3
|
|
|
|
|
6
|
($type, $width) = @{$days->{$default_calendar}{$type}{$width}{alias}}{qw(context type)}; |
|
3
|
|
|
|
|
27
|
|
3194
|
3
|
|
|
|
|
8
|
redo BUNDLES; |
3195
|
|
|
|
|
|
|
} |
3196
|
10
|
|
|
|
|
14
|
my $result = $days->{$default_calendar}{$type}{$width}; |
3197
|
10
|
100
|
|
|
|
31
|
return [ @{$result}{qw( mon tue wed thu fri sat sun )} ] if keys %$result; |
|
7
|
|
|
|
|
135
|
|
3198
|
|
|
|
|
|
|
} |
3199
|
0
|
0
|
|
|
|
0
|
if ($default_calendar ne 'gregorian') { |
3200
|
0
|
|
|
|
|
0
|
$default_calendar = 'gregorian'; |
3201
|
0
|
|
|
|
|
0
|
redo BUNDLES; |
3202
|
|
|
|
|
|
|
} |
3203
|
|
|
|
|
|
|
} |
3204
|
|
|
|
|
|
|
|
3205
|
0
|
|
|
|
|
0
|
return []; |
3206
|
|
|
|
|
|
|
} |
3207
|
|
|
|
|
|
|
|
3208
|
|
|
|
|
|
|
sub _build_day_format_wide { |
3209
|
2
|
|
|
2
|
|
851
|
my $self = shift; |
3210
|
2
|
|
|
|
|
8
|
my ($type, $width) = (qw(format wide)); |
3211
|
|
|
|
|
|
|
|
3212
|
2
|
|
|
|
|
12
|
return $self->_build_any_day($type, $width); |
3213
|
|
|
|
|
|
|
} |
3214
|
|
|
|
|
|
|
|
3215
|
|
|
|
|
|
|
sub _build_day_format_abbreviated { |
3216
|
1
|
|
|
1
|
|
944
|
my $self = shift; |
3217
|
1
|
|
|
|
|
4
|
my ($type, $width) = (qw(format abbreviated)); |
3218
|
|
|
|
|
|
|
|
3219
|
1
|
|
|
|
|
5
|
return $self->_build_any_day($type, $width); |
3220
|
|
|
|
|
|
|
} |
3221
|
|
|
|
|
|
|
|
3222
|
|
|
|
|
|
|
sub _build_day_format_narrow { |
3223
|
1
|
|
|
1
|
|
647
|
my $self = shift; |
3224
|
1
|
|
|
|
|
3
|
my ($type, $width) = (qw(format narrow)); |
3225
|
|
|
|
|
|
|
|
3226
|
1
|
|
|
|
|
3
|
return $self->_build_any_day($type, $width); |
3227
|
|
|
|
|
|
|
} |
3228
|
|
|
|
|
|
|
|
3229
|
|
|
|
|
|
|
sub _build_day_stand_alone_wide { |
3230
|
1
|
|
|
1
|
|
566
|
my $self = shift; |
3231
|
1
|
|
|
|
|
3
|
my ($type, $width) = ('stand-alone', 'wide'); |
3232
|
|
|
|
|
|
|
|
3233
|
1
|
|
|
|
|
4
|
return $self->_build_any_day($type, $width); |
3234
|
|
|
|
|
|
|
} |
3235
|
|
|
|
|
|
|
|
3236
|
|
|
|
|
|
|
sub _build_day_stand_alone_abbreviated { |
3237
|
1
|
|
|
1
|
|
606
|
my $self = shift; |
3238
|
1
|
|
|
|
|
4
|
my ($type, $width) = ('stand-alone', 'abbreviated'); |
3239
|
|
|
|
|
|
|
|
3240
|
1
|
|
|
|
|
3
|
return $self->_build_any_day($type, $width); |
3241
|
|
|
|
|
|
|
} |
3242
|
|
|
|
|
|
|
|
3243
|
|
|
|
|
|
|
sub _build_day_stand_alone_narrow { |
3244
|
1
|
|
|
1
|
|
600
|
my $self = shift; |
3245
|
1
|
|
|
|
|
16
|
my ($type, $width) = ('stand-alone', 'narrow'); |
3246
|
|
|
|
|
|
|
|
3247
|
1
|
|
|
|
|
4
|
return $self->_build_any_day($type, $width); |
3248
|
|
|
|
|
|
|
} |
3249
|
|
|
|
|
|
|
|
3250
|
|
|
|
|
|
|
sub _build_any_quarter { |
3251
|
6
|
|
|
6
|
|
14
|
my ($self, $type, $width) = @_; |
3252
|
|
|
|
|
|
|
|
3253
|
6
|
|
|
|
|
20
|
my $default_calendar = $self->default_calendar(); |
3254
|
|
|
|
|
|
|
|
3255
|
6
|
|
|
|
|
16
|
my @bundles = $self->_find_bundle('calendar_quarters'); |
3256
|
|
|
|
|
|
|
BUNDLES: { |
3257
|
6
|
|
|
|
|
41
|
foreach my $bundle (@bundles) { |
|
9
|
|
|
|
|
16
|
|
3258
|
12
|
|
|
|
|
27
|
my $quarters= $bundle->calendar_quarters; |
3259
|
|
|
|
|
|
|
|
3260
|
12
|
50
|
|
|
|
29
|
if (exists $quarters->{$default_calendar}{alias}) { |
3261
|
0
|
|
|
|
|
0
|
$default_calendar = $quarters->{$default_calendar}{alias}; |
3262
|
0
|
|
|
|
|
0
|
redo BUNDLES; |
3263
|
|
|
|
|
|
|
} |
3264
|
|
|
|
|
|
|
|
3265
|
12
|
100
|
|
|
|
36
|
if (exists $quarters->{$default_calendar}{$type}{$width}{alias}) { |
3266
|
3
|
|
|
|
|
8
|
($type, $width) = @{$quarters->{$default_calendar}{$type}{$width}{alias}}{qw(context type)}; |
|
3
|
|
|
|
|
12
|
|
3267
|
3
|
|
|
|
|
6
|
redo BUNDLES; |
3268
|
|
|
|
|
|
|
} |
3269
|
|
|
|
|
|
|
|
3270
|
9
|
|
|
|
|
13
|
my $result = $quarters->{$default_calendar}{$type}{$width}; |
3271
|
9
|
100
|
|
|
|
31
|
return [ @{$result}{qw( 0 1 2 3 )} ] if keys %$result; |
|
6
|
|
|
|
|
113
|
|
3272
|
|
|
|
|
|
|
} |
3273
|
0
|
0
|
|
|
|
0
|
if ($default_calendar ne 'gregorian') { |
3274
|
0
|
|
|
|
|
0
|
$default_calendar = 'gregorian'; |
3275
|
0
|
|
|
|
|
0
|
redo BUNDLES; |
3276
|
|
|
|
|
|
|
} |
3277
|
|
|
|
|
|
|
} |
3278
|
|
|
|
|
|
|
|
3279
|
0
|
|
|
|
|
0
|
return []; |
3280
|
|
|
|
|
|
|
} |
3281
|
|
|
|
|
|
|
|
3282
|
|
|
|
|
|
|
sub _build_quarter_format_wide { |
3283
|
1
|
|
|
1
|
|
577
|
my $self = shift; |
3284
|
1
|
|
|
|
|
5
|
my ($type, $width) = (qw( format wide )); |
3285
|
|
|
|
|
|
|
|
3286
|
1
|
|
|
|
|
6
|
return $self->_build_any_quarter($type, $width); |
3287
|
|
|
|
|
|
|
} |
3288
|
|
|
|
|
|
|
|
3289
|
|
|
|
|
|
|
sub _build_quarter_format_abbreviated { |
3290
|
1
|
|
|
1
|
|
979
|
my $self = shift; |
3291
|
1
|
|
|
|
|
5
|
my ($type, $width) = (qw(format abbreviated)); |
3292
|
|
|
|
|
|
|
|
3293
|
1
|
|
|
|
|
4
|
return $self->_build_any_quarter($type, $width); |
3294
|
|
|
|
|
|
|
} |
3295
|
|
|
|
|
|
|
|
3296
|
|
|
|
|
|
|
sub _build_quarter_format_narrow { |
3297
|
1
|
|
|
1
|
|
553
|
my $self = shift; |
3298
|
1
|
|
|
|
|
5
|
my ($type, $width) = (qw(format narrow)); |
3299
|
|
|
|
|
|
|
|
3300
|
1
|
|
|
|
|
4
|
return $self->_build_any_quarter($type, $width); |
3301
|
|
|
|
|
|
|
} |
3302
|
|
|
|
|
|
|
|
3303
|
|
|
|
|
|
|
sub _build_quarter_stand_alone_wide { |
3304
|
1
|
|
|
1
|
|
539
|
my $self = shift; |
3305
|
1
|
|
|
|
|
4
|
my ($type, $width) = ('stand-alone', 'wide'); |
3306
|
|
|
|
|
|
|
|
3307
|
1
|
|
|
|
|
3
|
return $self->_build_any_quarter($type, $width); |
3308
|
|
|
|
|
|
|
} |
3309
|
|
|
|
|
|
|
|
3310
|
|
|
|
|
|
|
sub _build_quarter_stand_alone_abbreviated { |
3311
|
1
|
|
|
1
|
|
537
|
my $self = shift; |
3312
|
1
|
|
|
|
|
4
|
my ($type, $width) = ('stand-alone', 'abbreviated'); |
3313
|
|
|
|
|
|
|
|
3314
|
1
|
|
|
|
|
5
|
return $self->_build_any_quarter($type, $width); |
3315
|
|
|
|
|
|
|
} |
3316
|
|
|
|
|
|
|
|
3317
|
|
|
|
|
|
|
sub _build_quarter_stand_alone_narrow { |
3318
|
1
|
|
|
1
|
|
537
|
my $self = shift; |
3319
|
1
|
|
|
|
|
3
|
my ($type, $width) = ('stand-alone', 'narrow'); |
3320
|
|
|
|
|
|
|
|
3321
|
1
|
|
|
|
|
4
|
return $self->_build_any_quarter($type, $width); |
3322
|
|
|
|
|
|
|
} |
3323
|
|
|
|
|
|
|
|
3324
|
|
|
|
|
|
|
sub get_day_period { |
3325
|
|
|
|
|
|
|
# Time in hhmm |
3326
|
3
|
|
|
3
|
1
|
4628
|
my ($self, $time, $type) = @_; |
3327
|
3
|
|
50
|
|
|
31
|
$type //= 'default'; |
3328
|
|
|
|
|
|
|
|
3329
|
3
|
|
|
|
|
14
|
my $default_calendar = $self->default_calendar(); |
3330
|
|
|
|
|
|
|
|
3331
|
3
|
|
|
|
|
14
|
my $bundle = $self->_find_bundle('day_period_data'); |
3332
|
|
|
|
|
|
|
|
3333
|
3
|
|
|
|
|
82
|
my $day_period = $bundle->day_period_data; |
3334
|
3
|
|
|
|
|
83
|
$day_period = $self->$day_period($default_calendar, $time, $type); |
3335
|
|
|
|
|
|
|
|
3336
|
|
|
|
|
|
|
# The day period for root is commented out but I need that data so will |
3337
|
|
|
|
|
|
|
# fix up here as a default |
3338
|
3
|
0
|
33
|
|
|
11
|
$day_period ||= $time < 1200 ? 'am' : 'pm'; |
3339
|
|
|
|
|
|
|
|
3340
|
3
|
|
|
|
|
83
|
my $am_pm = $self->am_pm_format_abbreviated; |
3341
|
|
|
|
|
|
|
|
3342
|
3
|
|
|
|
|
41
|
return $am_pm->{$day_period}; |
3343
|
|
|
|
|
|
|
} |
3344
|
|
|
|
|
|
|
|
3345
|
|
|
|
|
|
|
sub _build_any_am_pm { |
3346
|
10
|
|
|
10
|
|
21
|
my ($self, $type, $width) = @_; |
3347
|
|
|
|
|
|
|
|
3348
|
10
|
|
|
|
|
30
|
my $default_calendar = $self->default_calendar(); |
3349
|
10
|
|
|
|
|
17
|
my @result; |
3350
|
10
|
|
|
|
|
24
|
my @bundles = $self->_find_bundle('day_periods'); |
3351
|
10
|
|
|
|
|
67
|
my %return; |
3352
|
|
|
|
|
|
|
|
3353
|
|
|
|
|
|
|
BUNDLES: { |
3354
|
10
|
|
|
|
|
19
|
foreach my $bundle (@bundles) { |
|
19
|
|
|
|
|
32
|
|
3355
|
38
|
|
|
|
|
76
|
my $am_pm = $bundle->day_periods; |
3356
|
|
|
|
|
|
|
|
3357
|
38
|
50
|
|
|
|
67
|
if (exists $am_pm->{$default_calendar}{alias}) { |
3358
|
0
|
|
|
|
|
0
|
$default_calendar = $am_pm->{$default_calendar}{alias}; |
3359
|
0
|
|
|
|
|
0
|
redo BUNDLES; |
3360
|
|
|
|
|
|
|
} |
3361
|
|
|
|
|
|
|
|
3362
|
38
|
50
|
|
|
|
71
|
if (exists $am_pm->{$default_calendar}{$type}{alias}) { |
3363
|
0
|
|
|
|
|
0
|
$type = $am_pm->{$default_calendar}{$type}{alias}; |
3364
|
0
|
|
|
|
|
0
|
redo BUNDLES; |
3365
|
|
|
|
|
|
|
} |
3366
|
|
|
|
|
|
|
|
3367
|
38
|
100
|
|
|
|
83
|
if (exists $am_pm->{$default_calendar}{$type}{$width}{alias}) { |
3368
|
9
|
|
|
|
|
13
|
my $original_width = $width; |
3369
|
9
|
|
|
|
|
19
|
$width = $am_pm->{$default_calendar}{$type}{$width}{alias}{width}; |
3370
|
9
|
|
|
|
|
16
|
$type = $am_pm->{$default_calendar}{$type}{$original_width}{alias}{context}; |
3371
|
9
|
|
|
|
|
20
|
redo BUNDLES; |
3372
|
|
|
|
|
|
|
} |
3373
|
|
|
|
|
|
|
|
3374
|
29
|
|
|
|
|
41
|
my $result = $am_pm->{$default_calendar}{$type}{$width}; |
3375
|
|
|
|
|
|
|
|
3376
|
29
|
|
|
|
|
68
|
foreach (keys %$result) { |
3377
|
164
|
100
|
|
|
|
311
|
$return{$_} = $result->{$_} unless exists $return{$_}; |
3378
|
|
|
|
|
|
|
} |
3379
|
|
|
|
|
|
|
} |
3380
|
|
|
|
|
|
|
} |
3381
|
|
|
|
|
|
|
|
3382
|
10
|
|
|
|
|
104
|
return \%return; |
3383
|
|
|
|
|
|
|
} |
3384
|
|
|
|
|
|
|
|
3385
|
|
|
|
|
|
|
# The first 3 are to link in with Date::Time::Locale |
3386
|
|
|
|
|
|
|
sub _build_am_pm_wide { |
3387
|
1
|
|
|
1
|
|
533
|
my $self = shift; |
3388
|
1
|
|
|
|
|
4
|
my ($type, $width) = (qw( format wide )); |
3389
|
|
|
|
|
|
|
|
3390
|
1
|
|
|
|
|
6
|
my $result = $self->_build_any_am_pm($type, $width); |
3391
|
|
|
|
|
|
|
|
3392
|
1
|
|
|
|
|
23
|
return [ @$result{qw( am pm )} ]; |
3393
|
|
|
|
|
|
|
} |
3394
|
|
|
|
|
|
|
|
3395
|
|
|
|
|
|
|
sub _build_am_pm_abbreviated { |
3396
|
2
|
|
|
2
|
|
1704
|
my $self = shift; |
3397
|
2
|
|
|
|
|
9
|
my ($type, $width) = (qw( format abbreviated )); |
3398
|
|
|
|
|
|
|
|
3399
|
2
|
|
|
|
|
10
|
my $result = $self->_build_any_am_pm($type, $width); |
3400
|
|
|
|
|
|
|
|
3401
|
2
|
|
|
|
|
44
|
return [ @$result{qw( am pm )} ]; |
3402
|
|
|
|
|
|
|
} |
3403
|
|
|
|
|
|
|
|
3404
|
|
|
|
|
|
|
sub _build_am_pm_narrow { |
3405
|
1
|
|
|
1
|
|
533
|
my $self = shift; |
3406
|
1
|
|
|
|
|
5
|
my ($type, $width) = (qw( format narrow )); |
3407
|
|
|
|
|
|
|
|
3408
|
1
|
|
|
|
|
4
|
my $result = $self->_build_any_am_pm($type, $width); |
3409
|
|
|
|
|
|
|
|
3410
|
1
|
|
|
|
|
19
|
return [ @$result{qw( am pm )} ]; |
3411
|
|
|
|
|
|
|
} |
3412
|
|
|
|
|
|
|
|
3413
|
|
|
|
|
|
|
# Now we do the full set of data |
3414
|
|
|
|
|
|
|
sub _build_am_pm_format_wide { |
3415
|
1
|
|
|
1
|
|
541
|
my $self = shift; |
3416
|
1
|
|
|
|
|
4
|
my ($type, $width) = (qw( format wide )); |
3417
|
|
|
|
|
|
|
|
3418
|
1
|
|
|
|
|
3
|
return $self->_build_any_am_pm($type, $width); |
3419
|
|
|
|
|
|
|
} |
3420
|
|
|
|
|
|
|
|
3421
|
|
|
|
|
|
|
sub _build_am_pm_format_abbreviated { |
3422
|
1
|
|
|
1
|
|
632
|
my $self = shift; |
3423
|
1
|
|
|
|
|
4
|
my ($type, $width) = (qw( format abbreviated )); |
3424
|
|
|
|
|
|
|
|
3425
|
1
|
|
|
|
|
4
|
return $self->_build_any_am_pm($type, $width); |
3426
|
|
|
|
|
|
|
} |
3427
|
|
|
|
|
|
|
|
3428
|
|
|
|
|
|
|
sub _build_am_pm_format_narrow { |
3429
|
1
|
|
|
1
|
|
594
|
my $self = shift; |
3430
|
1
|
|
|
|
|
4
|
my ($type, $width) = (qw( format narrow )); |
3431
|
|
|
|
|
|
|
|
3432
|
1
|
|
|
|
|
5
|
return $self->_build_any_am_pm($type, $width); |
3433
|
|
|
|
|
|
|
} |
3434
|
|
|
|
|
|
|
|
3435
|
|
|
|
|
|
|
sub _build_am_pm_stand_alone_wide { |
3436
|
1
|
|
|
1
|
|
601
|
my $self = shift; |
3437
|
1
|
|
|
|
|
4
|
my ($type, $width) = ('stand-alone', 'wide'); |
3438
|
|
|
|
|
|
|
|
3439
|
1
|
|
|
|
|
5
|
return $self->_build_any_am_pm($type, $width); |
3440
|
|
|
|
|
|
|
} |
3441
|
|
|
|
|
|
|
|
3442
|
|
|
|
|
|
|
sub _build_am_pm_stand_alone_abbreviated { |
3443
|
1
|
|
|
1
|
|
598
|
my $self = shift; |
3444
|
1
|
|
|
|
|
4
|
my ($type, $width) = ('stand-alone', 'abbreviated'); |
3445
|
|
|
|
|
|
|
|
3446
|
1
|
|
|
|
|
4
|
return $self->_build_any_am_pm($type, $width); |
3447
|
|
|
|
|
|
|
} |
3448
|
|
|
|
|
|
|
|
3449
|
|
|
|
|
|
|
sub _build_am_pm_stand_alone_narrow { |
3450
|
1
|
|
|
1
|
|
602
|
my $self = shift; |
3451
|
1
|
|
|
|
|
5
|
my ($type, $width) = ('stand-alone', 'narrow'); |
3452
|
|
|
|
|
|
|
|
3453
|
1
|
|
|
|
|
5
|
return $self->_build_any_am_pm($type, $width); |
3454
|
|
|
|
|
|
|
} |
3455
|
|
|
|
|
|
|
|
3456
|
|
|
|
|
|
|
sub _build_any_era { |
3457
|
9
|
|
|
9
|
|
17
|
my ($self, $width) = @_; |
3458
|
|
|
|
|
|
|
|
3459
|
9
|
|
|
|
|
24
|
my $default_calendar = $self->default_calendar(); |
3460
|
9
|
|
|
|
|
21
|
my @bundles = $self->_find_bundle('eras'); |
3461
|
|
|
|
|
|
|
BUNDLES: { |
3462
|
9
|
|
|
|
|
55
|
foreach my $bundle (@bundles) { |
|
9
|
|
|
|
|
17
|
|
3463
|
9
|
|
|
|
|
23
|
my $eras = $bundle->eras; |
3464
|
|
|
|
|
|
|
|
3465
|
9
|
50
|
|
|
|
25
|
if (exists $eras->{$default_calendar}{alias}) { |
3466
|
0
|
|
|
|
|
0
|
$default_calendar = $eras->{$default_calendar}{alias}; |
3467
|
0
|
|
|
|
|
0
|
redo BUNDLES; |
3468
|
|
|
|
|
|
|
} |
3469
|
|
|
|
|
|
|
|
3470
|
9
|
50
|
|
|
|
32
|
if (exists $eras->{$default_calendar}{$width}{alias}) { |
3471
|
0
|
|
|
|
|
0
|
$width = $eras->{$default_calendar}{$width}{alias}; |
3472
|
0
|
|
|
|
|
0
|
redo BUNDLES; |
3473
|
|
|
|
|
|
|
} |
3474
|
|
|
|
|
|
|
|
3475
|
9
|
|
|
|
|
17
|
my $result = $eras->{$default_calendar}{$width}; |
3476
|
|
|
|
|
|
|
|
3477
|
9
|
|
|
|
|
10
|
my @result; |
3478
|
9
|
|
|
|
|
39
|
@result[keys %$result] = values %$result; |
3479
|
|
|
|
|
|
|
|
3480
|
9
|
50
|
|
|
|
111
|
return \@result if keys %$result; |
3481
|
|
|
|
|
|
|
} |
3482
|
0
|
0
|
|
|
|
0
|
if ($default_calendar ne 'gregorian') { |
3483
|
0
|
|
|
|
|
0
|
$default_calendar = 'gregorian'; |
3484
|
0
|
|
|
|
|
0
|
redo BUNDLES; |
3485
|
|
|
|
|
|
|
} |
3486
|
|
|
|
|
|
|
} |
3487
|
|
|
|
|
|
|
|
3488
|
0
|
|
|
|
|
0
|
return []; |
3489
|
|
|
|
|
|
|
} |
3490
|
|
|
|
|
|
|
|
3491
|
|
|
|
|
|
|
# The next three are for DateDime::Locale |
3492
|
|
|
|
|
|
|
sub _build_era_wide { |
3493
|
1
|
|
|
1
|
|
576
|
my $self = shift; |
3494
|
1
|
|
|
|
|
3
|
my ($width) = (qw( wide )); |
3495
|
|
|
|
|
|
|
|
3496
|
1
|
|
|
|
|
5
|
my $result = $self->_build_any_era($width); |
3497
|
|
|
|
|
|
|
|
3498
|
1
|
|
|
|
|
23
|
return [@$result[0, 1]]; |
3499
|
|
|
|
|
|
|
} |
3500
|
|
|
|
|
|
|
|
3501
|
|
|
|
|
|
|
sub _build_era_abbreviated { |
3502
|
1
|
|
|
1
|
|
900
|
my $self = shift; |
3503
|
1
|
|
|
|
|
3
|
my ($width) = (qw( abbreviated )); |
3504
|
|
|
|
|
|
|
|
3505
|
1
|
|
|
|
|
5
|
my $result = $self->_build_any_era($width); |
3506
|
|
|
|
|
|
|
|
3507
|
1
|
|
|
|
|
18
|
return [@$result[0, 1]]; |
3508
|
|
|
|
|
|
|
} |
3509
|
|
|
|
|
|
|
|
3510
|
|
|
|
|
|
|
sub _build_era_narrow { |
3511
|
1
|
|
|
1
|
|
528
|
my $self = shift; |
3512
|
1
|
|
|
|
|
3
|
my ($width) = (qw( narrow )); |
3513
|
|
|
|
|
|
|
|
3514
|
1
|
|
|
|
|
4
|
my $result = $self->_build_any_era($width); |
3515
|
|
|
|
|
|
|
|
3516
|
1
|
|
|
|
|
17
|
return [@$result[0, 1]]; |
3517
|
|
|
|
|
|
|
} |
3518
|
|
|
|
|
|
|
|
3519
|
|
|
|
|
|
|
# Now get all the era data |
3520
|
|
|
|
|
|
|
sub _build_era_format_wide { |
3521
|
2
|
|
|
2
|
|
1122
|
my $self = shift; |
3522
|
2
|
|
|
|
|
4
|
my ($width) = (qw( wide )); |
3523
|
|
|
|
|
|
|
|
3524
|
2
|
|
|
|
|
10
|
return $self->_build_any_era($width); |
3525
|
|
|
|
|
|
|
} |
3526
|
|
|
|
|
|
|
|
3527
|
|
|
|
|
|
|
sub _build_era_format_abbreviated { |
3528
|
2
|
|
|
2
|
|
1053
|
my $self = shift; |
3529
|
2
|
|
|
|
|
4
|
my ($width) = (qw( abbreviated )); |
3530
|
|
|
|
|
|
|
|
3531
|
2
|
|
|
|
|
7
|
return $self->_build_any_era($width); |
3532
|
|
|
|
|
|
|
} |
3533
|
|
|
|
|
|
|
|
3534
|
|
|
|
|
|
|
sub _build_era_format_narrow { |
3535
|
2
|
|
|
2
|
|
1040
|
my $self = shift; |
3536
|
2
|
|
|
|
|
6
|
my ($type, $width) = (qw( narrow )); |
3537
|
|
|
|
|
|
|
|
3538
|
2
|
|
|
|
|
7
|
return $self->_build_any_era($type, $width); |
3539
|
|
|
|
|
|
|
} |
3540
|
|
|
|
|
|
|
|
3541
|
|
|
|
|
|
|
*_build_era_stand_alone_wide = \&_build_era_format_wide; |
3542
|
|
|
|
|
|
|
*_build_era_stand_alone_abbreviated = \&_build_era_format_abbreviated; |
3543
|
|
|
|
|
|
|
*_build_era_stand_alone_narrow = \&_build_era_format_narrow; |
3544
|
|
|
|
|
|
|
|
3545
|
|
|
|
|
|
|
sub _build_any_date_format { |
3546
|
9
|
|
|
9
|
|
22
|
my ($self, $width) = @_; |
3547
|
9
|
|
|
|
|
29
|
my $default_calendar = $self->default_calendar(); |
3548
|
|
|
|
|
|
|
|
3549
|
9
|
|
|
|
|
25
|
my @bundles = $self->_find_bundle('date_formats'); |
3550
|
|
|
|
|
|
|
|
3551
|
|
|
|
|
|
|
BUNDLES: { |
3552
|
9
|
|
|
|
|
71
|
foreach my $bundle (@bundles) { |
|
9
|
|
|
|
|
18
|
|
3553
|
9
|
|
|
|
|
36
|
my $date_formats = $bundle->date_formats; |
3554
|
9
|
50
|
|
|
|
28
|
if (exists $date_formats->{alias}) { |
3555
|
0
|
|
|
|
|
0
|
$default_calendar = $date_formats->{alias}; |
3556
|
0
|
|
|
|
|
0
|
redo BUNDLES; |
3557
|
|
|
|
|
|
|
} |
3558
|
|
|
|
|
|
|
|
3559
|
9
|
|
|
|
|
40
|
my $result = $date_formats->{$default_calendar}{$width}; |
3560
|
9
|
50
|
|
|
|
99
|
return $result if $result; |
3561
|
|
|
|
|
|
|
} |
3562
|
0
|
0
|
|
|
|
0
|
if ($default_calendar ne 'gregorian') { |
3563
|
0
|
|
|
|
|
0
|
$default_calendar = 'gregorian'; |
3564
|
0
|
|
|
|
|
0
|
redo BUNDLES; |
3565
|
|
|
|
|
|
|
} |
3566
|
|
|
|
|
|
|
} |
3567
|
|
|
|
|
|
|
|
3568
|
0
|
|
|
|
|
0
|
return ''; |
3569
|
|
|
|
|
|
|
} |
3570
|
|
|
|
|
|
|
|
3571
|
|
|
|
|
|
|
sub _build_date_format_full { |
3572
|
1
|
|
|
1
|
|
33
|
my $self = shift; |
3573
|
|
|
|
|
|
|
|
3574
|
1
|
|
|
|
|
4
|
my ($width) = ('full'); |
3575
|
1
|
|
|
|
|
5
|
return $self->_build_any_date_format($width); |
3576
|
|
|
|
|
|
|
} |
3577
|
|
|
|
|
|
|
|
3578
|
|
|
|
|
|
|
sub _build_date_format_long { |
3579
|
1
|
|
|
1
|
|
940
|
my $self = shift; |
3580
|
|
|
|
|
|
|
|
3581
|
1
|
|
|
|
|
3
|
my ($width) = ('long'); |
3582
|
1
|
|
|
|
|
5
|
return $self->_build_any_date_format($width); |
3583
|
|
|
|
|
|
|
} |
3584
|
|
|
|
|
|
|
|
3585
|
|
|
|
|
|
|
sub _build_date_format_medium { |
3586
|
1
|
|
|
1
|
|
707
|
my $self = shift; |
3587
|
|
|
|
|
|
|
|
3588
|
1
|
|
|
|
|
4
|
my ($width) = ('medium'); |
3589
|
1
|
|
|
|
|
3
|
return $self->_build_any_date_format($width); |
3590
|
|
|
|
|
|
|
} |
3591
|
|
|
|
|
|
|
|
3592
|
|
|
|
|
|
|
sub _build_date_format_short { |
3593
|
1
|
|
|
1
|
|
649
|
my $self = shift; |
3594
|
|
|
|
|
|
|
|
3595
|
1
|
|
|
|
|
3
|
my ($width) = ('short'); |
3596
|
1
|
|
|
|
|
16
|
return $self->_build_any_date_format($width); |
3597
|
|
|
|
|
|
|
} |
3598
|
|
|
|
|
|
|
|
3599
|
|
|
|
|
|
|
sub _build_any_time_format { |
3600
|
9
|
|
|
9
|
|
24
|
my ($self, $width) = @_; |
3601
|
9
|
|
|
|
|
28
|
my $default_calendar = $self->default_calendar(); |
3602
|
|
|
|
|
|
|
|
3603
|
9
|
|
|
|
|
24
|
my @bundles = $self->_find_bundle('time_formats'); |
3604
|
|
|
|
|
|
|
|
3605
|
|
|
|
|
|
|
BUNDLES: { |
3606
|
9
|
|
|
|
|
68
|
foreach my $bundle (@bundles) { |
|
9
|
|
|
|
|
22
|
|
3607
|
9
|
|
|
|
|
32
|
my $time_formats = $bundle->time_formats; |
3608
|
9
|
50
|
|
|
|
38
|
if (exists $time_formats->{$default_calendar}{alias}) { |
3609
|
0
|
|
|
|
|
0
|
$default_calendar = $time_formats->{$default_calendar}{alias}; |
3610
|
0
|
|
|
|
|
0
|
redo BUNDLES; |
3611
|
|
|
|
|
|
|
} |
3612
|
|
|
|
|
|
|
|
3613
|
9
|
|
|
|
|
22
|
my $result = $time_formats->{$default_calendar}{$width}; |
3614
|
9
|
50
|
|
|
|
26
|
if ($result) { |
3615
|
9
|
|
|
|
|
30
|
my $time_separator = $self->_get_time_separator; |
3616
|
9
|
|
|
|
|
42
|
$result =~ s/:/$time_separator/g; |
3617
|
9
|
|
|
|
|
96
|
return $result; |
3618
|
|
|
|
|
|
|
} |
3619
|
|
|
|
|
|
|
} |
3620
|
0
|
0
|
|
|
|
0
|
if ($default_calendar ne 'gregorian') { |
3621
|
0
|
|
|
|
|
0
|
$default_calendar = 'gregorian'; |
3622
|
0
|
|
|
|
|
0
|
redo BUNDLES; |
3623
|
|
|
|
|
|
|
} |
3624
|
|
|
|
|
|
|
} |
3625
|
0
|
|
|
|
|
0
|
return ''; |
3626
|
|
|
|
|
|
|
} |
3627
|
|
|
|
|
|
|
|
3628
|
|
|
|
|
|
|
sub _build_time_format_full { |
3629
|
1
|
|
|
1
|
|
654
|
my $self = shift; |
3630
|
1
|
|
|
|
|
3
|
my $width = 'full'; |
3631
|
|
|
|
|
|
|
|
3632
|
1
|
|
|
|
|
5
|
return $self->_build_any_time_format($width); |
3633
|
|
|
|
|
|
|
} |
3634
|
|
|
|
|
|
|
|
3635
|
|
|
|
|
|
|
sub _build_time_format_long { |
3636
|
1
|
|
|
1
|
|
930
|
my $self = shift; |
3637
|
|
|
|
|
|
|
|
3638
|
1
|
|
|
|
|
4
|
my $width = 'long'; |
3639
|
1
|
|
|
|
|
5
|
return $self->_build_any_time_format($width); |
3640
|
|
|
|
|
|
|
} |
3641
|
|
|
|
|
|
|
|
3642
|
|
|
|
|
|
|
sub _build_time_format_medium { |
3643
|
1
|
|
|
1
|
|
651
|
my $self = shift; |
3644
|
|
|
|
|
|
|
|
3645
|
1
|
|
|
|
|
2
|
my $width = 'medium'; |
3646
|
1
|
|
|
|
|
4
|
return $self->_build_any_time_format($width); |
3647
|
|
|
|
|
|
|
} |
3648
|
|
|
|
|
|
|
|
3649
|
|
|
|
|
|
|
sub _build_time_format_short { |
3650
|
1
|
|
|
1
|
|
693
|
my $self = shift; |
3651
|
|
|
|
|
|
|
|
3652
|
1
|
|
|
|
|
3
|
my $width = 'short'; |
3653
|
1
|
|
|
|
|
4
|
return $self->_build_any_time_format($width); |
3654
|
|
|
|
|
|
|
} |
3655
|
|
|
|
|
|
|
|
3656
|
|
|
|
|
|
|
sub _build_any_datetime_format { |
3657
|
5
|
|
|
5
|
|
16
|
my ($self, $width) = @_; |
3658
|
5
|
|
|
|
|
18
|
my $default_calendar = $self->default_calendar(); |
3659
|
|
|
|
|
|
|
|
3660
|
5
|
|
|
|
|
17
|
my @bundles = $self->_find_bundle('datetime_formats'); |
3661
|
|
|
|
|
|
|
|
3662
|
|
|
|
|
|
|
BUNDLES: { |
3663
|
5
|
|
|
|
|
41
|
foreach my $bundle (@bundles) { |
|
5
|
|
|
|
|
12
|
|
3664
|
5
|
|
|
|
|
21
|
my $datetime_formats = $bundle->datetime_formats; |
3665
|
5
|
50
|
|
|
|
20
|
if (exists $datetime_formats->{$default_calendar}{alias}) { |
3666
|
0
|
|
|
|
|
0
|
$default_calendar = $datetime_formats->{$default_calendar}{alias}; |
3667
|
0
|
|
|
|
|
0
|
redo BUNDLES; |
3668
|
|
|
|
|
|
|
} |
3669
|
|
|
|
|
|
|
|
3670
|
5
|
|
|
|
|
27
|
my $result = $datetime_formats->{$default_calendar}{$width}; |
3671
|
5
|
50
|
|
|
|
28
|
return $result if $result; |
3672
|
|
|
|
|
|
|
} |
3673
|
0
|
0
|
|
|
|
0
|
if ($default_calendar ne 'gregorian') { |
3674
|
0
|
|
|
|
|
0
|
$default_calendar = 'gregorian'; |
3675
|
0
|
|
|
|
|
0
|
redo BUNDLES; |
3676
|
|
|
|
|
|
|
} |
3677
|
|
|
|
|
|
|
} |
3678
|
|
|
|
|
|
|
|
3679
|
0
|
|
|
|
|
0
|
return ''; |
3680
|
|
|
|
|
|
|
} |
3681
|
|
|
|
|
|
|
|
3682
|
|
|
|
|
|
|
sub _build_datetime_format_full { |
3683
|
2
|
|
|
2
|
|
15422
|
my $self = shift; |
3684
|
|
|
|
|
|
|
|
3685
|
2
|
|
|
|
|
6
|
my $width = 'full'; |
3686
|
2
|
|
|
|
|
7
|
my $format = $self->_build_any_datetime_format($width); |
3687
|
|
|
|
|
|
|
|
3688
|
2
|
|
|
|
|
10
|
my $date = $self->_build_any_date_format($width); |
3689
|
2
|
|
|
|
|
9
|
my $time = $self->_build_any_time_format($width); |
3690
|
|
|
|
|
|
|
|
3691
|
2
|
|
|
|
|
8
|
$format =~ s/\{0\}/$time/; |
3692
|
2
|
|
|
|
|
9
|
$format =~ s/\{1\}/$date/; |
3693
|
|
|
|
|
|
|
|
3694
|
2
|
|
|
|
|
41
|
return $format; |
3695
|
|
|
|
|
|
|
} |
3696
|
|
|
|
|
|
|
|
3697
|
|
|
|
|
|
|
sub _build_datetime_format_long { |
3698
|
1
|
|
|
1
|
|
4883
|
my $self = shift; |
3699
|
|
|
|
|
|
|
|
3700
|
1
|
|
|
|
|
3
|
my $width = 'long'; |
3701
|
1
|
|
|
|
|
4
|
my $format = $self->_build_any_datetime_format($width); |
3702
|
|
|
|
|
|
|
|
3703
|
1
|
|
|
|
|
3
|
my $date = $self->_build_any_date_format($width); |
3704
|
1
|
|
|
|
|
4
|
my $time = $self->_build_any_time_format($width); |
3705
|
|
|
|
|
|
|
|
3706
|
1
|
|
|
|
|
5
|
$format =~ s/\{0\}/$time/; |
3707
|
1
|
|
|
|
|
5
|
$format =~ s/\{1\}/$date/; |
3708
|
|
|
|
|
|
|
|
3709
|
1
|
|
|
|
|
18
|
return $format; |
3710
|
|
|
|
|
|
|
} |
3711
|
|
|
|
|
|
|
|
3712
|
|
|
|
|
|
|
sub _build_datetime_format_medium { |
3713
|
1
|
|
|
1
|
|
658
|
my $self = shift; |
3714
|
|
|
|
|
|
|
|
3715
|
1
|
|
|
|
|
3
|
my $width = 'medium'; |
3716
|
1
|
|
|
|
|
3
|
my $format = $self->_build_any_datetime_format($width); |
3717
|
|
|
|
|
|
|
|
3718
|
1
|
|
|
|
|
4
|
my $date = $self->_build_any_date_format($width); |
3719
|
1
|
|
|
|
|
4
|
my $time = $self->_build_any_time_format($width); |
3720
|
|
|
|
|
|
|
|
3721
|
1
|
|
|
|
|
3
|
$format =~ s/\{0\}/$time/; |
3722
|
1
|
|
|
|
|
5
|
$format =~ s/\{1\}/$date/; |
3723
|
|
|
|
|
|
|
|
3724
|
1
|
|
|
|
|
18
|
return $format; |
3725
|
|
|
|
|
|
|
} |
3726
|
|
|
|
|
|
|
|
3727
|
|
|
|
|
|
|
sub _build_datetime_format_short { |
3728
|
1
|
|
|
1
|
|
626
|
my $self = shift; |
3729
|
|
|
|
|
|
|
|
3730
|
1
|
|
|
|
|
3
|
my $width = 'short'; |
3731
|
1
|
|
|
|
|
4
|
my $format = $self->_build_any_datetime_format($width); |
3732
|
|
|
|
|
|
|
|
3733
|
1
|
|
|
|
|
4
|
my $date = $self->_build_any_date_format($width); |
3734
|
1
|
|
|
|
|
4
|
my $time = $self->_build_any_time_format($width); |
3735
|
|
|
|
|
|
|
|
3736
|
1
|
|
|
|
|
4
|
$format =~ s/\{0\}/$time/; |
3737
|
1
|
|
|
|
|
4
|
$format =~ s/\{1\}/$date/; |
3738
|
|
|
|
|
|
|
|
3739
|
1
|
|
|
|
|
18
|
return $format; |
3740
|
|
|
|
|
|
|
} |
3741
|
|
|
|
|
|
|
|
3742
|
|
|
|
|
|
|
sub _build_format_data { |
3743
|
0
|
|
|
0
|
|
0
|
my $self = shift; |
3744
|
0
|
|
|
|
|
0
|
my $default_calendar = $self->default_calendar(); |
3745
|
|
|
|
|
|
|
|
3746
|
0
|
|
|
|
|
0
|
my @bundles = $self->_find_bundle('datetime_formats_available_formats'); |
3747
|
0
|
|
|
|
|
0
|
foreach my $calendar ($default_calendar, 'gregorian') { |
3748
|
0
|
|
|
|
|
0
|
foreach my $bundle (@bundles) { |
3749
|
0
|
|
|
|
|
0
|
my $datetime_formats_available_formats = $bundle->datetime_formats_available_formats; |
3750
|
0
|
|
|
|
|
0
|
my $result = $datetime_formats_available_formats->{$calendar}; |
3751
|
0
|
0
|
|
|
|
0
|
return $result if $result; |
3752
|
|
|
|
|
|
|
} |
3753
|
|
|
|
|
|
|
} |
3754
|
|
|
|
|
|
|
|
3755
|
0
|
|
|
|
|
0
|
return {}; |
3756
|
|
|
|
|
|
|
} |
3757
|
|
|
|
|
|
|
|
3758
|
|
|
|
|
|
|
sub format_for { |
3759
|
0
|
|
|
0
|
1
|
0
|
my ($self, $format) = @_; |
3760
|
|
|
|
|
|
|
|
3761
|
0
|
|
|
|
|
0
|
my $format_data = $self->format_data; |
3762
|
|
|
|
|
|
|
|
3763
|
0
|
|
0
|
|
|
0
|
return $format_data->{$format} // ''; |
3764
|
|
|
|
|
|
|
} |
3765
|
|
|
|
|
|
|
|
3766
|
|
|
|
|
|
|
sub _build_available_formats { |
3767
|
0
|
|
|
0
|
|
0
|
my $self = shift; |
3768
|
|
|
|
|
|
|
|
3769
|
0
|
|
|
|
|
0
|
my $format_data = $self->format_data; |
3770
|
|
|
|
|
|
|
|
3771
|
0
|
|
|
|
|
0
|
return [keys %$format_data]; |
3772
|
|
|
|
|
|
|
} |
3773
|
|
|
|
|
|
|
|
3774
|
|
|
|
|
|
|
sub _build_default_date_format_length { |
3775
|
0
|
|
|
0
|
|
0
|
my $self = shift; |
3776
|
|
|
|
|
|
|
|
3777
|
0
|
|
|
|
|
0
|
my $default_calendar = $self->default_calendar(); |
3778
|
|
|
|
|
|
|
|
3779
|
0
|
|
|
|
|
0
|
my @bundles = $self->_find_bundle('date_formats'); |
3780
|
0
|
|
|
|
|
0
|
foreach my $calendar ($default_calendar, 'gregorian') { |
3781
|
0
|
|
|
|
|
0
|
foreach my $bundle (@bundles) { |
3782
|
0
|
|
|
|
|
0
|
my $date_formats = $bundle->date_formats; |
3783
|
0
|
|
|
|
|
0
|
my $result = $date_formats->{$calendar}{default}; |
3784
|
0
|
0
|
|
|
|
0
|
return $result if $result; |
3785
|
|
|
|
|
|
|
} |
3786
|
|
|
|
|
|
|
} |
3787
|
|
|
|
|
|
|
} |
3788
|
|
|
|
|
|
|
|
3789
|
|
|
|
|
|
|
sub _build_default_time_format_length { |
3790
|
0
|
|
|
0
|
|
0
|
my $self = shift; |
3791
|
|
|
|
|
|
|
|
3792
|
0
|
|
|
|
|
0
|
my $default_calendar = $self->default_calendar(); |
3793
|
|
|
|
|
|
|
|
3794
|
0
|
|
|
|
|
0
|
my @bundles = $self->_find_bundle('time_formats'); |
3795
|
0
|
|
|
|
|
0
|
foreach my $calendar ($default_calendar, 'gregorian') { |
3796
|
0
|
|
|
|
|
0
|
foreach my $bundle (@bundles) { |
3797
|
0
|
|
|
|
|
0
|
my $time_formats = $bundle->time_formats; |
3798
|
0
|
|
|
|
|
0
|
my $result = $time_formats->{$calendar}{default}; |
3799
|
0
|
0
|
|
|
|
0
|
return $result if $result; |
3800
|
|
|
|
|
|
|
} |
3801
|
|
|
|
|
|
|
} |
3802
|
|
|
|
|
|
|
} |
3803
|
|
|
|
|
|
|
|
3804
|
|
|
|
|
|
|
sub _build_prefers_24_hour_time { |
3805
|
1
|
|
|
1
|
|
636
|
my $self = shift; |
3806
|
|
|
|
|
|
|
|
3807
|
1
|
50
|
|
|
|
19
|
return $self->time_format_short() =~ /h|K/ ? 0 : 1; |
3808
|
|
|
|
|
|
|
} |
3809
|
|
|
|
|
|
|
|
3810
|
|
|
|
|
|
|
{ |
3811
|
|
|
|
|
|
|
my %days_2_number = ( |
3812
|
|
|
|
|
|
|
mon => 1, |
3813
|
|
|
|
|
|
|
tue => 2, |
3814
|
|
|
|
|
|
|
wen => 3, |
3815
|
|
|
|
|
|
|
thu => 4, |
3816
|
|
|
|
|
|
|
fri => 5, |
3817
|
|
|
|
|
|
|
sat => 6, |
3818
|
|
|
|
|
|
|
sun => 7, |
3819
|
|
|
|
|
|
|
); |
3820
|
|
|
|
|
|
|
|
3821
|
|
|
|
|
|
|
sub _build_first_day_of_week { |
3822
|
|
|
|
|
|
|
|
3823
|
1
|
|
|
1
|
|
659
|
my $self = shift; |
3824
|
|
|
|
|
|
|
|
3825
|
1
|
|
|
|
|
4
|
my $first_day = $self->week_data_first_day; |
3826
|
|
|
|
|
|
|
|
3827
|
1
|
|
|
|
|
24
|
return $days_2_number{$first_day}; |
3828
|
|
|
|
|
|
|
} |
3829
|
|
|
|
|
|
|
} |
3830
|
|
|
|
|
|
|
|
3831
|
|
|
|
|
|
|
# Sub to mangle Unicode regex to Perl regex |
3832
|
|
|
|
|
|
|
# Backwards compatibility hack |
3833
|
21
|
50
|
|
21
|
|
208
|
*_unicode_to_perl = eval <<'EOT' || \&_new_perl; |
|
21
|
|
|
21
|
|
57
|
|
|
21
|
|
|
189
|
|
947
|
|
|
21
|
|
|
|
|
217
|
|
|
21
|
|
|
|
|
52
|
|
|
21
|
|
|
|
|
1733
|
|
|
189
|
|
|
|
|
463
|
|
|
189
|
|
|
|
|
715
|
|
|
189
|
|
|
|
|
1709
|
|
|
336
|
|
|
|
|
7370
|
|
|
189
|
|
|
|
|
3349
|
|
3834
|
|
|
|
|
|
|
sub { |
3835
|
|
|
|
|
|
|
my $regex = shift; |
3836
|
|
|
|
|
|
|
|
3837
|
|
|
|
|
|
|
return '' unless length $regex; |
3838
|
|
|
|
|
|
|
$regex =~ s/ |
3839
|
|
|
|
|
|
|
(?:\\\\)*+ # Pairs of \ |
3840
|
|
|
|
|
|
|
(?!\\) # Not followed by \ |
3841
|
|
|
|
|
|
|
\K # But we don't want to keep that |
3842
|
|
|
|
|
|
|
(?<set> # Capture this |
3843
|
|
|
|
|
|
|
\[ # Start a set |
3844
|
|
|
|
|
|
|
(?: |
3845
|
|
|
|
|
|
|
[^\[\]\\]+ # One or more of not []\ |
3846
|
|
|
|
|
|
|
| # or |
3847
|
|
|
|
|
|
|
(?: |
3848
|
|
|
|
|
|
|
(?:\\\\)*+ # One or more pairs of \ without back tracking |
3849
|
|
|
|
|
|
|
\\. # Followed by an escaped character |
3850
|
|
|
|
|
|
|
) |
3851
|
|
|
|
|
|
|
| # or |
3852
|
|
|
|
|
|
|
(?&set) # An inner set |
3853
|
|
|
|
|
|
|
)++ # Do the inside set stuff one or more times without backtracking |
3854
|
|
|
|
|
|
|
\] # End the set |
3855
|
|
|
|
|
|
|
) |
3856
|
|
|
|
|
|
|
/ _convert($1) /xeg; |
3857
|
|
|
|
|
|
|
no warnings "experimental::regex_sets"; |
3858
|
|
|
|
|
|
|
no warnings "deprecated"; # Because CLDR uses surrogates |
3859
|
|
|
|
|
|
|
return qr/$regex/x; |
3860
|
|
|
|
|
|
|
}; |
3861
|
|
|
|
|
|
|
|
3862
|
|
|
|
|
|
|
EOT |
3863
|
|
|
|
|
|
|
|
3864
|
|
|
|
|
|
|
# Backwards compatibility hack |
3865
|
336
|
100
|
|
336
|
|
838
|
*_convert = eval <<'EOT' || \&_new_perl; |
|
336
|
100
|
|
|
|
858
|
|
|
336
|
|
|
|
|
822
|
|
|
0
|
|
|
|
|
0
|
|
|
336
|
|
|
|
|
521
|
|
|
336
|
|
|
|
|
2773
|
|
|
336
|
|
|
|
|
799
|
|
|
336
|
|
|
|
|
641
|
|
|
330
|
|
|
|
|
7892
|
|
|
6
|
|
|
|
|
40
|
|
3866
|
|
|
|
|
|
|
sub { |
3867
|
|
|
|
|
|
|
my $set = shift; |
3868
|
|
|
|
|
|
|
|
3869
|
|
|
|
|
|
|
# Some definitions |
3870
|
|
|
|
|
|
|
my $posix = qr/(?(DEFINE) |
3871
|
|
|
|
|
|
|
(?<posix> (?> \[: .+? :\] ) ) |
3872
|
|
|
|
|
|
|
)/x; |
3873
|
|
|
|
|
|
|
|
3874
|
|
|
|
|
|
|
# Convert Unicode escapes \u1234 to characters |
3875
|
|
|
|
|
|
|
$set =~ s/\\u(\p{Ahex}+)/chr(hex($1))/egx; |
3876
|
|
|
|
|
|
|
|
3877
|
|
|
|
|
|
|
# Check to see if this is a normal character set |
3878
|
|
|
|
|
|
|
my $normal = 0; |
3879
|
|
|
|
|
|
|
|
3880
|
|
|
|
|
|
|
$normal = 1 if $set =~ /^ |
3881
|
|
|
|
|
|
|
\s* # Possible white space |
3882
|
|
|
|
|
|
|
\[ # Opening set |
3883
|
|
|
|
|
|
|
^? # Possible negation |
3884
|
|
|
|
|
|
|
(?: # One of |
3885
|
|
|
|
|
|
|
[^\[\]]++ # Not an open or close set |
3886
|
|
|
|
|
|
|
| # Or |
3887
|
|
|
|
|
|
|
(?<=\\)[\[\]] # An open or close set preceded by \ |
3888
|
|
|
|
|
|
|
| # Or |
3889
|
|
|
|
|
|
|
(?: |
3890
|
|
|
|
|
|
|
\s* # Possible white space |
3891
|
|
|
|
|
|
|
(?&posix) # A posix class |
3892
|
|
|
|
|
|
|
(?! # Not followed by |
3893
|
|
|
|
|
|
|
\s* # Possible white space |
3894
|
|
|
|
|
|
|
[&-] # A Unicode regex op |
3895
|
|
|
|
|
|
|
\s* # Possible white space |
3896
|
|
|
|
|
|
|
\[ # A set opener |
3897
|
|
|
|
|
|
|
) |
3898
|
|
|
|
|
|
|
) |
3899
|
|
|
|
|
|
|
)+ |
3900
|
|
|
|
|
|
|
\] # Close the set |
3901
|
|
|
|
|
|
|
\s* # Possible white space |
3902
|
|
|
|
|
|
|
$ |
3903
|
|
|
|
|
|
|
$posix |
3904
|
|
|
|
|
|
|
/x; |
3905
|
|
|
|
|
|
|
|
3906
|
|
|
|
|
|
|
# Convert posix to perl |
3907
|
|
|
|
|
|
|
$set =~ s/\[:(.*?):\]/\\p{$1}/g; |
3908
|
|
|
|
|
|
|
|
3909
|
|
|
|
|
|
|
if ($normal) { |
3910
|
|
|
|
|
|
|
return "$set"; |
3911
|
|
|
|
|
|
|
} |
3912
|
|
|
|
|
|
|
|
3913
|
|
|
|
|
|
|
return Unicode::Regex::Set::parse($set); |
3914
|
|
|
|
|
|
|
} |
3915
|
|
|
|
|
|
|
|
3916
|
|
|
|
|
|
|
EOT |
3917
|
|
|
|
|
|
|
|
3918
|
|
|
|
|
|
|
# The following pod is for methods defined in the Moo Role |
3919
|
|
|
|
|
|
|
# files that are automatically generated from the data |
3920
|
|
|
|
|
|
|
=back |
3921
|
|
|
|
|
|
|
|
3922
|
|
|
|
|
|
|
=head2 Valid codes |
3923
|
|
|
|
|
|
|
|
3924
|
|
|
|
|
|
|
=over 4 |
3925
|
|
|
|
|
|
|
|
3926
|
|
|
|
|
|
|
=item valid_languages() |
3927
|
|
|
|
|
|
|
|
3928
|
|
|
|
|
|
|
This method returns a list containing all the valid language codes |
3929
|
|
|
|
|
|
|
|
3930
|
|
|
|
|
|
|
=item valid_scripts() |
3931
|
|
|
|
|
|
|
|
3932
|
|
|
|
|
|
|
This method returns a list containing all the valid script codes |
3933
|
|
|
|
|
|
|
|
3934
|
|
|
|
|
|
|
=item valid_regions() |
3935
|
|
|
|
|
|
|
|
3936
|
|
|
|
|
|
|
This method returns a list containing all the valid region codes |
3937
|
|
|
|
|
|
|
|
3938
|
|
|
|
|
|
|
=item valid_variants() |
3939
|
|
|
|
|
|
|
|
3940
|
|
|
|
|
|
|
This method returns a list containing all the valid variant codes |
3941
|
|
|
|
|
|
|
|
3942
|
|
|
|
|
|
|
=item key_aliases() |
3943
|
|
|
|
|
|
|
|
3944
|
|
|
|
|
|
|
This method returns a hash that maps valid keys to their valid aliases |
3945
|
|
|
|
|
|
|
|
3946
|
|
|
|
|
|
|
=item key_names() |
3947
|
|
|
|
|
|
|
|
3948
|
|
|
|
|
|
|
This method returns a hash that maps valid key aliases to their valid keys |
3949
|
|
|
|
|
|
|
|
3950
|
|
|
|
|
|
|
=item valid_keys() |
3951
|
|
|
|
|
|
|
|
3952
|
|
|
|
|
|
|
This method returns a hash of valid keys and the valid type codes you |
3953
|
|
|
|
|
|
|
can have with each key |
3954
|
|
|
|
|
|
|
|
3955
|
|
|
|
|
|
|
=item language_aliases() |
3956
|
|
|
|
|
|
|
|
3957
|
|
|
|
|
|
|
This method returns a hash that maps valid language codes to their valid aliases |
3958
|
|
|
|
|
|
|
|
3959
|
|
|
|
|
|
|
=item region_aliases() |
3960
|
|
|
|
|
|
|
|
3961
|
|
|
|
|
|
|
This method returns a hash that maps valid region codes to their valid aliases |
3962
|
|
|
|
|
|
|
|
3963
|
|
|
|
|
|
|
=item variant_aliases() |
3964
|
|
|
|
|
|
|
|
3965
|
|
|
|
|
|
|
This method returns a hash that maps valid variant codes to their valid aliases |
3966
|
|
|
|
|
|
|
|
3967
|
|
|
|
|
|
|
=back |
3968
|
|
|
|
|
|
|
|
3969
|
|
|
|
|
|
|
=head2 Information about weeks |
3970
|
|
|
|
|
|
|
|
3971
|
|
|
|
|
|
|
There are no standard codes for the days of the weeks so CLDR uses the following |
3972
|
|
|
|
|
|
|
three letter codes to represent unlocalised days |
3973
|
|
|
|
|
|
|
|
3974
|
|
|
|
|
|
|
=over 4 |
3975
|
|
|
|
|
|
|
|
3976
|
|
|
|
|
|
|
=item sun |
3977
|
|
|
|
|
|
|
|
3978
|
|
|
|
|
|
|
Sunday |
3979
|
|
|
|
|
|
|
|
3980
|
|
|
|
|
|
|
=item mon |
3981
|
|
|
|
|
|
|
|
3982
|
|
|
|
|
|
|
Monday |
3983
|
|
|
|
|
|
|
|
3984
|
|
|
|
|
|
|
=item tue |
3985
|
|
|
|
|
|
|
|
3986
|
|
|
|
|
|
|
Tuesday |
3987
|
|
|
|
|
|
|
|
3988
|
|
|
|
|
|
|
=item wed |
3989
|
|
|
|
|
|
|
|
3990
|
|
|
|
|
|
|
Wednesday |
3991
|
|
|
|
|
|
|
|
3992
|
|
|
|
|
|
|
=item thu |
3993
|
|
|
|
|
|
|
|
3994
|
|
|
|
|
|
|
Thursday |
3995
|
|
|
|
|
|
|
|
3996
|
|
|
|
|
|
|
=item fri |
3997
|
|
|
|
|
|
|
|
3998
|
|
|
|
|
|
|
Friday |
3999
|
|
|
|
|
|
|
|
4000
|
|
|
|
|
|
|
=item sat |
4001
|
|
|
|
|
|
|
|
4002
|
|
|
|
|
|
|
Saturday |
4003
|
|
|
|
|
|
|
|
4004
|
|
|
|
|
|
|
=back |
4005
|
|
|
|
|
|
|
|
4006
|
|
|
|
|
|
|
=cut |
4007
|
|
|
|
|
|
|
|
4008
|
|
|
|
|
|
|
sub _week_data { |
4009
|
4
|
|
|
4
|
|
9
|
my ($self, $region_id, $week_data_hash) = @_; |
4010
|
|
|
|
|
|
|
|
4011
|
4
|
|
33
|
|
|
118
|
$region_id //= ( $self->region_id || $self->likely_subtag->region_id ); |
|
|
|
33
|
|
|
|
|
4012
|
|
|
|
|
|
|
|
4013
|
4
|
100
|
|
|
|
18
|
return $week_data_hash->{$region_id} if exists $week_data_hash->{$region_id}; |
4014
|
|
|
|
|
|
|
|
4015
|
2
|
|
|
|
|
5
|
while (1) { |
4016
|
8
|
|
|
|
|
19
|
$region_id = $self->region_contained_by()->{$region_id}; |
4017
|
8
|
50
|
|
|
|
18
|
return unless defined $region_id; |
4018
|
8
|
100
|
|
|
|
26
|
return $week_data_hash->{$region_id} if exists $week_data_hash->{$region_id}; |
4019
|
|
|
|
|
|
|
} |
4020
|
|
|
|
|
|
|
} |
4021
|
|
|
|
|
|
|
|
4022
|
|
|
|
|
|
|
=over 4 |
4023
|
|
|
|
|
|
|
|
4024
|
|
|
|
|
|
|
=item week_data_min_days($region_id) |
4025
|
|
|
|
|
|
|
|
4026
|
|
|
|
|
|
|
This method takes an optional region id and returns a the minimum number of days |
4027
|
|
|
|
|
|
|
a week must have to count as the starting week of the new year. It uses the current |
4028
|
|
|
|
|
|
|
locale's region if no region id is passed in. |
4029
|
|
|
|
|
|
|
|
4030
|
|
|
|
|
|
|
=cut |
4031
|
|
|
|
|
|
|
|
4032
|
|
|
|
|
|
|
sub week_data_min_days { |
4033
|
1
|
|
|
1
|
1
|
4
|
my ($self, $region_id) = @_; |
4034
|
|
|
|
|
|
|
|
4035
|
1
|
|
|
|
|
6
|
my $week_data_hash = $self->_week_data_min_days(); |
4036
|
1
|
|
|
|
|
3
|
return _week_data($self, $region_id, $week_data_hash); |
4037
|
|
|
|
|
|
|
} |
4038
|
|
|
|
|
|
|
|
4039
|
|
|
|
|
|
|
=item week_data_first_day($region_id) |
4040
|
|
|
|
|
|
|
|
4041
|
|
|
|
|
|
|
This method takes an optional region id and returns the three letter code of the |
4042
|
|
|
|
|
|
|
first day of the week for that region. If no region id is passed in then it |
4043
|
|
|
|
|
|
|
uses the current locale's region. |
4044
|
|
|
|
|
|
|
|
4045
|
|
|
|
|
|
|
=cut |
4046
|
|
|
|
|
|
|
|
4047
|
|
|
|
|
|
|
sub week_data_first_day { |
4048
|
3
|
|
|
3
|
1
|
5919
|
my ($self, $region_id) = @_; |
4049
|
|
|
|
|
|
|
|
4050
|
3
|
100
|
|
|
|
15
|
if ($self->_test_default_fw) { |
4051
|
2
|
|
|
|
|
81
|
return $self->_default_fw; |
4052
|
|
|
|
|
|
|
} |
4053
|
|
|
|
|
|
|
|
4054
|
1
|
|
|
|
|
6
|
my $week_data_hash = $self->_week_data_first_day(); |
4055
|
1
|
|
|
|
|
4
|
my $first_day = _week_data($self, $region_id, $week_data_hash); |
4056
|
1
|
|
|
|
|
55
|
$self->_set_default_fw($first_day); |
4057
|
1
|
|
|
|
|
39
|
return $first_day; |
4058
|
|
|
|
|
|
|
} |
4059
|
|
|
|
|
|
|
|
4060
|
|
|
|
|
|
|
=item week_data_weekend_start() |
4061
|
|
|
|
|
|
|
|
4062
|
|
|
|
|
|
|
This method takes an optional region id and returns the three letter code of the |
4063
|
|
|
|
|
|
|
first day of the weekend for that region. If no region id is passed in then it |
4064
|
|
|
|
|
|
|
uses the current locale's region. |
4065
|
|
|
|
|
|
|
|
4066
|
|
|
|
|
|
|
=cut |
4067
|
|
|
|
|
|
|
|
4068
|
|
|
|
|
|
|
sub week_data_weekend_start { |
4069
|
1
|
|
|
1
|
1
|
4
|
my ($self, $region_id) = @_; |
4070
|
1
|
|
|
|
|
5
|
my $week_data_hash = $self->_week_data_weekend_start(); |
4071
|
|
|
|
|
|
|
|
4072
|
1
|
|
|
|
|
3
|
return _week_data($self, $region_id, $week_data_hash); |
4073
|
|
|
|
|
|
|
} |
4074
|
|
|
|
|
|
|
|
4075
|
|
|
|
|
|
|
=item week_data_weekend_end() |
4076
|
|
|
|
|
|
|
|
4077
|
|
|
|
|
|
|
This method takes an optional region id and returns the three letter code of the |
4078
|
|
|
|
|
|
|
last day of the weekend for that region. If no region id is passed in then it |
4079
|
|
|
|
|
|
|
uses the current locale's region. |
4080
|
|
|
|
|
|
|
|
4081
|
|
|
|
|
|
|
=cut |
4082
|
|
|
|
|
|
|
|
4083
|
|
|
|
|
|
|
sub week_data_weekend_end { |
4084
|
1
|
|
|
1
|
1
|
3
|
my ($self, $region_id) = @_; |
4085
|
1
|
|
|
|
|
5
|
my $week_data_hash = $self->_week_data_weekend_end(); |
4086
|
|
|
|
|
|
|
|
4087
|
1
|
|
|
|
|
3
|
return _week_data($self, $region_id, $week_data_hash); |
4088
|
|
|
|
|
|
|
} |
4089
|
|
|
|
|
|
|
|
4090
|
|
|
|
|
|
|
=item month_patterns($context, $width, $type) |
4091
|
|
|
|
|
|
|
|
4092
|
|
|
|
|
|
|
The Chinese lunar calendar can insert a leap month after nearly any month of its year; |
4093
|
|
|
|
|
|
|
when this happens, the month takes the name of the preceding month plus a special marker. |
4094
|
|
|
|
|
|
|
The Hindu lunar calendars can insert a leap month before any one or two months of the year; |
4095
|
|
|
|
|
|
|
when this happens, not only does the leap month take the name of the following month plus a |
4096
|
|
|
|
|
|
|
special marker, the following month also takes a special marker. Moreover, in the Hindu |
4097
|
|
|
|
|
|
|
calendar sometimes a month is skipped, in which case the preceding month takes a special marker |
4098
|
|
|
|
|
|
|
plus the names of both months. The monthPatterns() method returns an array ref of month names |
4099
|
|
|
|
|
|
|
with the marker added. |
4100
|
|
|
|
|
|
|
|
4101
|
|
|
|
|
|
|
=cut |
4102
|
|
|
|
|
|
|
|
4103
|
|
|
|
|
|
|
my %month_functions = ( |
4104
|
|
|
|
|
|
|
format => { |
4105
|
|
|
|
|
|
|
wide => 'month_format_wide', |
4106
|
|
|
|
|
|
|
abbreviated => 'month_format_abbreviated', |
4107
|
|
|
|
|
|
|
narrow => 'month_format_narrow', |
4108
|
|
|
|
|
|
|
}, |
4109
|
|
|
|
|
|
|
'stand-alone' => { |
4110
|
|
|
|
|
|
|
wide => 'month_stand_alone_wide', |
4111
|
|
|
|
|
|
|
abbreviated => 'month_stand_alone_abbreviated', |
4112
|
|
|
|
|
|
|
narrow => 'month_stand_alone_narrow', |
4113
|
|
|
|
|
|
|
} |
4114
|
|
|
|
|
|
|
); |
4115
|
|
|
|
|
|
|
|
4116
|
|
|
|
|
|
|
sub month_patterns { |
4117
|
1
|
|
|
1
|
1
|
4221
|
my ($self, $context, $width, $type) = @_; |
4118
|
|
|
|
|
|
|
|
4119
|
1
|
|
|
|
|
28
|
my @months; |
4120
|
1
|
50
|
|
|
|
6
|
if ($context eq 'numeric') { |
4121
|
0
|
|
|
|
|
0
|
@months = ( 1 .. 14 ); |
4122
|
|
|
|
|
|
|
} |
4123
|
|
|
|
|
|
|
else { |
4124
|
1
|
|
|
|
|
5
|
my $months_method = $month_functions{$context}{$width}; |
4125
|
1
|
|
|
|
|
43
|
my $months = $self->$months_method; |
4126
|
1
|
|
|
|
|
32
|
@months = @$months; |
4127
|
|
|
|
|
|
|
} |
4128
|
|
|
|
|
|
|
|
4129
|
1
|
|
|
|
|
4
|
my $default_calendar = $self->default_calendar(); |
4130
|
|
|
|
|
|
|
|
4131
|
1
|
|
|
|
|
3
|
my @bundles = $self->_find_bundle('month_patterns'); |
4132
|
|
|
|
|
|
|
|
4133
|
1
|
|
|
|
|
11
|
my $result; |
4134
|
|
|
|
|
|
|
BUNDLES: { |
4135
|
1
|
|
|
|
|
3
|
foreach my $bundle (@bundles) { |
|
2
|
|
|
|
|
6
|
|
4136
|
2
|
|
|
|
|
7
|
my $month_patterns = $bundle->month_patterns; |
4137
|
2
|
50
|
|
|
|
8
|
if (exists $month_patterns->{$default_calendar}{alias}) { |
4138
|
0
|
|
|
|
|
0
|
$default_calendar = $month_patterns->{$default_calendar}{alias}; |
4139
|
0
|
|
|
|
|
0
|
redo BUNDLES; |
4140
|
|
|
|
|
|
|
} |
4141
|
|
|
|
|
|
|
|
4142
|
|
|
|
|
|
|
# Check for width alias |
4143
|
2
|
100
|
|
|
|
8
|
if (exists $month_patterns->{$default_calendar}{$context}{$width}{alias}) { |
4144
|
1
|
|
|
|
|
4
|
$context = $month_patterns->{$default_calendar}{$context}{$width}{alias}{context}; |
4145
|
1
|
|
|
|
|
3
|
$width = $month_patterns->{$default_calendar}{$context}{$width}{alias}{width}; |
4146
|
1
|
|
|
|
|
4
|
redo BUNDLES; |
4147
|
|
|
|
|
|
|
} |
4148
|
|
|
|
|
|
|
|
4149
|
1
|
|
|
|
|
3
|
$result = $month_patterns->{$default_calendar}{$context}{$width}{$type}; |
4150
|
1
|
50
|
|
|
|
4
|
last BUNDLES if $result; |
4151
|
|
|
|
|
|
|
} |
4152
|
0
|
0
|
|
|
|
0
|
if ($default_calendar ne 'gregorian') { |
4153
|
0
|
|
|
|
|
0
|
$default_calendar = 'gregorian'; |
4154
|
0
|
|
|
|
|
0
|
redo BUNDLES; |
4155
|
|
|
|
|
|
|
} |
4156
|
|
|
|
|
|
|
} |
4157
|
|
|
|
|
|
|
|
4158
|
1
|
50
|
|
|
|
6
|
if ($result) { |
4159
|
1
|
|
|
|
|
3
|
foreach my $month (@months) { |
4160
|
12
|
|
|
|
|
26
|
(my $fixed_month = $result) =~ s/\{0\}/$month/g; |
4161
|
12
|
|
|
|
|
22
|
$month = $fixed_month; |
4162
|
|
|
|
|
|
|
} |
4163
|
|
|
|
|
|
|
} |
4164
|
|
|
|
|
|
|
|
4165
|
1
|
|
|
|
|
13
|
return \@months; |
4166
|
|
|
|
|
|
|
} |
4167
|
|
|
|
|
|
|
|
4168
|
|
|
|
|
|
|
=item cyclic_name_sets($context, $width, $type) |
4169
|
|
|
|
|
|
|
|
4170
|
|
|
|
|
|
|
This method returns an arrayref containing the cyclic names for the locale's |
4171
|
|
|
|
|
|
|
default calendar using the given context, width and type. |
4172
|
|
|
|
|
|
|
|
4173
|
|
|
|
|
|
|
Context can can currently only be c<format> |
4174
|
|
|
|
|
|
|
|
4175
|
|
|
|
|
|
|
Width is one of C<abbreviated>, C<narrow> or C<wide> |
4176
|
|
|
|
|
|
|
|
4177
|
|
|
|
|
|
|
Type is one of C<dayParts>, C<days>, C<months>, C<solarTerms>, C<years> or C<zodiacs> |
4178
|
|
|
|
|
|
|
|
4179
|
|
|
|
|
|
|
=cut |
4180
|
|
|
|
|
|
|
|
4181
|
|
|
|
|
|
|
sub cyclic_name_sets { |
4182
|
1
|
|
|
1
|
1
|
4
|
my ($self, $context, $width, $type) = @_; |
4183
|
|
|
|
|
|
|
|
4184
|
1
|
|
|
|
|
5
|
my @bundles = $self->_find_bundle('cyclic_name_sets'); |
4185
|
1
|
|
|
|
|
12
|
my $default_calendar = $self->default_calendar(); |
4186
|
1
|
|
|
|
|
4
|
foreach my $bundle (@bundles) { |
4187
|
2
|
|
|
|
|
8
|
my $cyclic_name_set = $bundle->cyclic_name_sets(); |
4188
|
|
|
|
|
|
|
NAME_SET: { |
4189
|
2
|
50
|
|
|
|
4
|
if (my $alias_calendar = $cyclic_name_set->{$default_calendar}{alias}) { |
|
3
|
|
|
|
|
9
|
|
4190
|
0
|
|
|
|
|
0
|
$default_calendar = $alias_calendar; |
4191
|
0
|
|
|
|
|
0
|
redo NAME_SET; |
4192
|
|
|
|
|
|
|
} |
4193
|
|
|
|
|
|
|
|
4194
|
3
|
50
|
|
|
|
10
|
if (my $type_alias = $cyclic_name_set->{$default_calendar}{$type}{alias}) { |
4195
|
0
|
|
|
|
|
0
|
$type = $type_alias; |
4196
|
0
|
|
|
|
|
0
|
redo NAME_SET; |
4197
|
|
|
|
|
|
|
} |
4198
|
|
|
|
|
|
|
|
4199
|
3
|
100
|
|
|
|
10
|
if (my $width_alias = $cyclic_name_set->{$default_calendar}{$type}{$context}{$width}{alias}) { |
4200
|
1
|
|
|
|
|
4
|
$context = $width_alias->{context}; |
4201
|
1
|
|
|
|
|
2
|
$type = $width_alias->{name_set}; |
4202
|
1
|
|
|
|
|
3
|
$width = $width_alias->{type}; |
4203
|
1
|
|
|
|
|
4
|
redo NAME_SET; |
4204
|
|
|
|
|
|
|
} |
4205
|
|
|
|
|
|
|
|
4206
|
|
|
|
|
|
|
my $return = [ |
4207
|
2
|
|
|
|
|
9
|
@{ $cyclic_name_set->{$default_calendar}{$type}{$context}{$width} } |
4208
|
2
|
|
|
|
|
4
|
{sort { $a <=> $b } keys %{ $cyclic_name_set->{$default_calendar}{$type}{$context}{$width} }} |
|
28
|
|
|
|
|
43
|
|
|
2
|
|
|
|
|
15
|
|
4209
|
|
|
|
|
|
|
]; |
4210
|
|
|
|
|
|
|
|
4211
|
2
|
100
|
|
|
|
18
|
return $return if @$return; |
4212
|
|
|
|
|
|
|
} |
4213
|
|
|
|
|
|
|
} |
4214
|
0
|
|
|
|
|
0
|
return []; |
4215
|
|
|
|
|
|
|
} |
4216
|
|
|
|
|
|
|
|
4217
|
|
|
|
|
|
|
=back |
4218
|
|
|
|
|
|
|
|
4219
|
|
|
|
|
|
|
=head2 Region Containment |
4220
|
|
|
|
|
|
|
|
4221
|
|
|
|
|
|
|
=over 4 |
4222
|
|
|
|
|
|
|
|
4223
|
|
|
|
|
|
|
=item region_contains() |
4224
|
|
|
|
|
|
|
|
4225
|
|
|
|
|
|
|
This method returns a hash ref keyed on region id. The value is an array ref. |
4226
|
|
|
|
|
|
|
Each element of the array ref is a region id of a region immediately |
4227
|
|
|
|
|
|
|
contained in the region used as the key |
4228
|
|
|
|
|
|
|
|
4229
|
|
|
|
|
|
|
=item region_contained_by() |
4230
|
|
|
|
|
|
|
|
4231
|
|
|
|
|
|
|
This method returns a hash ref keyed on region id. The value of the hash |
4232
|
|
|
|
|
|
|
is the region id of the immediately containing region. |
4233
|
|
|
|
|
|
|
|
4234
|
|
|
|
|
|
|
=back |
4235
|
|
|
|
|
|
|
|
4236
|
|
|
|
|
|
|
=head2 Numbering Systems |
4237
|
|
|
|
|
|
|
|
4238
|
|
|
|
|
|
|
=over 4 |
4239
|
|
|
|
|
|
|
|
4240
|
|
|
|
|
|
|
=item numbering_system() |
4241
|
|
|
|
|
|
|
|
4242
|
|
|
|
|
|
|
This method returns a hash ref keyed on numbering system id which, for a given |
4243
|
|
|
|
|
|
|
locale, can be got by calling the default_numbering_system() method. The values |
4244
|
|
|
|
|
|
|
of the hash are a two element hash ref the keys being C<type> and C<data>. If the |
4245
|
|
|
|
|
|
|
type is C<numeric> then the data is an array ref of characters. The position in the |
4246
|
|
|
|
|
|
|
array matches the numeric value of the character. If the type is C<algorithmic> |
4247
|
|
|
|
|
|
|
then data is the name of the algorithm used to display numbers in that format. |
4248
|
|
|
|
|
|
|
|
4249
|
|
|
|
|
|
|
=back |
4250
|
|
|
|
|
|
|
|
4251
|
|
|
|
|
|
|
=head2 Number Formatting |
4252
|
|
|
|
|
|
|
|
4253
|
|
|
|
|
|
|
=over 4 |
4254
|
|
|
|
|
|
|
|
4255
|
|
|
|
|
|
|
=item format_number($number, $format, $currency, $for_cash) |
4256
|
|
|
|
|
|
|
|
4257
|
|
|
|
|
|
|
This method formats the number $number using the format $format. If the format contains |
4258
|
|
|
|
|
|
|
the currency symbol C<¤> then the currency symbol for the currency code in $currency |
4259
|
|
|
|
|
|
|
will be used. If $currency is undef() then the default currency code for the locale |
4260
|
|
|
|
|
|
|
will be used. |
4261
|
|
|
|
|
|
|
|
4262
|
|
|
|
|
|
|
Note that currency codes are based on region so if you do not pass in a currency |
4263
|
|
|
|
|
|
|
and your locale did not get passed a region in the constructor you are going |
4264
|
|
|
|
|
|
|
to end up with the L<likely sub tag's|/likely_subtags> idea of the currency. This |
4265
|
|
|
|
|
|
|
functionality may be removed or at least changed to emit a warning in future |
4266
|
|
|
|
|
|
|
releases. |
4267
|
|
|
|
|
|
|
|
4268
|
|
|
|
|
|
|
$for_cash is only used during currency formatting. If true then cash rounding |
4269
|
|
|
|
|
|
|
will be used otherwise financial rounding will be used. |
4270
|
|
|
|
|
|
|
|
4271
|
|
|
|
|
|
|
This function also handles rule based number formatting. If $format is string equivalent |
4272
|
|
|
|
|
|
|
to one of the current locale's public rule based number formats then $number will be |
4273
|
|
|
|
|
|
|
formatted according to that rule. |
4274
|
|
|
|
|
|
|
|
4275
|
|
|
|
|
|
|
=item format_currency($number, $for_cash) |
4276
|
|
|
|
|
|
|
|
4277
|
|
|
|
|
|
|
This method formats the number $number using the default currency and currency format for the locale. |
4278
|
|
|
|
|
|
|
If $for_cash is a true value then cash rounding will be used otherwise financial rounding will be used. |
4279
|
|
|
|
|
|
|
|
4280
|
|
|
|
|
|
|
=item default_currency_formt |
4281
|
|
|
|
|
|
|
|
4282
|
|
|
|
|
|
|
This method returns the currency format for the current locale |
4283
|
|
|
|
|
|
|
|
4284
|
|
|
|
|
|
|
It takes no paramaters |
4285
|
|
|
|
|
|
|
|
4286
|
|
|
|
|
|
|
=item add_currency_symbol($format, $symbol) |
4287
|
|
|
|
|
|
|
|
4288
|
|
|
|
|
|
|
This method returns the format with the currency symbol $symbol correctly inserted |
4289
|
|
|
|
|
|
|
into the format |
4290
|
|
|
|
|
|
|
|
4291
|
|
|
|
|
|
|
=item parse_number_format($format, $currency, $currency_data, $for_cash) |
4292
|
|
|
|
|
|
|
|
4293
|
|
|
|
|
|
|
This method parses a CLDR numeric format string into a hash ref containing data used to |
4294
|
|
|
|
|
|
|
format a number. If a currency is being formatted then $currency contains the |
4295
|
|
|
|
|
|
|
currency code, $currency_data is a hashref containing the currency rounding |
4296
|
|
|
|
|
|
|
information and $for_cash is a flag to signal cash or financial rounding. |
4297
|
|
|
|
|
|
|
|
4298
|
|
|
|
|
|
|
This should probably be a private function. |
4299
|
|
|
|
|
|
|
|
4300
|
|
|
|
|
|
|
=item round($number, $increment, $decimal_digits) |
4301
|
|
|
|
|
|
|
|
4302
|
|
|
|
|
|
|
This method returns $number rounded to the nearest $increment with $decimal_digits |
4303
|
|
|
|
|
|
|
digits after the decimal point |
4304
|
|
|
|
|
|
|
|
4305
|
|
|
|
|
|
|
=item get_formatted_number($number, $format, $currency_data, $for_cash) |
4306
|
|
|
|
|
|
|
|
4307
|
|
|
|
|
|
|
This method takes the $format produced by parse_number_format() and uses it to |
4308
|
|
|
|
|
|
|
parse $number. It returns a string containing the parsed number. If a currency |
4309
|
|
|
|
|
|
|
is being formatted then $currency_data is a hashref containing the currency |
4310
|
|
|
|
|
|
|
rounding information and $for_cash is a flag to signal cash or financial rounding. |
4311
|
|
|
|
|
|
|
|
4312
|
|
|
|
|
|
|
=item get_digits() |
4313
|
|
|
|
|
|
|
|
4314
|
|
|
|
|
|
|
This method returns an array containing the digits used by the locale, The order of the |
4315
|
|
|
|
|
|
|
array is the order of the digits. It the locale's numbering system is C<algorithmic> it |
4316
|
|
|
|
|
|
|
will return C<[0,1,2,3,4,5,6,7,8,9]> |
4317
|
|
|
|
|
|
|
|
4318
|
|
|
|
|
|
|
=item default_numbering_system() |
4319
|
|
|
|
|
|
|
|
4320
|
|
|
|
|
|
|
This method returns the numbering system id for the locale. |
4321
|
|
|
|
|
|
|
|
4322
|
|
|
|
|
|
|
=item default_currency_format() |
4323
|
|
|
|
|
|
|
|
4324
|
|
|
|
|
|
|
This method returns the locale's currenc format. This can be used by the number formatting code to |
4325
|
|
|
|
|
|
|
correctly format the locale's currency |
4326
|
|
|
|
|
|
|
|
4327
|
|
|
|
|
|
|
=item currency_format($format_type) |
4328
|
|
|
|
|
|
|
|
4329
|
|
|
|
|
|
|
This method returns the format string for the currencies for the locale |
4330
|
|
|
|
|
|
|
|
4331
|
|
|
|
|
|
|
There are two types of formatting I<standard> and I<accounting> you can |
4332
|
|
|
|
|
|
|
pass C<standard> or C<accounting> as the paramater to the method to pick one of |
4333
|
|
|
|
|
|
|
these ot it will use the locales default |
4334
|
|
|
|
|
|
|
|
4335
|
|
|
|
|
|
|
=cut |
4336
|
|
|
|
|
|
|
|
4337
|
|
|
|
|
|
|
sub currency_format { |
4338
|
22
|
|
|
22
|
1
|
26296
|
my ($self, $default_currency_format) = @_; |
4339
|
|
|
|
|
|
|
|
4340
|
22
|
50
|
100
|
|
|
128
|
die "Invalid Currency format: must be one of 'standard' or 'accounting'" |
|
|
|
66
|
|
|
|
|
4341
|
|
|
|
|
|
|
if defined $default_currency_format |
4342
|
|
|
|
|
|
|
&& $default_currency_format ne 'standard' |
4343
|
|
|
|
|
|
|
&& $default_currency_format ne 'accounting'; |
4344
|
|
|
|
|
|
|
|
4345
|
22
|
|
66
|
|
|
186
|
$default_currency_format //= $self->default_currency_format; |
4346
|
22
|
|
|
|
|
78
|
my @bundles = $self->_find_bundle('number_currency_formats'); |
4347
|
|
|
|
|
|
|
|
4348
|
22
|
|
|
|
|
196
|
my $format = {}; |
4349
|
22
|
|
|
|
|
120
|
my $default_numbering_system = $self->default_numbering_system(); |
4350
|
22
|
|
|
|
|
66
|
foreach my $bundle (@bundles) { |
4351
|
|
|
|
|
|
|
NUMBER_SYSTEM: { |
4352
|
22
|
|
|
|
|
38
|
$format = $bundle->number_currency_formats(); |
|
22
|
|
|
|
|
78
|
|
4353
|
22
|
50
|
|
|
|
90
|
if (exists $format->{$default_numbering_system}{alias}) { |
4354
|
0
|
|
|
|
|
0
|
$default_numbering_system = $format->{$default_numbering_system}{alias}; |
4355
|
0
|
|
|
|
|
0
|
redo NUMBER_SYSTEM; |
4356
|
|
|
|
|
|
|
} |
4357
|
|
|
|
|
|
|
|
4358
|
22
|
50
|
|
|
|
86
|
if (exists $format->{$default_numbering_system}{pattern}{default}{$default_currency_format}{alias}) { |
4359
|
0
|
|
|
|
|
0
|
$default_currency_format = $format->{$default_numbering_system}{pattern}{default}{$default_currency_format}{alias}; |
4360
|
0
|
|
|
|
|
0
|
redo NUMBER_SYSTEM; |
4361
|
|
|
|
|
|
|
} |
4362
|
|
|
|
|
|
|
} |
4363
|
|
|
|
|
|
|
|
4364
|
22
|
50
|
|
|
|
74
|
last if exists $format->{$default_numbering_system}{pattern}{default}{$default_currency_format} |
4365
|
|
|
|
|
|
|
} |
4366
|
|
|
|
|
|
|
|
4367
|
22
|
100
|
|
|
|
62
|
$default_currency_format = 'accounting' if $default_currency_format eq 'account'; |
4368
|
|
|
|
|
|
|
|
4369
|
|
|
|
|
|
|
return join ';', |
4370
|
|
|
|
|
|
|
$format->{$default_numbering_system}{pattern}{default}{$default_currency_format}{positive}, |
4371
|
|
|
|
|
|
|
defined $format->{$default_numbering_system}{pattern}{default}{$default_currency_format}{negative} |
4372
|
|
|
|
|
|
|
? $format->{$default_numbering_system}{pattern}{default}{$default_currency_format}{negative} |
4373
|
22
|
100
|
|
|
|
295
|
: (); |
4374
|
|
|
|
|
|
|
} |
4375
|
|
|
|
|
|
|
|
4376
|
|
|
|
|
|
|
=back |
4377
|
|
|
|
|
|
|
|
4378
|
|
|
|
|
|
|
=head2 Measurement Information |
4379
|
|
|
|
|
|
|
|
4380
|
|
|
|
|
|
|
=over 4 |
4381
|
|
|
|
|
|
|
|
4382
|
|
|
|
|
|
|
=item measurement_system() |
4383
|
|
|
|
|
|
|
|
4384
|
|
|
|
|
|
|
This method returns a hash ref keyed on region, the value being the measurement system |
4385
|
|
|
|
|
|
|
id for the region. If the region you are interested in is not listed use the |
4386
|
|
|
|
|
|
|
region_contained_by() method until you find an entry. |
4387
|
|
|
|
|
|
|
|
4388
|
|
|
|
|
|
|
=item paper_size() |
4389
|
|
|
|
|
|
|
|
4390
|
|
|
|
|
|
|
This method returns a hash ref keyed on region, the value being the paper size used |
4391
|
|
|
|
|
|
|
in that region. If the region you are interested in is not listed use the |
4392
|
|
|
|
|
|
|
region_contained_by() method until you find an entry. |
4393
|
|
|
|
|
|
|
|
4394
|
|
|
|
|
|
|
=back |
4395
|
|
|
|
|
|
|
|
4396
|
|
|
|
|
|
|
=head2 Likely Tags |
4397
|
|
|
|
|
|
|
|
4398
|
|
|
|
|
|
|
=over 4 |
4399
|
|
|
|
|
|
|
|
4400
|
|
|
|
|
|
|
=item likely_subtags() |
4401
|
|
|
|
|
|
|
|
4402
|
|
|
|
|
|
|
A full locale tag requires, as a minimum, a language, script and region code. However for |
4403
|
|
|
|
|
|
|
some locales it is possible to infer the missing element if the other two are given, e.g. |
4404
|
|
|
|
|
|
|
given C<en_GB> you can infer the script will be latn. It is also possible to fill in the |
4405
|
|
|
|
|
|
|
missing elements of a locale with sensible defaults given sufficient knowledge of the layout |
4406
|
|
|
|
|
|
|
of the CLDR data and usage patterns of locales around the world. |
4407
|
|
|
|
|
|
|
|
4408
|
|
|
|
|
|
|
This function returns a hash ref keyed on partial locale id's with the value being the locale |
4409
|
|
|
|
|
|
|
id for the most likely language, script and region code for the key. |
4410
|
|
|
|
|
|
|
|
4411
|
|
|
|
|
|
|
=item likely_subtag() |
4412
|
|
|
|
|
|
|
|
4413
|
|
|
|
|
|
|
This method returns a Locale::CLDR object with any missing elements from the language, script or |
4414
|
|
|
|
|
|
|
region, filled in with data from the likely_subtags hash |
4415
|
|
|
|
|
|
|
|
4416
|
|
|
|
|
|
|
=back |
4417
|
|
|
|
|
|
|
|
4418
|
|
|
|
|
|
|
=head2 Currency Information |
4419
|
|
|
|
|
|
|
|
4420
|
|
|
|
|
|
|
=over 4 |
4421
|
|
|
|
|
|
|
|
4422
|
|
|
|
|
|
|
=item currency_fractions() |
4423
|
|
|
|
|
|
|
|
4424
|
|
|
|
|
|
|
This method returns a hash ref keyed on currency id. The value is a hash ref containing four keys. |
4425
|
|
|
|
|
|
|
The keys are |
4426
|
|
|
|
|
|
|
|
4427
|
|
|
|
|
|
|
=over 8 |
4428
|
|
|
|
|
|
|
|
4429
|
|
|
|
|
|
|
=item digits |
4430
|
|
|
|
|
|
|
|
4431
|
|
|
|
|
|
|
The number of decimal digits normally formatted. |
4432
|
|
|
|
|
|
|
|
4433
|
|
|
|
|
|
|
=item rounding |
4434
|
|
|
|
|
|
|
|
4435
|
|
|
|
|
|
|
The rounding increment, in units of 10^-digits. |
4436
|
|
|
|
|
|
|
|
4437
|
|
|
|
|
|
|
=item cashdigits |
4438
|
|
|
|
|
|
|
|
4439
|
|
|
|
|
|
|
The number of decimal digits to be used when formatting quantities used in cash transactions (as opposed |
4440
|
|
|
|
|
|
|
to a quantity that would appear in a more formal setting, such as on a bank statement). |
4441
|
|
|
|
|
|
|
|
4442
|
|
|
|
|
|
|
=item cashrounding |
4443
|
|
|
|
|
|
|
|
4444
|
|
|
|
|
|
|
The cash rounding increment, in units of 10^-cashdigits. |
4445
|
|
|
|
|
|
|
|
4446
|
|
|
|
|
|
|
=back |
4447
|
|
|
|
|
|
|
|
4448
|
|
|
|
|
|
|
=item default_currency($region_id) |
4449
|
|
|
|
|
|
|
|
4450
|
|
|
|
|
|
|
This method returns the default currency id for the region id. |
4451
|
|
|
|
|
|
|
If no region id is given then the current locale's is used |
4452
|
|
|
|
|
|
|
|
4453
|
|
|
|
|
|
|
=cut |
4454
|
|
|
|
|
|
|
|
4455
|
|
|
|
|
|
|
sub default_currency { |
4456
|
17
|
|
|
17
|
1
|
41
|
my ($self, $region_id) = @_; |
4457
|
|
|
|
|
|
|
|
4458
|
17
|
100
|
|
|
|
55
|
return $self->_default_cu if $self->_test_default_cu(); |
4459
|
|
|
|
|
|
|
|
4460
|
9
|
|
33
|
|
|
237
|
$region_id //= $self->region_id; |
4461
|
|
|
|
|
|
|
|
4462
|
9
|
50
|
|
|
|
27
|
if (! $region_id) { |
4463
|
0
|
|
|
|
|
0
|
$region_id = $self->likely_subtag->region_id; |
4464
|
0
|
|
|
|
|
0
|
warn "Locale::CLDR::default_currency:- No region given using $region_id at "; |
4465
|
|
|
|
|
|
|
} |
4466
|
|
|
|
|
|
|
|
4467
|
9
|
|
|
|
|
29
|
my $default_currencies = $self->_default_currency; |
4468
|
|
|
|
|
|
|
|
4469
|
9
|
50
|
|
|
|
43
|
return $default_currencies->{$region_id} if exists $default_currencies->{$region_id}; |
4470
|
|
|
|
|
|
|
|
4471
|
0
|
|
|
|
|
0
|
while (1) { |
4472
|
0
|
|
|
|
|
0
|
$region_id = $self->region_contained_by($region_id); |
4473
|
0
|
0
|
|
|
|
0
|
last unless $region_id; |
4474
|
0
|
0
|
|
|
|
0
|
if (exists $default_currencies->{$region_id}) { |
4475
|
0
|
|
|
|
|
0
|
$self->_set_default_cu($default_currencies->{$region_id}); |
4476
|
0
|
|
|
|
|
0
|
return $default_currencies->{$region_id}; |
4477
|
|
|
|
|
|
|
} |
4478
|
|
|
|
|
|
|
} |
4479
|
|
|
|
|
|
|
} |
4480
|
|
|
|
|
|
|
|
4481
|
|
|
|
|
|
|
=item currency_symbol($currency_id) |
4482
|
|
|
|
|
|
|
|
4483
|
|
|
|
|
|
|
This method returns the currency symbol for the given currency id in the current locale. |
4484
|
|
|
|
|
|
|
If no currency id is given it uses the locale's default currency |
4485
|
|
|
|
|
|
|
|
4486
|
|
|
|
|
|
|
=cut |
4487
|
|
|
|
|
|
|
|
4488
|
|
|
|
|
|
|
sub currency_symbol { |
4489
|
17
|
|
|
17
|
1
|
41
|
my ($self, $currency_id) = @_; |
4490
|
|
|
|
|
|
|
|
4491
|
17
|
|
33
|
|
|
50
|
$currency_id //= $self->default_currency; |
4492
|
|
|
|
|
|
|
|
4493
|
17
|
|
|
|
|
53
|
my @bundles = reverse $self->_find_bundle('currencies'); |
4494
|
17
|
|
|
|
|
145
|
foreach my $bundle (@bundles) { |
4495
|
17
|
|
|
|
|
113
|
my $symbol = $bundle->currencies()->{uc $currency_id}{symbol}; |
4496
|
17
|
50
|
|
|
|
87
|
return $symbol if $symbol; |
4497
|
|
|
|
|
|
|
} |
4498
|
|
|
|
|
|
|
|
4499
|
0
|
|
|
|
|
0
|
return ''; |
4500
|
|
|
|
|
|
|
} |
4501
|
|
|
|
|
|
|
|
4502
|
|
|
|
|
|
|
=back |
4503
|
|
|
|
|
|
|
|
4504
|
|
|
|
|
|
|
=head2 Calendar Information |
4505
|
|
|
|
|
|
|
|
4506
|
|
|
|
|
|
|
=over 4 |
4507
|
|
|
|
|
|
|
|
4508
|
|
|
|
|
|
|
=item calendar_preferences() |
4509
|
|
|
|
|
|
|
|
4510
|
|
|
|
|
|
|
This method returns a hash ref keyed on region id. The values are array refs containing the preferred |
4511
|
|
|
|
|
|
|
calendar id's in order of preference. |
4512
|
|
|
|
|
|
|
|
4513
|
|
|
|
|
|
|
=item default_calendar($region) |
4514
|
|
|
|
|
|
|
|
4515
|
|
|
|
|
|
|
This method returns the default calendar id for the given region. If no region id given it |
4516
|
|
|
|
|
|
|
used the region of the current locale. |
4517
|
|
|
|
|
|
|
|
4518
|
|
|
|
|
|
|
=back |
4519
|
|
|
|
|
|
|
|
4520
|
|
|
|
|
|
|
=cut |
4521
|
|
|
|
|
|
|
|
4522
|
|
|
|
|
|
|
has 'Lexicon' => ( |
4523
|
|
|
|
|
|
|
isa => HashRef, |
4524
|
|
|
|
|
|
|
init_arg => undef, |
4525
|
|
|
|
|
|
|
is => 'ro', |
4526
|
|
|
|
|
|
|
clearer => 'reset_lexicon', |
4527
|
|
|
|
|
|
|
default => sub { return {} }, |
4528
|
|
|
|
|
|
|
); |
4529
|
|
|
|
|
|
|
|
4530
|
|
|
|
|
|
|
sub _add_to_lexicon { |
4531
|
3
|
|
|
3
|
|
9
|
my ($self, $key, $value) = @_; |
4532
|
3
|
|
|
|
|
21
|
$self->Lexicon()->{$key} = $value; |
4533
|
|
|
|
|
|
|
} |
4534
|
|
|
|
|
|
|
|
4535
|
|
|
|
|
|
|
sub _get_from_lexicon { |
4536
|
9
|
|
|
9
|
|
21
|
my ($self, $key) = @_; |
4537
|
9
|
|
|
|
|
38
|
return $self->Lexicon()->{$key}; |
4538
|
|
|
|
|
|
|
} |
4539
|
|
|
|
|
|
|
|
4540
|
|
|
|
|
|
|
=head2 Make text emulation |
4541
|
|
|
|
|
|
|
|
4542
|
|
|
|
|
|
|
Locale::CLDR has a Locle::Maketext alike system called LocaleText |
4543
|
|
|
|
|
|
|
|
4544
|
|
|
|
|
|
|
=head3 The Lexicon |
4545
|
|
|
|
|
|
|
|
4546
|
|
|
|
|
|
|
The Lexicon stores the items that will be localized by the localetext method. You |
4547
|
|
|
|
|
|
|
can manipulate it by the following methods |
4548
|
|
|
|
|
|
|
|
4549
|
|
|
|
|
|
|
=over 4 |
4550
|
|
|
|
|
|
|
|
4551
|
|
|
|
|
|
|
=item reset_lexicon() |
4552
|
|
|
|
|
|
|
|
4553
|
|
|
|
|
|
|
This method empties the lexicon |
4554
|
|
|
|
|
|
|
|
4555
|
|
|
|
|
|
|
=item add_to_lexicon($identifier => $localized_text, ...) |
4556
|
|
|
|
|
|
|
|
4557
|
|
|
|
|
|
|
This method adds data to the locales lexicon. |
4558
|
|
|
|
|
|
|
|
4559
|
|
|
|
|
|
|
$identifier is the string passed to localetext() to get the localised version of the text. Each identfier is unique |
4560
|
|
|
|
|
|
|
|
4561
|
|
|
|
|
|
|
$localized_text is the value that is used to create the current locales version of the string. It uses L<Locale::Maketext|Locale::Maketext's> |
4562
|
|
|
|
|
|
|
bracket formatting syntax with some additional methods and some changes to how numerate() works. See below |
4563
|
|
|
|
|
|
|
|
4564
|
|
|
|
|
|
|
Multiple entries can be added by one call to add_to_lexicon() |
4565
|
|
|
|
|
|
|
|
4566
|
|
|
|
|
|
|
=item add_plural_to_lexicon( $identifier => { $pluralform => $localized_text, ... }, ... ) |
4567
|
|
|
|
|
|
|
|
4568
|
|
|
|
|
|
|
$identifier is the string passed to localetext() to get the localised version of the text. Each identfier is unique and must be different |
4569
|
|
|
|
|
|
|
from the identifiers given to add_to_lexicon() |
4570
|
|
|
|
|
|
|
|
4571
|
|
|
|
|
|
|
$pluralform is one of the CLDR's plural forms, these are C<zero, one, two, few, many> and C<other> |
4572
|
|
|
|
|
|
|
|
4573
|
|
|
|
|
|
|
$localized_text is the value that is used to create the current locales version of the string. It uses L<Locale::Maketext|Locale::Maketext's> |
4574
|
|
|
|
|
|
|
bracket formatting syntax with some additional methods and some changes to how numerate() works. See below |
4575
|
|
|
|
|
|
|
|
4576
|
|
|
|
|
|
|
=back |
4577
|
|
|
|
|
|
|
|
4578
|
|
|
|
|
|
|
=head3 Format of maketext strings |
4579
|
|
|
|
|
|
|
|
4580
|
|
|
|
|
|
|
The make text emulation uses the same bracket and escape mecanism as Locale::Maketext. ie ~ is used |
4581
|
|
|
|
|
|
|
to turn a [ from a metta character into a normal one and you need to doubble up the ~ if you want it to appear in |
4582
|
|
|
|
|
|
|
your output. This allows you to embed into you output constructs that will change depending on the locale. |
4583
|
|
|
|
|
|
|
|
4584
|
|
|
|
|
|
|
=head4 Examples of output strings |
4585
|
|
|
|
|
|
|
|
4586
|
|
|
|
|
|
|
Due to the way macro expantion works in localetext any element of the [ ... ] construct except the first may be |
4587
|
|
|
|
|
|
|
substutied by a _1 marker |
4588
|
|
|
|
|
|
|
|
4589
|
|
|
|
|
|
|
=over 4 |
4590
|
|
|
|
|
|
|
|
4591
|
|
|
|
|
|
|
=item You scored [numf,_1] |
4592
|
|
|
|
|
|
|
|
4593
|
|
|
|
|
|
|
localetext() will replace C<[numf,_1]> with the correctly formatted version of the number you passed in as the first paramater |
4594
|
|
|
|
|
|
|
after the identifier. |
4595
|
|
|
|
|
|
|
|
4596
|
|
|
|
|
|
|
=item You have [plural,_1,coins] |
4597
|
|
|
|
|
|
|
|
4598
|
|
|
|
|
|
|
This will substutite the correct plural form of the coins text into the string |
4599
|
|
|
|
|
|
|
|
4600
|
|
|
|
|
|
|
=item This is [gnum,_1,type,gender,declention] |
4601
|
|
|
|
|
|
|
|
4602
|
|
|
|
|
|
|
This will substute the correctly gendered spellout rule for the number given in _1 |
4603
|
|
|
|
|
|
|
|
4604
|
|
|
|
|
|
|
=cut |
4605
|
|
|
|
|
|
|
|
4606
|
|
|
|
|
|
|
sub add_to_lexicon { |
4607
|
1
|
|
|
1
|
1
|
11
|
my $self = shift; |
4608
|
1
|
50
|
|
|
|
5
|
die "Incorrect number of peramaters to add_to_lexicon()\n" if @_ % 2; |
4609
|
1
|
|
|
|
|
6
|
my %parameters = @_; |
4610
|
|
|
|
|
|
|
|
4611
|
1
|
|
|
|
|
5
|
foreach my $identifier (keys %parameters) { |
4612
|
1
|
|
|
|
|
4
|
$self->_add_to_lexicon( $identifier => { default => $self->_parse_localetext_text($parameters{$identifier})}); |
4613
|
|
|
|
|
|
|
} |
4614
|
|
|
|
|
|
|
} |
4615
|
|
|
|
|
|
|
|
4616
|
|
|
|
|
|
|
sub add_plural_to_lexicon { |
4617
|
1
|
|
|
1
|
1
|
1333
|
my $self = shift; |
4618
|
1
|
50
|
|
|
|
6
|
die "Incorrect number of peramaters to add_to_lexicon()\n" if @_ % 2; |
4619
|
1
|
|
|
|
|
6
|
my %parameters = @_; |
4620
|
|
|
|
|
|
|
|
4621
|
1
|
|
|
|
|
6
|
foreach my $identifier (keys %parameters) { |
4622
|
2
|
|
|
|
|
3
|
my %plurals; |
4623
|
2
|
|
|
|
|
5
|
foreach my $plural ( keys %{$parameters{$identifier}} ) { |
|
2
|
|
|
|
|
8
|
|
4624
|
|
|
|
|
|
|
die "Invalid plural form $plural for $identifier\n" |
4625
|
8
|
50
|
|
|
|
20
|
unless grep { $_ eq $plural } qw(zero one two few many other); |
|
48
|
|
|
|
|
101
|
|
4626
|
|
|
|
|
|
|
|
4627
|
8
|
|
|
|
|
26
|
$plurals{$plural} = $self->_parse_localetext_text($parameters{$identifier}{$plural}, 1); |
4628
|
|
|
|
|
|
|
} |
4629
|
|
|
|
|
|
|
|
4630
|
2
|
|
|
|
|
12
|
$self->_add_to_lexicon( $identifier => \%plurals ); |
4631
|
|
|
|
|
|
|
} |
4632
|
|
|
|
|
|
|
} |
4633
|
|
|
|
|
|
|
|
4634
|
|
|
|
|
|
|
# This method converts the string passed in into a sub ref and parsed out the bracketed |
4635
|
|
|
|
|
|
|
# elements into method calls on the locale object |
4636
|
|
|
|
|
|
|
my %methods = ( |
4637
|
|
|
|
|
|
|
gnum => '_make_text_gnum', |
4638
|
|
|
|
|
|
|
numf => '_make_text_numf', |
4639
|
|
|
|
|
|
|
plural => '_make_text_plural', |
4640
|
|
|
|
|
|
|
expand => '_make_text_expand', |
4641
|
|
|
|
|
|
|
); |
4642
|
|
|
|
|
|
|
|
4643
|
|
|
|
|
|
|
sub _parse_localetext_text { |
4644
|
9
|
|
|
9
|
|
21
|
my ($self, $text, $is_plural) = @_; |
4645
|
|
|
|
|
|
|
|
4646
|
9
|
|
|
|
|
16
|
my $original = $text; |
4647
|
|
|
|
|
|
|
# Short circuit if no [ in text |
4648
|
9
|
|
50
|
|
|
20
|
$text //= ''; |
4649
|
9
|
100
|
|
0
|
|
35
|
return sub { $text } if $text !~ /\[/; |
|
0
|
|
|
|
|
0
|
|
4650
|
7
|
|
|
|
|
11
|
my $in_group = 0; |
4651
|
|
|
|
|
|
|
|
4652
|
7
|
|
|
|
|
11
|
my $sub = 'sub { join \'\' '; |
4653
|
|
|
|
|
|
|
# loop over text to find the first bracket group |
4654
|
7
|
|
|
|
|
18
|
while (length $text) { |
4655
|
8
|
|
|
|
|
40
|
my ($raw) = $text =~ /^ ( (?: (?: ~~ )*+ ~ \[ | [^\[] )++ ) /x; |
4656
|
8
|
100
|
|
|
|
183
|
if (length $raw) { |
4657
|
2
|
|
|
|
|
13
|
$text =~ s/^ ( (?: (?: ~~ )*+ ~ \[ | [^\[] )++ ) //gx; |
4658
|
|
|
|
|
|
|
# Fix up escapes |
4659
|
2
|
|
|
|
|
5
|
$raw =~ s/(?:~~)*+\K~\[/[/g; |
4660
|
2
|
|
|
|
|
5
|
$raw =~ s/(?:~~)*+\K~,/,/g; |
4661
|
2
|
|
|
|
|
4
|
$raw =~ s/~~/~/g; |
4662
|
|
|
|
|
|
|
|
4663
|
|
|
|
|
|
|
# Escape stuff for perl |
4664
|
2
|
|
|
|
|
6
|
$raw =~ s/\\/\\\\/g; |
4665
|
2
|
|
|
|
|
3
|
$raw =~ s/'/\\'/g; |
4666
|
|
|
|
|
|
|
|
4667
|
2
|
|
|
|
|
7
|
$sub .= ", '$raw'"; |
4668
|
|
|
|
|
|
|
} |
4669
|
|
|
|
|
|
|
|
4670
|
8
|
50
|
|
|
|
23
|
last unless length $text; # exit loop if nothing left to do |
4671
|
8
|
|
|
|
|
34
|
my ($method) = $text =~ /^( \[ [^\]]+? \] )/x; |
4672
|
8
|
|
|
|
|
33
|
$text =~ s/^( \[ [^\]]+? \] )//xg; |
4673
|
|
|
|
|
|
|
|
4674
|
|
|
|
|
|
|
# check for no method but have text left |
4675
|
8
|
50
|
33
|
|
|
27
|
die "Malformatted make text data '$original'" |
4676
|
|
|
|
|
|
|
if ! length $method && length $text; |
4677
|
|
|
|
|
|
|
|
4678
|
|
|
|
|
|
|
# Check for a [ in the method as this is an error |
4679
|
8
|
50
|
|
|
|
22
|
die "Malformatted make text data '$original'" |
4680
|
|
|
|
|
|
|
if $method =~ /^\[.*\[/; |
4681
|
|
|
|
|
|
|
|
4682
|
|
|
|
|
|
|
# check for [_\d+] This just adds a stringified version of the params |
4683
|
8
|
50
|
|
|
|
31
|
if ( my ($number) = $method =~ / \[ \s* _ [0-9]+ \s* \] /x ) { |
4684
|
0
|
0
|
|
|
|
0
|
if ($number == 0) {# Special case |
4685
|
0
|
|
|
|
|
0
|
$sub .= ', "@_[1 .. @_ -1 ]"'; |
4686
|
|
|
|
|
|
|
} |
4687
|
|
|
|
|
|
|
else { |
4688
|
0
|
|
|
|
|
0
|
$sub .= ', "$_[$number]"'; |
4689
|
|
|
|
|
|
|
} |
4690
|
0
|
|
|
|
|
0
|
next; |
4691
|
|
|
|
|
|
|
} |
4692
|
|
|
|
|
|
|
|
4693
|
|
|
|
|
|
|
# now we should have [ method, param, ... ] |
4694
|
|
|
|
|
|
|
# strip of the [ and ] |
4695
|
8
|
|
|
|
|
42
|
$method =~ s/ \[ \s* (.*?) \s* \] /$1/x; |
4696
|
|
|
|
|
|
|
|
4697
|
|
|
|
|
|
|
# sort out ~, and ~~ |
4698
|
8
|
|
|
|
|
18
|
$method =~ s/(?:~~)*+\K~,/\x{00}/g; |
4699
|
8
|
|
|
|
|
15
|
$method =~ s/~~/~/g; |
4700
|
8
|
|
|
|
|
26
|
($method, my @params) = split /,/, $method; |
4701
|
|
|
|
|
|
|
|
4702
|
|
|
|
|
|
|
# if $is_plural is true we wont have a method |
4703
|
8
|
100
|
|
|
|
19
|
if ($is_plural) { |
4704
|
6
|
|
|
|
|
12
|
$params[0] = $method; |
4705
|
6
|
|
|
|
|
11
|
$method = 'expand'; |
4706
|
|
|
|
|
|
|
} |
4707
|
|
|
|
|
|
|
|
4708
|
|
|
|
|
|
|
die "Unknown method $method in make text data '$original'" |
4709
|
8
|
50
|
|
|
|
24
|
unless exists $methods{lc $method}; |
4710
|
|
|
|
|
|
|
|
4711
|
|
|
|
|
|
|
@params = |
4712
|
10
|
|
|
|
|
20
|
map { s/([\\'])/\\$1/g; $_ } |
|
10
|
|
|
|
|
26
|
|
4713
|
10
|
|
|
|
|
49
|
map { s/_([0-9])+/\$_[$1]/gx; $_ } |
|
10
|
|
|
|
|
25
|
|
4714
|
8
|
|
|
|
|
15
|
map { s/\x{00}/,/g; $_ } |
|
10
|
|
|
|
|
16
|
|
|
10
|
|
|
|
|
25
|
|
4715
|
|
|
|
|
|
|
@params; |
4716
|
|
|
|
|
|
|
|
4717
|
8
|
50
|
|
|
|
65
|
$sub .= ", \$_[0]->$methods{lc $method}(" |
|
|
50
|
|
|
|
|
|
4718
|
|
|
|
|
|
|
. (scalar @params ? '"' : '') |
4719
|
|
|
|
|
|
|
. join('","', @params) |
4720
|
|
|
|
|
|
|
. (scalar @params ? '"' : '') |
4721
|
|
|
|
|
|
|
. '), '; |
4722
|
|
|
|
|
|
|
} |
4723
|
|
|
|
|
|
|
|
4724
|
7
|
|
|
|
|
14
|
$sub .= '}'; |
4725
|
|
|
|
|
|
|
|
4726
|
7
|
|
|
|
|
833
|
return eval "$sub"; |
4727
|
|
|
|
|
|
|
} |
4728
|
|
|
|
|
|
|
|
4729
|
|
|
|
|
|
|
sub _make_text_gnum { |
4730
|
0
|
|
|
0
|
|
0
|
my ($self, $number, $type, $gender, $declention) = @_; |
4731
|
21
|
|
|
21
|
|
285
|
no if $] >= 5.017011, warnings => 'experimental::smartmatch'; |
|
21
|
|
|
|
|
60
|
|
|
21
|
|
|
|
|
289
|
|
4732
|
0
|
|
0
|
|
|
0
|
$type //= 'ordinal'; |
4733
|
0
|
|
0
|
|
|
0
|
$gender //= 'neuter'; |
4734
|
|
|
|
|
|
|
|
4735
|
0
|
0
|
|
|
|
0
|
die "Invalid number type ($type) in makelocale\n" |
4736
|
|
|
|
|
|
|
unless $type ~~ [qw(ordinal cardinal)]; |
4737
|
|
|
|
|
|
|
|
4738
|
0
|
0
|
|
|
|
0
|
die "Invalid gender ($gender) in makelocale\n" |
4739
|
|
|
|
|
|
|
unless $gender ~~ [qw(masculine feminine nuter)]; |
4740
|
|
|
|
|
|
|
|
4741
|
0
|
0
|
|
|
|
0
|
my @names = ( |
4742
|
|
|
|
|
|
|
( defined $declention ? "spellout-$type-$gender-$declention" : ()), |
4743
|
|
|
|
|
|
|
"spellout-$type-$gender", |
4744
|
|
|
|
|
|
|
"spellout-$type", |
4745
|
|
|
|
|
|
|
); |
4746
|
|
|
|
|
|
|
|
4747
|
0
|
|
|
|
|
0
|
my %formats; |
4748
|
0
|
|
|
|
|
0
|
@formats{ grep { /^spellout-$type/ } $self->_get_valid_algorithmic_formats() } = (); |
|
0
|
|
|
|
|
0
|
|
4749
|
|
|
|
|
|
|
|
4750
|
0
|
|
|
|
|
0
|
foreach my $name (@names) { |
4751
|
0
|
0
|
|
|
|
0
|
return $self->format_number($number, $name) if exists $formats{$name}; |
4752
|
|
|
|
|
|
|
} |
4753
|
|
|
|
|
|
|
|
4754
|
0
|
|
|
|
|
0
|
return $self->format_number($number); |
4755
|
|
|
|
|
|
|
} |
4756
|
|
|
|
|
|
|
|
4757
|
|
|
|
|
|
|
sub _make_text_numf { |
4758
|
6
|
|
|
6
|
|
16
|
my ( $self, $number ) = @_; |
4759
|
|
|
|
|
|
|
|
4760
|
6
|
|
|
|
|
24
|
return $self->format_number($number); |
4761
|
|
|
|
|
|
|
} |
4762
|
|
|
|
|
|
|
|
4763
|
|
|
|
|
|
|
sub _make_text_plural { |
4764
|
6
|
|
|
6
|
|
16
|
my ($self, $number, $identifier) = @_; |
4765
|
|
|
|
|
|
|
|
4766
|
6
|
|
|
|
|
33
|
my $plural = $self->plural($number); |
4767
|
|
|
|
|
|
|
|
4768
|
6
|
|
|
|
|
20
|
my $text = $self->_get_from_lexicon($identifier)->{$plural}; |
4769
|
6
|
|
|
|
|
15
|
$number = $self->_make_text_numf($number); |
4770
|
|
|
|
|
|
|
|
4771
|
6
|
|
|
|
|
190
|
return $self->$text($number); |
4772
|
|
|
|
|
|
|
} |
4773
|
|
|
|
|
|
|
|
4774
|
|
|
|
|
|
|
sub _make_text_expand { |
4775
|
6
|
|
|
6
|
|
12
|
shift; |
4776
|
6
|
|
|
|
|
56
|
return @_; |
4777
|
|
|
|
|
|
|
} |
4778
|
|
|
|
|
|
|
|
4779
|
|
|
|
|
|
|
=item localetext($identifer, @parameters) |
4780
|
|
|
|
|
|
|
|
4781
|
|
|
|
|
|
|
This method looks up the identifier in the current locales lexicon and then formats the returned text |
4782
|
|
|
|
|
|
|
as part in the current locale the identifier is the same as the identifier passed into the |
4783
|
|
|
|
|
|
|
add_to_lexicon() metod. The parameters are the values required by the [ ... ] expantions in the |
4784
|
|
|
|
|
|
|
localised text. |
4785
|
|
|
|
|
|
|
|
4786
|
|
|
|
|
|
|
=cut |
4787
|
|
|
|
|
|
|
|
4788
|
|
|
|
|
|
|
sub localetext { |
4789
|
3
|
|
|
3
|
1
|
18
|
my ($self, $identifier, @params) = @_; |
4790
|
|
|
|
|
|
|
|
4791
|
3
|
|
|
|
|
12
|
my $text = $self->_get_from_lexicon($identifier); |
4792
|
|
|
|
|
|
|
|
4793
|
3
|
50
|
|
|
|
14
|
if ( ref $params[-1] eq 'HASH' ) { |
4794
|
0
|
|
|
|
|
0
|
my $plural = $params[-1]{plural}; |
4795
|
0
|
|
|
|
|
0
|
return $text->{$plural}($self, @params[0 .. @params -1]); |
4796
|
|
|
|
|
|
|
} |
4797
|
3
|
|
|
|
|
86
|
return $text->{default}($self, @params); |
4798
|
|
|
|
|
|
|
} |
4799
|
|
|
|
|
|
|
|
4800
|
|
|
|
|
|
|
=back |
4801
|
|
|
|
|
|
|
|
4802
|
|
|
|
|
|
|
=head2 Collation |
4803
|
|
|
|
|
|
|
|
4804
|
|
|
|
|
|
|
=over 4 |
4805
|
|
|
|
|
|
|
|
4806
|
|
|
|
|
|
|
=item collation() |
4807
|
|
|
|
|
|
|
|
4808
|
|
|
|
|
|
|
This method returns a Locale::CLDR::Collator object. This is still in development. Future releases will |
4809
|
|
|
|
|
|
|
try and match the API from L<Unicode::Collate> as much as possible and add tailoring for locales. |
4810
|
|
|
|
|
|
|
|
4811
|
|
|
|
|
|
|
=back |
4812
|
|
|
|
|
|
|
|
4813
|
|
|
|
|
|
|
=cut |
4814
|
|
|
|
|
|
|
|
4815
|
|
|
|
|
|
|
sub collation { |
4816
|
5
|
|
|
5
|
1
|
33391
|
my $self = shift; |
4817
|
|
|
|
|
|
|
|
4818
|
5
|
|
|
|
|
35
|
my %params = @_; |
4819
|
5
|
|
33
|
|
|
71
|
$params{type} //= $self->_collation_type; |
4820
|
5
|
|
33
|
|
|
44
|
$params{alternate} //= $self->_collation_alternate; |
4821
|
5
|
|
33
|
|
|
45
|
$params{backwards} //= $self->_collation_backwards; |
4822
|
5
|
|
33
|
|
|
46
|
$params{case_level} //= $self->_collation_case_level; |
4823
|
5
|
|
33
|
|
|
45
|
$params{case_ordering} //= $self->_collation_case_ordering; |
4824
|
5
|
|
33
|
|
|
50
|
$params{normalization} //= $self->_collation_normalization; |
4825
|
5
|
|
33
|
|
|
58
|
$params{numeric} //= $self->_collation_numeric; |
4826
|
5
|
|
33
|
|
|
45
|
$params{reorder} //= $self->_collation_reorder; |
4827
|
5
|
|
66
|
|
|
24
|
$params{strength} //= $self->_collation_strength; |
4828
|
5
|
|
33
|
|
|
53
|
$params{max_variable} //= $self->_collation_max_variable; |
4829
|
|
|
|
|
|
|
|
4830
|
5
|
|
|
|
|
124
|
return Locale::CLDR::Collator->new(locale => $self, %params); |
4831
|
|
|
|
|
|
|
} |
4832
|
|
|
|
|
|
|
|
4833
|
|
|
|
|
|
|
sub _collation_overrides { |
4834
|
5
|
|
|
5
|
|
22
|
my ($self, $type) = @_; |
4835
|
|
|
|
|
|
|
|
4836
|
5
|
|
|
|
|
34
|
my @bundles = reverse $self->_find_bundle('collation'); |
4837
|
|
|
|
|
|
|
|
4838
|
5
|
|
|
|
|
62
|
my $override = ''; |
4839
|
5
|
|
|
|
|
19
|
foreach my $bundle (@bundles) { |
4840
|
0
|
0
|
|
|
|
0
|
last if $override = $bundle->collation()->{$type}; |
4841
|
|
|
|
|
|
|
} |
4842
|
|
|
|
|
|
|
|
4843
|
5
|
50
|
33
|
|
|
31
|
if ($type ne 'standard' && ! $override) { |
4844
|
0
|
|
|
|
|
0
|
foreach my $bundle (@bundles) { |
4845
|
0
|
0
|
|
|
|
0
|
last if $override = $bundle->collation()->{standard}; |
4846
|
|
|
|
|
|
|
} |
4847
|
|
|
|
|
|
|
} |
4848
|
|
|
|
|
|
|
|
4849
|
5
|
|
50
|
|
|
48
|
return $override || []; |
4850
|
|
|
|
|
|
|
} |
4851
|
|
|
|
|
|
|
|
4852
|
|
|
|
|
|
|
sub _collation_type { |
4853
|
5
|
|
|
5
|
|
15
|
my $self = shift; |
4854
|
|
|
|
|
|
|
|
4855
|
5
|
0
|
33
|
|
|
43
|
return $self->extensions()->{co} if ref $self->extensions() && $self->extensions()->{co}; |
4856
|
5
|
|
|
|
|
29
|
my @bundles = reverse $self->_find_bundle('collation_type'); |
4857
|
5
|
|
|
|
|
62
|
my $collation_type = ''; |
4858
|
|
|
|
|
|
|
|
4859
|
5
|
|
|
|
|
19
|
foreach my $bundle (@bundles) { |
4860
|
0
|
0
|
|
|
|
0
|
last if $collation_type = $bundle->collation_type(); |
4861
|
|
|
|
|
|
|
} |
4862
|
|
|
|
|
|
|
|
4863
|
5
|
|
50
|
|
|
48
|
return $collation_type || 'standard'; |
4864
|
|
|
|
|
|
|
} |
4865
|
|
|
|
|
|
|
|
4866
|
|
|
|
|
|
|
sub _collation_alternate { |
4867
|
5
|
|
|
5
|
|
12
|
my $self = shift; |
4868
|
|
|
|
|
|
|
|
4869
|
5
|
0
|
33
|
|
|
26
|
return $self->extensions()->{ka} if ref $self->extensions() && $self->extensions()->{ka}; |
4870
|
5
|
|
|
|
|
18
|
my @bundles = reverse $self->_find_bundle('collation_alternate'); |
4871
|
5
|
|
|
|
|
44
|
my $collation_alternate = ''; |
4872
|
|
|
|
|
|
|
|
4873
|
5
|
|
|
|
|
19
|
foreach my $bundle (@bundles) { |
4874
|
0
|
0
|
|
|
|
0
|
last if $collation_alternate = $bundle->collation_alternate(); |
4875
|
|
|
|
|
|
|
} |
4876
|
|
|
|
|
|
|
|
4877
|
5
|
|
50
|
|
|
37
|
return $collation_alternate || 'noignore'; |
4878
|
|
|
|
|
|
|
} |
4879
|
|
|
|
|
|
|
|
4880
|
|
|
|
|
|
|
sub _collation_backwards { |
4881
|
5
|
|
|
5
|
|
11
|
my $self = shift; |
4882
|
|
|
|
|
|
|
|
4883
|
5
|
0
|
33
|
|
|
27
|
return $self->extensions()->{kb} if ref $self->extensions() && $self->extensions()->{kb}; |
4884
|
5
|
|
|
|
|
20
|
my @bundles = reverse $self->_find_bundle('collation_backwards'); |
4885
|
5
|
|
|
|
|
41
|
my $collation_backwards = ''; |
4886
|
|
|
|
|
|
|
|
4887
|
5
|
|
|
|
|
19
|
foreach my $bundle (@bundles) { |
4888
|
0
|
0
|
|
|
|
0
|
last if $collation_backwards = $bundle->collation_backwards(); |
4889
|
|
|
|
|
|
|
} |
4890
|
|
|
|
|
|
|
|
4891
|
5
|
|
50
|
|
|
39
|
return $collation_backwards || 'noignore'; |
4892
|
|
|
|
|
|
|
} |
4893
|
|
|
|
|
|
|
|
4894
|
|
|
|
|
|
|
sub _collation_case_level { |
4895
|
5
|
|
|
5
|
|
12
|
my $self = shift; |
4896
|
|
|
|
|
|
|
|
4897
|
5
|
0
|
33
|
|
|
25
|
return $self->extensions()->{kc} if ref $self->extensions() && $self->extensions()->{kc}; |
4898
|
5
|
|
|
|
|
18
|
my @bundles = reverse $self->_find_bundle('collation_case_level'); |
4899
|
5
|
|
|
|
|
42
|
my $collation_case_level = ''; |
4900
|
|
|
|
|
|
|
|
4901
|
5
|
|
|
|
|
19
|
foreach my $bundle (@bundles) { |
4902
|
0
|
0
|
|
|
|
0
|
last if $collation_case_level = $bundle->collation_case_level(); |
4903
|
|
|
|
|
|
|
} |
4904
|
|
|
|
|
|
|
|
4905
|
5
|
|
50
|
|
|
44
|
return $collation_case_level || 'false'; |
4906
|
|
|
|
|
|
|
} |
4907
|
|
|
|
|
|
|
|
4908
|
|
|
|
|
|
|
sub _collation_case_ordering { |
4909
|
5
|
|
|
5
|
|
13
|
my $self = shift; |
4910
|
|
|
|
|
|
|
|
4911
|
5
|
0
|
33
|
|
|
24
|
return $self->extensions()->{kf} if ref $self->extensions() && $self->extensions()->{kf}; |
4912
|
5
|
|
|
|
|
20
|
my @bundles = reverse $self->_find_bundle('collation_case_ordering'); |
4913
|
5
|
|
|
|
|
40
|
my $collation_case_ordering = ''; |
4914
|
|
|
|
|
|
|
|
4915
|
5
|
|
|
|
|
22
|
foreach my $bundle (@bundles) { |
4916
|
0
|
0
|
|
|
|
0
|
last if $collation_case_ordering = $bundle->collation_case_ordering(); |
4917
|
|
|
|
|
|
|
} |
4918
|
|
|
|
|
|
|
|
4919
|
5
|
|
50
|
|
|
38
|
return $collation_case_ordering || 'false'; |
4920
|
|
|
|
|
|
|
} |
4921
|
|
|
|
|
|
|
|
4922
|
|
|
|
|
|
|
sub _collation_normalization { |
4923
|
5
|
|
|
5
|
|
13
|
my $self = shift; |
4924
|
|
|
|
|
|
|
|
4925
|
5
|
0
|
33
|
|
|
27
|
return $self->extensions()->{kk} if ref $self->extensions() && $self->extensions()->{kk}; |
4926
|
5
|
|
|
|
|
22
|
my @bundles = reverse $self->_find_bundle('collation_normalization'); |
4927
|
5
|
|
|
|
|
41
|
my $collation_normalization = ''; |
4928
|
|
|
|
|
|
|
|
4929
|
5
|
|
|
|
|
15
|
foreach my $bundle (@bundles) { |
4930
|
0
|
0
|
|
|
|
0
|
last if $collation_normalization = $bundle->collation_normalization(); |
4931
|
|
|
|
|
|
|
} |
4932
|
|
|
|
|
|
|
|
4933
|
5
|
|
50
|
|
|
38
|
return $collation_normalization || 'true'; |
4934
|
|
|
|
|
|
|
} |
4935
|
|
|
|
|
|
|
|
4936
|
|
|
|
|
|
|
sub _collation_numeric { |
4937
|
5
|
|
|
5
|
|
15
|
my $self = shift; |
4938
|
|
|
|
|
|
|
|
4939
|
5
|
0
|
33
|
|
|
28
|
return $self->extensions()->{kn} if ref $self->extensions() && $self->extensions()->{kn}; |
4940
|
5
|
|
|
|
|
20
|
my @bundles = reverse $self->_find_bundle('collation_numeric'); |
4941
|
5
|
|
|
|
|
42
|
my $collation_numeric = ''; |
4942
|
|
|
|
|
|
|
|
4943
|
5
|
|
|
|
|
20
|
foreach my $bundle (@bundles) { |
4944
|
0
|
0
|
|
|
|
0
|
last if $collation_numeric = $bundle->collation_numeric(); |
4945
|
|
|
|
|
|
|
} |
4946
|
|
|
|
|
|
|
|
4947
|
5
|
|
50
|
|
|
41
|
return $collation_numeric || 'false'; |
4948
|
|
|
|
|
|
|
} |
4949
|
|
|
|
|
|
|
|
4950
|
|
|
|
|
|
|
sub _collation_reorder { |
4951
|
5
|
|
|
5
|
|
13
|
my $self = shift; |
4952
|
|
|
|
|
|
|
|
4953
|
5
|
0
|
33
|
|
|
26
|
return $self->extensions()->{kr} if ref $self->extensions() && $self->extensions()->{kr}; |
4954
|
5
|
|
|
|
|
17
|
my @bundles = reverse $self->_find_bundle('collation_reorder'); |
4955
|
5
|
|
|
|
|
45
|
my $collation_reorder = []; |
4956
|
|
|
|
|
|
|
|
4957
|
5
|
|
|
|
|
18
|
foreach my $bundle (@bundles) { |
4958
|
0
|
0
|
0
|
|
|
0
|
last if ref( $collation_reorder = $bundle->collation_reorder()) && @$collation_reorder; |
4959
|
|
|
|
|
|
|
} |
4960
|
|
|
|
|
|
|
|
4961
|
5
|
|
50
|
|
|
29
|
return $collation_reorder || []; |
4962
|
|
|
|
|
|
|
} |
4963
|
|
|
|
|
|
|
|
4964
|
|
|
|
|
|
|
sub _collation_strength { |
4965
|
1
|
|
|
1
|
|
2
|
my $self = shift; |
4966
|
|
|
|
|
|
|
|
4967
|
1
|
|
33
|
|
|
6
|
my $collation_strength = ref $self->extensions() && $self->extensions()->{ks}; |
4968
|
1
|
50
|
|
|
|
4
|
if ($collation_strength) { |
4969
|
0
|
|
|
|
|
0
|
$collation_strength =~ s/^level//; |
4970
|
0
|
0
|
|
|
|
0
|
$collation_strength = 5 unless ($collation_strength + 0); |
4971
|
0
|
|
|
|
|
0
|
return $collation_strength; |
4972
|
|
|
|
|
|
|
} |
4973
|
|
|
|
|
|
|
|
4974
|
1
|
|
|
|
|
3
|
my @bundles = reverse $self->_find_bundle('collation_strength'); |
4975
|
1
|
|
|
|
|
9
|
$collation_strength = 0; |
4976
|
|
|
|
|
|
|
|
4977
|
1
|
|
|
|
|
4
|
foreach my $bundle (@bundles) { |
4978
|
0
|
0
|
|
|
|
0
|
last if $collation_strength = $bundle->collation_strength(); |
4979
|
|
|
|
|
|
|
} |
4980
|
|
|
|
|
|
|
|
4981
|
1
|
|
50
|
|
|
7
|
return $collation_strength || 3; |
4982
|
|
|
|
|
|
|
} |
4983
|
|
|
|
|
|
|
|
4984
|
|
|
|
|
|
|
sub _collation_max_variable { |
4985
|
5
|
|
|
5
|
|
12
|
my $self = shift; |
4986
|
|
|
|
|
|
|
|
4987
|
5
|
0
|
33
|
|
|
27
|
return $self->extensions()->{kv} if ref $self->extensions() && $self->extensions()->{kv}; |
4988
|
5
|
|
|
|
|
17
|
my @bundles = reverse $self->_find_bundle('collation_max_variable'); |
4989
|
5
|
|
|
|
|
41
|
my $collation_max_variable = ''; |
4990
|
|
|
|
|
|
|
|
4991
|
5
|
|
|
|
|
21
|
foreach my $bundle (@bundles) { |
4992
|
0
|
0
|
|
|
|
0
|
last if $collation_max_variable = $bundle->collation_max_variable(); |
4993
|
|
|
|
|
|
|
} |
4994
|
|
|
|
|
|
|
|
4995
|
5
|
|
50
|
|
|
37
|
return $collation_max_variable || 3; |
4996
|
|
|
|
|
|
|
} |
4997
|
|
|
|
|
|
|
|
4998
|
|
|
|
|
|
|
=head1 Locales |
4999
|
|
|
|
|
|
|
|
5000
|
|
|
|
|
|
|
Other locales can be found on CPAN. You can install Language packs from the |
5001
|
|
|
|
|
|
|
Locale::CLDR::Locales::* packages. You will in future be able to install language |
5002
|
|
|
|
|
|
|
packs for a given region by looking for a Bundle::Locale::CLDR::* package. |
5003
|
|
|
|
|
|
|
|
5004
|
|
|
|
|
|
|
If you are looking for a language pack that is not yet published then get hold of |
5005
|
|
|
|
|
|
|
the version 0.25.4 from http://search.cpan.org/CPAN/authors/id/J/JG/JGNI/Locale-CLDR-v0.25.4.tar.gz |
5006
|
|
|
|
|
|
|
which has data for all locals alternatively you can get hold of the latest version of the |
5007
|
|
|
|
|
|
|
code from git hub at https://github.com/ThePilgrim/perlcldr |
5008
|
|
|
|
|
|
|
|
5009
|
|
|
|
|
|
|
=head1 AUTHOR |
5010
|
|
|
|
|
|
|
|
5011
|
|
|
|
|
|
|
John Imrie, C<< <JGNI at cpan dot org> >> |
5012
|
|
|
|
|
|
|
|
5013
|
|
|
|
|
|
|
=head1 BUGS |
5014
|
|
|
|
|
|
|
|
5015
|
|
|
|
|
|
|
Please report any bugs or feature requests to C<bug-locale-cldr at rt.cpan.org>, or through |
5016
|
|
|
|
|
|
|
the web interface at L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Locale-CLDR>. I will be notified, and then you'll |
5017
|
|
|
|
|
|
|
automatically be notified of progress on your bug as I make changes. |
5018
|
|
|
|
|
|
|
|
5019
|
|
|
|
|
|
|
=head1 SUPPORT |
5020
|
|
|
|
|
|
|
|
5021
|
|
|
|
|
|
|
You can find documentation for this module with the perldoc command. |
5022
|
|
|
|
|
|
|
|
5023
|
|
|
|
|
|
|
perldoc Locale::CLDR |
5024
|
|
|
|
|
|
|
|
5025
|
|
|
|
|
|
|
You can also look for information at: |
5026
|
|
|
|
|
|
|
|
5027
|
|
|
|
|
|
|
=over 4 |
5028
|
|
|
|
|
|
|
|
5029
|
|
|
|
|
|
|
=item * RT: CPAN's request tracker |
5030
|
|
|
|
|
|
|
|
5031
|
|
|
|
|
|
|
L<http://rt.cpan.org/NoAuth/Bugs.html?Dist=Locale-CLDR> |
5032
|
|
|
|
|
|
|
|
5033
|
|
|
|
|
|
|
=item * AnnoCPAN: Annotated CPAN documentation |
5034
|
|
|
|
|
|
|
|
5035
|
|
|
|
|
|
|
L<http://annocpan.org/dist/Locale-CLDR> |
5036
|
|
|
|
|
|
|
|
5037
|
|
|
|
|
|
|
=item * CPAN Ratings |
5038
|
|
|
|
|
|
|
|
5039
|
|
|
|
|
|
|
L<http://cpanratings.perl.org/d/Locale-CLDR> |
5040
|
|
|
|
|
|
|
|
5041
|
|
|
|
|
|
|
=item * Search CPAN |
5042
|
|
|
|
|
|
|
|
5043
|
|
|
|
|
|
|
L<http://search.cpan.org/dist/Locale-CLDR/> |
5044
|
|
|
|
|
|
|
|
5045
|
|
|
|
|
|
|
=back |
5046
|
|
|
|
|
|
|
|
5047
|
|
|
|
|
|
|
|
5048
|
|
|
|
|
|
|
=head1 ACKNOWLEDGEMENTS |
5049
|
|
|
|
|
|
|
|
5050
|
|
|
|
|
|
|
Everyone at the Unicode Consortium for providing the data. |
5051
|
|
|
|
|
|
|
|
5052
|
|
|
|
|
|
|
Karl Williams for his tireless work on Unicode in the Perl |
5053
|
|
|
|
|
|
|
regex engine. |
5054
|
|
|
|
|
|
|
|
5055
|
|
|
|
|
|
|
=head1 COPYRIGHT & LICENSE |
5056
|
|
|
|
|
|
|
|
5057
|
|
|
|
|
|
|
Copyright 2009-2015 John Imrie. |
5058
|
|
|
|
|
|
|
|
5059
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or modify it |
5060
|
|
|
|
|
|
|
under the terms of either: the GNU General Public License as published |
5061
|
|
|
|
|
|
|
by the Free Software Foundation; or the Artistic License. |
5062
|
|
|
|
|
|
|
|
5063
|
|
|
|
|
|
|
See http://dev.perl.org/licenses/ for more information. |
5064
|
|
|
|
|
|
|
|
5065
|
|
|
|
|
|
|
=cut |
5066
|
|
|
|
|
|
|
|
5067
|
|
|
|
|
|
|
1; # End of Locale::CLDR |