lawrencepit-i18n 0.1.6

Sign up to get free protection for your applications and to get access to all the features.
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2008 The Ruby I18n team
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.textile ADDED
@@ -0,0 +1,20 @@
1
+ h1. Ruby I18n gem
2
+
3
+ I18n and localization solution for Ruby.
4
+
5
+ For information please refer to http://rails-i18n.org
6
+
7
+ h2. Authors
8
+
9
+ * "Matt Aimonetti":http://railsontherun.com
10
+ * "Sven Fuchs":http://www.artweb-design.de
11
+ * "Joshua Harvey":http://www.workingwithrails.com/person/759-joshua-harvey
12
+ * "Saimon Moore":http://saimonmoore.net
13
+ * "Stephan Soller":http://www.arkanis-development.de
14
+
15
+ h2. License
16
+
17
+ MIT License. See the included MIT-LICENCE file.
18
+
19
+
20
+
data/lib/i18n.rb ADDED
@@ -0,0 +1,226 @@
1
+ # Authors:: Matt Aimonetti (http://railsontherun.com/),
2
+ # Sven Fuchs (http://www.artweb-design.de),
3
+ # Joshua Harvey (http://www.workingwithrails.com/person/759-joshua-harvey),
4
+ # Saimon Moore (http://saimonmoore.net),
5
+ # Stephan Soller (http://www.arkanis-development.de/)
6
+ # Copyright:: Copyright (c) 2008 The Ruby i18n Team
7
+ # License:: MIT
8
+ require 'i18n/backend/simple'
9
+ require 'i18n/exceptions'
10
+
11
+ module I18n
12
+ @@backend = nil
13
+ @@load_path = nil
14
+ @@default_locale = :'en'
15
+ @@default_separator = '.'
16
+ @@exception_handler = :default_exception_handler
17
+
18
+ class << self
19
+ # Returns the current backend. Defaults to +Backend::Simple+.
20
+ def backend
21
+ @@backend ||= Backend::Simple.new
22
+ end
23
+
24
+ # Sets the current backend. Used to set a custom backend.
25
+ def backend=(backend)
26
+ @@backend = backend
27
+ end
28
+
29
+ # Returns the current default locale. Defaults to :'en'
30
+ def default_locale
31
+ @@default_locale
32
+ end
33
+
34
+ # Sets the current default locale. Used to set a custom default locale.
35
+ def default_locale=(locale)
36
+ @@default_locale = locale
37
+ end
38
+
39
+ # Returns the current locale. Defaults to I18n.default_locale.
40
+ def locale
41
+ Thread.current[:locale] ||= default_locale
42
+ end
43
+
44
+ # Sets the current locale pseudo-globally, i.e. in the Thread.current hash.
45
+ def locale=(locale)
46
+ Thread.current[:locale] = locale
47
+ end
48
+
49
+ # Returns an array of locales for which translations are available
50
+ def available_locales
51
+ backend.available_locales
52
+ end
53
+
54
+ # Returns the current default scope separator. Defaults to '.'
55
+ def default_separator
56
+ @@default_separator
57
+ end
58
+
59
+ # Sets the current default scope separator.
60
+ def default_separator=(separator)
61
+ @@default_separator = separator
62
+ end
63
+
64
+ # Sets the exception handler.
65
+ def exception_handler=(exception_handler)
66
+ @@exception_handler = exception_handler
67
+ end
68
+
69
+ # Allow clients to register paths providing translation data sources. The
70
+ # backend defines acceptable sources.
71
+ #
72
+ # E.g. the provided SimpleBackend accepts a list of paths to translation
73
+ # files which are either named *.rb and contain plain Ruby Hashes or are
74
+ # named *.yml and contain YAML data. So for the SimpleBackend clients may
75
+ # register translation files like this:
76
+ # I18n.load_path << 'path/to/locale/en.yml'
77
+ def load_path
78
+ @@load_path ||= []
79
+ end
80
+
81
+ # Sets the load path instance. Custom implementations are expected to
82
+ # behave like a Ruby Array.
83
+ def load_path=(load_path)
84
+ @@load_path = load_path
85
+ end
86
+
87
+ # Tells the backend to reload translations. Used in situations like the
88
+ # Rails development environment. Backends can implement whatever strategy
89
+ # is useful.
90
+ def reload!
91
+ backend.reload!
92
+ end
93
+
94
+ # Translates, pluralizes and interpolates a given key using a given locale,
95
+ # scope, and default, as well as interpolation values.
96
+ #
97
+ # *LOOKUP*
98
+ #
99
+ # Translation data is organized as a nested hash using the upper-level keys
100
+ # as namespaces. <em>E.g.</em>, ActionView ships with the translation:
101
+ # <tt>:date => {:formats => {:short => "%b %d"}}</tt>.
102
+ #
103
+ # Translations can be looked up at any level of this hash using the key argument
104
+ # and the scope option. <em>E.g.</em>, in this example <tt>I18n.t :date</tt>
105
+ # returns the whole translations hash <tt>{:formats => {:short => "%b %d"}}</tt>.
106
+ #
107
+ # Key can be either a single key or a dot-separated key (both Strings and Symbols
108
+ # work). <em>E.g.</em>, the short format can be looked up using both:
109
+ # I18n.t 'date.formats.short'
110
+ # I18n.t :'date.formats.short'
111
+ #
112
+ # Scope can be either a single key, a dot-separated key or an array of keys
113
+ # or dot-separated keys. Keys and scopes can be combined freely. So these
114
+ # examples will all look up the same short date format:
115
+ # I18n.t 'date.formats.short'
116
+ # I18n.t 'formats.short', :scope => 'date'
117
+ # I18n.t 'short', :scope => 'date.formats'
118
+ # I18n.t 'short', :scope => %w(date formats)
119
+ #
120
+ # *INTERPOLATION*
121
+ #
122
+ # Translations can contain interpolation variables which will be replaced by
123
+ # values passed to #translate as part of the options hash, with the keys matching
124
+ # the interpolation variable names.
125
+ #
126
+ # <em>E.g.</em>, with a translation <tt>:foo => "foo {{bar}}"</tt> the option
127
+ # value for the key +bar+ will be interpolated into the translation:
128
+ # I18n.t :foo, :bar => 'baz' # => 'foo baz'
129
+ #
130
+ # *PLURALIZATION*
131
+ #
132
+ # Translation data can contain pluralized translations. Pluralized translations
133
+ # are arrays of singluar/plural versions of translations like <tt>['Foo', 'Foos']</tt>.
134
+ #
135
+ # Note that <tt>I18n::Backend::Simple</tt> only supports an algorithm for English
136
+ # pluralization rules. Other algorithms can be supported by custom backends.
137
+ #
138
+ # This returns the singular version of a pluralized translation:
139
+ # I18n.t :foo, :count => 1 # => 'Foo'
140
+ #
141
+ # These both return the plural version of a pluralized translation:
142
+ # I18n.t :foo, :count => 0 # => 'Foos'
143
+ # I18n.t :foo, :count => 2 # => 'Foos'
144
+ #
145
+ # The <tt>:count</tt> option can be used both for pluralization and interpolation.
146
+ # <em>E.g.</em>, with the translation
147
+ # <tt>:foo => ['{{count}} foo', '{{count}} foos']</tt>, count will
148
+ # be interpolated to the pluralized translation:
149
+ # I18n.t :foo, :count => 1 # => '1 foo'
150
+ #
151
+ # *DEFAULTS*
152
+ #
153
+ # This returns the translation for <tt>:foo</tt> or <tt>default</tt> if no translation was found:
154
+ # I18n.t :foo, :default => 'default'
155
+ #
156
+ # This returns the translation for <tt>:foo</tt> or the translation for <tt>:bar</tt> if no
157
+ # translation for <tt>:foo</tt> was found:
158
+ # I18n.t :foo, :default => :bar
159
+ #
160
+ # Returns the translation for <tt>:foo</tt> or the translation for <tt>:bar</tt>
161
+ # or <tt>default</tt> if no translations for <tt>:foo</tt> and <tt>:bar</tt> were found.
162
+ # I18n.t :foo, :default => [:bar, 'default']
163
+ #
164
+ # *BULK LOOKUP*
165
+ #
166
+ # This returns an array with the translations for <tt>:foo</tt> and <tt>:bar</tt>.
167
+ # I18n.t [:foo, :bar]
168
+ #
169
+ # Can be used with dot-separated nested keys:
170
+ # I18n.t [:'baz.foo', :'baz.bar']
171
+ #
172
+ # Which is the same as using a scope option:
173
+ # I18n.t [:foo, :bar], :scope => :baz
174
+ #
175
+ # *LAMBDAS*
176
+ #
177
+ # Both translations and defaults can be given as Ruby lambdas. Lambdas will be
178
+ # called and passed the key and options.
179
+ #
180
+ # E.g. assuming the key <tt>:salutation</tt> resolves to:
181
+ # lambda { |key, options| options[:gender] == 'm' ? "Mr. {{options[:name]}}" : "Mrs. {{options[:name]}}" }
182
+ #
183
+ # Then <tt>I18n.t(:salutation, :gender => 'w', :name => 'Smith') will result in "Mrs. Smith".
184
+ #
185
+ # It is recommended to use/implement lambdas in an "idempotent" way. E.g. when
186
+ # a cache layer is put in front of I18n.translate it will generate a cache key
187
+ # from the argument values passed to #translate. Therefor your lambdas should
188
+ # always return the same translations/values per unique combination of argument
189
+ # values.
190
+ def translate(key, options = {})
191
+ locale = options.delete(:locale) || I18n.locale
192
+ backend.translate(locale, key, options)
193
+ rescue I18n::ArgumentError => e
194
+ raise e if options[:raise]
195
+ send(@@exception_handler, e, locale, key, options)
196
+ end
197
+ alias :t :translate
198
+
199
+ # Localizes certain objects, such as dates and numbers to local formatting.
200
+ def localize(object, options = {})
201
+ locale = options[:locale] || I18n.locale
202
+ format = options[:format] || :default
203
+ backend.localize(locale, object, format)
204
+ end
205
+ alias :l :localize
206
+
207
+ protected
208
+ # Handles exceptions raised in the backend. All exceptions except for
209
+ # MissingTranslationData exceptions are re-raised. When a MissingTranslationData
210
+ # was caught and the option :raise is not set the handler returns an error
211
+ # message string containing the key/scope.
212
+ def default_exception_handler(exception, locale, key, options)
213
+ return exception.message if MissingTranslationData === exception
214
+ raise exception
215
+ end
216
+
217
+ # Merges the given locale, key and scope into a single array of keys.
218
+ # Splits keys that contain dots into multiple keys. Makes sure all
219
+ # keys are Symbols.
220
+ def normalize_translation_keys(locale, key, scope, separator = nil)
221
+ keys = [locale] + Array(scope) + Array(key)
222
+ keys = keys.map { |k| k.to_s.split(separator || I18n.default_separator) }
223
+ keys.flatten.map { |k| k.to_sym }
224
+ end
225
+ end
226
+ end
@@ -0,0 +1,235 @@
1
+ require 'yaml'
2
+
3
+ module I18n
4
+ module Backend
5
+ class Simple
6
+ RESERVED_KEYS = [:scope, :default, :separator]
7
+ MATCH = /(\\\\)?\{\{([^\}]+)\}\}/
8
+
9
+ # Accepts a list of paths to translation files. Loads translations from
10
+ # plain Ruby (*.rb) or YAML files (*.yml). See #load_rb and #load_yml
11
+ # for details.
12
+ def load_translations(*filenames)
13
+ filenames.each { |filename| load_file(filename) }
14
+ end
15
+
16
+ # Stores translations for the given locale in memory.
17
+ # This uses a deep merge for the translations hash, so existing
18
+ # translations will be overwritten by new ones only at the deepest
19
+ # level of the hash.
20
+ def store_translations(locale, data)
21
+ merge_translations(locale, data)
22
+ end
23
+
24
+ def translate(locale, key, options = {})
25
+ raise InvalidLocale.new(locale) if locale.nil?
26
+ return key.map { |k| translate(locale, k, options) } if key.is_a?(Array)
27
+
28
+ count, scope, default, separator = options.values_at(:count, *RESERVED_KEYS)
29
+ values = options.reject { |name, value| RESERVED_KEYS.include?(name) }
30
+
31
+ entry = lookup(locale, key, scope, separator)
32
+ entry = entry.nil? ? default(locale, key, default, options) : resolve(locale, key, entry, options)
33
+
34
+ raise(I18n::MissingTranslationData.new(locale, key, options)) if entry.nil?
35
+ entry = pluralize(locale, entry, count)
36
+ entry = interpolate(locale, entry, values)
37
+ entry
38
+ end
39
+
40
+ # Acts the same as +strftime+, but returns a localized version of the
41
+ # formatted date string. Takes a key from the date/time formats
42
+ # translations as a format argument (<em>e.g.</em>, <tt>:short</tt> in <tt>:'date.formats'</tt>).
43
+ def localize(locale, object, format = :default, options={})
44
+ raise ArgumentError, "Object must be a Date, DateTime or Time object. #{object.inspect} given." unless object.respond_to?(:strftime)
45
+
46
+ if Symbol === format
47
+ type = object.respond_to?(:sec) ? 'time' : 'date'
48
+ format = lookup(locale, :"#{type}.formats.#{format}")
49
+ end
50
+
51
+ format = resolve(locale, object, format, options.merge(:raise => true))
52
+
53
+ # TODO only translate these if the format string is actually present
54
+ # TODO check which format strings are present, then bulk translate them, then replace them
55
+
56
+ format.gsub!(/%a/, translate(locale, :"date.abbr_day_names", :format => format)[object.wday])
57
+ format.gsub!(/%A/, translate(locale, :"date.day_names", :format => format)[object.wday])
58
+ format.gsub!(/%b/, translate(locale, :"date.abbr_month_names", :format => format)[object.mon])
59
+ format.gsub!(/%B/, translate(locale, :"date.month_names", :format => format)[object.mon])
60
+ format.gsub!(/%p/, translate(locale, :"time.#{object.hour < 12 ? :am : :pm}", :format => format)) if object.respond_to?(:hour)
61
+
62
+ object.strftime(format)
63
+ end
64
+
65
+ def initialized?
66
+ @initialized ||= false
67
+ end
68
+
69
+ # Returns an array of locales for which translations are available
70
+ def available_locales
71
+ init_translations unless initialized?
72
+ translations.keys
73
+ end
74
+
75
+ def reload!
76
+ @initialized = false
77
+ @translations = nil
78
+ end
79
+
80
+ protected
81
+ def init_translations
82
+ load_translations(*I18n.load_path.flatten)
83
+ @initialized = true
84
+ end
85
+
86
+ def translations
87
+ @translations ||= {}
88
+ end
89
+
90
+ # Looks up a translation from the translations hash. Returns nil if
91
+ # eiher key is nil, or locale, scope or key do not exist as a key in the
92
+ # nested translations hash. Splits keys or scopes containing dots
93
+ # into multiple keys, i.e. <tt>currency.format</tt> is regarded the same as
94
+ # <tt>%w(currency format)</tt>.
95
+ def lookup(locale, key, scope = [], separator = nil)
96
+ return unless key
97
+ init_translations unless initialized?
98
+ keys = I18n.send(:normalize_translation_keys, locale, key, scope, separator)
99
+ keys.inject(translations) do |result, k|
100
+ if (x = result[k.to_sym]).nil?
101
+ return nil
102
+ else
103
+ x
104
+ end
105
+ end
106
+ end
107
+
108
+ # Evaluates defaults.
109
+ # If given subject is an Array, it walks the array and returns the
110
+ # first translation that can be resolved. Otherwise it tries to resolve
111
+ # the translation directly.
112
+ def default(locale, object, subject, options = {})
113
+ options = options.dup.reject { |key, value| key == :default }
114
+ case subject
115
+ when Array
116
+ subject.each do |subject|
117
+ result = resolve(locale, object, subject, options) and return result
118
+ end and nil
119
+ else
120
+ resolve(locale, object, subject, options)
121
+ end
122
+ end
123
+
124
+ # Resolves a translation.
125
+ # If the given subject is a Symbol, it will be translated with the
126
+ # given options. If it is a Proc then it will be evaluated. All other
127
+ # subjects will be returned directly.
128
+ def resolve(locale, object, subject, options = {})
129
+ case subject
130
+ when Symbol
131
+ translate(locale, subject, options)
132
+ when Proc
133
+ resolve(locale, object, subject.call(object, options), options = {})
134
+ else
135
+ subject
136
+ end
137
+ rescue MissingTranslationData
138
+ nil
139
+ end
140
+
141
+ # Picks a translation from an array according to English pluralization
142
+ # rules. It will pick the first translation if count is not equal to 1
143
+ # and the second translation if it is equal to 1. Other backends can
144
+ # implement more flexible or complex pluralization rules.
145
+ def pluralize(locale, entry, count)
146
+ return entry unless entry.is_a?(Hash) and count
147
+
148
+ key = :zero if count == 0 && entry.has_key?(:zero)
149
+ key ||= count == 1 ? :one : :other
150
+ raise InvalidPluralizationData.new(entry, count) unless entry.has_key?(key)
151
+ entry[key]
152
+ end
153
+
154
+ # Interpolates values into a given string.
155
+ #
156
+ # interpolate "file {{file}} opened by \\{{user}}", :file => 'test.txt', :user => 'Mr. X'
157
+ # # => "file test.txt opened by {{user}}"
158
+ #
159
+ # Note that you have to double escape the <tt>\\</tt> when you want to escape
160
+ # the <tt>{{...}}</tt> key in a string (once for the string and once for the
161
+ # interpolation).
162
+ def interpolate(locale, string, values = {})
163
+ return string unless string.is_a?(String)
164
+
165
+ string.gsub!(MATCH) do
166
+ escaped, key = $1, $2.to_sym
167
+
168
+ if escaped
169
+ key
170
+ elsif RESERVED_KEYS.include?(key)
171
+ raise ReservedInterpolationKey.new(key, string)
172
+ elsif !values.include?(key)
173
+ raise MissingInterpolationArgument.new(key, string)
174
+ else
175
+ values[key].to_s
176
+ end
177
+ end
178
+ string
179
+ end
180
+
181
+ # Loads a single translations file by delegating to #load_rb or
182
+ # #load_yml depending on the file extension and directly merges the
183
+ # data to the existing translations. Raises I18n::UnknownFileType
184
+ # for all other file extensions.
185
+ def load_file(filename)
186
+ type = File.extname(filename).tr('.', '').downcase
187
+ raise UnknownFileType.new(type, filename) unless respond_to?(:"load_#{type}")
188
+ data = send :"load_#{type}", filename # TODO raise a meaningful exception if this does not yield a Hash
189
+ data.each { |locale, d| merge_translations(locale, d) }
190
+ end
191
+
192
+ # Loads a plain Ruby translations file. eval'ing the file must yield
193
+ # a Hash containing translation data with locales as toplevel keys.
194
+ def load_rb(filename)
195
+ eval(IO.read(filename), binding, filename)
196
+ end
197
+
198
+ # Loads a YAML translations file. The data must have locales as
199
+ # toplevel keys.
200
+ def load_yml(filename)
201
+ YAML::load(IO.read(filename))
202
+ end
203
+
204
+ # Deep merges the given translations hash with the existing translations
205
+ # for the given locale
206
+ def merge_translations(locale, data)
207
+ locale = locale.to_sym
208
+ translations[locale] ||= {}
209
+ data = deep_symbolize_keys(data)
210
+
211
+ # deep_merge by Stefan Rusterholz, see http://www.ruby-forum.com/topic/142809
212
+ merger = proc { |key, v1, v2| Hash === v1 && Hash === v2 ? v1.merge(v2, &merger) : v2 }
213
+ translations[locale].merge!(data, &merger)
214
+ end
215
+
216
+ # Return a new hash with all keys and nested keys converted to symbols.
217
+ def deep_symbolize_keys(hash)
218
+ hash.inject({}) { |result, (key, value)|
219
+ value = deep_symbolize_keys(value) if value.is_a?(Hash)
220
+ result[(key.to_sym rescue key) || key] = value
221
+ result
222
+ }
223
+ end
224
+
225
+ # Flatten the given array once
226
+ def flatten_once(array)
227
+ result = []
228
+ for element in array # a little faster than each
229
+ result.push(*element)
230
+ end
231
+ result
232
+ end
233
+ end
234
+ end
235
+ end
@@ -0,0 +1,53 @@
1
+ module I18n
2
+ class ArgumentError < ::ArgumentError; end
3
+
4
+ class InvalidLocale < ArgumentError
5
+ attr_reader :locale
6
+ def initialize(locale)
7
+ @locale = locale
8
+ super "#{locale.inspect} is not a valid locale"
9
+ end
10
+ end
11
+
12
+ class MissingTranslationData < ArgumentError
13
+ attr_reader :locale, :key, :options
14
+ def initialize(locale, key, options)
15
+ @key, @locale, @options = key, locale, options
16
+ keys = I18n.send(:normalize_translation_keys, locale, key, options[:scope])
17
+ keys << 'no key' if keys.size < 2
18
+ super "translation missing: #{keys.join(', ')}"
19
+ end
20
+ end
21
+
22
+ class InvalidPluralizationData < ArgumentError
23
+ attr_reader :entry, :count
24
+ def initialize(entry, count)
25
+ @entry, @count = entry, count
26
+ super "translation data #{entry.inspect} can not be used with :count => #{count}"
27
+ end
28
+ end
29
+
30
+ class MissingInterpolationArgument < ArgumentError
31
+ attr_reader :key, :string
32
+ def initialize(key, string)
33
+ @key, @string = key, string
34
+ super "interpolation argument #{key} missing in #{string.inspect}"
35
+ end
36
+ end
37
+
38
+ class ReservedInterpolationKey < ArgumentError
39
+ attr_reader :key, :string
40
+ def initialize(key, string)
41
+ @key, @string = key, string
42
+ super "reserved key #{key.inspect} used in #{string.inspect}"
43
+ end
44
+ end
45
+
46
+ class UnknownFileType < ArgumentError
47
+ attr_reader :type, :filename
48
+ def initialize(type, filename)
49
+ @type, @filename = type, filename
50
+ super "can not load translations from #{filename}, the file type #{type} is not known"
51
+ end
52
+ end
53
+ end
metadata ADDED
@@ -0,0 +1,61 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: lawrencepit-i18n
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.6
5
+ platform: ruby
6
+ authors:
7
+ - Sven Fuchs
8
+ - Joshua Harvey
9
+ - Matt Aimonetti
10
+ - Stephan Soller
11
+ - Saimon Moore
12
+ autorequire:
13
+ bindir: bin
14
+ cert_chain: []
15
+
16
+ date: 2009-06-17 00:00:00 -07:00
17
+ default_executable:
18
+ dependencies: []
19
+
20
+ description: Add Internationalization support to your Ruby application.
21
+ email: rails-i18n@googlegroups.com
22
+ executables: []
23
+
24
+ extensions: []
25
+
26
+ extra_rdoc_files: []
27
+
28
+ files:
29
+ - lib/i18n/backend/simple.rb
30
+ - lib/i18n/exceptions.rb
31
+ - lib/i18n.rb
32
+ - MIT-LICENSE
33
+ - README.textile
34
+ has_rdoc: false
35
+ homepage: http://rails-i18n.org
36
+ post_install_message:
37
+ rdoc_options: []
38
+
39
+ require_paths:
40
+ - lib
41
+ required_ruby_version: !ruby/object:Gem::Requirement
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ version: "0"
46
+ version:
47
+ required_rubygems_version: !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - ">="
50
+ - !ruby/object:Gem::Version
51
+ version: "0"
52
+ version:
53
+ requirements: []
54
+
55
+ rubyforge_project:
56
+ rubygems_version: 1.2.0
57
+ signing_key:
58
+ specification_version: 2
59
+ summary: Internationalization support for Ruby
60
+ test_files: []
61
+