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.
- data/Gemfile +32 -0
- data/History.txt +78 -0
- data/README.md +72 -62
- data/Rakefile +22 -0
- data/js/lib/compiler.rb +40 -0
- data/js/lib/mustache/bundle.coffee +14 -0
- data/js/lib/mustache/calendars/datetime.coffee +240 -0
- data/js/lib/mustache/calendars/timespan.coffee +52 -0
- data/js/lib/mustache/plurals/rules.coffee +14 -0
- data/js/lib/renderers/base.rb +18 -0
- data/js/lib/renderers/bundle.rb +18 -0
- data/js/lib/renderers/calendars/datetime_renderer.rb +34 -0
- data/js/lib/renderers/calendars/timespan_renderer.rb +39 -0
- data/js/lib/renderers/plurals/rules/plural_rules_compiler.rb +89 -0
- data/js/lib/renderers/plurals/rules/plural_rules_renderer.rb +26 -0
- data/js/lib/twitter_cldr_js.rb +85 -0
- data/js/spec/js/calendars/datetime_spec.js +418 -0
- data/js/spec/js/calendars/timespan_spec.js +91 -0
- data/js/spec/js/plurals/plural_rules_spec.js +28 -0
- data/js/spec/js/support/jasmine.yml +8 -0
- data/js/spec/rb/renderers/plurals/plural_rules_compiler_spec.rb +52 -0
- data/js/spec/rb/spec_helper.rb +13 -0
- data/lib/twitter_cldr.rb +2 -1
- data/lib/twitter_cldr/collation.rb +2 -1
- data/lib/twitter_cldr/collation/collator.rb +49 -31
- data/lib/twitter_cldr/collation/{sort_key.rb → sort_key_builder.rb} +31 -8
- data/lib/twitter_cldr/collation/trie.rb +116 -24
- data/lib/twitter_cldr/collation/trie_builder.rb +54 -28
- data/lib/twitter_cldr/collation/trie_with_fallback.rb +55 -0
- data/lib/twitter_cldr/core_ext/array.rb +14 -1
- data/lib/twitter_cldr/core_ext/calendars/datetime.rb +8 -2
- data/lib/twitter_cldr/core_ext/calendars/timespan.rb +5 -5
- data/lib/twitter_cldr/formatters/calendars/timespan_formatter.rb +10 -10
- data/lib/twitter_cldr/formatters/plurals/rules.rb +3 -5
- data/lib/twitter_cldr/resources.rb +11 -0
- data/lib/twitter_cldr/resources/import.rb +12 -0
- data/lib/twitter_cldr/resources/import/tailoring.rb +193 -0
- data/lib/twitter_cldr/{shared/resources.rb → resources/loader.rb} +17 -4
- data/lib/twitter_cldr/shared.rb +0 -1
- data/lib/twitter_cldr/tokenizers/base.rb +9 -9
- data/lib/twitter_cldr/tokenizers/calendars/datetime_tokenizer.rb +0 -4
- data/lib/twitter_cldr/tokenizers/calendars/timespan_tokenizer.rb +21 -7
- data/lib/twitter_cldr/utils.rb +11 -0
- data/lib/twitter_cldr/version.rb +1 -1
- data/resources/collation/tailoring/af.yml +3 -0
- data/resources/collation/tailoring/ar.yml +21 -0
- data/resources/collation/tailoring/ca.yml +9 -0
- data/resources/collation/tailoring/cs.yml +25 -0
- data/resources/collation/tailoring/da.yml +59 -0
- data/resources/collation/tailoring/de.yml +3 -0
- data/resources/collation/tailoring/el.yml +3 -0
- data/resources/collation/tailoring/en.yml +3 -0
- data/resources/collation/tailoring/es.yml +5 -0
- data/resources/collation/tailoring/eu.yml +3 -0
- data/resources/collation/tailoring/fa.yml +73 -0
- data/resources/collation/tailoring/fi.yml +61 -0
- data/resources/collation/tailoring/fil.yml +11 -0
- data/resources/collation/tailoring/fr.yml +3 -0
- data/resources/collation/tailoring/he.yml +3 -0
- data/resources/collation/tailoring/hi.yml +7 -0
- data/resources/collation/tailoring/hu.yml +125 -0
- data/resources/collation/tailoring/id.yml +3 -0
- data/resources/collation/tailoring/it.yml +3 -0
- data/resources/collation/tailoring/ja.yml +14647 -0
- data/resources/collation/tailoring/ko.yml +14953 -0
- data/resources/collation/tailoring/ms.yml +3 -0
- data/resources/collation/tailoring/nb.yml +59 -0
- data/resources/collation/tailoring/nl.yml +3 -0
- data/resources/collation/tailoring/pl.yml +37 -0
- data/resources/collation/tailoring/pt.yml +3 -0
- data/resources/collation/tailoring/ru.yml +3 -0
- data/resources/collation/tailoring/sv.yml +63 -0
- data/resources/collation/tailoring/th.yml +19 -0
- data/resources/collation/tailoring/tr.yml +27 -0
- data/resources/collation/tailoring/uk.yml +5 -0
- data/resources/collation/tailoring/ur.yml +163 -0
- data/resources/collation/tailoring/zh-Hant.yml +3 -0
- data/resources/collation/tailoring/zh.yml +149 -0
- data/resources/custom/locales/af/units.yml +19 -0
- data/resources/custom/locales/ar/units.yml +35 -0
- data/resources/custom/locales/ca/units.yml +19 -0
- data/resources/custom/locales/cs/units.yml +23 -0
- data/resources/custom/locales/da/units.yml +19 -0
- data/resources/custom/locales/de/units.yml +19 -0
- data/resources/custom/locales/el/units.yml +19 -0
- data/resources/custom/locales/en/units.yml +18 -0
- data/resources/custom/locales/es/units.yml +19 -0
- data/resources/custom/locales/eu/units.yml +19 -0
- data/resources/custom/locales/fa/units.yml +15 -0
- data/resources/custom/locales/fi/units.yml +19 -0
- data/resources/custom/locales/fil/units.yml +19 -0
- data/resources/custom/locales/fr/units.yml +19 -0
- data/resources/custom/locales/he/units.yml +19 -0
- data/resources/custom/locales/hi/units.yml +19 -0
- data/resources/custom/locales/hu/units.yml +15 -0
- data/resources/custom/locales/id/units.yml +15 -0
- data/resources/custom/locales/it/units.yml +19 -0
- data/resources/custom/locales/ja/units.yml +15 -0
- data/resources/custom/locales/ko/units.yml +15 -0
- data/resources/custom/locales/ms/units.yml +15 -0
- data/resources/custom/locales/nb/units.yml +19 -0
- data/resources/custom/locales/nl/units.yml +19 -0
- data/resources/custom/locales/pl/units.yml +23 -0
- data/resources/custom/locales/pt/units.yml +19 -0
- data/resources/custom/locales/ru/units.yml +27 -0
- data/resources/custom/locales/sv/units.yml +19 -0
- data/resources/custom/locales/th/units.yml +15 -0
- data/resources/custom/locales/tr/units.yml +15 -0
- data/resources/custom/locales/uk/units.yml +27 -0
- data/resources/custom/locales/ur/units.yml +19 -0
- data/resources/custom/locales/zh-Hant/units.yml +15 -0
- data/resources/custom/locales/zh/units.yml +15 -0
- data/resources/locales/af/units.yml +112 -65
- data/resources/locales/ar/units.yml +196 -126
- data/resources/locales/ca/units.yml +112 -70
- data/resources/locales/cs/units.yml +140 -91
- data/resources/locales/da/units.yml +98 -56
- data/resources/locales/de/units.yml +112 -70
- data/resources/locales/el/units.yml +119 -84
- data/resources/locales/en/units.yml +84 -42
- data/resources/locales/es/units.yml +112 -70
- data/resources/locales/eu/units.yml +105 -68
- data/resources/locales/fa/units.yml +98 -63
- data/resources/locales/fi/units.yml +112 -70
- data/resources/locales/fil/units.yml +98 -56
- data/resources/locales/fr/units.yml +112 -70
- data/resources/locales/he/units.yml +98 -56
- data/resources/locales/hi/units.yml +98 -56
- data/resources/locales/hu/units.yml +84 -49
- data/resources/locales/id/units.yml +84 -49
- data/resources/locales/it/units.yml +98 -56
- data/resources/locales/ja/units.yml +84 -49
- data/resources/locales/ko/units.yml +84 -49
- data/resources/locales/ms/units.yml +112 -63
- data/resources/locales/nb/units.yml +106 -64
- data/resources/locales/nl/units.yml +98 -56
- data/resources/locales/pl/units.yml +181 -112
- data/resources/locales/pt/units.yml +112 -70
- data/resources/locales/ru/units.yml +168 -112
- data/resources/locales/sv/units.yml +112 -70
- data/resources/locales/th/units.yml +84 -49
- data/resources/locales/tr/units.yml +84 -49
- data/resources/locales/uk/units.yml +168 -112
- data/resources/locales/ur/units.yml +112 -63
- data/resources/locales/zh-Hant/units.yml +84 -49
- data/resources/locales/zh/units.yml +84 -49
- data/spec/collation/collation_spec.rb +1 -1
- data/spec/collation/collator_spec.rb +120 -48
- data/spec/collation/sort_key_builder_spec.rb +80 -0
- data/spec/collation/tailoring_spec.rb +137 -0
- data/spec/collation/tailoring_tests/af.txt +321 -0
- data/spec/collation/tailoring_tests/ar.txt +188 -0
- data/spec/collation/tailoring_tests/ca.txt +446 -0
- data/spec/collation/tailoring_tests/cs.txt +273 -0
- data/spec/collation/tailoring_tests/da.txt +293 -0
- data/spec/collation/tailoring_tests/de.txt +414 -0
- data/spec/collation/tailoring_tests/el.txt +228 -0
- data/spec/collation/tailoring_tests/en.txt +399 -0
- data/spec/collation/tailoring_tests/es.txt +402 -0
- data/spec/collation/tailoring_tests/eu.txt +183 -0
- data/spec/collation/tailoring_tests/fa.txt +263 -0
- data/spec/collation/tailoring_tests/fi.txt +389 -0
- data/spec/collation/tailoring_tests/fil.txt +279 -0
- data/spec/collation/tailoring_tests/fr.txt +363 -0
- data/spec/collation/tailoring_tests/he.txt +167 -0
- data/spec/collation/tailoring_tests/hi.txt +230 -0
- data/spec/collation/tailoring_tests/hu.txt +773 -0
- data/spec/collation/tailoring_tests/id.txt +171 -0
- data/spec/collation/tailoring_tests/it.txt +231 -0
- data/spec/collation/tailoring_tests/ja.txt +4287 -0
- data/spec/collation/tailoring_tests/ko.txt +1761 -0
- data/spec/collation/tailoring_tests/ms.txt +531 -0
- data/spec/collation/tailoring_tests/nb.txt +375 -0
- data/spec/collation/tailoring_tests/nl.txt +273 -0
- data/spec/collation/tailoring_tests/pl.txt +225 -0
- data/spec/collation/tailoring_tests/pt.txt +405 -0
- data/spec/collation/tailoring_tests/ru.txt +213 -0
- data/spec/collation/tailoring_tests/sv.txt +353 -0
- data/spec/collation/tailoring_tests/th.txt +239 -0
- data/spec/collation/tailoring_tests/tr.txt +414 -0
- data/spec/collation/tailoring_tests/uk.txt +218 -0
- data/spec/collation/tailoring_tests/ur.txt +284 -0
- data/spec/collation/tailoring_tests/zh-Hant.txt +626 -0
- data/spec/collation/tailoring_tests/zh.txt +717 -0
- data/spec/collation/trie_builder_spec.rb +131 -51
- data/spec/collation/trie_spec.rb +301 -26
- data/spec/collation/trie_with_fallback_spec.rb +41 -0
- data/spec/core_ext/array_spec.rb +46 -3
- data/spec/core_ext/calendars/date_spec.rb +24 -24
- data/spec/core_ext/calendars/datetime_spec.rb +7 -0
- data/spec/core_ext/calendars/time_spec.rb +2 -2
- data/spec/formatters/calendars/timespan_formatter_spec.rb +47 -18
- data/spec/formatters/plurals/rules_spec.rb +3 -11
- data/spec/readme_spec.rb +15 -15
- data/spec/resources/loader_spec.rb +94 -0
- data/spec/spec_helper.rb +6 -0
- data/spec/tokenizers/calendars/timespan_tokenizer_spec.rb +1 -1
- data/spec/twitter_cldr_spec.rb +3 -3
- data/spec/utils_spec.rb +38 -0
- data/twitter_cldr.gemspec +25 -0
- metadata +156 -110
- data/spec/collation/sort_key_spec.rb +0 -56
- 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
|
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
|
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
|
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
|
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
|
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(:
|
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
|
150
|
-
ts.to_s(:hour)
|
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
|
154
|
-
ts.to_s(:hour)
|
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
|
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
|
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
|
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`
|
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
|
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
|
-
*
|
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
|
data/js/lib/compiler.rb
ADDED
@@ -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
|