twitter_cldr 1.2.0 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (154) hide show
  1. data/README.md +34 -18
  2. data/lib/twitter_cldr.rb +15 -21
  3. data/lib/twitter_cldr/core_ext.rb +2 -1
  4. data/lib/twitter_cldr/core_ext/array.rb +22 -0
  5. data/lib/twitter_cldr/core_ext/numbers/localized_number.rb +0 -1
  6. data/lib/twitter_cldr/core_ext/string.rb +10 -2
  7. data/lib/twitter_cldr/formatters/calendars/datetime_formatter.rb +4 -1
  8. data/lib/twitter_cldr/formatters/numbers/currency_formatter.rb +7 -2
  9. data/lib/twitter_cldr/formatters/numbers/decimal_formatter.rb +5 -1
  10. data/lib/twitter_cldr/formatters/numbers/number_formatter.rb +1 -1
  11. data/lib/twitter_cldr/formatters/numbers/percent_formatter.rb +5 -3
  12. data/lib/twitter_cldr/formatters/plurals/rules.rb +9 -5
  13. data/lib/twitter_cldr/normalizers/nfkd.rb +3 -1
  14. data/lib/twitter_cldr/shared.rb +2 -0
  15. data/lib/twitter_cldr/shared/calendar.rb +64 -0
  16. data/lib/twitter_cldr/shared/currencies.rb +6 -2
  17. data/lib/twitter_cldr/shared/languages.rb +10 -6
  18. data/lib/twitter_cldr/shared/numbers.rb +26 -0
  19. data/lib/twitter_cldr/shared/resources.rb +26 -9
  20. data/lib/twitter_cldr/shared/unicode_data.rb +26 -6
  21. data/lib/twitter_cldr/tokenizers/calendars/datetime_tokenizer.rb +5 -3
  22. data/lib/twitter_cldr/tokenizers/numbers/number_tokenizer.rb +1 -1
  23. data/lib/twitter_cldr/version.rb +1 -1
  24. data/resources/{ar → locales/ar}/calendars.yml +30 -33
  25. data/resources/{ar → locales/ar}/languages.yml +120 -118
  26. data/resources/{ar → locales/ar}/numbers.yml +8 -9
  27. data/resources/{ar → locales/ar}/plurals.yml +0 -0
  28. data/resources/{da → locales/da}/calendars.yml +24 -9
  29. data/resources/{da → locales/da}/languages.yml +14 -8
  30. data/resources/{da → locales/da}/numbers.yml +1 -2
  31. data/resources/{da → locales/da}/plurals.yml +0 -0
  32. data/resources/{de → locales/de}/calendars.yml +42 -8
  33. data/resources/{de → locales/de}/languages.yml +47 -42
  34. data/resources/{de → locales/de}/numbers.yml +1 -2
  35. data/resources/{de → locales/de}/plurals.yml +0 -0
  36. data/resources/{en → locales/en}/calendars.yml +16 -7
  37. data/resources/{en → locales/en}/languages.yml +53 -5
  38. data/resources/{en → locales/en}/numbers.yml +1 -2
  39. data/resources/{en → locales/en}/plurals.yml +0 -0
  40. data/resources/{es → locales/es}/calendars.yml +29 -15
  41. data/resources/{es → locales/es}/languages.yml +7 -5
  42. data/resources/{es → locales/es}/numbers.yml +3 -3
  43. data/resources/{es → locales/es}/plurals.yml +0 -0
  44. data/resources/{fa → locales/fa}/calendars.yml +87 -18
  45. data/resources/{fa → locales/fa}/languages.yml +13 -9
  46. data/resources/locales/fa/numbers.yml +29 -0
  47. data/resources/{fa → locales/fa}/plurals.yml +0 -0
  48. data/resources/{fi → locales/fi}/calendars.yml +64 -14
  49. data/resources/{fi → locales/fi}/languages.yml +47 -36
  50. data/resources/{fi → locales/fi}/numbers.yml +1 -2
  51. data/resources/{fi → locales/fi}/plurals.yml +0 -0
  52. data/resources/{fil → locales/fil}/calendars.yml +32 -23
  53. data/resources/{fil → locales/fil}/languages.yml +75 -22
  54. data/resources/{fil → locales/fil}/numbers.yml +1 -2
  55. data/resources/{fil → locales/fil}/plurals.yml +0 -0
  56. data/resources/{fr → locales/fr}/calendars.yml +54 -12
  57. data/resources/{fr → locales/fr}/languages.yml +5 -2
  58. data/resources/{fr → locales/fr}/numbers.yml +1 -2
  59. data/resources/{fr → locales/fr}/plurals.yml +0 -0
  60. data/resources/{he → locales/he}/calendars.yml +74 -38
  61. data/resources/{he → locales/he}/languages.yml +41 -26
  62. data/resources/{he → locales/he}/numbers.yml +1 -2
  63. data/resources/{he → locales/he}/plurals.yml +0 -0
  64. data/resources/{hi → locales/hi}/calendars.yml +36 -42
  65. data/resources/{hi → locales/hi}/languages.yml +8 -3
  66. data/resources/{hi → locales/hi}/numbers.yml +1 -2
  67. data/resources/{hi → locales/hi}/plurals.yml +0 -0
  68. data/resources/{hu → locales/hu}/calendars.yml +95 -19
  69. data/resources/{hu → locales/hu}/languages.yml +15 -4
  70. data/resources/{hu → locales/hu}/numbers.yml +1 -2
  71. data/resources/{hu → locales/hu}/plurals.yml +0 -0
  72. data/resources/{id → locales/id}/calendars.yml +56 -39
  73. data/resources/{id → locales/id}/languages.yml +148 -141
  74. data/resources/{id → locales/id}/numbers.yml +1 -2
  75. data/resources/{id → locales/id}/plurals.yml +0 -0
  76. data/resources/{it → locales/it}/calendars.yml +51 -15
  77. data/resources/{it → locales/it}/languages.yml +5 -5
  78. data/resources/{it → locales/it}/numbers.yml +2 -2
  79. data/resources/{it → locales/it}/plurals.yml +0 -0
  80. data/resources/{ja → locales/ja}/calendars.yml +26 -36
  81. data/resources/{ja → locales/ja}/languages.yml +29 -16
  82. data/resources/{ja → locales/ja}/numbers.yml +2 -3
  83. data/resources/{ja → locales/ja}/plurals.yml +0 -0
  84. data/resources/{ko → locales/ko}/calendars.yml +18 -9
  85. data/resources/{ko → locales/ko}/languages.yml +13 -10
  86. data/resources/{ko → locales/ko}/numbers.yml +1 -2
  87. data/resources/{ko → locales/ko}/plurals.yml +0 -0
  88. data/resources/{ms → locales/ms}/calendars.yml +91 -53
  89. data/resources/locales/ms/languages.yml +157 -0
  90. data/resources/{ms → locales/ms}/numbers.yml +1 -2
  91. data/resources/{ms → locales/ms}/plurals.yml +0 -0
  92. data/resources/{nl → locales/nl}/calendars.yml +38 -9
  93. data/resources/{nl → locales/nl}/languages.yml +28 -21
  94. data/resources/{nl → locales/nl}/numbers.yml +1 -2
  95. data/resources/{nl → locales/nl}/plurals.yml +0 -0
  96. data/resources/{no → locales/no}/calendars.yml +11 -6
  97. data/resources/{no → locales/no}/languages.yml +0 -0
  98. data/resources/{no → locales/no}/numbers.yml +1 -2
  99. data/resources/{no → locales/no}/plurals.yml +0 -0
  100. data/resources/{pl → locales/pl}/calendars.yml +80 -15
  101. data/resources/{pl → locales/pl}/languages.yml +6 -6
  102. data/resources/{pl → locales/pl}/numbers.yml +3 -2
  103. data/resources/{pl → locales/pl}/plurals.yml +0 -0
  104. data/resources/{pt → locales/pt}/calendars.yml +34 -8
  105. data/resources/{pt → locales/pt}/languages.yml +12 -4
  106. data/resources/{pt → locales/pt}/numbers.yml +1 -2
  107. data/resources/{pt → locales/pt}/plurals.yml +0 -0
  108. data/resources/{ru → locales/ru}/calendars.yml +69 -30
  109. data/resources/{ru → locales/ru}/languages.yml +18 -16
  110. data/resources/{ru → locales/ru}/numbers.yml +2 -3
  111. data/resources/{ru → locales/ru}/plurals.yml +0 -0
  112. data/resources/{sv → locales/sv}/calendars.yml +95 -15
  113. data/resources/{sv → locales/sv}/languages.yml +30 -8
  114. data/resources/{sv → locales/sv}/numbers.yml +1 -2
  115. data/resources/{sv → locales/sv}/plurals.yml +0 -0
  116. data/resources/{th → locales/th}/calendars.yml +89 -64
  117. data/resources/{th → locales/th}/languages.yml +5 -3
  118. data/resources/{th → locales/th}/numbers.yml +1 -2
  119. data/resources/{th → locales/th}/plurals.yml +0 -0
  120. data/resources/{tr → locales/tr}/calendars.yml +93 -19
  121. data/resources/{tr → locales/tr}/languages.yml +30 -28
  122. data/resources/{tr → locales/tr}/numbers.yml +2 -3
  123. data/resources/{tr → locales/tr}/plurals.yml +0 -0
  124. data/resources/{ur → locales/ur}/calendars.yml +33 -37
  125. data/resources/locales/ur/languages.yml +163 -0
  126. data/resources/{ur → locales/ur}/numbers.yml +1 -2
  127. data/resources/{ur → locales/ur}/plurals.yml +0 -0
  128. data/resources/{zh-Hant → locales/zh-Hant}/calendars.yml +76 -44
  129. data/resources/{zh-Hant → locales/zh-Hant}/languages.yml +122 -22
  130. data/resources/{zh-Hant → locales/zh-Hant}/numbers.yml +3 -4
  131. data/resources/{zh → locales/zh}/calendars.yml +81 -24
  132. data/resources/{zh → locales/zh}/languages.yml +13 -14
  133. data/resources/{zh → locales/zh}/numbers.yml +1 -2
  134. data/resources/{zh → locales/zh}/plurals.yml +0 -0
  135. data/spec/core_ext/array_spec.rb +16 -0
  136. data/spec/core_ext/calendars/date_spec.rb +6 -1
  137. data/spec/core_ext/calendars/datetime_spec.rb +6 -1
  138. data/spec/core_ext/calendars/time_spec.rb +6 -1
  139. data/spec/core_ext/numbers/localized_number_spec.rb +38 -8
  140. data/spec/core_ext/string_spec.rb +14 -1
  141. data/spec/formatters/numbers/number_formatter_spec.rb +3 -3
  142. data/spec/formatters/plurals/rules_spec.rb +3 -3
  143. data/spec/readme_spec.rb +190 -0
  144. data/spec/shared/calendar_spec.rb +133 -0
  145. data/spec/shared/numbers_spec.rb +35 -0
  146. data/spec/shared/resources_spec.rb +33 -15
  147. data/spec/tokenizers/calendars/date_tokenizer_spec.rb +37 -26
  148. data/spec/tokenizers/calendars/datetime_tokenizer_spec.rb +36 -29
  149. data/spec/tokenizers/calendars/time_tokenizer_spec.rb +22 -18
  150. data/spec/twitter_cldr_spec.rb +21 -7
  151. metadata +166 -114
  152. data/resources/fa/numbers.yml +0 -30
  153. data/resources/ms/languages.yml +0 -54
  154. data/resources/ur/languages.yml +0 -81
data/README.md CHANGED
@@ -48,9 +48,9 @@ Fixnum, Bignum, and Float objects are supported. Here are some examples:
48
48
  1337.localize(:es).to_s # 1.337
49
49
 
50
50
  # currencies, default USD
51
- 1337.localize(:es).to_currency.to_s # $1.337,00
52
- 1337.localize(:es).to_currency.to_s(:currency => "EUR") # 1.337,00
53
- 1337.localize(:es).to_currency.to_s(:currency => "Peru") # S/. 1.337,00
51
+ 1337.localize(:es).to_currency.to_s # 1.337,00 $
52
+ 1337.localize(:es).to_currency.to_s(:currency => "EUR") # 1.337,00
53
+ 1337.localize(:es).to_currency.to_s(:currency => "Peru") # 1.337,00 S/.
54
54
 
55
55
  # percentages
56
56
  1337.localize(:es).to_percent.to_s # 1.337%
@@ -92,10 +92,10 @@ TwitterCldr::Shared::Currencies.for_code("CAD") # { :currency => "Dol
92
92
  Date, Time, and DateTime objects are supported:
93
93
 
94
94
  ```ruby
95
- DateTime.now.localize(:es).to_full_s # "21:44:57 UTC -0800 lunes 12 de diciembre de 2011"
96
- DateTime.now.localize(:es).to_long_s # "21:45:42 -08:00 12 de diciembre de 2011"
97
- DateTime.now.localize(:es).to_medium_s # "21:46:09 12/12/2011"
98
- DateTime.now.localize(:es).to_short_s # "21:47 12/12/11"
95
+ DateTime.now.localize(:es).to_full_s # "lunes, 12 de diciembre de 2011 21:44:57 UTC -0800"
96
+ DateTime.now.localize(:es).to_long_s # "12 de diciembre de 2011 21:44:57 -08:00"
97
+ DateTime.now.localize(:es).to_medium_s # "12/12/2011 21:44:57"
98
+ DateTime.now.localize(:es).to_short_s # "12/12/11 21:44"
99
99
 
100
100
  Date.today.localize(:es).to_full_s # "lunes 12 de diciembre de 2011"
101
101
  Date.today.localize(:es).to_long_s # "12 de diciembre de 2011"
@@ -103,9 +103,9 @@ Date.today.localize(:es).to_medium_s # "12/12/2011"
103
103
  Date.today.localize(:es).to_short_s # "12/12/11"
104
104
 
105
105
  Time.now.localize(:es).to_full_s # "21:44:57 UTC -0800"
106
- Time.now.localize(:es).to_long_s # "21:45:42 -08:00"
107
- Time.now.localize(:es).to_medium_s # "21:46:09"
108
- Time.now.localize(:es).to_short_s # "21:47"
106
+ Time.now.localize(:es).to_long_s # "21:44:57 UTC"
107
+ Time.now.localize(:es).to_medium_s # "21:44:57"
108
+ Time.now.localize(:es).to_short_s # "21:44"
109
109
  ```
110
110
 
111
111
  The CLDR data set only includes 4 specific date formats, full, long, medium, and short, so you'll have to choose amongst them for the one that best fits your needs. Yes, it's limiting, but the 4 formats get the job done most of the time :)
@@ -183,7 +183,7 @@ The `LocalizedString` class supports all forms of interpolation and combines sup
183
183
  "five euros plus %.3f in tax" % (13.25 * 0.087)
184
184
 
185
185
  # Ruby 1.9
186
- "five euros plus %3.f in tax" % (13.25 * 0.087)
186
+ "five euros plus %.3f in tax" % (13.25 * 0.087)
187
187
  "there are %{count} horses in the barn" % { :count => "5" }
188
188
 
189
189
  # with TwitterCLDR
@@ -251,34 +251,50 @@ code_point.combining_class # "0"
251
251
  Convert characters to code points:
252
252
 
253
253
  ```ruby
254
- TwitterCldr::Normalizers::Base.char_to_code_point("¿") # "00BF"
254
+ TwitterCldr::Utils::CodePoints.from_string("¿") # ["00BF"]
255
255
  ```
256
256
 
257
257
  Convert code points to characters:
258
258
 
259
259
  ```ruby
260
- TwitterCldr::Normalizers::Base.code_point_to_char("00BF") # "¿"
260
+ TwitterCldr::Utils::CodePoints.to_string(["00BF"]) # "¿"
261
261
  ```
262
262
 
263
- Normalize/decompose a Unicode string (NFD only for now). Note that the normalized/decomposed string will almost always look the same as the original string because most character display systems automatically combine decomposed characters.
263
+ Normalize/decompose a Unicode string (NFD, NFKD implementations available). Note that the normalized string will almost always look the same as the original string because most character display systems automatically combine decomposed characters.
264
264
 
265
265
  ```ruby
266
266
  TwitterCldr::Normalizers::NFD.normalize("français") # "français"
267
- TwitterCldr::Normalizers::NFD.decompose("español") # "español"
268
267
  ```
269
268
 
270
- Normalization and decomposition are easier to see in hex:
269
+ Normalization is easier to see in hex:
271
270
 
272
271
  ```ruby
273
272
  # ["0065", "0073", "0070", "0061", "00F1", "006F", "006C"]
274
- code_points = "español".split('').map { |char| TwitterCldr::Normalizers::NFD.char_to_code_point(char) }
273
+ TwitterCldr::Utils::CodePoints.from_string("español")
275
274
 
276
275
  # ["0065", "0073", "0070", "0061", "006E", "0303", "006F", "006C"]
277
- TwitterCldr::Normalizers::NFD.normalize_code_points(code_points)
276
+ TwitterCldr::Utils::CodePoints.from_string(TwitterCldr::Normalizers::NFD.normalize("español"))
278
277
  ```
279
278
 
280
279
  Notice in the example above that the letter "ñ" was transformed from `00F1` to `006E 0303`, which represent the "n" and the "˜" respectively.
281
280
 
281
+ A few convenience methods also exist for `String` that make it easy to normalize and get code points for strings:
282
+
283
+ ```ruby
284
+ # ["0065", "0073", "0070", "0061", "00F1", "006F", "006C"]
285
+ "español".localize.code_points
286
+
287
+ # ["0065", "0073", "0070", "0061", "006E", "0303", "006F", "006C"]
288
+ "español".localize.normalize.code_points
289
+ ```
290
+
291
+ Specify a specific normalization algorithm via the :using option. Currently, only NFD and NFKD are supported (default is NFD):
292
+
293
+ ```ruby
294
+ # ["0065", "0073", "0070", "0061", "006E", "0303", "006F", "006C"]
295
+ "español".localize.normalize(:using => :NFKD).code_points
296
+ ```
297
+
282
298
  ## About Twitter-specific Locales
283
299
 
284
300
  Twitter tries to always use BCP-47 language codes. Data from the CLDR doesn't always match those codes, so TwitterCLDR provides a `convert_locale` method to convert between the two. All functionality throughout the entire gem defers to `convert_locale` before retrieving CLDR data. `convert_locale` supports Twitter-supported BCP-47 language codes as well as CLDR locale codes, so you don't have to guess which one to use. Here are a few examples:
data/lib/twitter_cldr.rb CHANGED
@@ -24,27 +24,28 @@ module TwitterCldr
24
24
 
25
25
  extend SingleForwardable
26
26
 
27
+ # version of CLDR that was used for generating YAML files in the resources/ directory
28
+ CLDR_VERSION = '21.0' # release date: 2012-02-10
29
+
27
30
  DEFAULT_LOCALE = :en
28
31
  DEFAULT_CALENDAR_TYPE = :gregorian
29
- RESOURCE_DIR = File.join(File.dirname(File.dirname(File.expand_path(__FILE__))), "resources")
30
32
 
31
- # maps twitter locales to cldr locales
32
- TWITTER_LOCALE_MAP = { :msa => :ms,
33
- :'zh-cn' => :zh,
34
- :'zh-tw' => :'zh-Hant' }
33
+ RESOURCES_DIR = File.join(File.dirname(File.dirname(File.expand_path(__FILE__))), 'resources')
35
34
 
36
- @@resources = TwitterCldr::Shared::Resources.new
35
+ # maps twitter locales to cldr locales
36
+ TWITTER_LOCALE_MAP = {
37
+ :msa => :ms,
38
+ :'zh-cn' => :zh,
39
+ :'zh-tw' => :'zh-Hant'
40
+ }
37
41
 
38
- def_delegator :resources, :resource_for, :get_resource
42
+ def_delegator :resources, :get_resource
43
+ def_delegator :resources, :get_locale_resource
39
44
 
40
45
  class << self
41
46
 
42
- def get_resource_file(locale, resource)
43
- File.join(RESOURCE_DIR, convert_locale(locale).to_s, "#{resource}.yml")
44
- end
45
-
46
47
  def resources
47
- @@resources
48
+ @resources ||= TwitterCldr::Shared::Resources.new
48
49
  end
49
50
 
50
51
  def get_locale
@@ -60,18 +61,11 @@ module TwitterCldr
60
61
 
61
62
  def convert_locale(locale)
62
63
  locale = locale.to_sym
63
- TWITTER_LOCALE_MAP.include?(locale) ? TWITTER_LOCALE_MAP[locale] : locale
64
+ TWITTER_LOCALE_MAP.fetch(locale, locale)
64
65
  end
65
66
 
66
67
  def supported_locales
67
- unless defined?(@@supported_locales)
68
- rejectable = [:shared]
69
- @@supported_locales = Dir.glob(File.join(File.dirname(File.dirname(__FILE__)), "resources/*")).map do |file|
70
- File.basename(file).to_sym
71
- end.reject { |file| rejectable.include?(file) }
72
- end
73
-
74
- @@supported_locales
68
+ @supported_locales ||= Dir.glob(File.join(RESOURCES_DIR, 'locales', '*')).map { |f| File.basename(f).to_sym }
75
69
  end
76
70
 
77
71
  def supported_locale?(locale)
@@ -7,4 +7,5 @@ require 'twitter_cldr/core_ext/numbers/bignum'
7
7
  require 'twitter_cldr/core_ext/numbers/fixnum'
8
8
  require 'twitter_cldr/core_ext/numbers/float'
9
9
  require 'twitter_cldr/core_ext/symbol'
10
- require 'twitter_cldr/core_ext/string'
10
+ require 'twitter_cldr/core_ext/string'
11
+ require 'twitter_cldr/core_ext/array'
@@ -0,0 +1,22 @@
1
+ # encoding: UTF-8
2
+
3
+ # Copyright 2012 Twitter, Inc
4
+ # http://www.apache.org/licenses/LICENSE-2.0
5
+
6
+ class Array
7
+ def localize(locale = TwitterCldr.get_locale)
8
+ TwitterCldr::LocalizedArray.new(self, locale)
9
+ end
10
+ end
11
+
12
+ module TwitterCldr
13
+ class LocalizedArray < LocalizedObject
14
+ def code_points_to_string
15
+ TwitterCldr::Utils::CodePoints.to_string(self.base_obj)
16
+ end
17
+
18
+ def formatter_const
19
+ nil
20
+ end
21
+ end
22
+ end
@@ -33,7 +33,6 @@ module TwitterCldr
33
33
  end
34
34
 
35
35
  def to_s(options = {})
36
- options = { :precision => 0 }.merge(options) if @base_obj.is_a?(Fixnum)
37
36
  @formatter.format(@base_obj, options)
38
37
  end
39
38
 
@@ -11,6 +11,7 @@ end
11
11
 
12
12
  module TwitterCldr
13
13
  class LocalizedString < LocalizedObject
14
+ VALID_NORMALIZERS = [:NFD, :NFKD]
14
15
 
15
16
  # Uses wrapped string object as a format specification and returns the result of applying it to +args+ (see
16
17
  # +TwitterCldr::Utils.interpolate+ method for interpolation syntax).
@@ -27,8 +28,15 @@ module TwitterCldr
27
28
  TwitterCldr::Formatters::PluralFormatter
28
29
  end
29
30
 
30
- def normalize
31
- LocalizedString.new(TwitterCldr::Normalizers::NFD.normalize(@base_obj), @locale)
31
+ def normalize(options = {})
32
+ options[:using] ||= :NFD
33
+
34
+ if VALID_NORMALIZERS.include?(options[:using])
35
+ normalizer_const = TwitterCldr::Normalizers.const_get(options[:using])
36
+ LocalizedString.new(normalizer_const.normalize(@base_obj), @locale)
37
+ else
38
+ raise ArgumentError.new("Invalid normalization form specified with :using option. Choices are [#{VALID_NORMALIZERS.map(&:to_s).join(", ")}]")
39
+ end
32
40
  end
33
41
 
34
42
  def code_points
@@ -169,7 +169,10 @@ module TwitterCldr
169
169
  end
170
170
 
171
171
  def period(time, pattern, length)
172
- @tokenizer.calendar[:periods][time.strftime('%p').downcase.to_sym]
172
+ # Always use :wide form. Day-period design was changed in CLDR -
173
+ # http://cldr.unicode.org/development/development-process/design-proposals/day-period-design that means some
174
+ # major changes are required for a full support of day periods.
175
+ @tokenizer.calendar[:periods][:format][:wide][time.strftime('%p').downcase.to_sym]
173
176
  end
174
177
 
175
178
  def hour(time, pattern, length)
@@ -6,8 +6,8 @@
6
6
  module TwitterCldr
7
7
  module Formatters
8
8
  class CurrencyFormatter < NumberFormatter
9
- DEFAULT_FORMAT_OPTIONS = { :precision => 2 }
10
9
  DEFAULT_CURRENCY_SYMBOL = "$"
10
+ DEFAULT_PRECISION = 2
11
11
 
12
12
  def initialize(options = {})
13
13
  @tokenizer = TwitterCldr::Tokenizers::NumberTokenizer.new(:locale => self.extract_locale(options), :type => :currency)
@@ -23,7 +23,12 @@ module TwitterCldr
23
23
  currency = { :symbol => DEFAULT_CURRENCY_SYMBOL }
24
24
  end
25
25
 
26
- super(number, DEFAULT_FORMAT_OPTIONS.merge(options)).gsub('¤', currency[:symbol])
26
+ super(number, options).gsub('¤', currency[:symbol])
27
+ end
28
+
29
+ def default_format_options_for(number)
30
+ precision = precision_from(number)
31
+ { :precision => precision == 0 ? DEFAULT_PRECISION : precision }
27
32
  end
28
33
  end
29
34
  end
@@ -12,11 +12,15 @@ module TwitterCldr
12
12
  end
13
13
 
14
14
  def format(number, options = {})
15
- super(Float(number), options)
15
+ super(number, options)
16
16
  rescue TypeError, ArgumentError
17
17
  number
18
18
  end
19
19
 
20
+ def default_format_options_for(number)
21
+ { :precision => precision_from(number) }
22
+ end
23
+
20
24
  protected
21
25
 
22
26
  def get_tokens(obj, options = {})
@@ -15,7 +15,7 @@ module TwitterCldr
15
15
  end
16
16
 
17
17
  def format(number, options = {})
18
- opts = { :precision => precision_from(number) }.merge(options)
18
+ opts = self.default_format_options_for(number).merge(options)
19
19
  prefix, suffix, integer_format, fraction_format = *partition_tokens(self.get_tokens(number, opts))
20
20
  int, fraction = parse_number(number, opts)
21
21
 
@@ -7,7 +7,6 @@ module TwitterCldr
7
7
  module Formatters
8
8
  class PercentFormatter < NumberFormatter
9
9
  DEFAULT_PERCENT_SIGN = "%"
10
- DEFAULT_FORMAT_OPTIONS = { :precision => 0 }
11
10
 
12
11
  def initialize(options = {})
13
12
  @tokenizer = TwitterCldr::Tokenizers::NumberTokenizer.new(:locale => self.extract_locale(options), :type => :percent)
@@ -15,8 +14,11 @@ module TwitterCldr
15
14
  end
16
15
 
17
16
  def format(number, options = {})
18
- opts = DEFAULT_FORMAT_OPTIONS.merge(options)
19
- super(number, opts).gsub('¤', @tokenizer.symbols[:percent_sign] || DEFAULT_PERCENT_SIGN)
17
+ super(number, options).gsub('¤', @tokenizer.symbols[:percent_sign] || DEFAULT_PERCENT_SIGN)
18
+ end
19
+
20
+ def default_format_options_for(number)
21
+ { :precision => 0 }
20
22
  end
21
23
  end
22
24
  end
@@ -6,20 +6,22 @@
6
6
  module TwitterCldr
7
7
  module Formatters
8
8
  module Plurals
9
- class Rules
9
+ module Rules
10
+
10
11
  class << self
12
+
11
13
  def all
12
- all_for(TwitterCldr::get_locale)
14
+ all_for(TwitterCldr.get_locale)
13
15
  end
14
16
 
15
17
  def all_for(locale)
16
18
  locale = TwitterCldr.convert_locale(locale.to_sym)
17
19
  get_resource(locale)[locale][:i18n][:plural][:keys]
18
20
  rescue
19
- []
21
+ nil
20
22
  end
21
23
 
22
- def rule_for(number, locale = TwitterCldr::get_locale)
24
+ def rule_for(number, locale = TwitterCldr.get_locale)
23
25
  locale = TwitterCldr.convert_locale(locale.to_sym)
24
26
  get_resource(locale)[locale][:i18n][:plural][:rule].call(number)
25
27
  rescue
@@ -30,9 +32,11 @@ module TwitterCldr
30
32
 
31
33
  def get_resource(locale)
32
34
  locale = TwitterCldr.convert_locale(locale)
33
- eval(TwitterCldr.get_resource(locale, "plurals")[locale])
35
+ eval(TwitterCldr.get_locale_resource(locale, :plurals)[locale])
34
36
  end
37
+
35
38
  end
39
+
36
40
  end
37
41
  end
38
42
  end
@@ -114,7 +114,9 @@ module TwitterCldr
114
114
  result.map { |cp_with_cc| cp_with_cc[0] }
115
115
  end
116
116
 
117
- # Performs stable sorting of a sequence of [code_point, combining_class] pairs.
117
+ # Performs stable sorting of a sequence of [code_point, combining_class] pairs. For sorting a regular bubble
118
+ # sort is used (with a small optimization that stops the algorithm if none of the elements were swapped during
119
+ # the iteration).
118
120
  #
119
121
  def stable_sort(code_points_with_cc)
120
122
  n = code_points_with_cc.size - 2
@@ -5,8 +5,10 @@
5
5
 
6
6
  module TwitterCldr
7
7
  module Shared
8
+ autoload :Calendar, 'twitter_cldr/shared/calendar'
8
9
  autoload :Currencies, 'twitter_cldr/shared/currencies'
9
10
  autoload :Languages, 'twitter_cldr/shared/languages'
11
+ autoload :Numbers, 'twitter_cldr/shared/numbers'
10
12
  autoload :Resources, 'twitter_cldr/shared/resources'
11
13
  autoload :UnicodeData, 'twitter_cldr/shared/unicode_data'
12
14
  end
@@ -0,0 +1,64 @@
1
+ # encoding: UTF-8
2
+
3
+ # Copyright 2012 Twitter, Inc
4
+ # http://www.apache.org/licenses/LICENSE-2.0
5
+
6
+ module TwitterCldr
7
+ module Shared
8
+ class Calendar
9
+
10
+ DEFAULT_FORMAT = :'stand-alone'
11
+
12
+ NAMES_FORMS = [:wide, :narrow, :abbreviated]
13
+
14
+ attr_reader :locale, :calendar_type
15
+
16
+ def initialize(locale = TwitterCldr.get_locale, calendar_type = TwitterCldr::DEFAULT_CALENDAR_TYPE)
17
+ @locale = TwitterCldr.convert_locale(locale)
18
+ @calendar_type = calendar_type
19
+ end
20
+
21
+ def months(names_form = :wide)
22
+ data = get_with_names_form(:months, names_form)
23
+ data && data.sort_by{ |m| m.first }.map { |m| m.last }
24
+ end
25
+
26
+ def weekdays(names_form = :wide)
27
+ get_with_names_form(:days, names_form)
28
+ end
29
+
30
+ private
31
+
32
+ def get_with_names_form(data_type, names_form)
33
+ get_data(data_type, DEFAULT_FORMAT, names_form) if NAMES_FORMS.include?(names_form.to_sym)
34
+ end
35
+
36
+ def get_data(*path)
37
+ data = traverse_path(calendar_data, path)
38
+ redirect = parse_redirect(data)
39
+ redirect ? get_data(*redirect) : data
40
+ end
41
+
42
+ def traverse_path(tree, path)
43
+ !path.empty? && tree.is_a?(Hash) ? traverse_path(tree[path.first], path[1..-1]) : tree
44
+ end
45
+
46
+ def parse_redirect(data)
47
+ $1.split('.').map(&:to_sym) if data.is_a?(Symbol) && data.to_s =~ redirect_regexp
48
+ end
49
+
50
+ def redirect_regexp
51
+ Regexp.new("^calendars\.#{calendar_type}\.(.*)$")
52
+ end
53
+
54
+ def calendar_data
55
+ @calendar_data ||= traverse_path(resource, [locale, :calendars, calendar_type])
56
+ end
57
+
58
+ def resource
59
+ TwitterCldr.get_locale_resource(@locale, :calendars)
60
+ end
61
+
62
+ end
63
+ end
64
+ end