i18n-inflector 2.0.1 → 2.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.yardopts +1 -0
- data/ChangeLog +412 -0
- data/Gemfile +1 -0
- data/Manifest.txt +6 -1
- data/README.rdoc +16 -11
- data/Rakefile +15 -2
- data/ci/i18n-inflector.gemspec +1 -1
- data/ci/i18nv4-Gemfile +15 -0
- data/docs/EXAMPLES +222 -0
- data/docs/HISTORY +31 -0
- data/docs/LEGAL +0 -1
- data/docs/RELATIONS +16 -13
- data/docs/TODO +25 -3
- data/lib/i18n-inflector/api.rb +964 -0
- data/lib/i18n-inflector/api_strict.rb +519 -0
- data/lib/i18n-inflector/backend.rb +77 -40
- data/lib/i18n-inflector/errors.rb +56 -14
- data/lib/i18n-inflector/inflection_data.rb +133 -105
- data/lib/i18n-inflector/inflection_data_strict.rb +290 -0
- data/lib/i18n-inflector/inflector.rb +21 -660
- data/lib/i18n-inflector/lazy_enum.rb +120 -0
- data/lib/i18n-inflector/long_comments.rb +203 -14
- data/lib/i18n-inflector/version.rb +1 -1
- data/lib/i18n-inflector.rb +5 -3
- data/test/inflector_test.rb +334 -34
- data/test/test_helper.rb +1 -1
- data.tar.gz.sig +0 -0
- metadata +10 -6
- metadata.gz.sig +0 -0
- data/lib/i18n-inflector/util.rb +0 -67
@@ -0,0 +1,964 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
#
|
3
|
+
# Author:: Paweł Wilk (mailto:pw@gnu.org)
|
4
|
+
# Copyright:: (c) 2011 by Paweł Wilk
|
5
|
+
# License:: This program is licensed under the terms of {file:LGPL GNU Lesser General Public License} or {file:COPYING Ruby License}.
|
6
|
+
#
|
7
|
+
# This file contains {I18n::Inflector::API} class,
|
8
|
+
# which is public API for I18n Inflector.
|
9
|
+
|
10
|
+
module I18n
|
11
|
+
module Inflector
|
12
|
+
|
13
|
+
# Instance of this class, the inflector, is attached
|
14
|
+
# to I18n backend. This class contains common operations
|
15
|
+
# that can be performed on inflections. It can operate
|
16
|
+
# on both unnamed an named patterns (regular and strict kinds).
|
17
|
+
# This class is used by backend methods to interpolate
|
18
|
+
# strings and load inflections.
|
19
|
+
#
|
20
|
+
# It uses the databases containing instances of
|
21
|
+
# {I18n::Inflector::InflectionData} and {I18n::Inflector::InflectionData_Strict}
|
22
|
+
# that are stored in the Hashes and indexed by locale names.
|
23
|
+
#
|
24
|
+
# Note that strict kinds used to handle named patterns
|
25
|
+
# internally are stored in a different database than
|
26
|
+
# regular kinds. Most of the methods of this class are also
|
27
|
+
# aware of strict kinds and will call proper methods handling
|
28
|
+
# strict inflection data when the +@+ symbol is detected
|
29
|
+
# at the beginning of the given identifier of a kind.
|
30
|
+
#
|
31
|
+
# ==== Usage
|
32
|
+
# You can access the instance of this class attached to
|
33
|
+
# default I18n backend by calling:
|
34
|
+
# I18n.backend.inflector
|
35
|
+
# or in a short form:
|
36
|
+
# I18n.inflector
|
37
|
+
# In case of named patterns (strict kinds):
|
38
|
+
# I18n.inflector.strict
|
39
|
+
#
|
40
|
+
# @see I18n::Inflector::API_Strict The API_Strict class
|
41
|
+
# for accessing inflection data for named
|
42
|
+
# patterns (strict kinds).
|
43
|
+
# @see file:EXAMPLES The examples of real-life usage.
|
44
|
+
# @api public
|
45
|
+
class API < API_Strict
|
46
|
+
|
47
|
+
# Options controlling the engine.
|
48
|
+
#
|
49
|
+
# @api public
|
50
|
+
# @return [I18n::Inflector::InflectionOptions] the set of options
|
51
|
+
# controlling inflection engine
|
52
|
+
# @see I18n::Inflector::InflectionOptions#raises
|
53
|
+
# @see I18n::Inflector::InflectionOptions#unknown_defaults
|
54
|
+
# @see I18n::Inflector::InflectionOptions#excluded_defaults
|
55
|
+
# @see I18n::Inflector::InflectionOptions#aliased_patterns
|
56
|
+
# @example Usage of +options+:
|
57
|
+
# # globally set raises flag
|
58
|
+
# I18n.inflector.options.raises = true
|
59
|
+
#
|
60
|
+
# # globally set raises flag (the same meaning as the example above)
|
61
|
+
# I18n.backend.inflector.options.raises = true
|
62
|
+
#
|
63
|
+
# # set raises flag just for this translation
|
64
|
+
# I18n.translate('welcome', :inflector_raises => true)
|
65
|
+
attr_reader :options
|
66
|
+
|
67
|
+
# @private
|
68
|
+
def strict
|
69
|
+
@strict ||= I18n::Inflector::API_Strict.new(@idb_strict, @options)
|
70
|
+
end
|
71
|
+
|
72
|
+
# Initilizes the inflector by creating internal databases
|
73
|
+
# used for storing inflection data and options.
|
74
|
+
#
|
75
|
+
# @api public
|
76
|
+
def initialize
|
77
|
+
super(nil, nil)
|
78
|
+
@idb_strict = {}
|
79
|
+
end
|
80
|
+
|
81
|
+
# Creates a database for the specified locale.
|
82
|
+
#
|
83
|
+
# @api public
|
84
|
+
# @raise [I18n::InvalidLocale] if there is no proper locale name
|
85
|
+
# @param [Symbol] locale the locale for which the inflections database is to be created
|
86
|
+
# @return [I18n::Inflector::InflectionData] the new object for keeping inflection data
|
87
|
+
def new_database(locale)
|
88
|
+
locale = prep_locale(locale)
|
89
|
+
@idb[locale] = I18n::Inflector::InflectionData.new(locale)
|
90
|
+
end
|
91
|
+
|
92
|
+
# Creates internal databases (regular and strict) for the specified locale.
|
93
|
+
#
|
94
|
+
# @api public
|
95
|
+
# @raise [I18n::InvalidLocale] if there is no proper locale name
|
96
|
+
# @param [Symbol] locale the locale for which the inflections databases are to be created
|
97
|
+
# @return [Array<I18n::Inflector::InflectionData,I18n::Inflector::InflectionData_Strict>] the
|
98
|
+
# array of objects for keeping inflection data
|
99
|
+
def new_databases(locale)
|
100
|
+
normal = new_databases(locale)
|
101
|
+
strict = strict.new_database(locale)
|
102
|
+
[normal, strict]
|
103
|
+
end
|
104
|
+
|
105
|
+
# Attaches instance of {I18n::Inflector::InflectionData} and
|
106
|
+
# optionally {I18n::Inflector::InflectionData_Strict}
|
107
|
+
# to the inflector.
|
108
|
+
#
|
109
|
+
# @api public
|
110
|
+
# @raise [I18n::InvalidLocale] if there is no proper locale name
|
111
|
+
# @note It doesn't create a copy of inflection data, but registers the given object(s).
|
112
|
+
# @return [I18n::Inflector::InflectionData,Array,nil]
|
113
|
+
# @overload add_database(db)
|
114
|
+
# @param [I18n::Inflector::InflectionData] db inflection data to add
|
115
|
+
# @return [I18n::Inflector::InflectionData,nil] the given object or +nil+
|
116
|
+
# if something went wrong (e.g. +nil+ was given as an argument)
|
117
|
+
# @overload add_database(db, db_strict)
|
118
|
+
# @note An array is returned and databases are
|
119
|
+
# used only if both databases are successfully attached. References to
|
120
|
+
# both databases will be unset if there would be a problem with attaching
|
121
|
+
# any of them.
|
122
|
+
# @param [I18n::Inflector::InflectionData] db inflection data to add
|
123
|
+
# @param [I18n::Inflector::InflectionData_Strict] db_strict strict inflection data to add
|
124
|
+
# @return [Array<I18n::Inflector::InflectionData,I18n::Inflector::InflectionData_Strict>,nil] the
|
125
|
+
# array of the given objects or +nil+ if something went wrong (e.g. +nil+ was
|
126
|
+
# given as the first argument)
|
127
|
+
def add_database(db, db_strict=nil)
|
128
|
+
r = super(db)
|
129
|
+
return r if (r.nil? || db_strict.nil?)
|
130
|
+
r_strict = strict.add_database(db_strict)
|
131
|
+
if r_strict.nil?
|
132
|
+
delete_database(db.locale)
|
133
|
+
return nil
|
134
|
+
end
|
135
|
+
[r, r_strict]
|
136
|
+
end
|
137
|
+
alias_method :add_databases, :add_database
|
138
|
+
|
139
|
+
# Deletes the internal databases for the specified locale.
|
140
|
+
#
|
141
|
+
# @api public
|
142
|
+
# @note It detaches the databases from {I18n::Inflector::API} instance.
|
143
|
+
# Other objects referring to them may still use it.
|
144
|
+
# @raise [I18n::InvalidLocale] if there is no proper locale name
|
145
|
+
# @param [Symbol] locale the locale for which the inflections database is to be deleted.
|
146
|
+
# @return [void]
|
147
|
+
def delete_databases(locale)
|
148
|
+
delete_database(locale)
|
149
|
+
strict.delete_database(locale)
|
150
|
+
end
|
151
|
+
|
152
|
+
# Checks if the given locale was configured to support inflection.
|
153
|
+
#
|
154
|
+
# @api public
|
155
|
+
# @note That method uses information from regular and strict kinds.
|
156
|
+
# @raise [I18n::InvalidLocale] if there is no proper locale name
|
157
|
+
# @return [Boolean] +true+ if a locale supports inflection
|
158
|
+
# @overload inflected_locale?(locale)
|
159
|
+
# Checks if the given locale was configured to support inflection.
|
160
|
+
# @param [Symbol] locale the locale to test
|
161
|
+
# @return [Boolean] +true+ if the given locale supports inflection
|
162
|
+
# @overload inflected_locale?
|
163
|
+
# Checks if the current locale was configured to support inflection.
|
164
|
+
# @return [Boolean] +true+ if the current locale supports inflection
|
165
|
+
def inflected_locale?(locale=nil)
|
166
|
+
super || strict.inflected_locale?(locale)
|
167
|
+
end
|
168
|
+
alias_method :locale?, :inflected_locale?
|
169
|
+
alias_method :locale_supported?, :inflected_locale?
|
170
|
+
|
171
|
+
# Gets locales which have configured inflection support.
|
172
|
+
#
|
173
|
+
# @api public
|
174
|
+
# @note That method uses information from regular and strict kinds.
|
175
|
+
# @return [Array<Symbol>] the array containing locales that support inflection
|
176
|
+
#
|
177
|
+
# @overload inflected_locales
|
178
|
+
# Gets locales which have configured inflection support.
|
179
|
+
# @return [Array<Symbol>] the array containing locales that support inflection
|
180
|
+
# @overload inflected_locales(kind)
|
181
|
+
# Gets locales which have configured inflection support for the given +kind+.
|
182
|
+
# @param [Symbol] kind the identifier of a kind
|
183
|
+
# @return [Array<Symbol>] the array containing locales that support inflection
|
184
|
+
# @note If +kind+ begins with the +@+ symbol then the variant of this method
|
185
|
+
# operating on strict kinds will be called ({I18n::Inflector::API_Strict#inflected_locales})
|
186
|
+
def inflected_locales(kind=nil)
|
187
|
+
if kind.to_s[0..0] == NAMED_MARKER
|
188
|
+
strict.inflected_locales(kind.to_s[1..-1])
|
189
|
+
else
|
190
|
+
(super + strict.inflected_locales(kind)).uniq
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
# Tests if a kind exists.
|
195
|
+
#
|
196
|
+
# @api public
|
197
|
+
# @raise [I18n::InvalidLocale] if there is no proper locale name
|
198
|
+
# @return [Boolean] +true+ if the given +kind+ exists, +false+ otherwise
|
199
|
+
# @note If +kind+ begins with the +@+ symbol then the variant of this method
|
200
|
+
# operating on strict kinds will be called ({I18n::Inflector::API_Strict#has_kind?})
|
201
|
+
# @overload has_kind?(kind)
|
202
|
+
# Tests if a regular kind exists for the current locale.
|
203
|
+
# @param [Symbol] kind the identifier of a kind
|
204
|
+
# @return [Boolean] +true+ if the given +kind+ exists for the current
|
205
|
+
# locale, +false+ otherwise
|
206
|
+
# @overload has_kind?(kind, locale)
|
207
|
+
# Tests if a regular kind exists for the given +locale+.
|
208
|
+
# @param [Symbol,String] kind the identifier of a kind
|
209
|
+
# @param [Symbol] locale the locale identifier
|
210
|
+
# @return [Boolean] +true+ if the given +kind+ exists, +false+ otherwise
|
211
|
+
def has_kind?(kind, locale=nil)
|
212
|
+
if kind.to_s[0..0] == NAMED_MARKER
|
213
|
+
return strict.has_kind?(kind.to_s[1..-1], locale)
|
214
|
+
end
|
215
|
+
super
|
216
|
+
end
|
217
|
+
|
218
|
+
# Reads default token for the given +kind+.
|
219
|
+
#
|
220
|
+
# @api public
|
221
|
+
# @return [Symbol,nil] the default token or +nil+
|
222
|
+
# @raise [I18n::InvalidLocale] if there is no proper locale name
|
223
|
+
# @note If +kind+ begins with the +@+ symbol then the variant of this method
|
224
|
+
# operating on strict kinds will be called ({I18n::Inflector::API_Strict#default_token})
|
225
|
+
# @overload default_token(kind)
|
226
|
+
# This method reads default token for the given +kind+ and the current locale.
|
227
|
+
# @param [Symbol,String] kind the kind of tokens
|
228
|
+
# @return [Symbol,nil] the default token or +nil+ if
|
229
|
+
# there is no default token
|
230
|
+
# @overload default_token(kind, locale)
|
231
|
+
# This method reads default token for the given +kind+ and the given +locale+.
|
232
|
+
# @param [Symbol,String] kind the kind of tokens
|
233
|
+
# @param [Symbol] locale the locale to use
|
234
|
+
# @return [Symbol,nil] the default token or +nil+ if
|
235
|
+
# there is no default token
|
236
|
+
def default_token(kind, locale=nil)
|
237
|
+
return nil if (kind.nil? || kind.to_s.empty?)
|
238
|
+
if kind.to_s[0..0] == NAMED_MARKER
|
239
|
+
return strict.default_token(kind.to_s[1..-1], locale)
|
240
|
+
end
|
241
|
+
super
|
242
|
+
end
|
243
|
+
|
244
|
+
# Checks if the given +token+ is an alias.
|
245
|
+
#
|
246
|
+
# @api public
|
247
|
+
# @note By default it uses regular kinds database, not strict kinds.
|
248
|
+
# @return [Boolean] +true+ if the given +token+ is an alias, +false+ otherwise
|
249
|
+
# @raise [I18n::InvalidLocale] if the given +locale+ is invalid
|
250
|
+
# @raise [ArgumentError] if the count of arguments is invalid
|
251
|
+
# @overload has_alias?(token)
|
252
|
+
# Uses current locale to check if the given +token+ is an alias.
|
253
|
+
# @param [Symbol,String] token name of the checked token
|
254
|
+
# @return [Boolean] +true+ if the given +token+ is an alias, +false+ otherwise
|
255
|
+
# @overload has_alias?(token, locale)
|
256
|
+
# Uses the given +locale+ to check if the given +token+ is an alias.
|
257
|
+
# @param [Symbol,String] token name of the checked token
|
258
|
+
# @param [Symbol] locale the locale to use
|
259
|
+
# @return [Boolean] +true+ if the given +token+ is an alias, +false+ otherwise
|
260
|
+
# @overload has_alias?(token, kind, locale)
|
261
|
+
# Uses the given +locale+ and +kind+ to check if the given +token+ is an alias.
|
262
|
+
# @note If +kind+ begins with the +@+ symbol then the variant of this method
|
263
|
+
# operating on strict kinds will be called ({I18n::Inflector::API_Strict#has_alias?})
|
264
|
+
# @param [Symbol,String] token name of the checked token
|
265
|
+
# @param [Symbol,String] kind the kind used to narrow the check
|
266
|
+
# @param [Symbol] locale the locale to use
|
267
|
+
# @return [Boolean] +true+ if the given +token+ is an alias, +false+ otherwise
|
268
|
+
# @overload has_alias?(token, strict_kind)
|
269
|
+
# Uses the current locale and the given +strict_kind+ (which name must begin with
|
270
|
+
# the +@+ symbol) to check if the given +token+ is an alias.
|
271
|
+
# @note It calls {I18n::Inflector::API_Strict#has_alias?} on strict kinds data.
|
272
|
+
# @param [Symbol,String] token name of the checked token
|
273
|
+
# @param [Symbol,String] strict_kind the kind of the given alias
|
274
|
+
# @return [Boolean] +true+ if the given +token+ is an alias, +false+ otherwise
|
275
|
+
def has_alias?(*args)
|
276
|
+
token, kind, locale = tkl_args(args)
|
277
|
+
return false if (token.nil? || token.to_s.empty?)
|
278
|
+
unless kind.nil?
|
279
|
+
kind = kind.to_s
|
280
|
+
reutrn false if kind.empty?
|
281
|
+
if kind[0..0] == NAMED_MARKER
|
282
|
+
return strict.has_alias?(token, kind[1..-1], locale)
|
283
|
+
end
|
284
|
+
kind = kind.to_sym
|
285
|
+
end
|
286
|
+
data_safe(locale).has_alias?(token.to_sym, kind)
|
287
|
+
end
|
288
|
+
alias_method :token_has_alias?, :has_alias?
|
289
|
+
|
290
|
+
# Checks if the given +token+ is a true token (not alias).
|
291
|
+
#
|
292
|
+
# @api public
|
293
|
+
# @note By default it uses regular kinds database, not strict kinds.
|
294
|
+
# @return [Boolean] +true+ if the given +token+ is a true token, +false+ otherwise
|
295
|
+
# @raise [I18n::InvalidLocale] if the given +locale+ is invalid
|
296
|
+
# @raise [ArgumentError] if the count of arguments is invalid
|
297
|
+
# @overload has_true_token?(token)
|
298
|
+
# Uses current locale to check if the given +token+ is a true token.
|
299
|
+
# @param [Symbol,String] token name of the checked token
|
300
|
+
# @return [Boolean] +true+ if the given +token+ is a true token, +false+ otherwise
|
301
|
+
# @overload has_true_token?(token, locale)
|
302
|
+
# Uses the given +locale+ to check if the given +token+ is a true token.
|
303
|
+
# @param [Symbol,String] token name of the checked token
|
304
|
+
# @param [Symbol] locale the locale to use
|
305
|
+
# @return [Boolean] +true+ if the given +token+ is a true token, +false+ otherwise
|
306
|
+
# @overload has_true_token?(token, kind, locale)
|
307
|
+
# Uses the given +locale+ and +kind+ to check if the given +token+ is a true token.
|
308
|
+
# @note If +kind+ begins with the +@+ symbol then the variant of this method
|
309
|
+
# operating on strict kinds will be called ({I18n::Inflector::API_Strict#has_true_token?})
|
310
|
+
# @param [Symbol,String] token name of the checked token
|
311
|
+
# @param [Symbol,String] kind the kind used to narrow the check
|
312
|
+
# @param [Symbol] locale the locale to use
|
313
|
+
# @return [Boolean] +true+ if the given +token+ is a true token, +false+ otherwise
|
314
|
+
# @overload has_true_token?(token, strict_kind)
|
315
|
+
# Uses the current locale and the given +strict_kind+ (which name must begin with
|
316
|
+
# the +@+ symbol) to check if the given +token+ is a true token.
|
317
|
+
# @note It calls {I18n::Inflector::API_Strict#has_true_token?} on strict kinds data.
|
318
|
+
# @param [Symbol,String] token name of the checked token
|
319
|
+
# @param [Symbol,String] strict_kind the kind of the given token
|
320
|
+
# @return [Boolean] +true+ if the given +token+ is a true token, +false+ otherwise
|
321
|
+
def has_true_token?(*args)
|
322
|
+
token, kind, locale = tkl_args(args)
|
323
|
+
return false if (token.nil? || token.to_s.empty?)
|
324
|
+
unless kind.nil?
|
325
|
+
kind = kind.to_s
|
326
|
+
return false if kind.empty?
|
327
|
+
if kind[0..0] == NAMED_MARKER
|
328
|
+
return strict.has_true_token?(token, kind[1..-1], locale)
|
329
|
+
end
|
330
|
+
kind = kind.to_sym
|
331
|
+
end
|
332
|
+
data_safe(locale).has_true_token?(token.to_sym, kind)
|
333
|
+
end
|
334
|
+
alias_method :token_has_true?, :has_true_token?
|
335
|
+
|
336
|
+
# Checks if the given +token+ exists. It may be an alias or a true token.
|
337
|
+
#
|
338
|
+
# @api public
|
339
|
+
# @note By default it uses regular kinds database, not strict kinds.
|
340
|
+
# @return [Boolean] +true+ if the given +token+ exists, +false+ otherwise
|
341
|
+
# @raise [I18n::InvalidLocale] if the given +locale+ is invalid
|
342
|
+
# @raise [ArgumentError] if the count of arguments is invalid
|
343
|
+
# @overload has_token?(token)
|
344
|
+
# Uses current locale to check if the given +token+ is a token.
|
345
|
+
# @param [Symbol,String] token name of the checked token
|
346
|
+
# @return [Boolean] +true+ if the given +token+ exists, +false+ otherwise
|
347
|
+
# @overload has_token?(token, locale)
|
348
|
+
# Uses the given +locale+ to check if the given +token+ exists.
|
349
|
+
# @param [Symbol,String] token name of the checked token
|
350
|
+
# @param [Symbol] locale the locale to use
|
351
|
+
# @return [Boolean] +true+ if the given +token+ exists, +false+ otherwise
|
352
|
+
# @overload has_token?(token, kind, locale)
|
353
|
+
# Uses the given +locale+ and +kind+ to check if the given +token+ exists.
|
354
|
+
# @note If +kind+ begins with the +@+ symbol then the variant of this method
|
355
|
+
# operating on strict kinds will be called ({I18n::Inflector::API_Strict#has_token?})
|
356
|
+
# @param [Symbol,String] token name of the checked token
|
357
|
+
# @param [Symbol,String] kind the kind used to narrow the check
|
358
|
+
# @param [Symbol] locale the locale to use
|
359
|
+
# @return [Boolean] +true+ if the given +token+ exists, +false+ otherwise
|
360
|
+
# @overload has_token?(token, strict_kind)
|
361
|
+
# Uses the current locale and the given +strict_kind+ (which name must begin with
|
362
|
+
# the +@+ symbol) to check if the given +token+ exists.
|
363
|
+
# @note It calls {I18n::Inflector::API_Strict#has_token?} on strict kinds data.
|
364
|
+
# @param [Symbol,String] token name of the checked token
|
365
|
+
# @param [Symbol,String] strict_kind the kind of the given token
|
366
|
+
# @return [Boolean] +true+ if the given +token+ exists, +false+ otherwise
|
367
|
+
def has_token?(*args)
|
368
|
+
token, kind, locale = tkl_args(args)
|
369
|
+
return false if (token.nil? || token.to_s.empty?)
|
370
|
+
unless kind.nil?
|
371
|
+
kind = kind.to_s
|
372
|
+
return false if kind.empty?
|
373
|
+
if kind[0..0] == NAMED_MARKER
|
374
|
+
return strict.has_token?(token, kind[1..-1], locale)
|
375
|
+
end
|
376
|
+
kind = kind.to_sym
|
377
|
+
end
|
378
|
+
data_safe(locale).has_token?(token.to_sym, kind)
|
379
|
+
end
|
380
|
+
alias_method :token_exists?, :has_token?
|
381
|
+
|
382
|
+
# Gets true token for the given +token+. If the token
|
383
|
+
# is an alias it will be resolved
|
384
|
+
# and a true token (target) will be returned.
|
385
|
+
# @note By default it uses regular kinds database, not strict kinds.
|
386
|
+
# @api public
|
387
|
+
# @return [Symbol,nil] the true token or +nil+
|
388
|
+
# @raise [I18n::InvalidLocale] if there is no proper locale name
|
389
|
+
# @overload true_token(token)
|
390
|
+
# Uses current locale to get a real token for the given +token+.
|
391
|
+
# @param [Symbol,String] token name of the checked token
|
392
|
+
# @return [Symbol,nil] the true token or +nil+
|
393
|
+
# @overload true_token(token, locale)
|
394
|
+
# Uses the given +locale+ to get a real token for the given +token+.
|
395
|
+
# If the token is an alias it will be resolved
|
396
|
+
# and a true token (target) will be returned.
|
397
|
+
# @param [Symbol,String] token name of the checked token
|
398
|
+
# @param [Symbol] locale the locale to use
|
399
|
+
# @return [Symbol,nil] the true token or +nil+
|
400
|
+
# @overload true_token(token, kind, locale)
|
401
|
+
# Uses the given +locale+ and +kind+ to get a real token for the given +token+.
|
402
|
+
# If the token is an alias it will be resolved
|
403
|
+
# and a true token (target) will be returned.
|
404
|
+
# @note If +kind+ begins with the +@+ symbol then the variant of this method
|
405
|
+
# operating on strict kinds will be called ({I18n::Inflector::API_Strict#true_token})
|
406
|
+
# @param [Symbol,String] token name of the checked token
|
407
|
+
# @param [Symbol,String] kind the kind of the given token
|
408
|
+
# @param [Symbol] locale the locale to use
|
409
|
+
# @return [Symbol,nil] the true token or +nil+
|
410
|
+
# @overload true_token(token, strict_kind)
|
411
|
+
# Uses the current locale and the given +strict_kind+ (which name must begin with
|
412
|
+
# the +@+ symbol) to get a real token for the given +token+.
|
413
|
+
# @note It calls {I18n::Inflector::API_Strict#true_token} on strict kinds data.
|
414
|
+
# @param [Symbol,String] token name of the checked token
|
415
|
+
# @param [Symbol,String] strict_kind the kind of the given token
|
416
|
+
# @return [Symbol,nil] the true token
|
417
|
+
def true_token(*args)
|
418
|
+
token, kind, locale = tkl_args(args)
|
419
|
+
return nil if (token.nil? || token.to_s.empty?)
|
420
|
+
unless kind.nil?
|
421
|
+
kind = kind.to_s
|
422
|
+
return nil if kind.empty?
|
423
|
+
if kind[0..0] == NAMED_MARKER
|
424
|
+
return strict.true_token(token, kind[1..-1], locale)
|
425
|
+
end
|
426
|
+
kind = kind.to_sym
|
427
|
+
end
|
428
|
+
data_safe(locale).get_true_token(token.to_sym, kind)
|
429
|
+
end
|
430
|
+
alias_method :resolve_alias, :true_token
|
431
|
+
|
432
|
+
# Gets a kind for the given +token+ (which may be an alias).
|
433
|
+
#
|
434
|
+
# @api public
|
435
|
+
# @note By default it uses regular kinds database, not strict kinds.
|
436
|
+
# @return [Symbol,nil] the kind of the given +token+ or +nil+
|
437
|
+
# @raise [I18n::InvalidLocale] if there is no proper locale name
|
438
|
+
# @overload kind(token)
|
439
|
+
# Uses the current locale to get a kind of the given +token+ (which may be an alias).
|
440
|
+
# @param [Symbol,String] token name of the token or alias
|
441
|
+
# @return [Symbol,nil] the kind of the given +token+
|
442
|
+
# @overload kind(token, locale)
|
443
|
+
# Uses the given +locale+ to get a kind of the given +token+ (which may be an alias).
|
444
|
+
# @param [Symbol,String] token name of the token or alias
|
445
|
+
# @param [Symbol] locale the locale to use
|
446
|
+
# @return [Symbol,nil] the kind of the given +token+
|
447
|
+
# @overload kind(token, kind, locale)
|
448
|
+
# Uses the given +locale+ to get a kind of the given +token+ (which may be an alias).
|
449
|
+
# @note If +kind+ begins with the +@+ symbol then the variant of this method
|
450
|
+
# operating on strict kinds will be called ({I18n::Inflector::API_Strict#kind})
|
451
|
+
# @param [Symbol,String] token name of the token or alias
|
452
|
+
# @param [Symbol,String] kind the kind name to narrow the search
|
453
|
+
# @param [Symbol] locale the locale to use
|
454
|
+
# @return [Symbol,nil] the kind of the given +token+
|
455
|
+
# @overload kind(token, strict_kind)
|
456
|
+
# Uses the current locale and the given +strict_kind+ (which name must begin with
|
457
|
+
# the +@+ symbol) to get a kind of the given +token+ (which may be an alias).
|
458
|
+
# @note It calls {I18n::Inflector::API_Strict#kind} on strict kinds data.
|
459
|
+
# @param [Symbol,String] token name of the token or alias
|
460
|
+
# @param [Symbol,String] kind the kind of the given token
|
461
|
+
# @return [Symbol,nil] the kind of the given +token+
|
462
|
+
def kind(*args)
|
463
|
+
token, kind, locale = tkl_args(args)
|
464
|
+
return nil if (token.nil? || token.to_s.empty?)
|
465
|
+
unless kind.nil?
|
466
|
+
kind = kind.to_s
|
467
|
+
return nil if kind.empty?
|
468
|
+
if kind[0..0] == NAMED_MARKER
|
469
|
+
return strict.kind(token, kind[1..-1], locale)
|
470
|
+
end
|
471
|
+
kind = kind.to_sym
|
472
|
+
end
|
473
|
+
data_safe(locale).get_kind(token.to_sym, kind)
|
474
|
+
end
|
475
|
+
|
476
|
+
# Gets available inflection tokens and their descriptions.
|
477
|
+
#
|
478
|
+
# @api public
|
479
|
+
# @note By default it uses regular kinds database, not strict kinds.
|
480
|
+
# @raise [I18n::InvalidLocale] if there is no proper locale name
|
481
|
+
# @return [Hash] the hash containing available inflection tokens and descriptions
|
482
|
+
# @note You cannot deduce where aliases are pointing to, since the information
|
483
|
+
# about a target is replaced by the description. To get targets use the
|
484
|
+
# {#raw_tokens} method. To simply list aliases and their targets use
|
485
|
+
# the {#aliases} method.
|
486
|
+
# @overload tokens
|
487
|
+
# Gets available inflection tokens and their descriptions.
|
488
|
+
# @return [Hash] the hash containing available inflection tokens as keys
|
489
|
+
# and their descriptions as values, including aliases,
|
490
|
+
# for all kinds.
|
491
|
+
# @overload tokens(kind)
|
492
|
+
# Gets available inflection tokens and their descriptions for some +kind+.
|
493
|
+
# @note If +kind+ begins with the +@+ symbol then the variant of this method
|
494
|
+
# operating on strict kinds will be called ({I18n::Inflector::API_Strict#tokens})
|
495
|
+
# @param [Symbol,String] kind the kind of inflection tokens to be returned
|
496
|
+
# @return [Hash] the hash containing available inflection tokens as keys
|
497
|
+
# and their descriptions as values, including aliases, for current locale.
|
498
|
+
# @overload tokens(kind, locale)
|
499
|
+
# Gets available inflection tokens and their descriptions for some +kind+ and +locale+.
|
500
|
+
# @note If +kind+ begins with the +@+ symbol then the variant of this method
|
501
|
+
# operating on strict kinds will be called ({I18n::Inflector::API_Strict#tokens})
|
502
|
+
# @param [Symbol,String] kind the kind of inflection tokens to be returned
|
503
|
+
# @param [Symbol] locale the locale to use
|
504
|
+
# @return [Hash] the hash containing available inflection tokens as keys
|
505
|
+
# and their descriptions as values, including aliases, for current locale
|
506
|
+
def tokens(kind=nil, locale=nil)
|
507
|
+
unless kind.nil?
|
508
|
+
kind = kind.to_s
|
509
|
+
return {} if kind.empty?
|
510
|
+
if kind[0..0] == NAMED_MARKER
|
511
|
+
return strict.tokens(kind[1..-1], locale)
|
512
|
+
end
|
513
|
+
kind = kind.to_sym
|
514
|
+
end
|
515
|
+
data_safe(locale).get_tokens(kind)
|
516
|
+
end
|
517
|
+
|
518
|
+
# Gets available inflection tokens and their values.
|
519
|
+
#
|
520
|
+
# @api public
|
521
|
+
# @return [Hash] the hash containing available inflection tokens and descriptions (or alias pointers)
|
522
|
+
# @raise [I18n::InvalidLocale] if there is no proper locale name
|
523
|
+
# @note You may deduce whether the returned values are aliases or true tokens
|
524
|
+
# by testing if a value is a type of Symbol or String.
|
525
|
+
# @overload tokens_raw
|
526
|
+
# Gets available inflection tokens and their values for regular kinds.
|
527
|
+
# @return [Hash] the hash containing available inflection tokens as keys
|
528
|
+
# and their descriptions as values. In case of aliases the returned
|
529
|
+
# values are Symbols
|
530
|
+
# @overload tokens_raw(kind)
|
531
|
+
# Gets available inflection tokens and their values for the given +kind+.
|
532
|
+
# @note If +kind+ begins with the +@+ symbol then the variant of this method
|
533
|
+
# operating on strict kinds will be called ({I18n::Inflector::API_Strict#tokens_raw})
|
534
|
+
# @param [Symbol,String] kind the kind of inflection tokens to be returned
|
535
|
+
# @return [Hash] the hash containing available inflection tokens as keys
|
536
|
+
# and their descriptions as values. In case of aliases the returned
|
537
|
+
# values are Symbols
|
538
|
+
# @overload tokens_raw(kind, locale)
|
539
|
+
# Gets available inflection tokens and their values for the given +kind+ and +locale+.
|
540
|
+
# @note If +kind+ begins with the +@+ symbol then the variant of this method
|
541
|
+
# operating on strict kinds will be called ({I18n::Inflector::API_Strict#tokens_raw})
|
542
|
+
# @param [Symbol,String] kind the kind of inflection tokens to be returned
|
543
|
+
# @param [Symbol] locale the locale to use
|
544
|
+
# @return [Hash] the hash containing available inflection tokens as keys
|
545
|
+
# and their descriptions as values. In case of aliases the returned
|
546
|
+
# values are Symbols
|
547
|
+
def tokens_raw(kind=nil, locale=nil)
|
548
|
+
unless kind.nil?
|
549
|
+
kind = kind.to_s
|
550
|
+
return {} if kind.empty?
|
551
|
+
if kind[0..0] == NAMED_MARKER
|
552
|
+
return strict.tokens_raw(kind[1..-1], locale)
|
553
|
+
end
|
554
|
+
kind = kind.to_sym
|
555
|
+
end
|
556
|
+
data_safe(locale).get_raw_tokens(kind)
|
557
|
+
end
|
558
|
+
alias_method :raw_tokens, :tokens_raw
|
559
|
+
|
560
|
+
# Gets true inflection tokens and their values.
|
561
|
+
#
|
562
|
+
# @api public
|
563
|
+
# @return [Hash] the hash containing available inflection tokens and descriptions
|
564
|
+
# @raise [I18n::InvalidLocale] if there is no proper locale name
|
565
|
+
# @note It returns only true tokens, not aliases.
|
566
|
+
# @overload tokens_true
|
567
|
+
# Gets true inflection tokens and their values for regular kinds.
|
568
|
+
# @return [Hash] the hash containing available inflection tokens as keys
|
569
|
+
# and their descriptions as values
|
570
|
+
# @overload tokens_true(kind)
|
571
|
+
# Gets true inflection tokens and their values for the given +kind+.
|
572
|
+
# @note If +kind+ begins with the +@+ symbol then the variant of this method
|
573
|
+
# operating on strict kinds will be called ({I18n::Inflector::API_Strict#tokens_true})
|
574
|
+
# @param [Symbol,String] kind the kind of inflection tokens to be returned
|
575
|
+
# @return [Hash] the hash containing available inflection tokens as keys
|
576
|
+
# and their descriptions as values
|
577
|
+
# @overload tokens_true(kind, locale)
|
578
|
+
# Gets true inflection tokens and their values for the given +kind+ and +value+.
|
579
|
+
# @note If +kind+ begins with the +@+ symbol then the variant of this method
|
580
|
+
# operating on strict kinds will be called ({I18n::Inflector::API_Strict#tokens_true})
|
581
|
+
# @param [Symbol,String] kind the kind of inflection tokens to be returned
|
582
|
+
# @param [Symbol] locale the locale to use
|
583
|
+
# @return [Hash] the hash containing available inflection tokens as keys
|
584
|
+
# and their descriptions as values
|
585
|
+
def tokens_true(kind=nil, locale=nil)
|
586
|
+
unless kind.nil?
|
587
|
+
kind = kind.to_s
|
588
|
+
return {} if kind.empty?
|
589
|
+
if kind[0..0] == NAMED_MARKER
|
590
|
+
return strict.tokens_true(kind[1..-1], locale)
|
591
|
+
end
|
592
|
+
kind = kind.to_sym
|
593
|
+
end
|
594
|
+
data_safe(locale).get_true_tokens(kind)
|
595
|
+
end
|
596
|
+
alias_method :true_tokens, :tokens_true
|
597
|
+
|
598
|
+
# Gets inflection aliases and their pointers.
|
599
|
+
#
|
600
|
+
# @api public
|
601
|
+
# @raise [I18n::InvalidLocale] if there is no proper locale name
|
602
|
+
# @return [Hash] the Hash containing available inflection aliases (<tt>alias => target</tt>)
|
603
|
+
# @overload aliases
|
604
|
+
# Gets inflection aliases and their pointers for regular kinds.
|
605
|
+
# @return [Hash] the Hash containing available inflection aliases
|
606
|
+
# @overload aliases(kind)
|
607
|
+
# Gets inflection aliases and their pointers for the given +kind+.
|
608
|
+
# @note If +kind+ begins with the +@+ symbol then the variant of this method
|
609
|
+
# operating on strict kinds will be called ({I18n::Inflector::API_Strict#aliases})
|
610
|
+
# @param [Symbol,String] kind the kind of aliases to get
|
611
|
+
# @return [Hash] the Hash containing available inflection aliases
|
612
|
+
# @overload aliases(kind, locale)
|
613
|
+
# Gets inflection aliases and their pointers for the given +kind+ and +locale+.
|
614
|
+
# @note If +kind+ begins with the +@+ symbol then the variant of this method
|
615
|
+
# operating on strict kinds will be called ({I18n::Inflector::API_Strict#aliases})
|
616
|
+
# @param [Symbol,String] kind the kind of aliases to get
|
617
|
+
# @param [Symbol] locale the locale to use
|
618
|
+
# @return [Hash] the Hash containing available inflection aliases
|
619
|
+
def aliases(kind=nil, locale=nil)
|
620
|
+
unless kind.nil?
|
621
|
+
kind = kind.to_s
|
622
|
+
return nil if kind.empty?
|
623
|
+
if kind[0..0] == NAMED_MARKER
|
624
|
+
return strict.aliases(kind[1..-1], locale)
|
625
|
+
end
|
626
|
+
kind = kind.to_sym
|
627
|
+
end
|
628
|
+
data_safe(locale).get_aliases(kind)
|
629
|
+
end
|
630
|
+
|
631
|
+
# Gets the description of the given inflection token.
|
632
|
+
#
|
633
|
+
# @api public
|
634
|
+
# @note If the given +token+ is really an alias it
|
635
|
+
# returns the description of the true token that
|
636
|
+
# it points to. By default it uses regular kinds database,
|
637
|
+
# not strict kinds.
|
638
|
+
# @raise [I18n::InvalidLocale] if there is no proper locale name
|
639
|
+
# @return [String,nil] the descriptive string or +nil+
|
640
|
+
# @overload token_description(token)
|
641
|
+
# Uses current locale to get description of the given inflection +token+.
|
642
|
+
# @param [Symbol] token the identifier of a token
|
643
|
+
# @return [String,nil] the descriptive string or +nil+ if something
|
644
|
+
# went wrong (e.g. token was not found)
|
645
|
+
# @overload token_description(token, locale)
|
646
|
+
# Uses the given +locale+ to get description of the given inflection +token+.
|
647
|
+
# @param [Symbol,String] token the identifier of a token
|
648
|
+
# @param [Symbol] locale the locale to use
|
649
|
+
# @return [String,nil] the descriptive string or +nil+ if something
|
650
|
+
# went wrong (e.g. token was not found)
|
651
|
+
# @overload token_description(token, kind, locale)
|
652
|
+
# Uses the given +locale+ and +kind+ to get description of the given inflection +token+.
|
653
|
+
# @note If +kind+ begins with the +@+ symbol then the variant of this method
|
654
|
+
# operating on strict kinds will be called ({I18n::Inflector::API_Strict#token_description})
|
655
|
+
# @param [Symbol,String] token the identifier of a token
|
656
|
+
# @param [Symbol,String] kind the kind to narrow the results
|
657
|
+
# @param [Symbol] locale the locale to use
|
658
|
+
# @return [String,nil] the descriptive string or +nil+ if something
|
659
|
+
# went wrong (e.g. token was not found or +kind+ mismatched)
|
660
|
+
# @overload token_description(token, strict_kind)
|
661
|
+
# Uses the default locale and the given +kind+ (which name must begin with
|
662
|
+
# the +@+ symbol) to get description of the given inflection +token+.
|
663
|
+
# @note It calls {I18n::Inflector::API_Strict#token_description} on strict kinds data.
|
664
|
+
# @param [Symbol,String] token the identifier of a token
|
665
|
+
# @param [Symbol,String] strict_kind the kind of a token
|
666
|
+
# @param [Symbol] locale the locale to use
|
667
|
+
# @return [String,nil] the descriptive string or +nil+ if something
|
668
|
+
# went wrong (e.g. token was not found or +kind+ mismatched)
|
669
|
+
def token_description(*args)
|
670
|
+
token, kind, locale = tkl_args(args)
|
671
|
+
return nil if (token.nil? || token.to_s.empty?)
|
672
|
+
unless kind.nil?
|
673
|
+
kind = kind.to_s
|
674
|
+
return nil if kind.empty?
|
675
|
+
if kind[0..0] == NAMED_MARKER
|
676
|
+
return strict.token_description(token, kind[1..-1], locale)
|
677
|
+
end
|
678
|
+
kind = kind.to_sym
|
679
|
+
end
|
680
|
+
data_safe(locale).get_description(token.to_sym, kind)
|
681
|
+
end
|
682
|
+
|
683
|
+
# Interpolates inflection values in the given +string+
|
684
|
+
# using kinds given in +options+ and a matching tokens.
|
685
|
+
#
|
686
|
+
# @param [String] string the translation string
|
687
|
+
# containing patterns to interpolate
|
688
|
+
# @param [String,Symbol] locale the locale identifier
|
689
|
+
# @param [Hash] options the options
|
690
|
+
# @option options [Boolean] :inflector_excluded_defaults (false) local switch
|
691
|
+
# that overrides global setting (see: {I18n::Inflector::InflectionOptions#excluded_defaults})
|
692
|
+
# @option options [Boolean] :inflector_unknown_defaults (true) local switch
|
693
|
+
# that overrides global setting (see: {I18n::Inflector::InflectionOptions#unknown_defaults})
|
694
|
+
# @option options [Boolean] :inflector_raises (false) local switch
|
695
|
+
# that overrides global setting (see: {I18n::Inflector::InflectionOptions#raises})
|
696
|
+
# @option options [Boolean] :inflector_aliased_patterns (false) local switch
|
697
|
+
# that overrides global setting (see: {I18n::Inflector::InflectionOptions#aliased_patterns})
|
698
|
+
# @return [String] the string with interpolated patterns
|
699
|
+
def interpolate(string, locale, options = {})
|
700
|
+
used_kinds = options.except(*INFLECTOR_RESERVED_KEYS)
|
701
|
+
sw, op = @options, options
|
702
|
+
raises = (s=op.delete :inflector_raises).nil? ? sw.raises : s
|
703
|
+
aliased_patterns = (s=op.delete :inflector_aliased_patterns).nil? ? sw.aliased_patterns : s
|
704
|
+
unknown_defaults = (s=op.delete :inflector_unknown_defaults).nil? ? sw.unknown_defaults : s
|
705
|
+
excluded_defaults = (s=op.delete :inflector_excluded_defaults).nil? ? sw.excluded_defaults : s
|
706
|
+
|
707
|
+
idb = @idb[locale]
|
708
|
+
idb_strict = @idb_strict[locale]
|
709
|
+
|
710
|
+
string.gsub(PATTERN) do
|
711
|
+
pattern_fix = $1
|
712
|
+
strict_kind = $2
|
713
|
+
pattern_content = $3
|
714
|
+
ext_pattern = $&
|
715
|
+
ext_value = nil
|
716
|
+
ext_freetext = ''
|
717
|
+
found = false
|
718
|
+
parsed_default_v= nil
|
719
|
+
|
720
|
+
# leave escaped pattern as-is
|
721
|
+
unless pattern_fix.empty?
|
722
|
+
ext_pattern = ext_pattern[1..-1]
|
723
|
+
next ext_pattern if ESCAPES[pattern_fix]
|
724
|
+
end
|
725
|
+
|
726
|
+
# set parsed kind if strict kind is given (named pattern is parsed)
|
727
|
+
if strict_kind.empty?
|
728
|
+
parsed_symbol = nil
|
729
|
+
strict_kind = nil
|
730
|
+
parsed_kind = nil
|
731
|
+
default_token = nil
|
732
|
+
subdb = idb
|
733
|
+
else
|
734
|
+
parsed_symbol = (NAMED_MARKER + strict_kind).to_sym
|
735
|
+
strict_kind = strict_kind.to_sym
|
736
|
+
parsed_kind = strict_kind
|
737
|
+
subdb = idb_strict
|
738
|
+
default_token = subdb.get_default_token(parsed_kind)
|
739
|
+
end
|
740
|
+
|
741
|
+
# process pattern content's
|
742
|
+
pattern_content.scan(TOKENS) do
|
743
|
+
ext_token = $1.to_s
|
744
|
+
ext_value = $2.to_s
|
745
|
+
ext_freetext = $3.to_s
|
746
|
+
tokens = Hash.new(false)
|
747
|
+
negatives = Hash.new(false)
|
748
|
+
kind = nil
|
749
|
+
option = nil
|
750
|
+
|
751
|
+
# token not found?
|
752
|
+
if ext_token.empty?
|
753
|
+
# free text not found too? that should never happend.
|
754
|
+
if ext_freetext.empty?
|
755
|
+
raise I18n::InvalidInflectionToken.new(ext_pattern, ext_token) if raises
|
756
|
+
end
|
757
|
+
next
|
758
|
+
end
|
759
|
+
|
760
|
+
# split tokens if comma is present and put into fast list
|
761
|
+
ext_token.split(OPERATOR_MULTI).each do |t|
|
762
|
+
# token name corrupted
|
763
|
+
if t.empty?
|
764
|
+
raise I18n::InvalidInflectionToken.new(ext_pattern, t) if raises
|
765
|
+
next
|
766
|
+
end
|
767
|
+
|
768
|
+
# mark negative-matching tokens and put them to negatives fast list
|
769
|
+
if t[0..0] == OPERATOR_NOT
|
770
|
+
t = t[1..-1]
|
771
|
+
if t.empty?
|
772
|
+
raise I18n::InvalidInflectionToken.new(ext_pattern, t) if raises
|
773
|
+
next
|
774
|
+
end
|
775
|
+
t = t.to_sym
|
776
|
+
t = subdb.get_true_token(t, strict_kind) if aliased_patterns
|
777
|
+
negatives[t] = true
|
778
|
+
end
|
779
|
+
|
780
|
+
t = t.to_sym
|
781
|
+
t = subdb.get_true_token(t, strict_kind) if aliased_patterns
|
782
|
+
|
783
|
+
# get kind for that token
|
784
|
+
kind = subdb.get_kind(t, strict_kind)
|
785
|
+
if kind.nil?
|
786
|
+
raise I18n::InvalidInflectionToken.new(ext_pattern, t) if raises
|
787
|
+
next
|
788
|
+
end
|
789
|
+
|
790
|
+
# set processed kind after matching first token in a pattern
|
791
|
+
if parsed_kind.nil?
|
792
|
+
parsed_kind = kind
|
793
|
+
parsed_symbol = kind.to_sym
|
794
|
+
default_token = subdb.get_default_token(parsed_kind)
|
795
|
+
elsif parsed_kind != kind
|
796
|
+
# tokens of different kinds in one regular (not named) pattern are prohibited
|
797
|
+
if raises
|
798
|
+
raise I18n::MisplacedInflectionToken.new(ext_pattern, t, parsed_symbol)
|
799
|
+
end
|
800
|
+
next
|
801
|
+
end
|
802
|
+
|
803
|
+
# use that token
|
804
|
+
tokens[t] = true unless negatives[t]
|
805
|
+
end
|
806
|
+
|
807
|
+
# self-explanatory
|
808
|
+
if (tokens.empty? && negatives.empty?)
|
809
|
+
raise I18n::InvalidInflectionToken.new(ext_pattern, ext_token) if raises
|
810
|
+
end
|
811
|
+
|
812
|
+
# try @-style option for strict kind, fallback to regular if not found
|
813
|
+
# and memorize option name for error reporting
|
814
|
+
oname = !strict_kind.nil? && options.has_key?(parsed_symbol) ?
|
815
|
+
parsed_symbol : (options.has_key?(kind) ? kind : nil)
|
816
|
+
|
817
|
+
# Get option if possible and memorize for error reporting;
|
818
|
+
# fallback to default token if option still not found
|
819
|
+
if oname.nil?
|
820
|
+
option = default_token
|
821
|
+
orig_option = nil
|
822
|
+
else
|
823
|
+
option = options[oname]
|
824
|
+
orig_option = option
|
825
|
+
end
|
826
|
+
|
827
|
+
if (option.nil? || option.to_s.empty?)
|
828
|
+
# if option is given but is unknown, empty or nil
|
829
|
+
# then use default option for a kind if unknown_defaults is switched on
|
830
|
+
option = unknown_defaults ? default_token : nil
|
831
|
+
else
|
832
|
+
# validate option and if it's unknown try in aliases
|
833
|
+
option = subdb.get_true_token(option.to_sym, strict_kind)
|
834
|
+
|
835
|
+
# if still nothing then fall back to default value
|
836
|
+
# for a kind if unknown_defaults switch is on
|
837
|
+
if option.nil?
|
838
|
+
option = unknown_defaults ? default_token : nil
|
839
|
+
end
|
840
|
+
end
|
841
|
+
|
842
|
+
# if the option is still unknown or bad
|
843
|
+
# raise an exception
|
844
|
+
if option.nil?
|
845
|
+
if raises
|
846
|
+
if oname.nil?
|
847
|
+
ex = InflectionOptionNotFound
|
848
|
+
oname = parsed_symbol
|
849
|
+
orig_option = nil
|
850
|
+
else
|
851
|
+
ex = InflectionOptionIncorrect
|
852
|
+
end
|
853
|
+
raise ex.new(ext_pattern, oname, ext_token, orig_option)
|
854
|
+
end
|
855
|
+
next
|
856
|
+
end
|
857
|
+
|
858
|
+
# memorize default value for further processing
|
859
|
+
# outside this block if excluded_defaults switch is on
|
860
|
+
parsed_default_v = ext_value if (excluded_defaults && !default_token.nil?)
|
861
|
+
|
862
|
+
# throw the value if the given option matches one of the tokens from group
|
863
|
+
# or negatively matches one of the negated tokens
|
864
|
+
case negatives.count
|
865
|
+
when 0 then next unless tokens[option]
|
866
|
+
when 1 then next if negatives[option]
|
867
|
+
end
|
868
|
+
|
869
|
+
# skip further evaluation of the pattern
|
870
|
+
# since the right token has been found
|
871
|
+
found = true
|
872
|
+
break
|
873
|
+
|
874
|
+
end # single token (or a group) processing
|
875
|
+
|
876
|
+
result = nil
|
877
|
+
|
878
|
+
# return value of a token that matches option's value
|
879
|
+
# given for a kind or try to return a free text
|
880
|
+
# if it's present
|
881
|
+
if found
|
882
|
+
result = ext_value
|
883
|
+
elsif (excluded_defaults && !parsed_kind.nil?)
|
884
|
+
# if there is excluded_defaults switch turned on
|
885
|
+
# and a correct token was found in an inflection option but
|
886
|
+
# has not been found in a pattern then interpolate
|
887
|
+
# the pattern with a value picked for the default
|
888
|
+
# token for that kind if a default token was present
|
889
|
+
# in a pattern
|
890
|
+
kind = nil
|
891
|
+
token = options[parsed_kind]
|
892
|
+
kind = subdb.get_kind(token)
|
893
|
+
result = parsed_default_v unless kind.nil?
|
894
|
+
end
|
895
|
+
|
896
|
+
pattern_fix + (result || ext_freetext)
|
897
|
+
|
898
|
+
end # single pattern processing
|
899
|
+
|
900
|
+
end
|
901
|
+
|
902
|
+
protected
|
903
|
+
|
904
|
+
# @private
|
905
|
+
def data(locale=nil)
|
906
|
+
@idb[prep_locale(locale)]
|
907
|
+
end
|
908
|
+
|
909
|
+
# @private
|
910
|
+
def data_safe(locale=nil)
|
911
|
+
@idb[prep_locale(locale)] || I18n::Inflector::InflectionData.new(locale)
|
912
|
+
end
|
913
|
+
|
914
|
+
# This method is the internal helper that prepares arguments
|
915
|
+
# containing +token+, +kind+ and +locale+.
|
916
|
+
#
|
917
|
+
# @note This method leaves +kind+ as is when it's +nil+ or empty. It sets
|
918
|
+
# +token+ to +nil+ when it's empty.
|
919
|
+
# @raise [I18n::InvalidLocale] if there is no proper locale name
|
920
|
+
# @raise [ArgumentError] if the count of arguments is invalid
|
921
|
+
# @return [Array<Symbol,Symbol,Symbol>] the array containing
|
922
|
+
# cleaned and validated +token+, +kind+ and +locale+
|
923
|
+
# @overload tkl_args(token, kind, locale)
|
924
|
+
# Prepares arguments containing +token+, +kind+ and +locale+.
|
925
|
+
# @param [String,Hash] token the token
|
926
|
+
# @param [String,Hash] kind the inflection kind
|
927
|
+
# @param [String,Hash] locale the locale identifier
|
928
|
+
# @return [Array<Symbol,Symbol,Symbol>] the array containing
|
929
|
+
# cleaned and validated +token+, +kind+ and +locale+
|
930
|
+
# @overload tkl_args(token, locale)
|
931
|
+
# Prepares arguments containing +token+ and +locale+.
|
932
|
+
# @param [String,Hash] token the token
|
933
|
+
# @param [String,Hash] locale the locale identifier
|
934
|
+
# @return [Array<Symbol,Symbol,Symbol>] the array containing
|
935
|
+
# cleaned and validated +token+, +kind+ and +locale+
|
936
|
+
# @overload tkl_args(token)
|
937
|
+
# Prepares arguments containing +token+.
|
938
|
+
# @param [String,Hash] token the token
|
939
|
+
# @return [Array<Symbol,Symbol,Symbol>] the array containing
|
940
|
+
# cleaned and validated +token+ and the current locale
|
941
|
+
# @overload tkl_args(token, strict_kind)
|
942
|
+
# Prepares arguments containing +token+ and +strict_kind+.
|
943
|
+
# @param [String,Hash] token the token
|
944
|
+
# @param [String,Hash] strict_kind the strict kind identifier beginning with +@+ symbol
|
945
|
+
# @return [Array<Symbol,Symbol,Symbol>] the array containing
|
946
|
+
# cleaned and validated +token+, +strict_kind+ and the current locale
|
947
|
+
def tkl_args(args)
|
948
|
+
token, kind, locale = case args.count
|
949
|
+
when 1 then [args[0], nil, nil]
|
950
|
+
when 2 then args[1].to_s[0..0] == NAMED_MARKER ? [args[0], args[1], nil] : [args[0], nil, args[1]]
|
951
|
+
when 3 then args
|
952
|
+
else raise ArgumentError.new("wrong number of arguments: #{args.count} for (1..3)")
|
953
|
+
end
|
954
|
+
[token,kind,locale]
|
955
|
+
end
|
956
|
+
|
957
|
+
end # class API
|
958
|
+
|
959
|
+
# @abstract This is for backward compatibility with the old naming scheme.
|
960
|
+
class Core < API
|
961
|
+
end
|
962
|
+
|
963
|
+
end # module Inflector
|
964
|
+
end # module I18n
|