ruby-cldr 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Gemfile +7 -0
- data/Gemfile.lock +23 -0
- data/README.textile +9 -6
- data/VERSION +1 -1
- data/lib/cldr.rb +1 -1
- data/lib/cldr/data.rb +9 -29
- data/lib/cldr/download.rb +2 -2
- data/lib/cldr/export.rb +8 -2
- data/lib/cldr/export/code.rb +34 -0
- data/lib/cldr/export/code/numbers.rb +29 -0
- data/lib/cldr/export/data.rb +36 -0
- data/lib/cldr/export/data/base.rb +61 -0
- data/lib/cldr/export/data/calendars.rb +14 -0
- data/lib/cldr/export/data/calendars/gregorian.rb +142 -0
- data/lib/cldr/export/data/currencies.rb +28 -0
- data/lib/cldr/export/data/delimiters.rb +29 -0
- data/lib/cldr/export/data/languages.rb +19 -0
- data/lib/cldr/export/data/numbers.rb +67 -0
- data/lib/cldr/export/data/plurals.rb +41 -0
- data/lib/cldr/{data → export/data}/plurals/cldr_grammar.treetop +0 -0
- data/lib/cldr/export/data/plurals/grammar.rb +538 -0
- data/lib/cldr/export/data/plurals/rules.rb +119 -0
- data/lib/cldr/export/data/territories.rb +19 -0
- data/lib/cldr/export/data/timezones.rb +27 -0
- data/lib/cldr/export/data/units.rb +29 -0
- data/lib/cldr/export/ruby.rb +1 -1
- data/lib/cldr/export/yaml.rb +1 -1
- data/lib/cldr/format.rb +1 -97
- data/lib/cldr/format/currency.rb +1 -1
- data/lib/cldr/format/date.rb +1 -1
- data/lib/cldr/format/datetime.rb +14 -18
- data/lib/cldr/format/datetime/base.rb +1 -1
- data/lib/cldr/format/decimal.rb +1 -1
- data/lib/cldr/format/decimal/base.rb +1 -1
- data/lib/cldr/format/decimal/fraction.rb +1 -1
- data/lib/cldr/format/decimal/integer.rb +1 -1
- data/lib/cldr/format/decimal/number.rb +1 -1
- data/lib/cldr/format/percent.rb +1 -1
- data/lib/cldr/format/time.rb +1 -1
- data/lib/cldr/thor.rb +3 -3
- data/test/all.rb +1 -1
- data/test/export/code/numbers_test.rb +11 -0
- data/test/{data → export/data}/all.rb +1 -1
- data/test/{data → export/data}/calendars_test.rb +18 -18
- data/test/{data → export/data}/currencies_test.rb +6 -6
- data/test/{data → export/data}/delimiters_test.rb +6 -6
- data/test/{data → export/data}/languages_test.rb +6 -6
- data/test/{data → export/data}/numbers_test.rb +8 -8
- data/test/export/data/plurals_test.rb +141 -0
- data/test/{data → export/data}/territories_test.rb +6 -6
- data/test/{data → export/data}/timezones_test.rb +6 -6
- data/test/{data → export/data}/units_test.rb +6 -6
- data/test/export_test.rb +8 -8
- data/test/{formats → format}/all.rb +1 -1
- data/test/format/currency_test.rb +0 -0
- data/test/format/date_test.rb +265 -0
- data/test/format/datetime_test.rb +18 -0
- data/test/{formats → format}/decimal/fraction_test.rb +4 -4
- data/test/{formats → format}/decimal/integer_test.rb +17 -17
- data/test/{formats → format}/decimal/number_test.rb +19 -19
- data/test/{formats → format}/decimal_test.rb +5 -5
- data/test/format/percent_test.rb +0 -0
- data/test/format/time_test.rb +195 -0
- data/test/test_autotest.rb +36 -0
- data/test/test_helper.rb +16 -1
- metadata +124 -114
- data/lib/cldr/data/base.rb +0 -66
- data/lib/cldr/data/calendars.rb +0 -12
- data/lib/cldr/data/calendars/gregorian.rb +0 -124
- data/lib/cldr/data/currencies.rb +0 -26
- data/lib/cldr/data/delimiters.rb +0 -21
- data/lib/cldr/data/languages.rb +0 -17
- data/lib/cldr/data/numbers.rb +0 -60
- data/lib/cldr/data/plurals.rb +0 -39
- data/lib/cldr/data/plurals/grammar.rb +0 -536
- data/lib/cldr/data/plurals/rules.rb +0 -113
- data/lib/cldr/data/territories.rb +0 -17
- data/lib/cldr/data/timezones.rb +0 -25
- data/lib/cldr/data/units.rb +0 -25
- data/test/data/plurals_test.rb +0 -132
- data/test/formats/datetime/all.rb +0 -3
- data/test/formats/datetime/date_test.rb +0 -31
- data/test/formats/datetime/datetime_test.rb +0 -18
- data/test/formats/datetime/day_test.rb +0 -41
- data/test/formats/datetime/hour_test.rb +0 -79
- data/test/formats/datetime/minute_test.rb +0 -25
- data/test/formats/datetime/month_test.rb +0 -76
- data/test/formats/datetime/period_test.rb +0 -20
- data/test/formats/datetime/quarter_test.rb +0 -118
- data/test/formats/datetime/second_test.rb +0 -80
- data/test/formats/datetime/time_test.rb +0 -33
- data/test/formats/datetime/timezone_test.rb +0 -23
- data/test/formats/datetime/year_test.rb +0 -57
- data/test/formats/format_test.rb +0 -66
- data/test/formats/rails_compat/all.rb +0 -3
- data/test/formats/rails_compat/format_integer_test.rb +0 -56
- data/test/formats/rails_compat/format_number_test.rb +0 -134
@@ -0,0 +1,119 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rexml/document'
|
3
|
+
|
4
|
+
module Cldr
|
5
|
+
module Export
|
6
|
+
module Data
|
7
|
+
class Plurals
|
8
|
+
class Rules < Array
|
9
|
+
class << self
|
10
|
+
def parse(xml)
|
11
|
+
rules = new
|
12
|
+
REXML::Document.new(xml).elements.each('//pluralRules') do |tag|
|
13
|
+
rule = Rule.new(tag.attributes['locales'].split(/\s+/))
|
14
|
+
tag.elements.each('pluralRule') { |tag| rule << [tag.attributes['count'], tag.text] }
|
15
|
+
rules << rule
|
16
|
+
end
|
17
|
+
rules
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def locales
|
22
|
+
@locales ||= map { |rule| rule.locales }.flatten.map(&:to_s).sort.map(&:to_sym)
|
23
|
+
end
|
24
|
+
|
25
|
+
def rule(locale)
|
26
|
+
detect { |rule| rule.locales.include?(locale.to_sym) }
|
27
|
+
end
|
28
|
+
|
29
|
+
def to_ruby(options = {})
|
30
|
+
namespaces = options[:namespaces] || [:i18n]
|
31
|
+
code = locales.map do |locale|
|
32
|
+
rule = self.rule(locale)
|
33
|
+
ruby = "{ :plural => { :keys => #{rule.keys.inspect}, :rule => #{rule.to_ruby} } }"
|
34
|
+
ruby = namespaces.reverse.inject(ruby) { |ruby, namespace| "{ #{namespace.inspect} => #{ruby} }"}
|
35
|
+
"#{locale.inspect} => #{ruby}"
|
36
|
+
end.join(",\n")
|
37
|
+
code = code.split("\n").map { |line| " #{line}" }.join("\n")
|
38
|
+
"{\n" + code + "\n}"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
class Rule < Array
|
43
|
+
class << self
|
44
|
+
def parse(code)
|
45
|
+
case code
|
46
|
+
when /and/
|
47
|
+
code.split(/and/).inject(Proposition.new('&&')) { |rule, code| rule << parse(code) }
|
48
|
+
when /or/
|
49
|
+
code.split(/or/).inject(Proposition.new('||')) { |rule, code| rule << parse(code) }
|
50
|
+
when /n( mod ([\d]+))? is (not )?([\d]+)/
|
51
|
+
Expression.new(:is, $2, !!$3, $4)
|
52
|
+
when /n( mod ([\d]+))?( not)? in ([\d]+\.\.[\d]+)/
|
53
|
+
Expression.new(:in, $2, !!$3, eval($4).to_a.inspect)
|
54
|
+
when /n within ([\d]+)\.\.([\d]+)/
|
55
|
+
Expression.new(:within, nil, nil, [$1, $2])
|
56
|
+
when /n/
|
57
|
+
Expression.new
|
58
|
+
else
|
59
|
+
raise "can not parse #{code}"
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
attr_reader :locales
|
65
|
+
|
66
|
+
def initialize(locales)
|
67
|
+
@locales = locales.map { |locale| locale.gsub('_', '-').to_sym }
|
68
|
+
end
|
69
|
+
|
70
|
+
def keys
|
71
|
+
inject([]) { |keys, (key, code)| keys << key.to_sym } << :other
|
72
|
+
end
|
73
|
+
|
74
|
+
def to_ruby
|
75
|
+
@condition ||= 'lambda { |n| ' + reverse.inject(':other') do |result, (key, code)|
|
76
|
+
code = self.class.parse(code).to_ruby
|
77
|
+
"#{code} ? :#{key} : #{result}"
|
78
|
+
end + ' }'
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
class Proposition < Array
|
83
|
+
def initialize(type = nil)
|
84
|
+
@type = type
|
85
|
+
end
|
86
|
+
|
87
|
+
def to_ruby
|
88
|
+
@ruby ||= map { |expr| expr.to_ruby }.join(" #{@type} ")
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
class Expression
|
93
|
+
attr_reader :operator, :operand, :mod, :negate
|
94
|
+
|
95
|
+
def initialize(operator = nil, mod = nil, negate = nil, operand = nil)
|
96
|
+
@operator, @mod, @negate, @operand = operator, mod, negate, operand
|
97
|
+
end
|
98
|
+
|
99
|
+
def to_ruby
|
100
|
+
@ruby ||= begin
|
101
|
+
op = 'n'
|
102
|
+
op << " % #{@mod}" if mod
|
103
|
+
case @operator
|
104
|
+
when :is
|
105
|
+
op + (@negate ? ' != ' : ' == ') + @operand
|
106
|
+
when :in
|
107
|
+
(@negate ? '!' : '') + "#{@operand}.include?(#{op})"
|
108
|
+
when :within
|
109
|
+
"#{op}.between?(#{@operand.first}, #{@operand.last})"
|
110
|
+
else
|
111
|
+
op
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Cldr
|
2
|
+
module Export
|
3
|
+
module Data
|
4
|
+
class Territories < Base
|
5
|
+
def initialize(locale)
|
6
|
+
super
|
7
|
+
update(:territories => territories)
|
8
|
+
end
|
9
|
+
|
10
|
+
def territories
|
11
|
+
@territories ||= select('localeDisplayNames/territories/territory').inject({}) do |result, node|
|
12
|
+
result[node.attribute('type').value.to_sym] = node.content unless draft?(node)
|
13
|
+
result
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# I probably don't really get timezones.
|
2
|
+
|
3
|
+
module Cldr
|
4
|
+
module Export
|
5
|
+
module Data
|
6
|
+
class Timezones < Base
|
7
|
+
def initialize(locale)
|
8
|
+
super
|
9
|
+
update(:timezones => timezones)
|
10
|
+
end
|
11
|
+
|
12
|
+
def timezones
|
13
|
+
@timezones ||= select('dates/timeZoneNames/zone').inject({}) do |result, zone|
|
14
|
+
type = zone.attribute('type').value.to_sym
|
15
|
+
city = select(zone, 'exemplarCity').first
|
16
|
+
result[type] = {}
|
17
|
+
# see en.xml, Europe/London, does not have an exemplarCity element
|
18
|
+
# instead it has long and short daylight names which otherwise only
|
19
|
+
# have metazones. (??)
|
20
|
+
result[type][:city] = city.content if city
|
21
|
+
result
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Cldr
|
2
|
+
module Export
|
3
|
+
module Data
|
4
|
+
class Units < Base
|
5
|
+
def initialize(locale)
|
6
|
+
super
|
7
|
+
update(:units => units)
|
8
|
+
end
|
9
|
+
|
10
|
+
def units
|
11
|
+
select('units/unit').inject({}) do |result, node|
|
12
|
+
result[node.attribute('type').value.to_sym] = unit(node)
|
13
|
+
result
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def unit(node)
|
18
|
+
node.xpath('unitPattern').inject({}) do |result, node|
|
19
|
+
alt = node.attribute('alt') ? node.attribute('alt').value.to_sym : :default
|
20
|
+
count = node.attribute('count') ? node.attribute('count').value.to_sym : :one
|
21
|
+
result[alt] ||= {}
|
22
|
+
result[alt][count] = node.content unless draft?(node)
|
23
|
+
result
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/lib/cldr/export/ruby.rb
CHANGED
data/lib/cldr/export/yaml.rb
CHANGED
data/lib/cldr/format.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
require 'core_ext/string/camelize'
|
3
3
|
|
4
|
-
|
4
|
+
module Cldr
|
5
5
|
module Format
|
6
6
|
autoload :Base, 'cldr/format/base'
|
7
7
|
autoload :Currency, 'cldr/format/currency'
|
@@ -13,101 +13,5 @@ class Cldr
|
|
13
13
|
autoload :Numeric, 'cldr/format/numeric'
|
14
14
|
autoload :Percent, 'cldr/format/percent'
|
15
15
|
autoload :Time, 'cldr/format/time'
|
16
|
-
|
17
|
-
def format(locale, object, options = {})
|
18
|
-
type = options.has_key?(:currency) ? :currency : options.delete(:as)
|
19
|
-
type ||= guess_type(object)
|
20
|
-
|
21
|
-
send(:"format_#{type}", locale, object, options)
|
22
|
-
end
|
23
|
-
|
24
|
-
def format_decimal(locale, number, options = {})
|
25
|
-
formatter(locale, :decimal, options.delete(:format)).apply(number, options)
|
26
|
-
end
|
27
|
-
alias :format_number :format_decimal
|
28
|
-
|
29
|
-
def format_integer(locale, number, options = {})
|
30
|
-
format_number(number, options.merge(:precision => 0))
|
31
|
-
end
|
32
|
-
alias :format_int :format_integer
|
33
|
-
|
34
|
-
def format_currency(locale, number, options = {})
|
35
|
-
if options[:currency].is_a?(Symbol)
|
36
|
-
options.merge!(:currency => lookup_currency(locale, options[:currency], number))
|
37
|
-
end
|
38
|
-
formatter(locale, :currency, options.delete(:format)).apply(number, options)
|
39
|
-
end
|
40
|
-
|
41
|
-
def format_percent(locale, number, options = {})
|
42
|
-
formatter(locale, :percent, options.delete(:format)).apply(number, options)
|
43
|
-
end
|
44
|
-
|
45
|
-
def format_date(locale, date, options = {})
|
46
|
-
formatter(locale, :date, options.delete(:format)).apply(date, options)
|
47
|
-
end
|
48
|
-
|
49
|
-
def format_time(locale, time, options = {})
|
50
|
-
formatter(locale, :time, options.delete(:format)).apply(time, options)
|
51
|
-
end
|
52
|
-
|
53
|
-
def format_datetime(locale, datetime, options = {})
|
54
|
-
format = options.delete(:format) || :default
|
55
|
-
(@formatters ||= {})[:"#{locale}.datetime.#{format}"] ||= begin
|
56
|
-
date = formatter(locale, :date, options.delete(:date_format) || format)
|
57
|
-
time = formatter(locale, :time, options.delete(:time_format) || format)
|
58
|
-
format = lookup_format(locale, :datetime, format)
|
59
|
-
Cldr::Format::Datetime.new(format, date, time).apply(datetime, options)
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
protected
|
64
|
-
|
65
|
-
def guess_type(object)
|
66
|
-
case object
|
67
|
-
when ::Numeric
|
68
|
-
:number
|
69
|
-
when ::Date, ::DateTime, ::Time
|
70
|
-
object.class.name.downcase
|
71
|
-
else
|
72
|
-
raise_unspecified_format_type!
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
def formatter(locale, type, format)
|
77
|
-
(@formatters ||= {})[:"#{locale}.#{type}.#{format}"] ||= begin
|
78
|
-
format = lookup_format(locale, type, format)
|
79
|
-
data = lookup_format_data(locale, type)
|
80
|
-
Cldr::Format.const_get(type.to_s.camelize).new(format, data)
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
def lookup_format(locale, type, format)
|
85
|
-
# Lookup the format string for the given type (e.g. :number).
|
86
|
-
raise_abstract!
|
87
|
-
end
|
88
|
-
|
89
|
-
def lookup_format_data(locale, type)
|
90
|
-
# Lookup the format data required for the given type (e.g. number
|
91
|
-
# symbols for type :number, calendar data for type :date etc.).
|
92
|
-
raise_abstract!
|
93
|
-
end
|
94
|
-
|
95
|
-
def lookup_currency(locale, currency, count)
|
96
|
-
# Lookup the currency representation for the given locale and amount.
|
97
|
-
# This might be a translation.
|
98
|
-
raise_abstract!
|
99
|
-
end
|
100
|
-
|
101
|
-
def raise_unspecified_format_type!
|
102
|
-
raise ArgumentError.new("You have to specify a format type, e.g. :as => :number.")
|
103
|
-
end
|
104
|
-
|
105
|
-
def raise_unspecified_currency!
|
106
|
-
raise ArgumentError.new("You have to specify a currency, e.g. :currency => 'EUR'.")
|
107
|
-
end
|
108
|
-
|
109
|
-
def raise_abstract!
|
110
|
-
raise "you have to implement this method"
|
111
|
-
end
|
112
16
|
end
|
113
17
|
end
|
data/lib/cldr/format/currency.rb
CHANGED
data/lib/cldr/format/date.rb
CHANGED
data/lib/cldr/format/datetime.rb
CHANGED
@@ -1,28 +1,24 @@
|
|
1
|
-
|
1
|
+
module Cldr
|
2
2
|
module Format
|
3
3
|
class Datetime
|
4
4
|
autoload :Base, 'cldr/format/datetime/base'
|
5
5
|
|
6
|
-
attr_reader :date, :time
|
7
|
-
|
6
|
+
attr_reader :format, :date, :time
|
7
|
+
|
8
8
|
def initialize(format, date, time)
|
9
|
-
@date, @time = date, time
|
10
|
-
compile(format)
|
9
|
+
@format, @date, @time = format, date, time
|
11
10
|
end
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
def compile_format(format)
|
22
|
-
"'" + format.gsub(%r(\{(0|1)\})) do |token|
|
23
|
-
"' + #{token == '{0}' ? 'time' : 'date'}.apply(datetime, options) + '"
|
24
|
-
end + "'"
|
11
|
+
|
12
|
+
def apply(datetime, options = {})
|
13
|
+
format.gsub(/(\{\{(date|time)\}\})/) do
|
14
|
+
case $2
|
15
|
+
when 'date'
|
16
|
+
options[:date] || date.apply(datetime, options)
|
17
|
+
when 'time'
|
18
|
+
options[:time] || time.apply(datetime, options)
|
19
|
+
end
|
25
20
|
end
|
21
|
+
end
|
26
22
|
end
|
27
23
|
end
|
28
24
|
end
|
data/lib/cldr/format/decimal.rb
CHANGED
data/lib/cldr/format/percent.rb
CHANGED
data/lib/cldr/format/time.rb
CHANGED