ruby-cldr 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. data/LICENSE +20 -0
  2. data/README.textile +104 -0
  3. data/Rakefile +18 -0
  4. data/TODO +68 -0
  5. data/VERSION +1 -0
  6. data/cldr.thor +5 -0
  7. data/lib/cldr/data/base.rb +66 -0
  8. data/lib/cldr/data/calendars/gregorian.rb +124 -0
  9. data/lib/cldr/data/calendars.rb +12 -0
  10. data/lib/cldr/data/currencies.rb +26 -0
  11. data/lib/cldr/data/delimiters.rb +21 -0
  12. data/lib/cldr/data/languages.rb +17 -0
  13. data/lib/cldr/data/numbers.rb +60 -0
  14. data/lib/cldr/data/plurals/cldr_grammar.treetop +50 -0
  15. data/lib/cldr/data/plurals/grammar.rb +536 -0
  16. data/lib/cldr/data/plurals/rules.rb +113 -0
  17. data/lib/cldr/data/plurals.rb +39 -0
  18. data/lib/cldr/data/territories.rb +17 -0
  19. data/lib/cldr/data/timezones.rb +25 -0
  20. data/lib/cldr/data/units.rb +25 -0
  21. data/lib/cldr/data.rb +34 -0
  22. data/lib/cldr/download.rb +20 -0
  23. data/lib/cldr/export/ruby.rb +16 -0
  24. data/lib/cldr/export/yaml.rb +39 -0
  25. data/lib/cldr/export.rb +69 -0
  26. data/lib/cldr/format/currency.rb +11 -0
  27. data/lib/cldr/format/date.rb +144 -0
  28. data/lib/cldr/format/datetime/base.rb +32 -0
  29. data/lib/cldr/format/datetime.rb +28 -0
  30. data/lib/cldr/format/decimal/base.rb +18 -0
  31. data/lib/cldr/format/decimal/fraction.rb +28 -0
  32. data/lib/cldr/format/decimal/integer.rb +46 -0
  33. data/lib/cldr/format/decimal/number.rb +44 -0
  34. data/lib/cldr/format/decimal.rb +32 -0
  35. data/lib/cldr/format/percent.rb +11 -0
  36. data/lib/cldr/format/time.rb +71 -0
  37. data/lib/cldr/format.rb +113 -0
  38. data/lib/cldr/thor.rb +33 -0
  39. data/lib/cldr.rb +7 -0
  40. data/lib/core_ext/hash/deep_merge.rb +7 -0
  41. data/lib/core_ext/hash/deep_stringify_keys.rb +11 -0
  42. data/lib/core_ext/hash/symbolize_keys.rb +10 -0
  43. data/lib/core_ext/string/camelize.rb +5 -0
  44. data/lib/core_ext/string/underscore.rb +9 -0
  45. data/test/all.rb +3 -0
  46. data/test/data/all.rb +3 -0
  47. data/test/data/calendars_test.rb +149 -0
  48. data/test/data/currencies_test.rb +47 -0
  49. data/test/data/delimiters_test.rb +31 -0
  50. data/test/data/languages_test.rb +67 -0
  51. data/test/data/numbers_test.rb +61 -0
  52. data/test/data/plurals_test.rb +132 -0
  53. data/test/data/territories_test.rb +51 -0
  54. data/test/data/timezones_test.rb +56 -0
  55. data/test/data/units_test.rb +36 -0
  56. data/test/export_test.rb +57 -0
  57. data/test/formats/all.rb +3 -0
  58. data/test/formats/datetime/all.rb +3 -0
  59. data/test/formats/datetime/date_test.rb +31 -0
  60. data/test/formats/datetime/datetime_test.rb +18 -0
  61. data/test/formats/datetime/day_test.rb +41 -0
  62. data/test/formats/datetime/hour_test.rb +79 -0
  63. data/test/formats/datetime/minute_test.rb +25 -0
  64. data/test/formats/datetime/month_test.rb +76 -0
  65. data/test/formats/datetime/period_test.rb +20 -0
  66. data/test/formats/datetime/quarter_test.rb +118 -0
  67. data/test/formats/datetime/second_test.rb +80 -0
  68. data/test/formats/datetime/time_test.rb +33 -0
  69. data/test/formats/datetime/timezone_test.rb +23 -0
  70. data/test/formats/datetime/year_test.rb +57 -0
  71. data/test/formats/decimal/fraction_test.rb +17 -0
  72. data/test/formats/decimal/integer_test.rb +67 -0
  73. data/test/formats/decimal/number_test.rb +77 -0
  74. data/test/formats/decimal_test.rb +19 -0
  75. data/test/formats/format_test.rb +66 -0
  76. data/test/formats/rails_compat/all.rb +3 -0
  77. data/test/formats/rails_compat/format_integer_test.rb +56 -0
  78. data/test/formats/rails_compat/format_number_test.rb +134 -0
  79. data/test/test_helper.rb +5 -0
  80. metadata +169 -0
@@ -0,0 +1,536 @@
1
+ # http://unicode.org/draft/reports/tr35/tr35.html#Language_Plural_Rules
2
+ #
3
+ # condition = and_condition ('or' and_condition)*
4
+ # and_condition = relation ('and' relation)*
5
+ # relation = is_relation | in_relation | within_relation | 'n' <EOL>
6
+ # is_relation = expr 'is' ('not')? value
7
+ # in_relation = expr ('not')? 'in' range
8
+ # within_relation = expr ('not')? 'within' range
9
+ # expr = 'n' ('mod' value)?
10
+ # value = digit+
11
+ # digit = 0|1|2|3|4|5|6|7|8|9
12
+ # range = value'..'value
13
+
14
+ class Cldr
15
+ module Data
16
+ class Plurals
17
+ module Grammar
18
+ include Treetop::Runtime
19
+
20
+ def root
21
+ @root || :or_condition
22
+ end
23
+
24
+ module OrCondition0
25
+ def and_condition
26
+ elements[1]
27
+ end
28
+ end
29
+
30
+ module OrCondition1
31
+ def and_condition
32
+ elements[0]
33
+ end
34
+
35
+ end
36
+
37
+ def _nt_or_condition
38
+ start_index = index
39
+ if node_cache[:or_condition].has_key?(index)
40
+ cached = node_cache[:or_condition][index]
41
+ @index = cached.interval.end if cached
42
+ return cached
43
+ end
44
+
45
+ i0, s0 = index, []
46
+ r1 = _nt_and_condition
47
+ s0 << r1
48
+ if r1
49
+ i3, s3 = index, []
50
+ if input.index(" or ", index) == index
51
+ r4 = instantiate_node(SyntaxNode,input, index...(index + 4))
52
+ @index += 4
53
+ else
54
+ terminal_parse_failure(" or ")
55
+ r4 = nil
56
+ end
57
+ s3 << r4
58
+ if r4
59
+ r5 = _nt_and_condition
60
+ s3 << r5
61
+ end
62
+ if s3.last
63
+ r3 = instantiate_node(SyntaxNode,input, i3...index, s3)
64
+ r3.extend(OrCondition0)
65
+ else
66
+ self.index = i3
67
+ r3 = nil
68
+ end
69
+ if r3
70
+ r2 = r3
71
+ else
72
+ r2 = instantiate_node(SyntaxNode,input, index...index)
73
+ end
74
+ s0 << r2
75
+ end
76
+ if s0.last
77
+ r0 = instantiate_node(SyntaxNode,input, i0...index, s0)
78
+ r0.extend(OrCondition1)
79
+ else
80
+ self.index = i0
81
+ r0 = nil
82
+ end
83
+
84
+ node_cache[:or_condition][start_index] = r0
85
+
86
+ return r0
87
+ end
88
+
89
+ module AndCondition0
90
+ def relation
91
+ elements[1]
92
+ end
93
+ end
94
+
95
+ module AndCondition1
96
+ def relation
97
+ elements[0]
98
+ end
99
+
100
+ end
101
+
102
+ def _nt_and_condition
103
+ start_index = index
104
+ if node_cache[:and_condition].has_key?(index)
105
+ cached = node_cache[:and_condition][index]
106
+ @index = cached.interval.end if cached
107
+ return cached
108
+ end
109
+
110
+ i0, s0 = index, []
111
+ r1 = _nt_relation
112
+ s0 << r1
113
+ if r1
114
+ i3, s3 = index, []
115
+ if input.index(" and ", index) == index
116
+ r4 = instantiate_node(SyntaxNode,input, index...(index + 5))
117
+ @index += 5
118
+ else
119
+ terminal_parse_failure(" and ")
120
+ r4 = nil
121
+ end
122
+ s3 << r4
123
+ if r4
124
+ r5 = _nt_relation
125
+ s3 << r5
126
+ end
127
+ if s3.last
128
+ r3 = instantiate_node(SyntaxNode,input, i3...index, s3)
129
+ r3.extend(AndCondition0)
130
+ else
131
+ self.index = i3
132
+ r3 = nil
133
+ end
134
+ if r3
135
+ r2 = r3
136
+ else
137
+ r2 = instantiate_node(SyntaxNode,input, index...index)
138
+ end
139
+ s0 << r2
140
+ end
141
+ if s0.last
142
+ r0 = instantiate_node(SyntaxNode,input, i0...index, s0)
143
+ r0.extend(AndCondition1)
144
+ else
145
+ self.index = i0
146
+ r0 = nil
147
+ end
148
+
149
+ node_cache[:and_condition][start_index] = r0
150
+
151
+ return r0
152
+ end
153
+
154
+ def _nt_relation
155
+ start_index = index
156
+ if node_cache[:relation].has_key?(index)
157
+ cached = node_cache[:relation][index]
158
+ @index = cached.interval.end if cached
159
+ return cached
160
+ end
161
+
162
+ i0 = index
163
+ r1 = _nt_is_relation
164
+ if r1
165
+ r0 = r1
166
+ else
167
+ r2 = _nt_in_relation
168
+ if r2
169
+ r0 = r2
170
+ else
171
+ r3 = _nt_within_relation
172
+ if r3
173
+ r0 = r3
174
+ else
175
+ if input.index("n", index) == index
176
+ r4 = instantiate_node(SyntaxNode,input, index...(index + 1))
177
+ @index += 1
178
+ else
179
+ terminal_parse_failure("n")
180
+ r4 = nil
181
+ end
182
+ if r4
183
+ r0 = r4
184
+ else
185
+ self.index = i0
186
+ r0 = nil
187
+ end
188
+ end
189
+ end
190
+ end
191
+
192
+ node_cache[:relation][start_index] = r0
193
+
194
+ return r0
195
+ end
196
+
197
+ module IsRelation0
198
+ def expr
199
+ elements[0]
200
+ end
201
+
202
+ def value
203
+ elements[3]
204
+ end
205
+ end
206
+
207
+ def _nt_is_relation
208
+ start_index = index
209
+ if node_cache[:is_relation].has_key?(index)
210
+ cached = node_cache[:is_relation][index]
211
+ @index = cached.interval.end if cached
212
+ return cached
213
+ end
214
+
215
+ i0, s0 = index, []
216
+ r1 = _nt_expr
217
+ s0 << r1
218
+ if r1
219
+ if input.index(" is ", index) == index
220
+ r2 = instantiate_node(SyntaxNode,input, index...(index + 4))
221
+ @index += 4
222
+ else
223
+ terminal_parse_failure(" is ")
224
+ r2 = nil
225
+ end
226
+ s0 << r2
227
+ if r2
228
+ if input.index("not ", index) == index
229
+ r4 = instantiate_node(SyntaxNode,input, index...(index + 4))
230
+ @index += 4
231
+ else
232
+ terminal_parse_failure("not ")
233
+ r4 = nil
234
+ end
235
+ if r4
236
+ r3 = r4
237
+ else
238
+ r3 = instantiate_node(SyntaxNode,input, index...index)
239
+ end
240
+ s0 << r3
241
+ if r3
242
+ r5 = _nt_value
243
+ s0 << r5
244
+ end
245
+ end
246
+ end
247
+ if s0.last
248
+ r0 = instantiate_node(SyntaxNode,input, i0...index, s0)
249
+ r0.extend(IsRelation0)
250
+ else
251
+ self.index = i0
252
+ r0 = nil
253
+ end
254
+
255
+ node_cache[:is_relation][start_index] = r0
256
+
257
+ return r0
258
+ end
259
+
260
+ module InRelation0
261
+ def expr
262
+ elements[0]
263
+ end
264
+
265
+ def range
266
+ elements[3]
267
+ end
268
+ end
269
+
270
+ def _nt_in_relation
271
+ start_index = index
272
+ if node_cache[:in_relation].has_key?(index)
273
+ cached = node_cache[:in_relation][index]
274
+ @index = cached.interval.end if cached
275
+ return cached
276
+ end
277
+
278
+ i0, s0 = index, []
279
+ r1 = _nt_expr
280
+ s0 << r1
281
+ if r1
282
+ if input.index(" not", index) == index
283
+ r3 = instantiate_node(SyntaxNode,input, index...(index + 4))
284
+ @index += 4
285
+ else
286
+ terminal_parse_failure(" not")
287
+ r3 = nil
288
+ end
289
+ if r3
290
+ r2 = r3
291
+ else
292
+ r2 = instantiate_node(SyntaxNode,input, index...index)
293
+ end
294
+ s0 << r2
295
+ if r2
296
+ if input.index(" in ", index) == index
297
+ r4 = instantiate_node(SyntaxNode,input, index...(index + 4))
298
+ @index += 4
299
+ else
300
+ terminal_parse_failure(" in ")
301
+ r4 = nil
302
+ end
303
+ s0 << r4
304
+ if r4
305
+ r5 = _nt_range
306
+ s0 << r5
307
+ end
308
+ end
309
+ end
310
+ if s0.last
311
+ r0 = instantiate_node(SyntaxNode,input, i0...index, s0)
312
+ r0.extend(InRelation0)
313
+ else
314
+ self.index = i0
315
+ r0 = nil
316
+ end
317
+
318
+ node_cache[:in_relation][start_index] = r0
319
+
320
+ return r0
321
+ end
322
+
323
+ module WithinRelation0
324
+ def expr
325
+ elements[0]
326
+ end
327
+
328
+ def range
329
+ elements[3]
330
+ end
331
+ end
332
+
333
+ def _nt_within_relation
334
+ start_index = index
335
+ if node_cache[:within_relation].has_key?(index)
336
+ cached = node_cache[:within_relation][index]
337
+ @index = cached.interval.end if cached
338
+ return cached
339
+ end
340
+
341
+ i0, s0 = index, []
342
+ r1 = _nt_expr
343
+ s0 << r1
344
+ if r1
345
+ if input.index(" not", index) == index
346
+ r3 = instantiate_node(SyntaxNode,input, index...(index + 4))
347
+ @index += 4
348
+ else
349
+ terminal_parse_failure(" not")
350
+ r3 = nil
351
+ end
352
+ if r3
353
+ r2 = r3
354
+ else
355
+ r2 = instantiate_node(SyntaxNode,input, index...index)
356
+ end
357
+ s0 << r2
358
+ if r2
359
+ if input.index(" within ", index) == index
360
+ r4 = instantiate_node(SyntaxNode,input, index...(index + 8))
361
+ @index += 8
362
+ else
363
+ terminal_parse_failure(" within ")
364
+ r4 = nil
365
+ end
366
+ s0 << r4
367
+ if r4
368
+ r5 = _nt_range
369
+ s0 << r5
370
+ end
371
+ end
372
+ end
373
+ if s0.last
374
+ r0 = instantiate_node(SyntaxNode,input, i0...index, s0)
375
+ r0.extend(WithinRelation0)
376
+ else
377
+ self.index = i0
378
+ r0 = nil
379
+ end
380
+
381
+ node_cache[:within_relation][start_index] = r0
382
+
383
+ return r0
384
+ end
385
+
386
+ module Expr0
387
+ def value
388
+ elements[1]
389
+ end
390
+ end
391
+
392
+ module Expr1
393
+ end
394
+
395
+ def _nt_expr
396
+ start_index = index
397
+ if node_cache[:expr].has_key?(index)
398
+ cached = node_cache[:expr][index]
399
+ @index = cached.interval.end if cached
400
+ return cached
401
+ end
402
+
403
+ i0, s0 = index, []
404
+ if input.index("n", index) == index
405
+ r1 = instantiate_node(SyntaxNode,input, index...(index + 1))
406
+ @index += 1
407
+ else
408
+ terminal_parse_failure("n")
409
+ r1 = nil
410
+ end
411
+ s0 << r1
412
+ if r1
413
+ i3, s3 = index, []
414
+ if input.index(" mod ", index) == index
415
+ r4 = instantiate_node(SyntaxNode,input, index...(index + 5))
416
+ @index += 5
417
+ else
418
+ terminal_parse_failure(" mod ")
419
+ r4 = nil
420
+ end
421
+ s3 << r4
422
+ if r4
423
+ r5 = _nt_value
424
+ s3 << r5
425
+ end
426
+ if s3.last
427
+ r3 = instantiate_node(SyntaxNode,input, i3...index, s3)
428
+ r3.extend(Expr0)
429
+ else
430
+ self.index = i3
431
+ r3 = nil
432
+ end
433
+ if r3
434
+ r2 = r3
435
+ else
436
+ r2 = instantiate_node(SyntaxNode,input, index...index)
437
+ end
438
+ s0 << r2
439
+ end
440
+ if s0.last
441
+ r0 = instantiate_node(SyntaxNode,input, i0...index, s0)
442
+ r0.extend(Expr1)
443
+ else
444
+ self.index = i0
445
+ r0 = nil
446
+ end
447
+
448
+ node_cache[:expr][start_index] = r0
449
+
450
+ return r0
451
+ end
452
+
453
+ module Range0
454
+ def value
455
+ elements[0]
456
+ end
457
+
458
+ def value
459
+ elements[2]
460
+ end
461
+ end
462
+
463
+ def _nt_range
464
+ start_index = index
465
+ if node_cache[:range].has_key?(index)
466
+ cached = node_cache[:range][index]
467
+ @index = cached.interval.end if cached
468
+ return cached
469
+ end
470
+
471
+ i0, s0 = index, []
472
+ r1 = _nt_value
473
+ s0 << r1
474
+ if r1
475
+ if input.index("..", index) == index
476
+ r2 = instantiate_node(SyntaxNode,input, index...(index + 2))
477
+ @index += 2
478
+ else
479
+ terminal_parse_failure("..")
480
+ r2 = nil
481
+ end
482
+ s0 << r2
483
+ if r2
484
+ r3 = _nt_value
485
+ s0 << r3
486
+ end
487
+ end
488
+ if s0.last
489
+ r0 = instantiate_node(SyntaxNode,input, i0...index, s0)
490
+ r0.extend(Range0)
491
+ else
492
+ self.index = i0
493
+ r0 = nil
494
+ end
495
+
496
+ node_cache[:range][start_index] = r0
497
+
498
+ return r0
499
+ end
500
+
501
+ def _nt_value
502
+ start_index = index
503
+ if node_cache[:value].has_key?(index)
504
+ cached = node_cache[:value][index]
505
+ @index = cached.interval.end if cached
506
+ return cached
507
+ end
508
+
509
+ s0, i0 = [], index
510
+ loop do
511
+ if input.index(Regexp.new('[0-9]'), index) == index
512
+ r1 = instantiate_node(SyntaxNode,input, index...(index + 1))
513
+ @index += 1
514
+ else
515
+ r1 = nil
516
+ end
517
+ if r1
518
+ s0 << r1
519
+ else
520
+ break
521
+ end
522
+ end
523
+ r0 = instantiate_node(SyntaxNode,input, i0...index, s0)
524
+
525
+ node_cache[:value][start_index] = r0
526
+
527
+ return r0
528
+ end
529
+ end
530
+ end
531
+
532
+ class Parser < Treetop::Runtime::CompiledParser
533
+ include Grammar
534
+ end
535
+ end
536
+ end
@@ -0,0 +1,113 @@
1
+ require 'rubygems'
2
+ require 'rexml/document'
3
+
4
+ class Cldr
5
+ module Data
6
+ class Plurals
7
+ class Rules < Array
8
+ class << self
9
+ def parse(xml)
10
+ rules = new
11
+ REXML::Document.new(xml).elements.each('//pluralRules') do |tag|
12
+ rule = Rule.new(tag.attributes['locales'].split(/\s+/))
13
+ tag.elements.each('pluralRule') { |tag| rule << [tag.attributes['count'], tag.text] }
14
+ rules << rule
15
+ end
16
+ rules
17
+ end
18
+ end
19
+
20
+ def locales
21
+ @locales ||= map { |rule| rule.locales }.flatten.map(&:to_s).sort.map(&:to_sym)
22
+ end
23
+
24
+ def rule(locale)
25
+ detect { |rule| rule.locales.include?(locale.to_sym) }
26
+ end
27
+
28
+ def to_ruby(options = {})
29
+ namespaces = options[:namespaces] || [:i18n]
30
+ code = locales.map do |locale|
31
+ rule = self.rule(locale)
32
+ ruby = "{ :plural => { :keys => #{rule.keys.inspect}, :rule => #{rule.to_ruby} } }"
33
+ ruby = namespaces.reverse.inject(ruby) { |ruby, namespace| "{ #{namespace.inspect} => #{ruby} }"}
34
+ "#{locale.inspect} => #{ruby}"
35
+ end.join(",\n")
36
+ code = code.split("\n").map { |line| " #{line}" }.join("\n")
37
+ "{\n" + code + "\n}"
38
+ end
39
+ end
40
+
41
+ class Rule < Array
42
+ class << self
43
+ def parse(code)
44
+ case code
45
+ when /and/
46
+ code.split(/and/).inject(Proposition.new('&&')) { |rule, code| rule << parse(code) }
47
+ when /or/
48
+ code.split(/or/).inject(Proposition.new('||')) { |rule, code| rule << parse(code) }
49
+ when /n( mod ([\d]+))? is (not )?([\d]+)/
50
+ Expression.new(:is, $2, !!$3, $4)
51
+ when /n( mod ([\d]+))?( not)? in ([\d]+\.\.[\d]+)/
52
+ Expression.new(:in, $2, !!$3, eval($4).to_a.inspect)
53
+ when /n/
54
+ Expression.new
55
+ else
56
+ raise "can not parse #{code}"
57
+ end
58
+ end
59
+ end
60
+
61
+ attr_reader :locales
62
+
63
+ def initialize(locales)
64
+ @locales = locales.map { |locale| locale.gsub('_', '-').to_sym }
65
+ end
66
+
67
+ def keys
68
+ inject([]) { |keys, (key, code)| keys << key.to_sym } << :other
69
+ end
70
+
71
+ def to_ruby
72
+ @condition ||= 'lambda { |n| ' + reverse.inject(':other') do |result, (key, code)|
73
+ code = self.class.parse(code).to_ruby
74
+ "#{code} ? :#{key} : #{result}"
75
+ end + ' }'
76
+ end
77
+ end
78
+
79
+ class Proposition < Array
80
+ def initialize(type = nil)
81
+ @type = type
82
+ end
83
+
84
+ def to_ruby
85
+ @ruby ||= map { |expr| expr.to_ruby }.join(" #{@type} ")
86
+ end
87
+ end
88
+
89
+ class Expression
90
+ attr_reader :operator, :operand, :mod, :negate
91
+
92
+ def initialize(operator = nil, mod = nil, negate = nil, operand = nil)
93
+ @operator, @mod, @negate, @operand = operator, mod, negate, operand
94
+ end
95
+
96
+ def to_ruby
97
+ @ruby ||= begin
98
+ op = 'n'
99
+ op << " % #{@mod}" if mod
100
+ case @operator
101
+ when :is
102
+ op + (@negate ? ' != ' : ' == ') + @operand
103
+ when :in
104
+ (@negate ? '!' : '') + "#{@operand}.include?(#{op})"
105
+ else
106
+ op
107
+ end
108
+ end
109
+ end
110
+ end
111
+ end
112
+ end
113
+ end
@@ -0,0 +1,39 @@
1
+ require 'fileutils'
2
+
3
+ class Cldr
4
+ module Data
5
+ class Plurals < String
6
+ autoload :Grammar, 'cldr/data/plurals/grammar'
7
+ autoload :Parser, 'cldr/data/plurals/grammar'
8
+ autoload :Rules, 'cldr/data/plurals/rules'
9
+ autoload :Rule, 'cldr/data/plurals/rules'
10
+ autoload :Proposition, 'cldr/data/plurals/rules'
11
+ autoload :Expression, 'cldr/data/plurals/rules'
12
+
13
+ class << self
14
+ def rules
15
+ @@rules ||= Rules.parse(source)
16
+ end
17
+
18
+ def source
19
+ File.read("#{Cldr::Data.dir}/supplemental/plurals.xml")
20
+ end
21
+ end
22
+
23
+ attr_reader :locale
24
+
25
+ def initialize(locale)
26
+ @locale = locale
27
+ super(rule ? ruby : "")
28
+ end
29
+
30
+ def ruby
31
+ "{ :#{locale} => { :i18n => {:plural => { :keys => #{rule.keys.inspect}, :rule => #{rule.to_ruby} } } } }"
32
+ end
33
+
34
+ def rule
35
+ @rule = Plurals.rules.rule(locale)
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,17 @@
1
+ class Cldr
2
+ module Data
3
+ class Territories < Base
4
+ def initialize(locale)
5
+ super
6
+ self[:territories] = territories
7
+ end
8
+
9
+ def territories
10
+ @territories ||= select('localeDisplayNames/territories/territory').inject({}) do |result, node|
11
+ result[node.attribute('type').value.to_sym] = node.content unless draft?(node)
12
+ result
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end