twitter_cldr 1.1.0 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +98 -0
- data/Rakefile +12 -4
- data/lib/{ext → twitter_cldr/core_ext}/calendars/date.rb +3 -3
- data/lib/twitter_cldr/core_ext/calendars/datetime.rb +45 -0
- data/lib/{ext → twitter_cldr/core_ext}/calendars/time.rb +3 -3
- data/lib/{ext → twitter_cldr/core_ext}/localized_object.rb +6 -2
- data/lib/{ext → twitter_cldr/core_ext}/numbers/bignum.rb +0 -0
- data/lib/{ext → twitter_cldr/core_ext}/numbers/fixnum.rb +0 -0
- data/lib/{ext → twitter_cldr/core_ext}/numbers/float.rb +0 -0
- data/lib/twitter_cldr/core_ext/numbers/localized_number.rb +55 -0
- data/lib/{ext/strings → twitter_cldr/core_ext}/string.rb +12 -0
- data/lib/{ext/strings → twitter_cldr/core_ext}/symbol.rb +0 -0
- data/lib/twitter_cldr/core_ext.rb +10 -0
- data/lib/{formatters → twitter_cldr/formatters}/base.rb +14 -8
- data/lib/{formatters → twitter_cldr/formatters}/calendars/date_formatter.rb +1 -1
- data/lib/{formatters → twitter_cldr/formatters}/calendars/datetime_formatter.rb +13 -13
- data/lib/{formatters → twitter_cldr/formatters}/calendars/time_formatter.rb +1 -1
- data/lib/{formatters → twitter_cldr/formatters}/numbers/currency_formatter.rb +0 -0
- data/lib/{formatters → twitter_cldr/formatters}/numbers/decimal_formatter.rb +0 -0
- data/lib/{formatters → twitter_cldr/formatters}/numbers/helpers/base.rb +0 -0
- data/lib/{formatters → twitter_cldr/formatters}/numbers/helpers/fraction.rb +0 -0
- data/lib/{formatters → twitter_cldr/formatters}/numbers/helpers/integer.rb +0 -0
- data/lib/{formatters → twitter_cldr/formatters}/numbers/number_formatter.rb +0 -0
- data/lib/{formatters → twitter_cldr/formatters}/numbers/percent_formatter.rb +0 -0
- data/lib/twitter_cldr/formatters/numbers.rb +14 -0
- data/lib/{formatters → twitter_cldr/formatters}/plurals/plural_formatter.rb +0 -0
- data/lib/{formatters → twitter_cldr/formatters}/plurals/rules.rb +2 -2
- data/lib/twitter_cldr/formatters/plurals.rb +12 -0
- data/lib/twitter_cldr/formatters.rb +23 -0
- data/lib/twitter_cldr/normalizers/nfd.rb +30 -0
- data/lib/twitter_cldr/normalizers/nfkd.rb +163 -0
- data/lib/twitter_cldr/normalizers.rb +11 -0
- data/lib/{shared → twitter_cldr/shared}/currencies.rb +0 -0
- data/lib/{shared → twitter_cldr/shared}/languages.rb +3 -3
- data/lib/{shared → twitter_cldr/shared}/resources.rb +0 -0
- data/lib/{shared → twitter_cldr/shared}/timezones.rb +0 -0
- data/lib/{shared → twitter_cldr/shared}/unicode_data.rb +3 -3
- data/lib/twitter_cldr/shared.rb +13 -0
- data/lib/{tokenizers → twitter_cldr/tokenizers}/base.rb +31 -10
- data/lib/twitter_cldr/tokenizers/calendars/date_tokenizer.rb +30 -0
- data/lib/twitter_cldr/tokenizers/calendars/datetime_tokenizer.rb +77 -0
- data/lib/{tokenizers → twitter_cldr/tokenizers}/calendars/time_tokenizer.rb +5 -5
- data/lib/twitter_cldr/tokenizers/composite_token.rb +26 -0
- data/lib/{tokenizers → twitter_cldr/tokenizers}/key_path.rb +0 -0
- data/lib/{tokenizers → twitter_cldr/tokenizers}/numbers/number_tokenizer.rb +0 -0
- data/lib/{tokenizers → twitter_cldr/tokenizers}/token.rb +0 -0
- data/lib/twitter_cldr/tokenizers.rb +17 -0
- data/lib/twitter_cldr/utils/code_points.rb +40 -0
- data/lib/{utils → twitter_cldr/utils}/interpolation.rb +0 -0
- data/lib/{utils.rb → twitter_cldr/utils.rb} +5 -3
- data/lib/{version.rb → twitter_cldr/version.rb} +1 -1
- data/lib/twitter_cldr.rb +9 -54
- data/resources/th/calendars.yml +17 -5
- data/spec/{ext → core_ext}/calendars/date_spec.rb +31 -6
- data/spec/core_ext/calendars/datetime_spec.rb +75 -0
- data/spec/{ext → core_ext}/calendars/time_spec.rb +31 -6
- data/spec/{ext → core_ext}/numbers/bignum_spec.rb +0 -0
- data/spec/{ext → core_ext}/numbers/fixnum_spec.rb +0 -0
- data/spec/{ext → core_ext}/numbers/float_spec.rb +0 -0
- data/spec/core_ext/numbers/localized_number_spec.rb +96 -0
- data/spec/{ext/strings → core_ext}/string_spec.rb +25 -0
- data/spec/{ext/strings → core_ext}/symbol_spec.rb +0 -0
- data/spec/normalizers/NormalizationTest.txt +18116 -287
- data/spec/normalizers/NormalizationTestShort.txt +602 -0
- data/spec/normalizers/nfd_spec.rb +21 -0
- data/spec/normalizers/normalization_spec.rb +96 -0
- data/spec/spec_helper.rb +2 -0
- data/spec/tokenizers/base_spec.rb +51 -0
- data/spec/tokenizers/calendars/date_tokenizer_spec.rb +11 -0
- data/spec/tokenizers/calendars/datetime_tokenizer_spec.rb +26 -0
- data/spec/tokenizers/composite_token_spec.rb +29 -0
- data/spec/utils/code_point_spec.rb +62 -0
- metadata +66 -99
- data/lib/ext/calendars/datetime.rb +0 -41
- data/lib/ext/numbers/localized_number.rb +0 -58
- data/lib/normalizers/base.rb +0 -17
- data/lib/normalizers/canonical/nfd.rb +0 -81
- data/lib/tokenizers/calendars/date_tokenizer.rb +0 -29
- data/lib/tokenizers/calendars/datetime_tokenizer.rb +0 -51
- data/spec/ext/calendars/datetime_spec.rb +0 -49
- data/spec/ext/numbers/localized_number_spec.rb +0 -59
- data/spec/normalizers/base_spec.rb +0 -16
- data/spec/normalizers/canonical/nfd_spec.rb +0 -50
data/README.md
CHANGED
@@ -144,6 +144,59 @@ TwitterCldr::Formatters::Plurals::Rules.rule_for(1, :ru) # :one
|
|
144
144
|
TwitterCldr::Formatters::Plurals::Rules.rule_for(2, :ru) # :few
|
145
145
|
```
|
146
146
|
|
147
|
+
### Plurals
|
148
|
+
|
149
|
+
In addition to providing access to plural rules, TwitterCLDR allows you to embed plurals directly in your source code:
|
150
|
+
|
151
|
+
```ruby
|
152
|
+
replacements = { :horse_count => 3,
|
153
|
+
:horses => { :one => "is 1 horse",
|
154
|
+
:other => "are %{horse_count} horses" } }
|
155
|
+
|
156
|
+
# "there are 3 horses in the barn"
|
157
|
+
"there %{horse_count:horses} in the barn".localize % replacements
|
158
|
+
```
|
159
|
+
|
160
|
+
Because providing a pluralization hash with the correct plural rules can be difficult, you can also embed plurals as a JSON hash into your string:
|
161
|
+
|
162
|
+
```ruby
|
163
|
+
str = 'there %<{ "horse_count": { "one": "is one horse", "other": "are %{horse_count} horses" } }> in the barn'
|
164
|
+
|
165
|
+
# "there are 3 horses in the barn"
|
166
|
+
str.localize % { :horse_count => 3 }
|
167
|
+
```
|
168
|
+
|
169
|
+
NOTE: If you're using TwitterCLDR with Rails 3, you may see an error if you try to use the `%` function on a localized string in your views. Strings in views in Rails 3 are instances of `SafeBuffer`, which patches the `gsub` method that the TwitterCLDR plural formatter relies on. To fix this issue, simply call `to_str` on any `SafeBuffer` before calling `localize`. More info [here](https://github.com/rails/rails/issues/1555). An example:
|
170
|
+
|
171
|
+
```ruby
|
172
|
+
# throws an error in Rails 3 views:
|
173
|
+
'%<{"count": {"one": "only one", "other": "tons more!"}}'.localize % { :count => 2 }
|
174
|
+
|
175
|
+
# works just fine:
|
176
|
+
'%<{"count": {"one": "only one", "other": "tons more!"}}'.to_str.localize % { :count => 2 }
|
177
|
+
```
|
178
|
+
|
179
|
+
The `LocalizedString` class supports all forms of interpolation and combines support from both Ruby 1.8 and 1.9:
|
180
|
+
|
181
|
+
```ruby
|
182
|
+
# Ruby 1.8
|
183
|
+
"five euros plus %.3f in tax" % (13.25 * 0.087)
|
184
|
+
|
185
|
+
# Ruby 1.9
|
186
|
+
"five euros plus %3.f in tax" % (13.25 * 0.087)
|
187
|
+
"there are %{count} horses in the barn" % { :count => "5" }
|
188
|
+
|
189
|
+
# with TwitterCLDR
|
190
|
+
"five euros plus %.3f in tax".localize % (13.25 * 0.087)
|
191
|
+
"there are %{count} horses in the barn".localize % { :count => "5" }
|
192
|
+
```
|
193
|
+
|
194
|
+
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:
|
195
|
+
|
196
|
+
```ruby
|
197
|
+
"five euros plus %<percent>.3f in %{noun}".localize % { :percent => 13.25 * 0.087, :noun => "tax" }
|
198
|
+
```
|
199
|
+
|
147
200
|
### World Languages
|
148
201
|
|
149
202
|
You can use the localize convenience method on language code symbols to get their equivalents in another language:
|
@@ -181,6 +234,51 @@ TwitterCldr::Shared::Languages.translate_language("chino tradicional", :es, :en)
|
|
181
234
|
TwitterCldr::Shared::Languages.translate_language("Traditional Chinese", :en, :es) # "chino tradicional"
|
182
235
|
```
|
183
236
|
|
237
|
+
### Unicode Data
|
238
|
+
|
239
|
+
TwitterCLDR provides ways to retrieve individual code points as well as normalize and decompose Unicode text.
|
240
|
+
|
241
|
+
Retrieve data for code points:
|
242
|
+
|
243
|
+
```ruby
|
244
|
+
code_point = TwitterCldr::Shared::UnicodeData.for_code_point("1F3E9")
|
245
|
+
code_point.name # "LOVE HOTEL"
|
246
|
+
code_point.bidi_mirrored # "N"
|
247
|
+
code_point.category # "So"
|
248
|
+
code_point.combining_class # "0"
|
249
|
+
```
|
250
|
+
|
251
|
+
Convert characters to code points:
|
252
|
+
|
253
|
+
```ruby
|
254
|
+
TwitterCldr::Normalizers::Base.char_to_code_point("¿") # "00BF"
|
255
|
+
```
|
256
|
+
|
257
|
+
Convert code points to characters:
|
258
|
+
|
259
|
+
```ruby
|
260
|
+
TwitterCldr::Normalizers::Base.code_point_to_char("00BF") # "¿"
|
261
|
+
```
|
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.
|
264
|
+
|
265
|
+
```ruby
|
266
|
+
TwitterCldr::Normalizers::NFD.normalize("français") # "français"
|
267
|
+
TwitterCldr::Normalizers::NFD.decompose("español") # "español"
|
268
|
+
```
|
269
|
+
|
270
|
+
Normalization and decomposition are easier to see in hex:
|
271
|
+
|
272
|
+
```ruby
|
273
|
+
# ["0065", "0073", "0070", "0061", "00F1", "006F", "006C"]
|
274
|
+
code_points = "español".split('').map { |char| TwitterCldr::Normalizers::NFD.char_to_code_point(char) }
|
275
|
+
|
276
|
+
# ["0065", "0073", "0070", "0061", "006E", "0303", "006F", "006C"]
|
277
|
+
TwitterCldr::Normalizers::NFD.normalize_code_points(code_points)
|
278
|
+
```
|
279
|
+
|
280
|
+
Notice in the example above that the letter "ñ" was transformed from `00F1` to `006E 0303`, which represent the "n" and the "˜" respectively.
|
281
|
+
|
184
282
|
## About Twitter-specific Locales
|
185
283
|
|
186
284
|
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/Rakefile
CHANGED
@@ -1,12 +1,11 @@
|
|
1
1
|
require 'rubygems' unless ENV['NO_RUBYGEMS']
|
2
2
|
|
3
|
-
require 'rspec/core/rake_task'
|
4
|
-
require 'rubygems/package_task'
|
5
|
-
require File.join(File.dirname(__FILE__), "lib/version")
|
6
|
-
|
7
3
|
require 'bundler'
|
8
4
|
require 'digest'
|
9
5
|
|
6
|
+
require 'rspec/core/rake_task'
|
7
|
+
require 'rubygems/package_task'
|
8
|
+
|
10
9
|
Bundler::GemHelper.install_tasks
|
11
10
|
|
12
11
|
task :default => :spec
|
@@ -16,6 +15,15 @@ RSpec::Core::RakeTask.new do |t|
|
|
16
15
|
t.pattern = './spec/**/*_spec.rb'
|
17
16
|
end
|
18
17
|
|
18
|
+
namespace :spec do
|
19
|
+
desc 'Run full specs suit'
|
20
|
+
task :full => [:full_spec_env, :spec]
|
21
|
+
|
22
|
+
task :full_spec_env do
|
23
|
+
ENV['FULL_SPEC'] = 'true'
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
19
27
|
if RUBY_VERSION < '1.9.0'
|
20
28
|
desc 'Run all examples with RCov'
|
21
29
|
RSpec::Core::RakeTask.new('spec:rcov') do |t|
|
@@ -4,8 +4,8 @@
|
|
4
4
|
# http://www.apache.org/licenses/LICENSE-2.0
|
5
5
|
|
6
6
|
class Date
|
7
|
-
def localize(locale = TwitterCldr.get_locale)
|
8
|
-
TwitterCldr::LocalizedDate.new(self, locale)
|
7
|
+
def localize(locale = TwitterCldr.get_locale, options = {})
|
8
|
+
TwitterCldr::LocalizedDate.new(self, locale, options)
|
9
9
|
end
|
10
10
|
end
|
11
11
|
|
@@ -13,7 +13,7 @@ module TwitterCldr
|
|
13
13
|
class LocalizedDate < LocalizedDateTime
|
14
14
|
def to_datetime(time)
|
15
15
|
time_obj = time.is_a?(LocalizedTime) ? time.base_obj : time
|
16
|
-
LocalizedDateTime.new(DateTime.parse("#{@base_obj.strftime("%Y-%m-%d")}T#{time_obj.strftime("%H:%M:%S%z")}"), @locale)
|
16
|
+
LocalizedDateTime.new(DateTime.parse("#{@base_obj.strftime("%Y-%m-%d")}T#{time_obj.strftime("%H:%M:%S%z")}"), @locale, :calendar_type => @calendar_type)
|
17
17
|
end
|
18
18
|
|
19
19
|
protected
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
# Copyright 2012 Twitter, Inc
|
4
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
5
|
+
|
6
|
+
class DateTime
|
7
|
+
def localize(locale = TwitterCldr.get_locale, options = {})
|
8
|
+
TwitterCldr::LocalizedDateTime.new(self, locale, options)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
module TwitterCldr
|
13
|
+
class LocalizedDateTime < LocalizedObject
|
14
|
+
attr_reader :calendar_type
|
15
|
+
|
16
|
+
def initialize(obj, locale, options = {})
|
17
|
+
super
|
18
|
+
@calendar_type = options[:calendar_type] || TwitterCldr::DEFAULT_CALENDAR_TYPE
|
19
|
+
end
|
20
|
+
|
21
|
+
TwitterCldr::Tokenizers::DateTimeTokenizer::VALID_TYPES.each do |format_type|
|
22
|
+
define_method "to_#{format_type}_s" do
|
23
|
+
@formatter.format(@base_obj, :type => format_type.to_sym)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def to_s
|
28
|
+
to_default_s
|
29
|
+
end
|
30
|
+
|
31
|
+
def to_date
|
32
|
+
LocalizedDate.new(Date.parse(@base_obj.strftime("%Y-%m-%dT%H:%M:%S%z")), @locale, :calendar_type => @calendar_type)
|
33
|
+
end
|
34
|
+
|
35
|
+
def to_time
|
36
|
+
LocalizedTime.new(Time.parse(@base_obj.strftime("%Y-%m-%dT%H:%M:%S%z")), @locale, :calendar_type => @calendar_type)
|
37
|
+
end
|
38
|
+
|
39
|
+
protected
|
40
|
+
|
41
|
+
def formatter_const
|
42
|
+
TwitterCldr::Formatters::DateTimeFormatter
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -4,8 +4,8 @@
|
|
4
4
|
# http://www.apache.org/licenses/LICENSE-2.0
|
5
5
|
|
6
6
|
class Time
|
7
|
-
def localize(locale = TwitterCldr.get_locale)
|
8
|
-
TwitterCldr::LocalizedTime.new(self, locale)
|
7
|
+
def localize(locale = TwitterCldr.get_locale, options = {})
|
8
|
+
TwitterCldr::LocalizedTime.new(self, locale, options)
|
9
9
|
end
|
10
10
|
end
|
11
11
|
|
@@ -13,7 +13,7 @@ module TwitterCldr
|
|
13
13
|
class LocalizedTime < LocalizedDateTime
|
14
14
|
def to_datetime(date)
|
15
15
|
date_obj = date.is_a?(LocalizedDate) ? date.base_obj : date
|
16
|
-
LocalizedDateTime.new(DateTime.parse("#{date_obj.strftime("%Y-%m-%d")}T#{@base_obj.strftime("%H:%M:%S%z")}"), @locale)
|
16
|
+
LocalizedDateTime.new(DateTime.parse("#{date_obj.strftime("%Y-%m-%d")}T#{@base_obj.strftime("%H:%M:%S%z")}"), @locale, :calendar_type => @calendar_type)
|
17
17
|
end
|
18
18
|
|
19
19
|
protected
|
@@ -7,10 +7,14 @@ module TwitterCldr
|
|
7
7
|
class LocalizedObject
|
8
8
|
attr_reader :locale, :base_obj, :formatter
|
9
9
|
|
10
|
-
def initialize(obj, locale)
|
10
|
+
def initialize(obj, locale, options = {})
|
11
11
|
@base_obj = obj
|
12
12
|
@locale = locale
|
13
|
-
|
13
|
+
|
14
|
+
options = options.dup
|
15
|
+
options[:locale] ||= @locale
|
16
|
+
|
17
|
+
@formatter = formatter_const.new(options) if formatter_const
|
14
18
|
end
|
15
19
|
|
16
20
|
def formatter_const
|
File without changes
|
File without changes
|
File without changes
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
# Copyright 2012 Twitter, Inc
|
4
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
5
|
+
|
6
|
+
module TwitterCldr
|
7
|
+
|
8
|
+
module LocalizedNumberMixin
|
9
|
+
def localize(locale = TwitterCldr.get_locale)
|
10
|
+
TwitterCldr::LocalizedNumber.new(self, locale)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class LocalizedNumber < LocalizedObject
|
15
|
+
TYPES = [:decimal, :currency, :percent]
|
16
|
+
DEFAULT_TYPE = :decimal
|
17
|
+
|
18
|
+
attr_reader :type
|
19
|
+
|
20
|
+
def initialize(obj, locale, options = {})
|
21
|
+
@options = options.dup
|
22
|
+
|
23
|
+
@type = @options.delete(:type) || DEFAULT_TYPE
|
24
|
+
raise ArgumentError.new("type #{@type} is not supported") unless @type && TYPES.include?(@type.to_sym)
|
25
|
+
|
26
|
+
super(obj, locale, @options)
|
27
|
+
end
|
28
|
+
|
29
|
+
TYPES.each do |type|
|
30
|
+
define_method "to_#{type}" do
|
31
|
+
to_type(type)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def to_s(options = {})
|
36
|
+
options = { :precision => 0 }.merge(options) if @base_obj.is_a?(Fixnum)
|
37
|
+
@formatter.format(@base_obj, options)
|
38
|
+
end
|
39
|
+
|
40
|
+
def plural_rule
|
41
|
+
TwitterCldr::Formatters::Plurals::Rules.rule_for(@base_obj, @locale)
|
42
|
+
end
|
43
|
+
|
44
|
+
protected
|
45
|
+
|
46
|
+
def formatter_const
|
47
|
+
TwitterCldr::Formatters.const_get("#{@type.to_s.capitalize}Formatter")
|
48
|
+
end
|
49
|
+
|
50
|
+
def to_type(target_type)
|
51
|
+
self.class.new(@base_obj, @locale, @options.merge(:type => target_type))
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
@@ -27,5 +27,17 @@ module TwitterCldr
|
|
27
27
|
TwitterCldr::Formatters::PluralFormatter
|
28
28
|
end
|
29
29
|
|
30
|
+
def normalize
|
31
|
+
LocalizedString.new(TwitterCldr::Normalizers::NFD.normalize(@base_obj), @locale)
|
32
|
+
end
|
33
|
+
|
34
|
+
def code_points
|
35
|
+
TwitterCldr::Utils::CodePoints.from_string(@base_obj)
|
36
|
+
end
|
37
|
+
|
38
|
+
def to_s
|
39
|
+
@base_obj.dup
|
40
|
+
end
|
41
|
+
|
30
42
|
end
|
31
43
|
end
|
File without changes
|
@@ -0,0 +1,10 @@
|
|
1
|
+
require 'twitter_cldr/core_ext/localized_object'
|
2
|
+
require 'twitter_cldr/core_ext/calendars/datetime'
|
3
|
+
require 'twitter_cldr/core_ext/calendars/date'
|
4
|
+
require 'twitter_cldr/core_ext/calendars/time'
|
5
|
+
require 'twitter_cldr/core_ext/numbers/localized_number'
|
6
|
+
require 'twitter_cldr/core_ext/numbers/bignum'
|
7
|
+
require 'twitter_cldr/core_ext/numbers/fixnum'
|
8
|
+
require 'twitter_cldr/core_ext/numbers/float'
|
9
|
+
require 'twitter_cldr/core_ext/symbol'
|
10
|
+
require 'twitter_cldr/core_ext/string'
|
@@ -9,26 +9,32 @@ module TwitterCldr
|
|
9
9
|
attr_reader :tokenizer
|
10
10
|
|
11
11
|
def format(obj, options = {})
|
12
|
-
|
12
|
+
process_tokens(self.get_tokens(obj, options), obj)
|
13
|
+
end
|
14
|
+
|
15
|
+
protected
|
13
16
|
|
14
|
-
|
17
|
+
def process_tokens(tokens, obj)
|
18
|
+
result = ''
|
19
|
+
|
20
|
+
tokens.each_with_index do |token, index|
|
15
21
|
case token.type
|
22
|
+
when :composite
|
23
|
+
result << eval(process_tokens(token.tokens, obj)).to_s
|
16
24
|
when :pattern
|
17
|
-
|
25
|
+
result << self.result_for_token(token, index, obj)
|
18
26
|
else
|
19
27
|
if token.value.size > 0 && token.value[0].chr == "'" && token.value[-1].chr == "'"
|
20
|
-
|
28
|
+
result << token.value[1..-2]
|
21
29
|
else
|
22
|
-
|
30
|
+
result << token.value
|
23
31
|
end
|
24
32
|
end
|
25
33
|
end
|
26
34
|
|
27
|
-
|
35
|
+
result
|
28
36
|
end
|
29
37
|
|
30
|
-
protected
|
31
|
-
|
32
38
|
def get_tokens(obj, options = {})
|
33
39
|
@tokenizer.tokens(options)
|
34
40
|
end
|
@@ -7,7 +7,7 @@ module TwitterCldr
|
|
7
7
|
module Formatters
|
8
8
|
class DateFormatter < DateTimeFormatter
|
9
9
|
def initialize(options = {})
|
10
|
-
@tokenizer = TwitterCldr::Tokenizers::DateTokenizer.new(:locale => extract_locale(options))
|
10
|
+
@tokenizer = TwitterCldr::Tokenizers::DateTokenizer.new(:locale => extract_locale(options), :calendar_type => options[:calendar_type])
|
11
11
|
end
|
12
12
|
end
|
13
13
|
end
|
@@ -41,7 +41,7 @@ module TwitterCldr
|
|
41
41
|
}
|
42
42
|
|
43
43
|
def initialize(options = {})
|
44
|
-
@tokenizer = TwitterCldr::Tokenizers::DateTimeTokenizer.new(:locale => extract_locale(options))
|
44
|
+
@tokenizer = TwitterCldr::Tokenizers::DateTimeTokenizer.new(:locale => extract_locale(options), :calendar_type => options[:calendar_type])
|
45
45
|
end
|
46
46
|
|
47
47
|
def result_for_token(token, index, date)
|
@@ -51,7 +51,7 @@ module TwitterCldr
|
|
51
51
|
protected
|
52
52
|
|
53
53
|
def era(date, pattern, length)
|
54
|
-
raise
|
54
|
+
raise NotImplementedError
|
55
55
|
end
|
56
56
|
|
57
57
|
def year(date, pattern, length)
|
@@ -62,11 +62,11 @@ module TwitterCldr
|
|
62
62
|
end
|
63
63
|
|
64
64
|
def year_of_week_of_year(date, pattern, length)
|
65
|
-
raise
|
65
|
+
raise NotImplementedError
|
66
66
|
end
|
67
67
|
|
68
68
|
def day_of_week_in_month(date, pattern, length) # e.g. 2nd Wed in July
|
69
|
-
raise
|
69
|
+
raise NotImplementedError
|
70
70
|
end
|
71
71
|
|
72
72
|
def quarter(date, pattern, length)
|
@@ -91,10 +91,10 @@ module TwitterCldr
|
|
91
91
|
when 2
|
92
92
|
quarter.to_s.rjust(length, '0')
|
93
93
|
when 3
|
94
|
-
raise '
|
94
|
+
raise NotImplementedError, 'requires cldr\'s "multiple inheritance"'
|
95
95
|
# @tokenizer.calendar[:quarters][:'stand-alone'][:abbreviated][key]
|
96
96
|
when 4
|
97
|
-
raise '
|
97
|
+
raise NotImplementedError, 'requires cldr\'s "multiple inheritance"'
|
98
98
|
# @tokenizer.calendar[:quarters][:'stand-alone'][:wide][key]
|
99
99
|
when 5
|
100
100
|
@tokenizer.calendar[:quarters][:'stand-alone'][:narrow][quarter]
|
@@ -112,7 +112,7 @@ module TwitterCldr
|
|
112
112
|
when 4
|
113
113
|
@tokenizer.calendar[:months][:format][:wide][date.month]
|
114
114
|
when 5
|
115
|
-
raise '
|
115
|
+
raise NotImplementedError, 'requires cldr\'s "multiple inheritance"'
|
116
116
|
@tokenizer.calendar[:months][:format][:narrow][date.month]
|
117
117
|
else
|
118
118
|
# raise unknown date format
|
@@ -126,10 +126,10 @@ module TwitterCldr
|
|
126
126
|
when 2
|
127
127
|
date.month.to_s.rjust(length, '0')
|
128
128
|
when 3
|
129
|
-
raise '
|
129
|
+
raise NotImplementedError, 'requires cldr\'s "multiple inheritance"'
|
130
130
|
@tokenizer.calendar[:months][:'stand-alone'][:abbreviated][date.month]
|
131
131
|
when 4
|
132
|
-
raise '
|
132
|
+
raise NotImplementedError, 'requires cldr\'s "multiple inheritance"'
|
133
133
|
@tokenizer.calendar[:months][:'stand-alone'][:wide][date.month]
|
134
134
|
when 5
|
135
135
|
@tokenizer.calendar[:months][:'stand-alone'][:narrow][date.month]
|
@@ -161,11 +161,11 @@ module TwitterCldr
|
|
161
161
|
|
162
162
|
def weekday_local(date, pattern, length)
|
163
163
|
# "Like E except adds a numeric value depending on the local starting day of the week"
|
164
|
-
raise '
|
164
|
+
raise NotImplementedError, 'need to defer a country to lookup the local first day of week from weekdata'
|
165
165
|
end
|
166
166
|
|
167
167
|
def weekday_local_stand_alone(date, pattern, length)
|
168
|
-
raise '
|
168
|
+
raise NotImplementedError, 'need to defer a country to lookup the local first day of week from weekdata'
|
169
169
|
end
|
170
170
|
|
171
171
|
def period(time, pattern, length)
|
@@ -196,7 +196,7 @@ module TwitterCldr
|
|
196
196
|
end
|
197
197
|
|
198
198
|
def second_fraction(time, pattern, length)
|
199
|
-
raise 'can not use the S format with more than 6 digits' if length > 6
|
199
|
+
raise ArgumentError.new('can not use the S format with more than 6 digits') if length > 6
|
200
200
|
(time.usec.to_f / 10 ** (6 - length)).round.to_s.rjust(length, '0')
|
201
201
|
end
|
202
202
|
|
@@ -210,7 +210,7 @@ module TwitterCldr
|
|
210
210
|
end
|
211
211
|
|
212
212
|
def timezone_generic_non_location(time, pattern, length)
|
213
|
-
raise '
|
213
|
+
raise NotImplementedError, 'requires timezone translation data'
|
214
214
|
end
|
215
215
|
|
216
216
|
def round_to(number, precision)
|
@@ -7,7 +7,7 @@ module TwitterCldr
|
|
7
7
|
module Formatters
|
8
8
|
class TimeFormatter < DateTimeFormatter
|
9
9
|
def initialize(options = {})
|
10
|
-
@tokenizer = TwitterCldr::Tokenizers::TimeTokenizer.new(:locale => extract_locale(options))
|
10
|
+
@tokenizer = TwitterCldr::Tokenizers::TimeTokenizer.new(:locale => extract_locale(options), :calendar_type => options[:calendar_type])
|
11
11
|
end
|
12
12
|
end
|
13
13
|
end
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -0,0 +1,14 @@
|
|
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 Formatters
|
8
|
+
module Numbers
|
9
|
+
autoload :Base, 'twitter_cldr/formatters/numbers/helpers/base'
|
10
|
+
autoload :Fraction, 'twitter_cldr/formatters/numbers/helpers/fraction'
|
11
|
+
autoload :Integer, 'twitter_cldr/formatters/numbers/helpers/integer'
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
File without changes
|
@@ -15,14 +15,14 @@ module TwitterCldr
|
|
15
15
|
def all_for(locale)
|
16
16
|
locale = TwitterCldr.convert_locale(locale.to_sym)
|
17
17
|
get_resource(locale)[locale][:i18n][:plural][:keys]
|
18
|
-
rescue
|
18
|
+
rescue
|
19
19
|
[]
|
20
20
|
end
|
21
21
|
|
22
22
|
def rule_for(number, locale = TwitterCldr::get_locale)
|
23
23
|
locale = TwitterCldr.convert_locale(locale.to_sym)
|
24
24
|
get_resource(locale)[locale][:i18n][:plural][:rule].call(number)
|
25
|
-
rescue
|
25
|
+
rescue
|
26
26
|
:other
|
27
27
|
end
|
28
28
|
|
@@ -0,0 +1,23 @@
|
|
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 Formatters
|
8
|
+
autoload :Base, 'twitter_cldr/formatters/base'
|
9
|
+
|
10
|
+
autoload :DateTimeFormatter, 'twitter_cldr/formatters/calendars/datetime_formatter'
|
11
|
+
autoload :DateFormatter, 'twitter_cldr/formatters/calendars/date_formatter'
|
12
|
+
autoload :TimeFormatter, 'twitter_cldr/formatters/calendars/time_formatter'
|
13
|
+
|
14
|
+
autoload :Numbers, 'twitter_cldr/formatters/numbers'
|
15
|
+
autoload :NumberFormatter, 'twitter_cldr/formatters/numbers/number_formatter'
|
16
|
+
autoload :DecimalFormatter, 'twitter_cldr/formatters/numbers/decimal_formatter'
|
17
|
+
autoload :CurrencyFormatter, 'twitter_cldr/formatters/numbers/currency_formatter'
|
18
|
+
autoload :PercentFormatter, 'twitter_cldr/formatters/numbers/percent_formatter'
|
19
|
+
|
20
|
+
autoload :Plurals, 'twitter_cldr/formatters/plurals'
|
21
|
+
autoload :PluralFormatter, 'twitter_cldr/formatters/plurals/plural_formatter'
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,30 @@
|
|
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 Normalizers
|
8
|
+
|
9
|
+
# Implements normalization of a Unicode string to Normalization Form D (NFD).
|
10
|
+
# This normalization includes only Canonical Decomposition.
|
11
|
+
#
|
12
|
+
class NFD < NFKD
|
13
|
+
|
14
|
+
class << self
|
15
|
+
|
16
|
+
protected
|
17
|
+
|
18
|
+
# Returns code point's Decomposition Mapping based on its Unicode data. Returns nil if the mapping has
|
19
|
+
# compatibility type (it contains compatibility formatting tag).
|
20
|
+
#
|
21
|
+
def decomposition_mapping(unicode_data)
|
22
|
+
mapping = parse_decomposition_mapping(unicode_data)
|
23
|
+
mapping unless compatibility_decomposition?(mapping)
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|