util 0.4.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/.yardopts +1 -0
- data/CECILL-C.EN +517 -0
- data/CECILL-C.FR +521 -0
- data/LICENSES.md +21 -0
- data/README.md +478 -0
- data/lib/util.rb +12 -0
- data/lib/util/args.rb +138 -0
- data/lib/util/communia.rb +8 -0
- data/lib/util/console_logger.rb +178 -0
- data/lib/util/downloader.rb +157 -0
- data/lib/util/i18n.rb +327 -0
- data/lib/util/lists.rb +6 -0
- data/lib/util/lists/iso639.rb +149 -0
- data/lib/util/result.rb +175 -0
- data/lib/util/test.rb +225 -0
- data/lib/util/yaml.rb +18 -0
- data/share/lists/iso639-3.yml +35528 -0
- data/test/unit.rb +20 -0
- data/test/unit/args.rb +22 -0
- data/test/unit/downloader.rb +145 -0
- data/test/unit/downloader/orig/simple.html +7 -0
- data/test/unit/i18n.rb +216 -0
- data/test/unit/i18n/CamelCase/eng.yml +2 -0
- data/test/unit/i18n/CamelCase/fra.yml +2 -0
- data/test/unit/i18n/aaj.yml +2 -0
- data/test/unit/i18n/en.yml +2 -0
- data/test/unit/i18n/fra.yml +2 -0
- data/test/unit/i18n/i18n +0 -0
- data/test/unit/i18n/prv.yml +2 -0
- data/test/unit/i18n/void/fra.yml/Yes-git-I-need-this-folder-even-if-it-is-empty +0 -0
- data/test/unit/i18n//316/261/316/273/316/271/316/261/317/202/fra.yml +2 -0
- data/test/unit/lists/iso639.rb +78 -0
- data/test/unit/result.rb +180 -0
- data/tools/create-iso639-3.rb +235 -0
- metadata +80 -0
data/lib/util/i18n.rb
ADDED
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
module Util
|
|
2
|
+
# A class for simple internationalization.
|
|
3
|
+
# Do not expect anything extraordinary.
|
|
4
|
+
class I18n
|
|
5
|
+
# If the provided default language does not work, the default default
|
|
6
|
+
# language is French.
|
|
7
|
+
DEFAULT_LANG = :fra
|
|
8
|
+
|
|
9
|
+
private_class_method :new
|
|
10
|
+
|
|
11
|
+
# Initialize the internationalization manager. Automatically called when
|
|
12
|
+
# using another method of the class.
|
|
13
|
+
def self.init
|
|
14
|
+
@default_lang = DEFAULT_LANG
|
|
15
|
+
@errors = []
|
|
16
|
+
@messages = {}
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# Simpler variant of register, where the module name is generated
|
|
20
|
+
# from its filename. No recursivity.
|
|
21
|
+
# @param [String] path path relative to which the +i18n+ folder is located
|
|
22
|
+
# @return [Boolean] true on success, false on error
|
|
23
|
+
def self.<< path
|
|
24
|
+
name = File.basename path.to_s, '.rb'
|
|
25
|
+
register name, path
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Get the current default language.
|
|
29
|
+
# @return [Symbol]
|
|
30
|
+
def self.default_lang
|
|
31
|
+
init unless initialized?
|
|
32
|
+
@default_lang
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# Check whether the internationalization system is initialized.
|
|
36
|
+
# @return [Boolean]
|
|
37
|
+
def self.initialized?
|
|
38
|
+
not @default_lang.nil?
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Obtain the translated message associated to a given
|
|
42
|
+
# internationalization token. If no options are provided, the
|
|
43
|
+
# default language and last used module will be used.
|
|
44
|
+
# @param [String] id internationalization token
|
|
45
|
+
# @param [Hash] opts options
|
|
46
|
+
# @option opts [#to_sym] :lang wanted language
|
|
47
|
+
# @option opts [String] :mod in which module to find the token
|
|
48
|
+
# @return [String] translated message, or +''+ in case of error
|
|
49
|
+
def self.message id, opts={}
|
|
50
|
+
init unless initialized?
|
|
51
|
+
if @messages.empty? then
|
|
52
|
+
@errors << [:messages_empty, nil]
|
|
53
|
+
return ''
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
require 'util/args'
|
|
57
|
+
id = Util::Args.check id, String, ''
|
|
58
|
+
o_lang, o_mod = Util::Opts.check opts, :lang, Symbol, @default_lang, \
|
|
59
|
+
:mod, String, @last_used_mod
|
|
60
|
+
|
|
61
|
+
mod = o_mod.empty? ? @last_used_mod : o_mod
|
|
62
|
+
mod = @messages.keys[0] if mod.empty?
|
|
63
|
+
if @messages[mod].nil? or @messages[mod].empty? then
|
|
64
|
+
@errors << [:msg_no_module_content, mod]
|
|
65
|
+
return ''
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
lang = (@messages[mod][o_lang].nil? or @messages[mod][o_lang].empty?) \
|
|
69
|
+
? @default_lang : o_lang
|
|
70
|
+
lang = (@messages[mod][lang].nil? or @messages[mod][lang].empty?) \
|
|
71
|
+
? DEFAULT_LANG : lang
|
|
72
|
+
if @messages[mod][lang].nil? or @messages[mod][lang].empty? then
|
|
73
|
+
data = [o_lang, @default_lang, DEFAULT_LANG].to_s
|
|
74
|
+
@errors << [:msg_no_valid_lang, data]
|
|
75
|
+
return ''
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
@last_used_mod = mod
|
|
79
|
+
@messages[mod][lang][id].to_s
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# Get the next error encountered while using I18n. Possible
|
|
83
|
+
# errors are the following.
|
|
84
|
+
# - +:messages_empty+ (data is +nil+): attempted to get a tranlated
|
|
85
|
+
# message before having registered any.
|
|
86
|
+
# - +:msg_no_module_content+ (data is the module name): attempted to get
|
|
87
|
+
# a translated message from a module that does not exist or
|
|
88
|
+
# contains no messages.
|
|
89
|
+
# - +:msg_no_valid_lang+ (data is an array of tried languages): attempted
|
|
90
|
+
# to get a translated message from a module where neither the asked
|
|
91
|
+
# language nor the default languages contain any messages.
|
|
92
|
+
# - +:reg_no_file+ (data is the provided path): the path provided to
|
|
93
|
+
# register messages contains no valid YAML file to use.
|
|
94
|
+
# - +:reg_no_name+ (data is the provided name): attempted to
|
|
95
|
+
# register messages with a module name that resolves to an empty string.
|
|
96
|
+
# - +:reg_path_not_dir+ (data is the provided path): the path provided to
|
|
97
|
+
# register messages is not a directory.
|
|
98
|
+
# - +:reg_path_not_exist+ (data is the provided path): the path provided
|
|
99
|
+
# to register messages does not exist.
|
|
100
|
+
# - +:reg_yaml_cant_open+ (data is the file path): the file cannot be
|
|
101
|
+
# opened or parsed by YAML.
|
|
102
|
+
# - +:set_def_unknown+ (data is the provided language code): attempted
|
|
103
|
+
# to set the default language to an invalid value.
|
|
104
|
+
# @return [Array<Symbol, Object>] error name and error data
|
|
105
|
+
def self.next_error
|
|
106
|
+
init unless initialized?
|
|
107
|
+
@errors.shift
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
# Register a set of internationalization tokens. Will search the
|
|
111
|
+
# same directory as the given path for YAML files whose file name
|
|
112
|
+
# is a valid language code, and extract the internationalized
|
|
113
|
+
# strings from them.
|
|
114
|
+
# @param [String] o_name name of the token-set
|
|
115
|
+
# @param [String] path file relative to which the YAML files
|
|
116
|
+
# will be searched (it is meant to be used with +__FILE__+).
|
|
117
|
+
# If nothing is provided, present working directory will be used.
|
|
118
|
+
# @param [Boolean] relative if true, will search +i18n+ folder
|
|
119
|
+
# next to the given path; if false, will search YAML files
|
|
120
|
+
# directly inside the given path
|
|
121
|
+
# @param [Boolean] recursive search subfolders too, and generate
|
|
122
|
+
# token-set names derived from the subfolders’ name
|
|
123
|
+
# @return [Boolean] true on success, false on error
|
|
124
|
+
def self.register o_name='', path='', relative=true, recursive=false
|
|
125
|
+
name, path, relative, recursive = \
|
|
126
|
+
register_check_args o_name, path, relative, recursive
|
|
127
|
+
return false if name == false
|
|
128
|
+
|
|
129
|
+
locations = register_get_locations name, path, recursive
|
|
130
|
+
|
|
131
|
+
messages = {}
|
|
132
|
+
locations.each do |loc|
|
|
133
|
+
register_get_messages loc, messages
|
|
134
|
+
end
|
|
135
|
+
return false if check_t messages.empty?, :reg_no_file, path
|
|
136
|
+
|
|
137
|
+
@messages.merge! messages do |k, ov, nv|
|
|
138
|
+
@messages[k] = ov.merge nv do |l, lov, lnv|
|
|
139
|
+
ov[l] = lov.merge lnv
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
@last_used_mod = name if @last_used_mod.nil?
|
|
144
|
+
true
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
# Set the default language to use from now on. Recommended is an
|
|
148
|
+
# ISO 639-3 language code, but any ISO 639 code, IETF BCP 47 language
|
|
149
|
+
# tag or ISO/IEC 15897 locale (a. k. a. POSIX locale) will work.
|
|
150
|
+
# @param [#to_sym] n_lang new default language
|
|
151
|
+
# @return [Boolean]
|
|
152
|
+
def self.set_default_lang n_lang
|
|
153
|
+
init unless initialized?
|
|
154
|
+
lang = n_lang.to_s.downcase
|
|
155
|
+
lang = $1 if lang.match /^(\w+)(?:_|-)/
|
|
156
|
+
lang = valid_lang? lang
|
|
157
|
+
return false if check_f lang, :set_def_unknown, n_lang
|
|
158
|
+
|
|
159
|
+
@default_lang = lang.to_sym
|
|
160
|
+
true
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
private
|
|
164
|
+
|
|
165
|
+
# Register an error if a given test yields a given result.
|
|
166
|
+
# @param [Boolean] trigger test result that shall trigger the error
|
|
167
|
+
# @param [Boolean] test test that might trigger the error
|
|
168
|
+
# @param [Symbol] err_name error name
|
|
169
|
+
# @param [Object] err_data data giving details on the error
|
|
170
|
+
# @return [Boolean] whether the error was triggered
|
|
171
|
+
def self.check trigger, test, err_name, err_data
|
|
172
|
+
@errors << [err_name, err_data] if test == trigger
|
|
173
|
+
test == trigger
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
# Register an error if the test is false
|
|
177
|
+
# @param [Boolean] test test that might trigger the error
|
|
178
|
+
# @param [Symbol] err_name error name
|
|
179
|
+
# @param [Object] err_data data giving details on the error
|
|
180
|
+
# @return [Boolean] whether the error was triggered
|
|
181
|
+
def self.check_f test, err_name, err_data=nil
|
|
182
|
+
check false, test, err_name, err_data
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
# Register an error if the test is true
|
|
186
|
+
# @param (see check_f)
|
|
187
|
+
# @return (see check_f)
|
|
188
|
+
def self.check_t test, err_name, err_data=nil
|
|
189
|
+
check true, test, err_name, err_data
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
# Verify the arguments given to I18n.register.
|
|
193
|
+
# @param (see register)
|
|
194
|
+
# @return [String, String, Boolean, Boolean] success
|
|
195
|
+
# @return [false] failure
|
|
196
|
+
def self.register_check_args o_name, path, relative, recursive
|
|
197
|
+
require 'util/args'
|
|
198
|
+
init unless initialized?
|
|
199
|
+
name, path, relative, recursive = Util::Args.check \
|
|
200
|
+
o_name, String, '', path, String, '', \
|
|
201
|
+
relative, FalseClass, true, recursive, TrueClass, false
|
|
202
|
+
return false if check_t name.empty?, :reg_no_name, o_name
|
|
203
|
+
|
|
204
|
+
path = relative ? './temp.rb' : '.' if path.empty?
|
|
205
|
+
if relative then
|
|
206
|
+
dir = File.dirname(File.expand_path path)
|
|
207
|
+
path = File.join dir, 'i18n'
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
return false if check_f File.exist?(path), :reg_path_not_exist, path
|
|
211
|
+
return false if check_f File.directory?(path), :reg_path_not_dir, path
|
|
212
|
+
[name, path, relative, recursive]
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
# Get the folder(s) in which to search for YAML files, and the
|
|
216
|
+
# associated module names.
|
|
217
|
+
# @param [String] name name of the root module
|
|
218
|
+
# @param [String] path path to the root folder
|
|
219
|
+
# @param [Boolean] recursive wether the search should be recursive
|
|
220
|
+
# @return [Array<Array<String, String>>]
|
|
221
|
+
def self.register_get_locations name, path, recursive
|
|
222
|
+
locations = []
|
|
223
|
+
dirs = [path]
|
|
224
|
+
begin
|
|
225
|
+
current = dirs.shift
|
|
226
|
+
glob = File.join current.gsub(/([?*{\[])/, "\\$1"), '*.yml'
|
|
227
|
+
# These characters have a meaning for +Dir.glob+ and might
|
|
228
|
+
# yield very strange results if they are not escaped.
|
|
229
|
+
|
|
230
|
+
slug = slugify(current.sub(path, '').sub(File::SEPARATOR, ''))
|
|
231
|
+
full_name = slug.empty? ? name : (name + '-' + slug)
|
|
232
|
+
locations << [glob, full_name]
|
|
233
|
+
Dir[File.join current, '*'].each do |f|
|
|
234
|
+
dirs << f if File.directory? f
|
|
235
|
+
end if recursive
|
|
236
|
+
end until dirs.empty?
|
|
237
|
+
locations
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
# Extract the messages from a given folder. Will use all files with
|
|
241
|
+
# the form +lang-code.yml+ that contain valid YAML for a hash, then
|
|
242
|
+
# convert the values to strings, and finally merge it in the
|
|
243
|
+
# existing list.
|
|
244
|
+
# @param [Array<String, String>] loc glob and module name to use
|
|
245
|
+
# @param [Hash] messages existing list
|
|
246
|
+
# @return [Hash] updated list
|
|
247
|
+
def self.register_get_messages loc, messages
|
|
248
|
+
require 'util/yaml'
|
|
249
|
+
glob, name = loc
|
|
250
|
+
langs = {}
|
|
251
|
+
|
|
252
|
+
Dir[glob].each do |f|
|
|
253
|
+
lang = File.basename(f, '.yml')
|
|
254
|
+
next unless lang = valid_lang?(lang)
|
|
255
|
+
lang = lang.to_sym
|
|
256
|
+
|
|
257
|
+
content = YAML.from_file f
|
|
258
|
+
check_f content, :reg_yaml_cant_open, f
|
|
259
|
+
next unless content.is_a? Hash
|
|
260
|
+
|
|
261
|
+
langs[lang] = {} unless content.empty?
|
|
262
|
+
content.each_pair do |k, v|
|
|
263
|
+
langs[lang][k.to_s] = v.to_s
|
|
264
|
+
end
|
|
265
|
+
end
|
|
266
|
+
|
|
267
|
+
return messages if langs.empty?
|
|
268
|
+
|
|
269
|
+
if messages.has_key? name then
|
|
270
|
+
messages[name].merge! langs do |k, ov, nv|
|
|
271
|
+
messages[name][k] = ov.merge nv
|
|
272
|
+
end
|
|
273
|
+
else
|
|
274
|
+
messages[name] = langs
|
|
275
|
+
end
|
|
276
|
+
|
|
277
|
+
messages
|
|
278
|
+
end
|
|
279
|
+
|
|
280
|
+
# Escape a path so that it can be used as a Hash key. Rules are as follows.
|
|
281
|
+
# - Any non-word character becomes a hyphen.
|
|
282
|
+
# - Multiple hyphens are reduced to just one.
|
|
283
|
+
# - Starting and trailing hyphens are removed.
|
|
284
|
+
# - Everything is downcased.
|
|
285
|
+
# - The {https://en.wikipedia.org/wiki/Base64 base64} representation
|
|
286
|
+
# of the path is used instead if the resulting slug is empty.
|
|
287
|
+
# - All directories’ slugs are joined by hyphens.
|
|
288
|
+
# @param [String] string path to transform in slug
|
|
289
|
+
# @return [String]
|
|
290
|
+
# @example
|
|
291
|
+
# I18n.slugify 'alias' # 'alias'
|
|
292
|
+
# I18n.slugify '今日は' # '今日は'
|
|
293
|
+
# I18n.slugify 'La vie de ma mère' # 'la-vie-de-ma-mère'
|
|
294
|
+
# I18n.slugify 'Ça va? Oui, et toi?' # 'ça-va-oui-et-toi'
|
|
295
|
+
# I18n.slugify '??!?' # 'Pz8hPw=='
|
|
296
|
+
# I18n.slugify 'hello/Darkneß/m41_0!d' # 'hello-darkneß-m41_0-d'
|
|
297
|
+
# I18n.slugify 'Estie/de/tabarnak/!!§!' # 'estie-de-tabarnak-ISHCpyE='
|
|
298
|
+
# @note {https://www.youtube.com/watch?v=DvR6-SQzqO8 For those who did
|
|
299
|
+
# not get the last example…}
|
|
300
|
+
def self.slugify string
|
|
301
|
+
require 'base64'
|
|
302
|
+
result = []
|
|
303
|
+
string.split(File::SEPARATOR).each do |part|
|
|
304
|
+
res = part.gsub(/[^[:word:]]/, '-').gsub(/-{2,}/, '-')
|
|
305
|
+
res = res.sub(/^-/, '').sub(/-$/, '').downcase
|
|
306
|
+
res = Base64.urlsafe_encode64(part) if res.empty?
|
|
307
|
+
result << res
|
|
308
|
+
end
|
|
309
|
+
result.join '-'
|
|
310
|
+
end
|
|
311
|
+
|
|
312
|
+
# From a given ISO 639 code, either get the valid corresponding
|
|
313
|
+
# ISO 639-3 code, or false.
|
|
314
|
+
# @param [#to_sym] lang language code to check
|
|
315
|
+
# @return [#to_sym] existing ISO 639-3 code
|
|
316
|
+
# @return [false] could not find a matching ISO 639-3 code
|
|
317
|
+
def self.valid_lang? lang
|
|
318
|
+
require 'util/lists/iso639'
|
|
319
|
+
iso = Util::Lists::ISO639
|
|
320
|
+
# Typecheck is already done by ISO639
|
|
321
|
+
return lang if iso::P3.exist?(lang)
|
|
322
|
+
if n_lang = iso::P3.from2(lang) then return n_lang; end
|
|
323
|
+
if n_lang = iso::P3.from1(lang) then return n_lang; end
|
|
324
|
+
false
|
|
325
|
+
end
|
|
326
|
+
end
|
|
327
|
+
end
|
data/lib/util/lists.rb
ADDED
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
require 'util/communia'
|
|
2
|
+
|
|
3
|
+
module Util
|
|
4
|
+
module Lists
|
|
5
|
+
# A module for {https://en.wikipedia.org/wiki/ISO_639 ISO 639} language codes.
|
|
6
|
+
module ISO639
|
|
7
|
+
private
|
|
8
|
+
|
|
9
|
+
# Methods common to all parts of ISO 639 standard.
|
|
10
|
+
class Common
|
|
11
|
+
private_class_method :new
|
|
12
|
+
|
|
13
|
+
# Get the data from the file into memory. Automatically called when
|
|
14
|
+
# using another method of the class.
|
|
15
|
+
# @param [String] filename file inside +share/lists+ to use
|
|
16
|
+
def self.init filename
|
|
17
|
+
require 'util/yaml'
|
|
18
|
+
path = File.join Util::SHARE_PATH, 'lists'
|
|
19
|
+
|
|
20
|
+
@complete = YAML.from_file File.join(path, filename), {}
|
|
21
|
+
@complete.freeze
|
|
22
|
+
|
|
23
|
+
@codes = @complete.keys
|
|
24
|
+
@codes.freeze
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Check whether the data is in memory and readable.
|
|
28
|
+
# @return [Boolean]
|
|
29
|
+
def self.initialized?
|
|
30
|
+
not @complete.nil?
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Full list of codes in a given part of the stadard.
|
|
34
|
+
# @return [Array<Symbol>]
|
|
35
|
+
def self.codes
|
|
36
|
+
init if @complete.nil?
|
|
37
|
+
@codes
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Full data for a given part of the standard.
|
|
41
|
+
# @return [Hash<Symbol, Hash>]
|
|
42
|
+
def self.complete
|
|
43
|
+
init if @complete.nil?
|
|
44
|
+
@complete
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# Check whether a given code exists in a given standard.
|
|
48
|
+
# @param [#to_sym] code
|
|
49
|
+
# @return [Boolean]
|
|
50
|
+
def self.exist? code
|
|
51
|
+
not category(code).nil?
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# Check whether a given code is deprecated in a given standard.
|
|
55
|
+
# @param [#to_sym] code
|
|
56
|
+
# @return [Boolean]
|
|
57
|
+
def self.deprecated? code
|
|
58
|
+
category(code) == :dep
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# Check whether a given code is for private use in a given standard.
|
|
62
|
+
# @param [#to_sym] code
|
|
63
|
+
# @return [Boolean]
|
|
64
|
+
def self.private? code
|
|
65
|
+
category(code) == :priv
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# Check whether a given code is valid to date in a given standard.
|
|
69
|
+
# @param [#to_sym] code
|
|
70
|
+
# @return [Boolean]
|
|
71
|
+
def self.valid? code
|
|
72
|
+
category(code) == :val
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
private
|
|
76
|
+
|
|
77
|
+
# Check which kind of code the argument is.
|
|
78
|
+
# @param [#to_sym] code
|
|
79
|
+
# @return [:dep, :priv, :val, nil]
|
|
80
|
+
def self.category code
|
|
81
|
+
init if @complete.nil?
|
|
82
|
+
require 'util/args'
|
|
83
|
+
code = Util::Args.check code, Symbol, false
|
|
84
|
+
return nil unless code
|
|
85
|
+
|
|
86
|
+
info = @complete[code]
|
|
87
|
+
base = code.to_s[0..1]
|
|
88
|
+
priv = (base <=> 'pz') + (base <=> 'qu') == 0
|
|
89
|
+
info.nil? \
|
|
90
|
+
? (priv ? :priv : nil)
|
|
91
|
+
: (info[:deprecated] ? :dep : :val)
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
public
|
|
96
|
+
|
|
97
|
+
# Codes from the ISO 639-3 standard.
|
|
98
|
+
# @example
|
|
99
|
+
# codes = Util::Lists::ISO639
|
|
100
|
+
# puts codes::P3.from1 'fr' # :fre
|
|
101
|
+
# puts codes::P3.exist? :prv # true
|
|
102
|
+
# puts codes::P3.valid? :prv # false
|
|
103
|
+
class P3 < Common
|
|
104
|
+
# Get the data into memory. Automatically called when using
|
|
105
|
+
# another method of the class.
|
|
106
|
+
def self.init
|
|
107
|
+
super 'iso639-3.yml'
|
|
108
|
+
|
|
109
|
+
@from1 = {}
|
|
110
|
+
@from2 = {}
|
|
111
|
+
@complete.each_pair do |k, v|
|
|
112
|
+
@from1[v[:p1]] = k unless v[:p1].nil?
|
|
113
|
+
@from2[v[:p2b]] = k unless v[:p2b].nil?
|
|
114
|
+
@from2[v[:p2t]] = k unless v[:p2t].nil?
|
|
115
|
+
end
|
|
116
|
+
@from1.freeze
|
|
117
|
+
|
|
118
|
+
('a'..'t').each do |a|
|
|
119
|
+
('a'..'z').each do |b|
|
|
120
|
+
code = "q#{a}#{b}".to_sym
|
|
121
|
+
@from2[code] = code
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
@from2.freeze
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
# Get the ISO 639-3 code associated to a given ISO 639-1 code.
|
|
128
|
+
# @param [#to_sym] code
|
|
129
|
+
# @return [Symbol]
|
|
130
|
+
def self.from1 code
|
|
131
|
+
init if @complete.nil?
|
|
132
|
+
require 'util/args'
|
|
133
|
+
code = Util::Args.check code, Symbol, false
|
|
134
|
+
@from1[code]
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
# Get the ISO 639-3 code associated to a given ISO 639-2 code.
|
|
138
|
+
# @param [#to_sym] code
|
|
139
|
+
# @return [Symbol]
|
|
140
|
+
def self.from2 code
|
|
141
|
+
init if @complete.nil?
|
|
142
|
+
require 'util/args'
|
|
143
|
+
code = Util::Args.check code, Symbol, false
|
|
144
|
+
@from2[code]
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
end
|