twitter_cldr 1.5.0 → 1.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (203) hide show
  1. data/Gemfile +32 -0
  2. data/History.txt +78 -0
  3. data/README.md +72 -62
  4. data/Rakefile +22 -0
  5. data/js/lib/compiler.rb +40 -0
  6. data/js/lib/mustache/bundle.coffee +14 -0
  7. data/js/lib/mustache/calendars/datetime.coffee +240 -0
  8. data/js/lib/mustache/calendars/timespan.coffee +52 -0
  9. data/js/lib/mustache/plurals/rules.coffee +14 -0
  10. data/js/lib/renderers/base.rb +18 -0
  11. data/js/lib/renderers/bundle.rb +18 -0
  12. data/js/lib/renderers/calendars/datetime_renderer.rb +34 -0
  13. data/js/lib/renderers/calendars/timespan_renderer.rb +39 -0
  14. data/js/lib/renderers/plurals/rules/plural_rules_compiler.rb +89 -0
  15. data/js/lib/renderers/plurals/rules/plural_rules_renderer.rb +26 -0
  16. data/js/lib/twitter_cldr_js.rb +85 -0
  17. data/js/spec/js/calendars/datetime_spec.js +418 -0
  18. data/js/spec/js/calendars/timespan_spec.js +91 -0
  19. data/js/spec/js/plurals/plural_rules_spec.js +28 -0
  20. data/js/spec/js/support/jasmine.yml +8 -0
  21. data/js/spec/rb/renderers/plurals/plural_rules_compiler_spec.rb +52 -0
  22. data/js/spec/rb/spec_helper.rb +13 -0
  23. data/lib/twitter_cldr.rb +2 -1
  24. data/lib/twitter_cldr/collation.rb +2 -1
  25. data/lib/twitter_cldr/collation/collator.rb +49 -31
  26. data/lib/twitter_cldr/collation/{sort_key.rb → sort_key_builder.rb} +31 -8
  27. data/lib/twitter_cldr/collation/trie.rb +116 -24
  28. data/lib/twitter_cldr/collation/trie_builder.rb +54 -28
  29. data/lib/twitter_cldr/collation/trie_with_fallback.rb +55 -0
  30. data/lib/twitter_cldr/core_ext/array.rb +14 -1
  31. data/lib/twitter_cldr/core_ext/calendars/datetime.rb +8 -2
  32. data/lib/twitter_cldr/core_ext/calendars/timespan.rb +5 -5
  33. data/lib/twitter_cldr/formatters/calendars/timespan_formatter.rb +10 -10
  34. data/lib/twitter_cldr/formatters/plurals/rules.rb +3 -5
  35. data/lib/twitter_cldr/resources.rb +11 -0
  36. data/lib/twitter_cldr/resources/import.rb +12 -0
  37. data/lib/twitter_cldr/resources/import/tailoring.rb +193 -0
  38. data/lib/twitter_cldr/{shared/resources.rb → resources/loader.rb} +17 -4
  39. data/lib/twitter_cldr/shared.rb +0 -1
  40. data/lib/twitter_cldr/tokenizers/base.rb +9 -9
  41. data/lib/twitter_cldr/tokenizers/calendars/datetime_tokenizer.rb +0 -4
  42. data/lib/twitter_cldr/tokenizers/calendars/timespan_tokenizer.rb +21 -7
  43. data/lib/twitter_cldr/utils.rb +11 -0
  44. data/lib/twitter_cldr/version.rb +1 -1
  45. data/resources/collation/tailoring/af.yml +3 -0
  46. data/resources/collation/tailoring/ar.yml +21 -0
  47. data/resources/collation/tailoring/ca.yml +9 -0
  48. data/resources/collation/tailoring/cs.yml +25 -0
  49. data/resources/collation/tailoring/da.yml +59 -0
  50. data/resources/collation/tailoring/de.yml +3 -0
  51. data/resources/collation/tailoring/el.yml +3 -0
  52. data/resources/collation/tailoring/en.yml +3 -0
  53. data/resources/collation/tailoring/es.yml +5 -0
  54. data/resources/collation/tailoring/eu.yml +3 -0
  55. data/resources/collation/tailoring/fa.yml +73 -0
  56. data/resources/collation/tailoring/fi.yml +61 -0
  57. data/resources/collation/tailoring/fil.yml +11 -0
  58. data/resources/collation/tailoring/fr.yml +3 -0
  59. data/resources/collation/tailoring/he.yml +3 -0
  60. data/resources/collation/tailoring/hi.yml +7 -0
  61. data/resources/collation/tailoring/hu.yml +125 -0
  62. data/resources/collation/tailoring/id.yml +3 -0
  63. data/resources/collation/tailoring/it.yml +3 -0
  64. data/resources/collation/tailoring/ja.yml +14647 -0
  65. data/resources/collation/tailoring/ko.yml +14953 -0
  66. data/resources/collation/tailoring/ms.yml +3 -0
  67. data/resources/collation/tailoring/nb.yml +59 -0
  68. data/resources/collation/tailoring/nl.yml +3 -0
  69. data/resources/collation/tailoring/pl.yml +37 -0
  70. data/resources/collation/tailoring/pt.yml +3 -0
  71. data/resources/collation/tailoring/ru.yml +3 -0
  72. data/resources/collation/tailoring/sv.yml +63 -0
  73. data/resources/collation/tailoring/th.yml +19 -0
  74. data/resources/collation/tailoring/tr.yml +27 -0
  75. data/resources/collation/tailoring/uk.yml +5 -0
  76. data/resources/collation/tailoring/ur.yml +163 -0
  77. data/resources/collation/tailoring/zh-Hant.yml +3 -0
  78. data/resources/collation/tailoring/zh.yml +149 -0
  79. data/resources/custom/locales/af/units.yml +19 -0
  80. data/resources/custom/locales/ar/units.yml +35 -0
  81. data/resources/custom/locales/ca/units.yml +19 -0
  82. data/resources/custom/locales/cs/units.yml +23 -0
  83. data/resources/custom/locales/da/units.yml +19 -0
  84. data/resources/custom/locales/de/units.yml +19 -0
  85. data/resources/custom/locales/el/units.yml +19 -0
  86. data/resources/custom/locales/en/units.yml +18 -0
  87. data/resources/custom/locales/es/units.yml +19 -0
  88. data/resources/custom/locales/eu/units.yml +19 -0
  89. data/resources/custom/locales/fa/units.yml +15 -0
  90. data/resources/custom/locales/fi/units.yml +19 -0
  91. data/resources/custom/locales/fil/units.yml +19 -0
  92. data/resources/custom/locales/fr/units.yml +19 -0
  93. data/resources/custom/locales/he/units.yml +19 -0
  94. data/resources/custom/locales/hi/units.yml +19 -0
  95. data/resources/custom/locales/hu/units.yml +15 -0
  96. data/resources/custom/locales/id/units.yml +15 -0
  97. data/resources/custom/locales/it/units.yml +19 -0
  98. data/resources/custom/locales/ja/units.yml +15 -0
  99. data/resources/custom/locales/ko/units.yml +15 -0
  100. data/resources/custom/locales/ms/units.yml +15 -0
  101. data/resources/custom/locales/nb/units.yml +19 -0
  102. data/resources/custom/locales/nl/units.yml +19 -0
  103. data/resources/custom/locales/pl/units.yml +23 -0
  104. data/resources/custom/locales/pt/units.yml +19 -0
  105. data/resources/custom/locales/ru/units.yml +27 -0
  106. data/resources/custom/locales/sv/units.yml +19 -0
  107. data/resources/custom/locales/th/units.yml +15 -0
  108. data/resources/custom/locales/tr/units.yml +15 -0
  109. data/resources/custom/locales/uk/units.yml +27 -0
  110. data/resources/custom/locales/ur/units.yml +19 -0
  111. data/resources/custom/locales/zh-Hant/units.yml +15 -0
  112. data/resources/custom/locales/zh/units.yml +15 -0
  113. data/resources/locales/af/units.yml +112 -65
  114. data/resources/locales/ar/units.yml +196 -126
  115. data/resources/locales/ca/units.yml +112 -70
  116. data/resources/locales/cs/units.yml +140 -91
  117. data/resources/locales/da/units.yml +98 -56
  118. data/resources/locales/de/units.yml +112 -70
  119. data/resources/locales/el/units.yml +119 -84
  120. data/resources/locales/en/units.yml +84 -42
  121. data/resources/locales/es/units.yml +112 -70
  122. data/resources/locales/eu/units.yml +105 -68
  123. data/resources/locales/fa/units.yml +98 -63
  124. data/resources/locales/fi/units.yml +112 -70
  125. data/resources/locales/fil/units.yml +98 -56
  126. data/resources/locales/fr/units.yml +112 -70
  127. data/resources/locales/he/units.yml +98 -56
  128. data/resources/locales/hi/units.yml +98 -56
  129. data/resources/locales/hu/units.yml +84 -49
  130. data/resources/locales/id/units.yml +84 -49
  131. data/resources/locales/it/units.yml +98 -56
  132. data/resources/locales/ja/units.yml +84 -49
  133. data/resources/locales/ko/units.yml +84 -49
  134. data/resources/locales/ms/units.yml +112 -63
  135. data/resources/locales/nb/units.yml +106 -64
  136. data/resources/locales/nl/units.yml +98 -56
  137. data/resources/locales/pl/units.yml +181 -112
  138. data/resources/locales/pt/units.yml +112 -70
  139. data/resources/locales/ru/units.yml +168 -112
  140. data/resources/locales/sv/units.yml +112 -70
  141. data/resources/locales/th/units.yml +84 -49
  142. data/resources/locales/tr/units.yml +84 -49
  143. data/resources/locales/uk/units.yml +168 -112
  144. data/resources/locales/ur/units.yml +112 -63
  145. data/resources/locales/zh-Hant/units.yml +84 -49
  146. data/resources/locales/zh/units.yml +84 -49
  147. data/spec/collation/collation_spec.rb +1 -1
  148. data/spec/collation/collator_spec.rb +120 -48
  149. data/spec/collation/sort_key_builder_spec.rb +80 -0
  150. data/spec/collation/tailoring_spec.rb +137 -0
  151. data/spec/collation/tailoring_tests/af.txt +321 -0
  152. data/spec/collation/tailoring_tests/ar.txt +188 -0
  153. data/spec/collation/tailoring_tests/ca.txt +446 -0
  154. data/spec/collation/tailoring_tests/cs.txt +273 -0
  155. data/spec/collation/tailoring_tests/da.txt +293 -0
  156. data/spec/collation/tailoring_tests/de.txt +414 -0
  157. data/spec/collation/tailoring_tests/el.txt +228 -0
  158. data/spec/collation/tailoring_tests/en.txt +399 -0
  159. data/spec/collation/tailoring_tests/es.txt +402 -0
  160. data/spec/collation/tailoring_tests/eu.txt +183 -0
  161. data/spec/collation/tailoring_tests/fa.txt +263 -0
  162. data/spec/collation/tailoring_tests/fi.txt +389 -0
  163. data/spec/collation/tailoring_tests/fil.txt +279 -0
  164. data/spec/collation/tailoring_tests/fr.txt +363 -0
  165. data/spec/collation/tailoring_tests/he.txt +167 -0
  166. data/spec/collation/tailoring_tests/hi.txt +230 -0
  167. data/spec/collation/tailoring_tests/hu.txt +773 -0
  168. data/spec/collation/tailoring_tests/id.txt +171 -0
  169. data/spec/collation/tailoring_tests/it.txt +231 -0
  170. data/spec/collation/tailoring_tests/ja.txt +4287 -0
  171. data/spec/collation/tailoring_tests/ko.txt +1761 -0
  172. data/spec/collation/tailoring_tests/ms.txt +531 -0
  173. data/spec/collation/tailoring_tests/nb.txt +375 -0
  174. data/spec/collation/tailoring_tests/nl.txt +273 -0
  175. data/spec/collation/tailoring_tests/pl.txt +225 -0
  176. data/spec/collation/tailoring_tests/pt.txt +405 -0
  177. data/spec/collation/tailoring_tests/ru.txt +213 -0
  178. data/spec/collation/tailoring_tests/sv.txt +353 -0
  179. data/spec/collation/tailoring_tests/th.txt +239 -0
  180. data/spec/collation/tailoring_tests/tr.txt +414 -0
  181. data/spec/collation/tailoring_tests/uk.txt +218 -0
  182. data/spec/collation/tailoring_tests/ur.txt +284 -0
  183. data/spec/collation/tailoring_tests/zh-Hant.txt +626 -0
  184. data/spec/collation/tailoring_tests/zh.txt +717 -0
  185. data/spec/collation/trie_builder_spec.rb +131 -51
  186. data/spec/collation/trie_spec.rb +301 -26
  187. data/spec/collation/trie_with_fallback_spec.rb +41 -0
  188. data/spec/core_ext/array_spec.rb +46 -3
  189. data/spec/core_ext/calendars/date_spec.rb +24 -24
  190. data/spec/core_ext/calendars/datetime_spec.rb +7 -0
  191. data/spec/core_ext/calendars/time_spec.rb +2 -2
  192. data/spec/formatters/calendars/timespan_formatter_spec.rb +47 -18
  193. data/spec/formatters/plurals/rules_spec.rb +3 -11
  194. data/spec/readme_spec.rb +15 -15
  195. data/spec/resources/loader_spec.rb +94 -0
  196. data/spec/spec_helper.rb +6 -0
  197. data/spec/tokenizers/calendars/timespan_tokenizer_spec.rb +1 -1
  198. data/spec/twitter_cldr_spec.rb +3 -3
  199. data/spec/utils_spec.rb +38 -0
  200. data/twitter_cldr.gemspec +25 -0
  201. metadata +156 -110
  202. data/spec/collation/sort_key_spec.rb +0 -56
  203. data/spec/shared/resources_spec.rb +0 -75
data/Gemfile ADDED
@@ -0,0 +1,32 @@
1
+ source 'http://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ group :development, :test do
6
+ gem 'rake'
7
+ end
8
+
9
+ group :development do
10
+ gem 'mustache', '~> 0.99.4'
11
+ gem 'nokogiri'
12
+
13
+ platform :ruby do
14
+ gem 'therubyracer', '~> 0.9.10'
15
+ gem 'uglifier', '~> 1.2.4'
16
+ gem 'coffee-script', '~> 2.2.0'
17
+ end
18
+ end
19
+
20
+ group :test do
21
+ gem 'rspec', '~> 2.11.0'
22
+ gem 'rr', '~> 1.0.4'
23
+ gem 'zip'
24
+
25
+ platform :ruby do
26
+ gem 'jasmine-headless-webkit', '~> 0.9.0.rc1'
27
+ end
28
+
29
+ platform :mri_18 do
30
+ gem 'rcov'
31
+ end
32
+ end
data/History.txt ADDED
@@ -0,0 +1,78 @@
1
+ === 1.6.0
2
+
3
+ * Added locale-aware collation via fractional collation element tailoring.
4
+ * Added #sort and #sort! methods to LocalizedArray.
5
+ * Added JavaScript relative time functionality, eg. "2 seconds ago".
6
+
7
+ === 1.5.0
8
+
9
+ * Added collation (sorting) support via the Unicode Collation Algorithm.
10
+ * Added Catalan, Basque, Greek, Afrikaans, Ukrainian, and Czech support along with calendar fixes for existing locales.
11
+ * DateTimeTokenizer now falls back on English if the given locale isn't supported.
12
+
13
+ === 1.4.1
14
+
15
+ * Added ability to use NFC and NFKC in core_ext/string
16
+
17
+ === 1.4.0
18
+
19
+ * Added NFC and NFKC algorithms.
20
+ * Refactored Shared::UnicodeData::Attributes into Shared::CodePoint.
21
+
22
+ === 1.3.6
23
+
24
+ * Added relative time functionality, eg. "2 seconds ago".
25
+
26
+ === 1.3.0
27
+
28
+ * Reorganized locale resources.
29
+ * Added explicit specs for examples in the README.
30
+ * ArgumentError now raised if a resource can't be found.
31
+ * Fixed behavior of the :precision option for number formatting.
32
+ * Updated CLDR data to v21 (http://cldr.unicode.org/index/downloads/cldr-21).
33
+ * Added support for localized arrays (i.e. arrays of Unicode code points).
34
+
35
+ === 1.2.0
36
+
37
+ * Added NFKD normalization algorithm.
38
+ * Formatter tokens now cached for better performance.
39
+ * Improvements to core extensions (Symbol, Date, etc).
40
+ * Added full normalization test from unicode.org.
41
+ * Autoload classes to improve performance.
42
+
43
+ === 1.1.0
44
+
45
+ * Plural support [@KL-7]
46
+ * Unicode data, decomposition [@timothyandrew]
47
+
48
+ === 1.0.1
49
+
50
+ * Fixed a US-ASCII bug that caused rake errors. This fix applies to both Ruby 1.8 and 1.9.
51
+ * Fixed a regexp error in a test function, as well as a tokenizer bug. All tests now pass.
52
+ * Added support for Travis, a distributed build platform.
53
+
54
+ === 1.0.0
55
+
56
+ * Look ma, I'm open source!
57
+
58
+ === 0.1.4
59
+
60
+ * Added functionality to gracefully fall back on default locale if chosen locale is unsupported.
61
+
62
+ === 0.1.3
63
+
64
+ * Added support for Arabic, Hebrew, Farsi, Thai, and Urdu.
65
+
66
+ === 0.1.2
67
+
68
+ * Added world language support.
69
+
70
+ === 0.1.1
71
+
72
+ * Localized dates, times, and datetimes can now be interchangeably converted to each other.
73
+ * Fixed a bug that would not allow lookup of resource data by string (only symbol).
74
+ * Added really basic plural support.
75
+
76
+ === 0.1.0
77
+
78
+ * Birthday!
data/README.md CHANGED
@@ -29,11 +29,11 @@ TwitterCldr.supported_locale?(:xx) # false
29
29
  ```
30
30
 
31
31
 
32
- TwitterCldr patches core Ruby objects like Fixnum and Date to make localization as straightforward as possible.
32
+ TwitterCldr patches core Ruby objects like `Fixnum` and `Date` to make localization as straightforward as possible.
33
33
 
34
34
  ### Numbers
35
35
 
36
- Fixnum, Bignum, and Float objects are supported. Here are some examples:
36
+ `Fixnum`, `Bignum`, and `Float` objects are supported. Here are some examples:
37
37
 
38
38
  ```ruby
39
39
  # default formatting with to_s
@@ -52,9 +52,9 @@ Fixnum, Bignum, and Float objects are supported. Here are some examples:
52
52
  1337.localize(:es).to_decimal.to_s(:precision => 3) # 1.337,000
53
53
  ```
54
54
 
55
- **Note**: The :precision option can be used with all these number formatters.
55
+ **Note**: The `:precision` option can be used with all these number formatters.
56
56
 
57
- Behind the scenes, these convenience methods are creating instances of LocalizedNumber. You can do the same thing if you're feeling adventurous:
57
+ Behind the scenes, these convenience methods are creating instances of `LocalizedNumber`. You can do the same thing if you're feeling adventurous:
58
58
 
59
59
  ```ruby
60
60
  num = TwitterCldr::LocalizedNumber.new(1337, :es)
@@ -63,7 +63,7 @@ num.to_currency.to_s # ...etc
63
63
 
64
64
  #### More on Currencies
65
65
 
66
- If you're looking for a list of supported countries and currencies, use the TwitterCldr::Shared::Currencies class:
66
+ If you're looking for a list of supported countries and currencies, use the `TwitterCldr::Shared::Currencies` class:
67
67
 
68
68
  ```ruby
69
69
  # all supported countries
@@ -81,7 +81,7 @@ TwitterCldr::Shared::Currencies.for_code("CAD") # { :currency => "Dol
81
81
 
82
82
  ### Dates and Times
83
83
 
84
- Date, Time, and DateTime objects are supported:
84
+ `Date`, `Time`, and `DateTime` objects are supported:
85
85
 
86
86
  ```ruby
87
87
  DateTime.now.localize(:es).to_full_s # "lunes, 12 de diciembre de 2011 21:44:57 UTC -0800"
@@ -102,7 +102,7 @@ Time.now.localize(:es).to_short_s # "21:44"
102
102
 
103
103
  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 :)
104
104
 
105
- Behind the scenes, these convenience methods are creating instances of LocalizedDate, LocalizedTime, and LocalizedDateTime. You can do the same thing if you're feeling adventurous:
105
+ Behind the scenes, these convenience methods are creating instances of `LocalizedDate`, `LocalizedTime`, and `LocalizedDateTime`. You can do the same thing if you're feeling adventurous:
106
106
 
107
107
  ```ruby
108
108
  dt = TwitterCldr::LocalizedDateTime.new(DateTime.now, :es)
@@ -114,44 +114,44 @@ dt.to_short_s # ...etc
114
114
  In addition to formatting full dates and times, TwitterCLDR supports relative time spans via several convenience methods and the `LocalizedTimespan` class. TwitterCLDR tries to guess the best time unit (eg. days, hours, minutes, etc) based on the length of the time span. Unless otherwise specified, TwitterCLDR will use the current date and time as the reference point for the calculation.
115
115
 
116
116
  ```ruby
117
- (DateTime.now - 1).localize.ago # 1 day ago
118
- (DateTime.now - 0.5).localize.ago # 12 hours ago (i.e. half a day)
117
+ (DateTime.now - 1).localize.ago.to_s # 1 day ago
118
+ (DateTime.now - 0.5).localize.ago.to_s # 12 hours ago (i.e. half a day)
119
119
 
120
- (DateTime.now + 1).localize.until # In 1 day
121
- (DateTime.now + 0.5).localize.until # In 12 hours
120
+ (DateTime.now + 1).localize.until.to_s # In 1 day
121
+ (DateTime.now + 0.5).localize.until.to_s # In 12 hours
122
122
  ```
123
123
 
124
124
  Specify other locales:
125
125
 
126
126
  ```ruby
127
- (DateTime.now - 1).localize(:de).ago # Vor 1 Tag
128
- (DateTime.now + 1).localize(:de).until # In 1 Tag
127
+ (DateTime.now - 1).localize(:de).ago.to_s # Vor 1 Tag
128
+ (DateTime.now + 1).localize(:de).until.to_s # In 1 Tag
129
129
  ```
130
130
 
131
131
  Force TwitterCLDR to use a specific time unit by including the `:unit` option:
132
132
 
133
133
  ```ruby
134
- (DateTime.now - 1).localize(:de).ago(:unit => :hour) # Vor 24 Stunden
135
- (DateTime.now + 1).localize(:de).until(:unit => :hour) # In 24 Stunden
134
+ (DateTime.now - 1).localize(:de).ago.to_s(:unit => :hour) # Vor 24 Stunden
135
+ (DateTime.now + 1).localize(:de).until.to_s(:unit => :hour) # In 24 Stunden
136
136
  ```
137
137
 
138
138
  Specify a different reference point for the time span calculation:
139
139
 
140
140
  ```ruby
141
141
  # 86400 = 1 day in seconds, 259200 = 3 days in seconds
142
- (Time.now + 86400).localize(:de).ago(:unit => :hour, :base_time => (Time.now + 259200)) # Vor 48 Stunden
142
+ (Time.now + 86400).localize(:de).ago(:base_time => (Time.now + 259200)).to_s(:unit => :hour) # Vor 48 Stunden
143
143
  ```
144
144
 
145
145
  Behind the scenes, these convenience methods are creating instances of `LocalizedTimespan`, whose constructor accepts a number of seconds as the first argument. You can do the same thing if you're feeling adventurous:
146
146
 
147
147
  ```ruby
148
- ts = TwitterCldr::LocalizedTimespan.new(86400, :de)
149
- ts.to_s # In 1 Tag
150
- ts.to_s(:hour) # In 24 Stunden
148
+ ts = TwitterCldr::LocalizedTimespan.new(86400, :locale => :de)
149
+ ts.to_s # In 1 Tag
150
+ ts.to_s(:unit => :hour) # In 24 Stunden
151
151
 
152
- ts = TwitterCldr::LocalizedTimespan.new(-86400, :de)
153
- ts.to_s # Vor 1 Tag
154
- ts.to_s(:hour) # Vor 24 Stunden
152
+ ts = TwitterCldr::LocalizedTimespan.new(-86400, :locale => :de)
153
+ ts.to_s # Vor 1 Tag
154
+ ts.to_s(:unit => :hour) # Vor 24 Stunden
155
155
  ```
156
156
 
157
157
  ### Plural Rules
@@ -166,7 +166,7 @@ TwitterCLDR makes it easy to find the plural rules for any numeric value:
166
166
  5.localize(:ru).plural_rule # :many
167
167
  ```
168
168
 
169
- Behind the scenes, these convenience methods use the TwitterCldr::Formatters::Plurals::Rules class. You can do the same thing (and a bit more) if you're feeling adventurous:
169
+ Behind the scenes, these convenience methods use the `TwitterCldr::Formatters::Plurals::Rules` class. You can do the same thing (and a bit more) if you're feeling adventurous:
170
170
 
171
171
  ```ruby
172
172
  # get all rules for the default locale
@@ -228,7 +228,7 @@ The `LocalizedString` class supports all forms of interpolation and combines sup
228
228
  "there are %{count} horses in the barn".localize % { :count => "5" }
229
229
  ```
230
230
 
231
- When you pass a Hash as an argument and specify placeholders with %<foo>d, TwitterCLDR will interpret the hash values as named arguments and format the string according to the instructions appended to the closing `>`. In this way, TwitterCLDR supports both Ruby 1.8 and 1.9 interpolation syntax in the same string:
231
+ When you pass a Hash as an argument and specify placeholders with `%<foo>d`, TwitterCLDR will interpret the hash values as named arguments and format the string according to the instructions appended to the closing `>`. In this way, TwitterCLDR supports both Ruby 1.8 and 1.9 interpolation syntax in the same string:
232
232
 
233
233
  ```ruby
234
234
  "five euros plus %<percent>.3f in %{noun}".localize % { :percent => 13.25 * 0.087, :noun => "tax" }
@@ -243,14 +243,14 @@ You can use the localize convenience method on language code symbols to get thei
243
243
  :ru.localize(:es).as_language_code # "ruso"
244
244
  ```
245
245
 
246
- Behind the scenes, these convenience methods are creating instances of LocalizedSymbol. You can do the same thing if you're feeling adventurous:
246
+ Behind the scenes, these convenience methods are creating instances of `LocalizedSymbol`. You can do the same thing if you're feeling adventurous:
247
247
 
248
248
  ```ruby
249
249
  ls = LocalizedSymbol.new(:ru, :es)
250
250
  ls.as_language_code # "ruso"
251
251
  ```
252
252
 
253
- In addition to translating language codes, TwitterCLDR provides access to the full set of supported languages via the TwitterCldr::Shared::Languages class:
253
+ In addition to translating language codes, TwitterCLDR provides access to the full set of supported languages via the `TwitterCldr::Shared::Languages` class:
254
254
 
255
255
  ```ruby
256
256
  # get all languages for the default locale
@@ -325,16 +325,53 @@ A few convenience methods also exist for `String` that make it easy to normalize
325
325
  "español".localize.normalize.code_points
326
326
  ```
327
327
 
328
- Specify a specific normalization algorithm via the :using option. Currently, only NFD and NFKD are supported (default is NFD):
328
+ Specify a specific normalization algorithm via the `:using` option. NFD, NFKD, NFC, and NFKC algorithms are all supported (default is NFD):
329
329
 
330
330
  ```ruby
331
331
  # ["0065", "0073", "0070", "0061", "006E", "0303", "006F", "006C"]
332
332
  "español".localize.normalize(:using => :NFKD).code_points
333
333
  ```
334
334
 
335
+ ### Sorting (Collation)
336
+
337
+ TwitterCLDR contains an implementation of the [Unicode Collation Algorithm (UCA)](http://unicode.org/reports/tr10/) that provides language-sensitive text sorting capabilities. Conveniently, all you have to do is use the `sort` method in combination with the familiar `localize` method. Notice the difference between the default Ruby sort, which simply compares bytes, and the proper language-aware sort from TwitterCLDR in this German example:
338
+
339
+ ```ruby
340
+ ["Art", "Wasa", "Älg", "Ved"].sort # ["Art", "Ved", "Wasa", "Älg"]
341
+ ["Art", "Wasa", "Älg", "Ved"].localize(:de).sort.to_a # ["Älg", "Art", "Ved", "Wasa"]
342
+ ```
343
+
344
+ Behind the scenes, these convenience methods are creating instances of `LocalizedArray`, then using the `TwitterCldr::Collation::Collator` class to sort the elements:
345
+
346
+ ```ruby
347
+ collator = TwitterCldr::Collation::Collator.new(:de)
348
+ collator.sort(["Art", "Wasa", "Älg", "Ved"]) # ["Älg", "Art", "Ved", "Wasa"]
349
+ collator.sort!(["Art", "Wasa", "Älg", "Ved"]) # ["Älg", "Art", "Ved", "Wasa"]
350
+ ```
351
+
352
+ The `TwitterCldr::Collation::Collator` class also provides methods to compare two strings, get sort keys, and calculate collation elements for individual strings:
353
+
354
+ ```ruby
355
+ collator = TwitterCldr::Collation::Collator.new(:de)
356
+ collator.compare("Art", "Älg") # 1
357
+ collator.compare("Älg", "Art") # -1
358
+ collator.compare("Art", "Art") # 0
359
+
360
+ collator.get_collation_elements("Älg") # [[39, 5, 143], [0, 157, 5], [61, 5, 5], [51, 5, 5]]
361
+
362
+ collator.get_sort_key("Älg") # [39, 61, 51, 1, 134, 157, 6, 1, 143, 7]
363
+ ```
364
+
365
+ **Note**: The collation algorithm in TwitterCLDR isn't quite complete. Here's what we still have to do:
366
+
367
+ 1. Backwards accent sorting for French.
368
+ 2. Uppercase-first sorting for languages like Danish.
369
+
370
+ **Note**: The TwitterCLDR collator does not currently pass all the collation tests provided by Unicode, but for some strange reasons. See the [summary](https://gist.github.com/f4ee3bd280a2257c5641) of these discrepancies if you're curious.
371
+
335
372
  ## About Twitter-specific Locales
336
373
 
337
- 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:
374
+ Twitter tries to always use BCP-47 language codes. Data from the CLDR doesn't always match those codes however, 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:
338
375
 
339
376
  ```ruby
340
377
  TwitterCldr.convert_locale(:'zh-cn') # :zh
@@ -363,16 +400,17 @@ No external requirements.
363
400
 
364
401
  ## Running Tests
365
402
 
366
- `bundle exec rake` should do the trick. Tests are written in RSpec using RR as the mocking framework.
403
+ `bundle exec rake` will run our basic test suite suitable for development. To run the full test suite, use `bundle exec rake spec:full`. The full test suite takes considerably longer to run because it runs against the complete normalization and collation test files from the Unicode Consortium. The basic test suite only runs normalization and collation tests against a small subset of the complete test file.
404
+
405
+ Tests are written in RSpec using RR as the mocking framework.
367
406
 
368
407
  ## JavaScript Support
369
- (Note: These changes have not yet been released as a gem.)
370
408
 
371
- TwitterCLDR currently supports localization of dates and times in JavaScript. More awesome features are coming soon.
409
+ TwitterCLDR currently supports localization of dates and times in JavaScript. More awesome features are coming soon. See [http://github.com/twitter/twitter-cldr-js](http://github.com/twitter/twitter-cldr-js) for details.
372
410
 
373
411
  ### Generating the JavaScript
374
412
 
375
- You can automatically generate the JavaScript versions of TwitterCLDR using this Rubygem. Here's the one-liner:
413
+ You can automatically generate the JavaScript version of TwitterCLDR using this Rubygem. Here's the one-liner:
376
414
 
377
415
  `bundle exec rake js:build OUTPUT_DIR=/path/to/desired/output/location`
378
416
 
@@ -388,30 +426,6 @@ TwitterCldr::Js.make(:locales => [:de, :sv, :ja, :ar], # generate files for Ge
388
426
  TwitterCldr::Js.install # copy files to output directory
389
427
  ```
390
428
 
391
- ### Dates and Times (JS)
392
-
393
- ```javascript
394
- // include twitter_cldr_es.js for the Spanish DateTimeFormatter
395
- var fmt = new TwitterCldr.DateTimeFormatter();
396
-
397
- fmt.format(new Date(), {"type": "full"}); // "lunes, 12 de diciembre de 2011 21:44:57 UTC -0800"
398
- fmt.format(new Date(), {"type": "long"}); // "12 de diciembre de 201121:45:42 -08:00"
399
- fmt.format(new Date(), {"type": "medium"}); // "12/12/2011 21:46:09"
400
- fmt.format(new Date(), {"type": "short"}); // "12/12/11 21:47"
401
-
402
- fmt.format(new Date(), {"format": "date", "type": "full"}); // "lunes, 12 de diciembre de 2011"
403
- fmt.format(new Date(), {"format": "date", "type": "long"}); // "12 de diciembre de 2011"
404
- fmt.format(new Date(), {"format": "date", "type": "medium"}); // "12/12/2011"
405
- fmt.format(new Date(), {"format": "date", "type": "short"}); // "12/12/11"
406
-
407
- fmt.format(new Date(), {"format": "time", "type": "full"}); // "21:44:57 UTC -0800"
408
- fmt.format(new Date(), {"format": "time", "type": "long"}); // "21:45:42 -08:00"
409
- fmt.format(new Date(), {"format": "time", "type": "medium"}); // "21:46:09"
410
- fmt.format(new Date(), {"format": "time", "type": "short"}); // "21:47"
411
- ```
412
-
413
- 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 :)
414
-
415
429
  ### Running Tests (JS)
416
430
 
417
431
  A JavaScript test suite comes with twitter-cldr-rb. You'll need to install the Qt libs to be able to run the suite, as it uses [jasmine](https://github.com/pivotal/jasmine-gem) and [jasmine-headless-webkit](http://johnbintz.github.com/jasmine-headless-webkit/).
@@ -425,7 +439,8 @@ The tests are located in `js/spec` and look similar to RSpec tests.
425
439
  ## Authors
426
440
 
427
441
  * Cameron C. Dutro: http://github.com/camertron
428
- * Portions taken from the ruby-cldr gem by Sven Fuchs: http://github.com/svenfuchs/ruby-cldr
442
+ * Kirill Lashuk: http://github.com/kl-7
443
+ * Portions adapted from the ruby-cldr gem by Sven Fuchs: http://github.com/svenfuchs/ruby-cldr
429
444
 
430
445
  ## Links
431
446
  * ruby-cldr gem: [http://github.com/svenfuchs/ruby-cldr](http://github.com/svenfuchs/ruby-cldr)
@@ -437,8 +452,3 @@ The tests are located in `js/spec` and look similar to RSpec tests.
437
452
  Copyright 2012 Twitter, Inc.
438
453
 
439
454
  Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0
440
-
441
- ## Future Plans
442
-
443
- * Implement Unicode Collation Algorithm (UCA) for sorting/searching.
444
- * Patch Ruby 1.8 strings to provide better Unicode support (probably using pack and unpack).
data/Rakefile CHANGED
@@ -38,6 +38,23 @@ if RUBY_VERSION < '1.9.0'
38
38
  end
39
39
  end
40
40
 
41
+ namespace :resources do
42
+ namespace :update do
43
+ desc 'Import tailoring resources from CLDR data (should be executed using JRuby 1.7 in 1.9 mode)'
44
+ task :tailoring do
45
+ require './lib/twitter_cldr'
46
+
47
+ importer = TwitterCldr::Resources::Import::Tailoring.new(
48
+ ENV.fetch('CLDR_DATA_PATH', '../cldr-tailoring/'),
49
+ './resources/collation/tailoring',
50
+ ENV.fetch('ICU4J_JAR_PATH', '../icu4j-49_1.jar')
51
+ )
52
+
53
+ TwitterCldr.supported_locales.each { |locale| importer.import(locale) }
54
+ end
55
+ end
56
+ end
57
+
41
58
  namespace :js do
42
59
  task :build do
43
60
  require File.expand_path(File.join(File.dirname(__FILE__), %w[lib twitter_cldr]))
@@ -53,7 +70,12 @@ namespace :js do
53
70
  TwitterCldr.require_js
54
71
  FileUtils.mkdir_p(TwitterCldr::Js.build_dir)
55
72
  TwitterCldr::Js.make(:locales => [:en])
73
+ puts "Running JavaScript tests (Jasmine)..."
56
74
  TwitterCldr::Js.test
57
75
  FileUtils.rm_rf(TwitterCldr::Js.build_dir)
76
+ puts "\nRunning Ruby tests (RSpec)..."
77
+ Dir.chdir(File.join(File.dirname(__FILE__), "js")) do
78
+ Rake::Task["spec"].execute
79
+ end
58
80
  end
59
81
  end
@@ -0,0 +1,40 @@
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 Js
8
+ class Compiler
9
+ def initialize(options = {})
10
+ @locales = options[:locales] || TwitterCldr.supported_locales
11
+ @features = options[:features] || renderers.keys
12
+ end
13
+
14
+ def compile
15
+ @locales.each do |locale|
16
+ contents = ""
17
+
18
+ @features.each do |feature|
19
+ renderer_const = renderers[feature]
20
+ contents << renderer_const.new(:locale => locale).render if renderer_const
21
+ end
22
+
23
+ bundle = TwitterCldr::Js::Renderers::Bundle.new
24
+ bundle[:contents] = contents
25
+ yield CoffeeScript.compile(bundle.render, :bare => true), TwitterCldr.twitter_locale(locale) if block_given?
26
+ end
27
+ end
28
+
29
+ private
30
+
31
+ def renderers
32
+ @renderers ||= {
33
+ :plural_rules => TwitterCldr::Js::Renderers::PluralRules::PluralRulesRenderer,
34
+ :timespan => TwitterCldr::Js::Renderers::Calendars::TimespanRenderer,
35
+ :datetime => TwitterCldr::Js::Renderers::Calendars::DateTimeRenderer
36
+ }
37
+ end
38
+ end
39
+ end
40
+ end