ruby-cldr 0.0.2 → 0.1.0

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.
Files changed (41) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +8 -2
  3. data/Gemfile.lock +55 -5
  4. data/VERSION +1 -1
  5. data/lib/cldr/download.rb +15 -11
  6. data/lib/cldr/export.rb +64 -16
  7. data/lib/cldr/export/data.rb +18 -10
  8. data/lib/cldr/export/data/calendars/gregorian.rb +45 -22
  9. data/lib/cldr/export/data/currencies.rb +6 -1
  10. data/lib/cldr/export/data/currency_digits_and_rounding.rb +22 -0
  11. data/lib/cldr/export/data/layout.rb +22 -0
  12. data/lib/cldr/export/data/lists.rb +28 -0
  13. data/lib/cldr/export/data/metazones.rb +45 -0
  14. data/lib/cldr/export/data/numbering_systems.rb +41 -0
  15. data/lib/cldr/export/data/numbers.rb +9 -0
  16. data/lib/cldr/export/data/plurals.rb +8 -7
  17. data/lib/cldr/export/data/plurals/rules.rb +114 -31
  18. data/lib/cldr/export/data/rbnf.rb +64 -0
  19. data/lib/cldr/export/data/rbnf_root.rb +19 -0
  20. data/lib/cldr/export/data/timezones.rb +29 -6
  21. data/lib/cldr/export/data/units.rb +23 -6
  22. data/lib/cldr/export/data/windows_zones.rb +23 -0
  23. data/lib/cldr/export/yaml.rb +2 -1
  24. data/lib/cldr/format/datetime/base.rb +1 -1
  25. data/lib/cldr/format/time.rb +1 -1
  26. data/lib/cldr/thor.rb +1 -1
  27. data/lib/core_ext/string/camelize.rb +1 -1
  28. data/test/export/data/calendars_test.rb +23 -18
  29. data/test/export/data/currencies_test.rb +24 -24
  30. data/test/export/data/languages_test.rb +52 -48
  31. data/test/export/data/metazones_test.rb +17 -0
  32. data/test/export/data/numbers_test.rb +34 -3
  33. data/test/export/data/plurals_test.rb +133 -32
  34. data/test/export/data/territories_test.rb +22 -22
  35. data/test/export/data/timezones_test.rb +49 -26
  36. data/test/export/data/units_test.rb +16 -17
  37. data/test/export/data/windows_zones_test.rb +12 -0
  38. data/test/export_test.rb +4 -1
  39. data/test/format/date_test.rb +2 -2
  40. data/test/test_autotest.rb +1 -1
  41. metadata +94 -32
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 81ab6a59909b72f15381d80ca49053ca46bc54fb
4
+ data.tar.gz: 32e6c9fcd5291e54460abaeafc0f12189cc541e6
5
+ SHA512:
6
+ metadata.gz: fd2828beca0c9f5828cfcf9b25c5e973d8183ab17b7b93e5dfab4d6b1e92002fa5706d52f8a8ada8b840b18043bdb5bfb4a14379993753b4c536abd411f2139a
7
+ data.tar.gz: e51615436d0dfb6718627014defbdeff88093345aa00467e325cad301ac6a5b9c868a85ad8d4c72eacf872f898a4dacfae7e71e81fbf0f2608c47d10e82b3af7
data/Gemfile CHANGED
@@ -1,7 +1,13 @@
1
- source :gemcutter
1
+ source "http://rubygems.org"
2
2
 
3
3
  gem 'thor'
4
4
  gem 'i18n'
5
5
  gem 'ya2yaml'
6
6
  gem 'nokogiri'
7
- gem 'jeweler', :group => :development
7
+
8
+ group :development do
9
+ gem 'rubyzip'
10
+ gem 'jeweler'
11
+ gem 'pry'
12
+ gem 'pry-nav'
13
+ end
data/Gemfile.lock CHANGED
@@ -1,14 +1,61 @@
1
1
  GEM
2
2
  remote: http://rubygems.org/
3
3
  specs:
4
- git (1.2.5)
4
+ addressable (2.3.5)
5
+ builder (3.2.2)
6
+ coderay (1.0.9)
7
+ descendants_tracker (0.0.3)
8
+ faraday (0.9.0)
9
+ multipart-post (>= 1.2, < 3)
10
+ git (1.2.6)
11
+ github_api (0.11.2)
12
+ addressable (~> 2.3)
13
+ descendants_tracker (~> 0.0.1)
14
+ faraday (~> 0.8, < 0.10)
15
+ hashie (>= 1.2)
16
+ multi_json (>= 1.7.5, < 2.0)
17
+ nokogiri (~> 1.6.0)
18
+ oauth2
19
+ hashie (2.0.5)
20
+ highline (1.6.20)
5
21
  i18n (0.6.0)
6
- jeweler (1.6.4)
7
- bundler (~> 1.0)
22
+ jeweler (2.0.1)
23
+ builder
24
+ bundler (>= 1.0)
8
25
  git (>= 1.2.5)
26
+ github_api
27
+ highline (>= 1.6.15)
28
+ nokogiri (>= 1.5.10)
9
29
  rake
10
- nokogiri (1.5.0)
11
- rake (0.9.2.2)
30
+ rdoc
31
+ json (1.8.1)
32
+ jwt (0.1.11)
33
+ multi_json (>= 1.5)
34
+ method_source (0.8.1)
35
+ mini_portile (0.5.2)
36
+ multi_json (1.8.4)
37
+ multi_xml (0.5.5)
38
+ multipart-post (2.0.0)
39
+ nokogiri (1.6.1)
40
+ mini_portile (~> 0.5.0)
41
+ oauth2 (0.9.3)
42
+ faraday (>= 0.8, < 0.10)
43
+ jwt (~> 0.1.8)
44
+ multi_json (~> 1.3)
45
+ multi_xml (~> 0.5)
46
+ rack (~> 1.2)
47
+ pry (0.9.12)
48
+ coderay (~> 1.0.5)
49
+ method_source (~> 0.8)
50
+ slop (~> 3.4)
51
+ pry-nav (0.2.3)
52
+ pry (~> 0.9.10)
53
+ rack (1.5.2)
54
+ rake (10.1.1)
55
+ rdoc (4.1.1)
56
+ json (~> 1.4)
57
+ rubyzip (1.1.0)
58
+ slop (3.4.3)
12
59
  thor (0.14.6)
13
60
  ya2yaml (0.30)
14
61
 
@@ -19,5 +66,8 @@ DEPENDENCIES
19
66
  i18n
20
67
  jeweler
21
68
  nokogiri
69
+ pry
70
+ pry-nav
71
+ rubyzip
22
72
  thor
23
73
  ya2yaml
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.2
1
+ 0.1.0
data/lib/cldr/download.rb CHANGED
@@ -1,20 +1,24 @@
1
- require 'fileutils'
2
- require 'net/http'
3
1
  require 'uri'
4
- require 'tempfile'
2
+ require 'open-uri'
3
+ require 'zip'
5
4
 
6
5
  module Cldr
7
6
  class << self
8
7
  def download(source = nil, target = nil)
9
- source ||= 'http://unicode.org/Public/cldr/21/core.zip'
8
+ source ||= 'http://unicode.org/Public/cldr/24/core.zip'
10
9
  target ||= File.expand_path('./vendor/cldr')
11
10
 
12
- source = URI.parse(source)
13
- tempfile = Tempfile.new('cldr-core')
14
-
15
- system("curl #{source} -o #{tempfile.path}")
16
- FileUtils.mkdir_p(target)
17
- system("unzip #{tempfile.path} -d #{target}")
11
+ URI.parse(source).open do |tempfile|
12
+ FileUtils.mkdir_p(target)
13
+ Zip.on_exists_proc = true
14
+ Zip::File.open(tempfile.path) do |file|
15
+ file.each do |entry|
16
+ path = target + '/' + entry.name
17
+ FileUtils.mkdir_p(File.dirname(path))
18
+ file.extract(entry, path)
19
+ end
20
+ end
21
+ end
18
22
  end
19
23
  end
20
- end
24
+ end
data/lib/cldr/export.rb CHANGED
@@ -3,6 +3,7 @@ require 'i18n/locale/fallbacks'
3
3
  require 'core_ext/string/camelize'
4
4
  require 'core_ext/string/underscore'
5
5
  require 'core_ext/hash/deep_stringify_keys'
6
+ require 'core_ext/hash/deep_merge'
6
7
 
7
8
  module Cldr
8
9
  module Export
@@ -11,6 +12,14 @@ module Cldr
11
12
  autoload :Ruby, 'cldr/export/ruby'
12
13
  autoload :Yaml, 'cldr/export/yaml'
13
14
 
15
+ SHARED_COMPONENTS = [
16
+ 'CurrencyDigitsAndRounding',
17
+ 'RbnfRoot',
18
+ 'Metazones',
19
+ 'WindowsZones',
20
+ 'NumberingSystems'
21
+ ]
22
+
14
23
  class << self
15
24
  def base_path
16
25
  @@base_path ||= File.expand_path('./data')
@@ -22,11 +31,20 @@ module Cldr
22
31
 
23
32
  def export(options = {}, &block)
24
33
  locales = options[:locales] || Data.locales
25
- components = options[:components] || Data.components
34
+ components = (options[:components] || Data.components).map { |c| c.to_s.camelize }
26
35
  self.base_path = options[:target] if options[:target]
27
36
 
37
+ shared_components, locale_components = components.partition do |component|
38
+ is_shared_component?(component)
39
+ end
40
+
41
+ shared_components.each do |component|
42
+ ex = exporter(component, options[:format])
43
+ ex.export('', component, options, &block)
44
+ end
45
+
28
46
  locales.each do |locale|
29
- components.each do |component|
47
+ locale_components.each do |component|
30
48
  exporter(component, options[:format]).export(locale, component, options, &block)
31
49
  end
32
50
  end
@@ -38,26 +56,45 @@ module Cldr
38
56
  end
39
57
 
40
58
  def data(component, locale, options = {})
41
- if component.to_s == 'Plurals'
42
- Data.const_get(component.to_s.camelize).new(locale)
43
- else
44
- data = locales(locale, options).inject({}) do |result, locale|
45
- data = Data.const_get(component.to_s.camelize).new(locale)
46
- if data
47
- data.is_a?(Hash) ? data.deep_merge(result) : data
59
+ case component.to_s
60
+ when 'Plurals'
61
+ plural_data(component, locale, options)
62
+ else
63
+ if is_shared_component?(component)
64
+ shared_data(component, options)
48
65
  else
49
- result
66
+ locale_based_data(component, locale, options)
50
67
  end
68
+ end
69
+ end
70
+
71
+ def locale_based_data(component, locale, options = {})
72
+ data = locales(locale, component, options).inject({}) do |result, locale|
73
+ data = Data.const_get(component.to_s.camelize).new(locale)
74
+ if data
75
+ data.is_a?(Hash) ? data.deep_merge(result) : data
76
+ else
77
+ result
51
78
  end
52
- # data = resolve_links if options[:merge] TODO!!
53
- data
54
79
  end
80
+
81
+ # data = resolve_links if options[:merge] TODO!!
82
+ data
55
83
  end
56
84
 
57
- def locales(locale, options)
85
+ def plural_data(component, locale, options = {})
86
+ data = locale_based_data(component, locale, options)
87
+ "{ :'#{locale}' => { :i18n => { :plural => { :keys => #{data[:keys].inspect}, :rule => #{data[:rule]} } } } }"
88
+ end
89
+
90
+ def shared_data(component, options = {})
91
+ Data.const_get(component.to_s.camelize).new
92
+ end
93
+
94
+ def locales(locale, component, options)
58
95
  locale = locale.to_s.gsub('_', '-')
59
- locales = options[:merge] ? I18n::Locale::Fallbacks.new[locale.to_sym] : [locale.to_sym]
60
- locales << :root
96
+ locales = options[:merge] ? I18n::Locale::Fallbacks.new[locale.to_sym] : [locale.to_sym]
97
+ locales << :root if component_should_merge_root?(component)
61
98
  locales
62
99
  end
63
100
 
@@ -68,7 +105,18 @@ module Cldr
68
105
  end
69
106
 
70
107
  def path(locale, component, extension)
71
- "#{Export.base_path}/#{locale.to_s.gsub('_', '-')}/#{component.to_s.underscore}.#{extension}"
108
+ path = [Export.base_path]
109
+ path << locale.to_s.gsub('_', '-') unless is_shared_component?(component)
110
+ path << "#{component.to_s.underscore}.#{extension}"
111
+ File.join(*path)
112
+ end
113
+
114
+ def is_shared_component?(component)
115
+ SHARED_COMPONENTS.include?(component)
116
+ end
117
+
118
+ def component_should_merge_root?(component)
119
+ component != "Rbnf"
72
120
  end
73
121
  end
74
122
  end
@@ -3,16 +3,24 @@ require 'core_ext/string/camelize'
3
3
  module Cldr
4
4
  module Export
5
5
  module Data
6
- autoload :Base, 'cldr/export/data/base'
7
- autoload :Calendars, 'cldr/export/data/calendars'
8
- autoload :Currencies, 'cldr/export/data/currencies'
9
- autoload :Delimiters, 'cldr/export/data/delimiters'
10
- autoload :Languages, 'cldr/export/data/languages'
11
- autoload :Numbers, 'cldr/export/data/numbers'
12
- autoload :Plurals, 'cldr/export/data/plurals'
13
- autoload :Territories, 'cldr/export/data/territories'
14
- autoload :Timezones, 'cldr/export/data/timezones'
15
- autoload :Units, 'cldr/export/data/units'
6
+ autoload :Base, 'cldr/export/data/base'
7
+ autoload :Calendars, 'cldr/export/data/calendars'
8
+ autoload :Currencies, 'cldr/export/data/currencies'
9
+ autoload :CurrencyDigitsAndRounding, 'cldr/export/data/currency_digits_and_rounding'
10
+ autoload :Delimiters, 'cldr/export/data/delimiters'
11
+ autoload :Languages, 'cldr/export/data/languages'
12
+ autoload :Numbers, 'cldr/export/data/numbers'
13
+ autoload :Plurals, 'cldr/export/data/plurals'
14
+ autoload :Territories, 'cldr/export/data/territories'
15
+ autoload :Timezones, 'cldr/export/data/timezones'
16
+ autoload :Metazones, 'cldr/export/data/metazones'
17
+ autoload :WindowsZones, 'cldr/export/data/windows_zones'
18
+ autoload :Units, 'cldr/export/data/units'
19
+ autoload :Lists, 'cldr/export/data/lists'
20
+ autoload :Layout, 'cldr/export/data/layout'
21
+ autoload :Rbnf, 'cldr/export/data/rbnf'
22
+ autoload :RbnfRoot, 'cldr/export/data/rbnf_root'
23
+ autoload :NumberingSystems, 'cldr/export/data/numbering_systems'
16
24
 
17
25
  class << self
18
26
  def dir
@@ -10,13 +10,14 @@ module Cldr
10
10
  :days => contexts('day'),
11
11
  :eras => eras,
12
12
  :quarters => contexts('quarter'),
13
- :periods => contexts('dayPeriod'),
13
+ :periods => contexts('dayPeriod', :group => "alt"),
14
14
  :fields => fields,
15
15
  :formats => {
16
16
  :date => formats('date'),
17
17
  :time => formats('time'),
18
18
  :datetime => formats('dateTime')
19
- }
19
+ },
20
+ :additional_formats => additional_formats
20
21
  )
21
22
  end
22
23
 
@@ -24,31 +25,39 @@ module Cldr
24
25
  @calendar ||= select('dates/calendars/calendar[@type="gregorian"]').first
25
26
  end
26
27
 
27
- def contexts(kind)
28
+ def contexts(kind, options = {})
28
29
  select(calendar, "#{kind}s/#{kind}Context").inject({}) do |result, node|
29
30
  context = node.attribute('type').value.to_sym
30
- result[context] = widths(node, kind, context)
31
+ result[context] = widths(node, kind, context, options)
31
32
  result
32
33
  end
33
34
  end
34
35
 
35
- def widths(node, kind, context)
36
+ def widths(node, kind, context, options = {})
36
37
  select(node, "#{kind}Width").inject({}) do |result, node|
37
- width = node.attribute('type').value.to_sym
38
- result[width] = elements(node, kind, context, width)
38
+ width = node.attribute('type').value.to_sym
39
+ result[width] = elements(node, kind, context, width, options)
39
40
  result
40
41
  end
41
42
  end
42
43
 
43
- def elements(node, kind, context, width)
44
+ def elements(node, kind, context, width, options = {})
44
45
  aliased = select(node, 'alias').first
46
+
45
47
  if aliased
46
48
  xpath_to_key(aliased.attribute('path').value, kind, context, width)
47
49
  else
48
50
  select(node, kind).inject({}) do |result, node|
49
51
  key = node.attribute('type').value
50
52
  key = key =~ /^\d*$/ ? key.to_i : key.to_sym
51
- result[key] = node.content
53
+
54
+ if options[:group] && found_group = node.attribute(options[:group])
55
+ result[found_group.value] ||= {}
56
+ result[found_group.value][key] = node.content
57
+ else
58
+ result[key] = node.content
59
+ end
60
+
52
61
  result
53
62
  end
54
63
  end
@@ -75,18 +84,22 @@ module Cldr
75
84
  end
76
85
 
77
86
  def eras
78
- base_path = calendar.path.gsub('/ldml/', '') + '/eras'
79
- keys = select("#{base_path}/*").map { |node| node.name }
80
-
81
- keys.inject({}) do |result, name|
82
- path = "#{base_path}/#{name}/*"
83
- key = name.gsub('era', '').gsub(/s$/, '').downcase.to_sym
84
- result[key] = select(path).inject({}) do |ret, node|
85
- type = node.attribute('type').value.to_i rescue 0
86
- ret[type] = node.content
87
- ret
87
+ if calendar
88
+ base_path = calendar.path.gsub('/ldml/', '') + '/eras'
89
+ keys = select("#{base_path}/*").map { |node| node.name }
90
+
91
+ keys.inject({}) do |result, name|
92
+ path = "#{base_path}/#{name}/*"
93
+ key = name.gsub('era', '').gsub(/s$/, '').downcase.to_sym
94
+ result[key] = select(path).inject({}) do |ret, node|
95
+ type = node.attribute('type').value.to_i rescue 0
96
+ ret[type] = node.content
97
+ ret
98
+ end
99
+ result
88
100
  end
89
- result
101
+ else
102
+ {}
90
103
  end
91
104
  end
92
105
 
@@ -110,7 +123,15 @@ module Cldr
110
123
  end
111
124
  formats
112
125
  end
113
-
126
+
127
+ def additional_formats
128
+ select(calendar, "dateTimeFormats/availableFormats/dateFormatItem").inject({}) do |result, node|
129
+ key = node.attribute('id').value
130
+ result[key] = node.content
131
+ result
132
+ end
133
+ end
134
+
114
135
  def default_format(type)
115
136
  if node = select(calendar, "#{type}Formats/default").first
116
137
  key = node.attribute('choice').value.to_sym
@@ -127,8 +148,10 @@ module Cldr
127
148
  end
128
149
  end
129
150
 
151
+ # NOTE: As of CLDR 23, this data moved from inside each "calendar" tag to under its parent, the "dates" tag.
152
+ # That probably means this `fields` method should be moved up to the parent as well.
130
153
  def fields
131
- select(calendar, "fields/field").inject({}) do |result, node|
154
+ select("dates/fields/field").inject({}) do |result, node|
132
155
  key = node.attribute('type').value.to_sym
133
156
  name = node.xpath('displayName').first
134
157
  result[key] = name.content if name
@@ -16,11 +16,16 @@ module Cldr
16
16
  end
17
17
 
18
18
  def currency(node)
19
- select(node, 'displayName').inject({}) do |result, node|
19
+ data = select(node, 'displayName').inject({}) do |result, node|
20
20
  count = node.attribute('count') ? node.attribute('count').value.to_sym : :one
21
21
  result[count] = node.content unless draft?(node)
22
22
  result
23
23
  end
24
+
25
+ symbol = select(node, 'symbol')
26
+ data[:symbol] = symbol.first.content if symbol.length > 0
27
+
28
+ data
24
29
  end
25
30
  end
26
31
  end
@@ -0,0 +1,22 @@
1
+ require 'nokogiri'
2
+
3
+ module Cldr
4
+ module Export
5
+ module Data
6
+ class CurrencyDigitsAndRounding < Hash
7
+ def initialize
8
+ path = "#{Cldr::Export::Data.dir}/supplemental/supplementalData.xml"
9
+ doc = File.open(path) { |file| Nokogiri::XML(file) }
10
+
11
+ currency_digits_and_rounding = doc.xpath('//currencyData/fractions/info').each do |node|
12
+ code = node.attr('iso4217')
13
+ digits = node.attr('digits').to_i
14
+ rounding = node.attr('rounding').to_i
15
+
16
+ self[code.upcase.to_sym] = { :digits => digits, :rounding => rounding }
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end