rfc5646 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.
- checksums.yaml +7 -0
- data/.gitignore +9 -0
- data/.rspec +2 -0
- data/.rubocop.yml +36 -0
- data/.travis.yml +13 -0
- data/CODE_OF_CONDUCT.md +13 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +202 -0
- data/README.md +84 -0
- data/Rakefile +4 -0
- data/bin/console +14 -0
- data/bin/setup +7 -0
- data/config/locales/locales.en.yml +8847 -0
- data/lib/rfc5646.rb +4 -0
- data/lib/rfc5646/engine.rb +4 -0
- data/lib/rfc5646/locale.rb +338 -0
- data/lib/rfc5646/version.rb +3 -0
- data/rfc5646.gemspec +28 -0
- metadata +146 -0
data/lib/rfc5646.rb
ADDED
@@ -0,0 +1,338 @@
|
|
1
|
+
require 'active_support/core_ext/object/try'
|
2
|
+
require 'active_support/core_ext/object/blank'
|
3
|
+
require 'i18n'
|
4
|
+
|
5
|
+
I18n.backend.load_translations('config/locales/locales.en.yml')
|
6
|
+
|
7
|
+
module Rfc5646
|
8
|
+
# Represents a locale that can be localized to. Locales are identified by
|
9
|
+
# their RFC 5646 code, which can be as simple as just a language (e.g., "en" for
|
10
|
+
# English), or arbitrary complex (e.g., "zh-cmn-Hans-CN" for Mandarin Chinese
|
11
|
+
# as spoken in China, simplified Han orthography). The entire RFC 5646 spec is
|
12
|
+
# supported by this class.
|
13
|
+
class Locale
|
14
|
+
# @private
|
15
|
+
RFC5646_EXTLANG = /(?<extlang>[a-zA-Z]{3})(-[a-zA-Z]{3}){0,2}/
|
16
|
+
# @private
|
17
|
+
RFC5646_ISO639 = /(?<iso639>[a-zA-Z]{2,3})(-#{RFC5646_EXTLANG.source})?/
|
18
|
+
# @private
|
19
|
+
RFC5646_RESERVED = /(?<reserved>[a-zA-Z]{4})/
|
20
|
+
# @private
|
21
|
+
RFC5646_SUBTAG = /(?<subtag>[a-zA-Z]{5,8})/
|
22
|
+
# @private
|
23
|
+
RFC5646_REGION = /(?<region>([a-zA-Z]{2}|\d{3}))/
|
24
|
+
# @private
|
25
|
+
RFC5646_VARIANT = /([a-zA-Z0-9]{5,8}|\d[a-zA-Z0-9]{3})/
|
26
|
+
# @private
|
27
|
+
RFC5646_SCRIPT = /(?<script>[a-zA-Z]{4})/
|
28
|
+
# @private
|
29
|
+
RFC5646_EXTENSION = /([0-9A-WY-Za-wy-z](-[a-zA-Z0-9]{2,8}){1,})/
|
30
|
+
# @private
|
31
|
+
RFC5646_LANGUAGE = /(#{RFC5646_ISO639.source}|#{RFC5646_RESERVED.source}|#{RFC5646_SUBTAG.source})/
|
32
|
+
# @private
|
33
|
+
RFC5646_PRIVATE = /x(?<privates>(-[a-zA-Z0-9]{1,8}){1,})/
|
34
|
+
# @private
|
35
|
+
RFC5646_FORMAT = /\A#{RFC5646_LANGUAGE.source}(-#{RFC5646_SCRIPT.source})?(-#{RFC5646_REGION.source})?(?<variants>(-#{RFC5646_VARIANT.source})*)(?<extensions>(-#{RFC5646_EXTENSION.source})*)(-#{RFC5646_PRIVATE.source})?\z/ # rubocop:disable Metrics/LineLength
|
36
|
+
|
37
|
+
# @return [String] The ISO 639 code for the base language (e.g., "de" for
|
38
|
+
# German).
|
39
|
+
attr_reader :iso639
|
40
|
+
# @return [String] The RFC 5646 code for the orthography (e.g., "Arab" for
|
41
|
+
# Arabic script).
|
42
|
+
attr_reader :script
|
43
|
+
# @return [String] The ISO 3166 country code for the regional dialect (e.g.,
|
44
|
+
# "BZ" for Belize). Some special values are also supported (e.g., "013" for
|
45
|
+
# Central America); see the spec for details.
|
46
|
+
attr_reader :region
|
47
|
+
# @return [Array<String>] The variant or nested subvariant of this locale.
|
48
|
+
# The full path to a subvariant is listed as a top-level Array; an example
|
49
|
+
# is `["sl", "rozaj", "1994"]`, indicating the 1994 standardization of the
|
50
|
+
# Resian orthography of the Rozaj dialect of Slovenian (in case we should
|
51
|
+
# ever want to localize one of our projects thusly). Variants can be
|
52
|
+
# regional or temporal dialects, or orthographies, or both, and are very
|
53
|
+
# specific.
|
54
|
+
attr_reader :variants
|
55
|
+
# @return [String] The dialect (not associated with a specific region or
|
56
|
+
# period in time) specifier. For example, "yue" indicates Yue Chinese
|
57
|
+
# (Cantonese).
|
58
|
+
attr_reader :extended_language
|
59
|
+
# @return [Array<String>] The user-defined extensions applied to this
|
60
|
+
# locale. The meaning of these is not specified in the spec, and left up
|
61
|
+
# to private use, and is ignored by this class, but stored for completeness.
|
62
|
+
attr_reader :extensions
|
63
|
+
|
64
|
+
class << self
|
65
|
+
# Generates a new instance from an RFC 5646 code.
|
66
|
+
#
|
67
|
+
# @param [String] ident The RFC 5646 code for the locale.
|
68
|
+
# @return [Locale] The instance representing that locale.
|
69
|
+
|
70
|
+
def from_rfc5646(ident)
|
71
|
+
ident = ident.tr('_', '-')
|
72
|
+
return nil unless (matches = RFC5646_FORMAT.match(ident))
|
73
|
+
attrs = RFC5646_FORMAT.named_captures.each_with_object({}) do |(name, offsets), hsh|
|
74
|
+
hsh[name] = offsets.map { |offset| matches[offset] }.compact
|
75
|
+
end
|
76
|
+
|
77
|
+
iso639 = attrs['iso639'].first
|
78
|
+
script = attrs['script'].first
|
79
|
+
return nil unless iso639
|
80
|
+
region = attrs['region'].first
|
81
|
+
if (variants = attrs['variants'].first)
|
82
|
+
variants = variants.split('-')
|
83
|
+
variants.shift
|
84
|
+
end
|
85
|
+
if (extensions = attrs['extensions'].first)
|
86
|
+
extensions = extensions.split('-')
|
87
|
+
extensions.shift
|
88
|
+
end
|
89
|
+
extlang = attrs['extlang'].first
|
90
|
+
|
91
|
+
Locale.new iso639, script, extlang, region, variants || [], extensions || []
|
92
|
+
end
|
93
|
+
|
94
|
+
# Returns an array of Locales representing all possible completions given a
|
95
|
+
# prefix portion of an RFC 5646 code. The resolution of the resultant array is
|
96
|
+
# determined by the resolution if the input prefix. Some examples:
|
97
|
+
#
|
98
|
+
# * If just the letter "e" is entered, Locales whose ISO 639 codes begin
|
99
|
+
# with the letter "e" will be returned (English, Spanish, etc.). These
|
100
|
+
# Locale instances will have no other fields specified.
|
101
|
+
# * If "en-U" is specified, Locale instances representing "en-US" and
|
102
|
+
# "en-UA", among others, will be returned, as well as "en-Ugar" (for all the
|
103
|
+
# sense it makes). "en-US-Ugar" would not be returned, as it is of a higher
|
104
|
+
# resolution than the input.
|
105
|
+
#
|
106
|
+
# @param [String] prefix A portion of an RFC 5646 code.
|
107
|
+
# @param [Fixnum] max A maximum number of completions to return.
|
108
|
+
# @return [Array<Locale>] Candidate completions as Locale instances.
|
109
|
+
|
110
|
+
def from_rfc5646_prefix(prefix, max = nil)
|
111
|
+
if prefix.include?('-')
|
112
|
+
prefix_path = prefix.split('-')
|
113
|
+
prefix = prefix_path.pop
|
114
|
+
parent_prefix = prefix_path.join('-')
|
115
|
+
parent = from_rfc5646(parent_prefix)
|
116
|
+
return [] unless parent
|
117
|
+
|
118
|
+
search_paths = if parent.variants.present?
|
119
|
+
# TODO: subvariants
|
120
|
+
[]
|
121
|
+
elsif parent.region # only possible completions are variants
|
122
|
+
[]
|
123
|
+
# TODO: variants
|
124
|
+
elsif parent.script # can be followed with variant or region
|
125
|
+
%w(locale.region)
|
126
|
+
else # can be followed with script, region, or variant
|
127
|
+
%w(locale.region locale.script)
|
128
|
+
end
|
129
|
+
|
130
|
+
keys = search_paths.map do |path|
|
131
|
+
I18n.t(path).select { |k, v| Locale.matches_prefix? prefix, k, v }.keys
|
132
|
+
end.flatten
|
133
|
+
keys.delete '_END_'
|
134
|
+
keys = keys[0, max] if max
|
135
|
+
|
136
|
+
return keys.map { |key| from_rfc5646 "#{parent_prefix}-#{key}" }
|
137
|
+
else
|
138
|
+
keys = I18n.t('locale.name').select { |k, v| Locale.matches_prefix? prefix, k, v }.keys
|
139
|
+
keys = keys[0, max] if max
|
140
|
+
return keys.map { |key| from_rfc5646 key }
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
# @private
|
145
|
+
def matches_prefix?(prefix, key, value)
|
146
|
+
return false unless value.is_a?(String)
|
147
|
+
return true if key.to_s.downcase.starts_with?(prefix.downcase)
|
148
|
+
return true if value.split(/\w+/).any? { |word| word.downcase.starts_with? prefix.downcase }
|
149
|
+
false
|
150
|
+
end
|
151
|
+
|
152
|
+
private
|
153
|
+
|
154
|
+
def fallbacks
|
155
|
+
@fallbacks ||= YAML.load_file(Rails.root.join('data', 'fallbacks.yml'))
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
# @private
|
160
|
+
def initialize(iso639, script = nil, extlang = nil, region = nil, variants = [], extensions = [])
|
161
|
+
@iso639 = iso639.try!(:downcase)
|
162
|
+
@region = region.try!(:upcase)
|
163
|
+
@variants = variants.map(&:downcase)
|
164
|
+
@extended_language = extlang.try!(:downcase)
|
165
|
+
@extensions = extensions
|
166
|
+
@script = script
|
167
|
+
end
|
168
|
+
|
169
|
+
# @return [String] The full RFC 5646 code for this locale.
|
170
|
+
|
171
|
+
def rfc5646
|
172
|
+
[iso639, script, extended_language, region, *variants].compact.join('-')
|
173
|
+
end
|
174
|
+
|
175
|
+
alias_method :to_param, :rfc5646
|
176
|
+
|
177
|
+
# Returns a human-readable localized name of the locale.
|
178
|
+
#
|
179
|
+
# @param [String] locale The locale to use (default locale is used by
|
180
|
+
# default).
|
181
|
+
# @return [String] The localized name of the locale.
|
182
|
+
|
183
|
+
def name(locale = nil)
|
184
|
+
I18n.with_locale(locale || I18n.locale) do
|
185
|
+
i18n_language = if extended_language
|
186
|
+
I18n.t "locale.extended.#{iso639}.#{extended_language}"
|
187
|
+
else
|
188
|
+
I18n.t "locale.name.#{iso639}"
|
189
|
+
end
|
190
|
+
|
191
|
+
i18n_dialect = if variants.present?
|
192
|
+
I18n.t "locale.variant.#{iso639}.#{variants.join '.'}._END_"
|
193
|
+
end
|
194
|
+
|
195
|
+
i18n_script = script ? I18n.t("locale.script.#{script}") : nil
|
196
|
+
i18n_region = region ? I18n.t("locale.region.#{region}") : nil
|
197
|
+
|
198
|
+
if i18n_region && i18n_dialect && i18n_script
|
199
|
+
I18n.t('locale.format.scripted_regional_dialectical',
|
200
|
+
script: i18n_script,
|
201
|
+
dialect: i18n_dialect,
|
202
|
+
region: i18n_region,
|
203
|
+
language: i18n_language
|
204
|
+
)
|
205
|
+
elsif i18n_region && i18n_dialect
|
206
|
+
I18n.t('locale.format.regional_dialectical',
|
207
|
+
dialect: i18n_dialect,
|
208
|
+
region: i18n_region,
|
209
|
+
language: i18n_language
|
210
|
+
)
|
211
|
+
elsif i18n_region && i18n_script
|
212
|
+
I18n.t('locale.format.scripted_regional',
|
213
|
+
script: i18n_script,
|
214
|
+
region: i18n_region,
|
215
|
+
language: i18n_language
|
216
|
+
)
|
217
|
+
elsif i18n_dialect && i18n_script
|
218
|
+
I18n.t('locale.format.scripted_dialectical',
|
219
|
+
script: i18n_script,
|
220
|
+
dialect: i18n_dialect,
|
221
|
+
language: i18n_language
|
222
|
+
)
|
223
|
+
elsif i18n_script
|
224
|
+
I18n.t('locale.format.scripted',
|
225
|
+
script: i18n_script,
|
226
|
+
language: i18n_language
|
227
|
+
)
|
228
|
+
elsif i18n_dialect
|
229
|
+
I18n.t('locale.format.dialectical',
|
230
|
+
dialect: i18n_dialect,
|
231
|
+
language: i18n_language
|
232
|
+
)
|
233
|
+
elsif i18n_region
|
234
|
+
I18n.t('locale.format.regional',
|
235
|
+
region: i18n_region,
|
236
|
+
language: i18n_language
|
237
|
+
)
|
238
|
+
else
|
239
|
+
i18n_language
|
240
|
+
end
|
241
|
+
end
|
242
|
+
end
|
243
|
+
|
244
|
+
# Tests for equality between two locales. Their full RFC 5646 codes must be
|
245
|
+
# equal.
|
246
|
+
#
|
247
|
+
# @param [Locale] other Another Locale.
|
248
|
+
# @return [true, false] Whether it is the same Locale as the receiver.
|
249
|
+
# @raise [ArgumentError] If `other` is not a Locale.
|
250
|
+
|
251
|
+
def ==(other)
|
252
|
+
case other
|
253
|
+
when Locale
|
254
|
+
rfc5646 == other.rfc5646
|
255
|
+
else
|
256
|
+
false
|
257
|
+
end
|
258
|
+
end
|
259
|
+
|
260
|
+
alias_method :eql?, :==
|
261
|
+
alias_method :equal?, :==
|
262
|
+
alias_method :===, :==
|
263
|
+
|
264
|
+
# @private
|
265
|
+
def hash
|
266
|
+
rfc5646.hash
|
267
|
+
end
|
268
|
+
|
269
|
+
# Returns the fallback order for this Locale. For example, fr-CA might
|
270
|
+
# fall back to fr, which then falls back to en. The fallback order is
|
271
|
+
# described in the `fallbacks.yml` file.
|
272
|
+
#
|
273
|
+
# @return [Array<Locale>] The fallback order of this locale, from most
|
274
|
+
# specific to most general. Note that this array includes the receiver.
|
275
|
+
|
276
|
+
def fallbacks
|
277
|
+
fallbacks = Array.wrap(self.class.fallbacks[rfc5646])
|
278
|
+
.map { |l| self.class.from_rfc5646 l }
|
279
|
+
fallbacks.unshift self
|
280
|
+
fallbacks
|
281
|
+
end
|
282
|
+
|
283
|
+
# Returns whether this Languge is a subset of the given locale. "en-US" is a
|
284
|
+
# child of "en".
|
285
|
+
#
|
286
|
+
# @param [Locale] parent Another locale.
|
287
|
+
# @return [true, false] Whether this locale is a child of `parent`.
|
288
|
+
|
289
|
+
def child_of?(parent)
|
290
|
+
return false if iso639 != parent.iso639
|
291
|
+
return false if parent.specificity > specificity
|
292
|
+
parent.specified_parts.all? { |part| specified_parts.include?(part) }
|
293
|
+
end
|
294
|
+
|
295
|
+
# @return [true, false] Whether this locale is a pseudo-locale.
|
296
|
+
def pseudo?
|
297
|
+
variants.include? 'pseudo'
|
298
|
+
end
|
299
|
+
|
300
|
+
# @private
|
301
|
+
def specificity
|
302
|
+
specificity = 1
|
303
|
+
specificity += 1 if script
|
304
|
+
specificity += 1 if region
|
305
|
+
specificity += variants.size
|
306
|
+
specificity += 1 if extended_language
|
307
|
+
specificity + extensions.size
|
308
|
+
end
|
309
|
+
|
310
|
+
# @private
|
311
|
+
def specified_parts
|
312
|
+
# relies on the fact that the namespace for each element of the code is
|
313
|
+
# *globally* unique, not just unique to the code element
|
314
|
+
(variants + extensions + [script, region, extended_language]).compact
|
315
|
+
end
|
316
|
+
|
317
|
+
# @private
|
318
|
+
def as_json(_options = nil)
|
319
|
+
{
|
320
|
+
rfc5646: rfc5646,
|
321
|
+
components: {
|
322
|
+
iso639: iso639,
|
323
|
+
script: script,
|
324
|
+
extended_language: extended_language,
|
325
|
+
region: region,
|
326
|
+
variants: variants,
|
327
|
+
exensions: extensions
|
328
|
+
},
|
329
|
+
name: name
|
330
|
+
}
|
331
|
+
end
|
332
|
+
|
333
|
+
# @private
|
334
|
+
def inspect
|
335
|
+
"#<#{self.class} #{rfc5646}>"
|
336
|
+
end
|
337
|
+
end
|
338
|
+
end
|
data/rfc5646.gemspec
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'rfc5646/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'rfc5646'
|
8
|
+
spec.version = Rfc5646::VERSION
|
9
|
+
spec.authors = ['Artyom Bolshakov']
|
10
|
+
spec.email = ['abolshakov@spbtv.com']
|
11
|
+
|
12
|
+
spec.summary = 'Parsing RFC 5646 locale'
|
13
|
+
spec.description = 'Parsing RFC 5646 locale'
|
14
|
+
spec.homepage = 'https://github.com/SPBTV/rfc5646'
|
15
|
+
spec.license = 'Apache 2.0'
|
16
|
+
|
17
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
18
|
+
spec.bindir = 'exe'
|
19
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
20
|
+
spec.require_paths = ['lib']
|
21
|
+
|
22
|
+
spec.add_runtime_dependency 'activesupport', '>= 3.0.0'
|
23
|
+
spec.add_runtime_dependency 'i18n', '~> 0.6'
|
24
|
+
spec.add_development_dependency 'bundler', '~> 1.10'
|
25
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
26
|
+
spec.add_development_dependency 'rspec', '~> 3.3'
|
27
|
+
spec.add_development_dependency 'rubocop', '~> 0.34.2'
|
28
|
+
end
|
metadata
ADDED
@@ -0,0 +1,146 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rfc5646
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Artyom Bolshakov
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-10-14 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: activesupport
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 3.0.0
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 3.0.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: i18n
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0.6'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0.6'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: bundler
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.10'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.10'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rake
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '10.0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '10.0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rspec
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '3.3'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '3.3'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rubocop
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: 0.34.2
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: 0.34.2
|
97
|
+
description: Parsing RFC 5646 locale
|
98
|
+
email:
|
99
|
+
- abolshakov@spbtv.com
|
100
|
+
executables: []
|
101
|
+
extensions: []
|
102
|
+
extra_rdoc_files: []
|
103
|
+
files:
|
104
|
+
- ".gitignore"
|
105
|
+
- ".rspec"
|
106
|
+
- ".rubocop.yml"
|
107
|
+
- ".travis.yml"
|
108
|
+
- CODE_OF_CONDUCT.md
|
109
|
+
- Gemfile
|
110
|
+
- LICENSE.txt
|
111
|
+
- README.md
|
112
|
+
- Rakefile
|
113
|
+
- bin/console
|
114
|
+
- bin/setup
|
115
|
+
- config/locales/locales.en.yml
|
116
|
+
- lib/rfc5646.rb
|
117
|
+
- lib/rfc5646/engine.rb
|
118
|
+
- lib/rfc5646/locale.rb
|
119
|
+
- lib/rfc5646/version.rb
|
120
|
+
- rfc5646.gemspec
|
121
|
+
homepage: https://github.com/SPBTV/rfc5646
|
122
|
+
licenses:
|
123
|
+
- Apache 2.0
|
124
|
+
metadata: {}
|
125
|
+
post_install_message:
|
126
|
+
rdoc_options: []
|
127
|
+
require_paths:
|
128
|
+
- lib
|
129
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
130
|
+
requirements:
|
131
|
+
- - ">="
|
132
|
+
- !ruby/object:Gem::Version
|
133
|
+
version: '0'
|
134
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
139
|
+
requirements: []
|
140
|
+
rubyforge_project:
|
141
|
+
rubygems_version: 2.4.5
|
142
|
+
signing_key:
|
143
|
+
specification_version: 4
|
144
|
+
summary: Parsing RFC 5646 locale
|
145
|
+
test_files: []
|
146
|
+
has_rdoc:
|