i18n-inflector 1.0.11 → 2.0.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.
- data/.yardopts +2 -1
- data/ChangeLog +141 -6
- data/Gemfile +1 -0
- data/Manifest.txt +6 -2
- data/README.rdoc +32 -28
- data/Rakefile +4 -7
- data/ci/i18n-inflector.gemspec +3 -3
- data/docs/COPYING +1 -1
- data/docs/HISTORY +16 -1
- data/docs/LEGAL +1 -1
- data/docs/{LGPL-LICENSE → LGPL} +0 -0
- data/docs/RELATIONS +25 -0
- data/docs/TODO +5 -5
- data/lib/i18n-inflector/backend.rb +268 -0
- data/lib/i18n-inflector/errors.rb +12 -9
- data/lib/i18n-inflector/inflection_data.rb +329 -0
- data/lib/i18n-inflector/inflector.rb +396 -564
- data/lib/i18n-inflector/long_comments.rb +329 -407
- data/lib/i18n-inflector/options.rb +201 -0
- data/lib/i18n-inflector/util.rb +67 -0
- data/lib/i18n-inflector/version.rb +2 -2
- data/lib/i18n-inflector.rb +5 -1
- data/test/inflector_test.rb +182 -101
- data.tar.gz.sig +0 -0
- metadata +29 -10
- metadata.gz.sig +0 -0
- data/lib/i18n-inflector/shortcuts.rb +0 -154
@@ -2,168 +2,159 @@
|
|
2
2
|
#
|
3
3
|
# Author:: Paweł Wilk (mailto:pw@gnu.org)
|
4
4
|
# Copyright:: (c) 2011 by Paweł Wilk
|
5
|
-
# License:: This program is licensed under the terms of {file:LGPL
|
5
|
+
# License:: This program is licensed under the terms of {file:LGPL GNU Lesser General Public License} or {file:COPYING Ruby License}.
|
6
6
|
#
|
7
|
-
# This file contains I18n::
|
8
|
-
# which extends I18n
|
7
|
+
# This file contains I18n::Inflector module,
|
8
|
+
# which extends I18n by adding the ability
|
9
9
|
# to interpolate patterns containing inflection tokens
|
10
|
-
# defined in translation data.
|
10
|
+
# defined in translation data and manipulate on that data.
|
11
11
|
|
12
12
|
module I18n
|
13
|
-
module Backend
|
14
|
-
module Inflector
|
15
13
|
|
16
|
-
|
17
|
-
|
18
|
-
|
14
|
+
class <<self
|
15
|
+
# This is proxy method that returns an inflector
|
16
|
+
# object used by the current I18n backend.
|
17
|
+
#
|
18
|
+
# @return [I18n::Inflector::Core] inflector the inflector
|
19
|
+
# used by the current backend
|
20
|
+
def inflector
|
21
|
+
I18n.backend.inflector
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
module Inflector
|
26
|
+
# Contains <tt>@{</tt> string that is used to quickly fallback
|
27
|
+
# to standard +translate+ method if it's not found.
|
28
|
+
FAST_MATCHER = '@{'
|
29
|
+
|
30
|
+
# Contains a regular expression that catches patterns.
|
31
|
+
PATTERN = /(.?)@\{([^\}]+)\}/
|
19
32
|
|
20
|
-
|
21
|
-
|
33
|
+
# Contains a regular expression that catches tokens.
|
34
|
+
TOKENS = /(?:([^\:\|]+):+([^\|]+)\1?)|([^:\|]+)/
|
22
35
|
|
23
|
-
|
24
|
-
|
36
|
+
# Contains a symbol that indicates an alias.
|
37
|
+
ALIAS_MARKER = '@'
|
25
38
|
|
26
|
-
|
27
|
-
|
39
|
+
# Conatins a symbol used to separate multiple tokens.
|
40
|
+
OPERATOR_MULTI = ','
|
28
41
|
|
29
|
-
|
30
|
-
|
42
|
+
# Conatins a symbol used to mark tokens as negative.
|
43
|
+
OPERATOR_NOT = '!'
|
31
44
|
|
32
|
-
|
33
|
-
|
34
|
-
RESERVED_KEYS : I18n::Backend::Base::RESERVED_KEYS
|
45
|
+
# Contains a list of escape symbols that cause pattern to be escaped.
|
46
|
+
ESCAPES = { '@' => true, '\\' => true }
|
35
47
|
|
36
|
-
|
37
|
-
|
38
|
-
|
48
|
+
# Reserved keys
|
49
|
+
INFLECTOR_RESERVED_KEYS = defined?(RESERVED_KEYS) ?
|
50
|
+
RESERVED_KEYS : I18n::Backend::Base::RESERVED_KEYS
|
39
51
|
|
40
|
-
|
52
|
+
# Instances of this class, the inflectors, are attached
|
53
|
+
# to I18n backends. This class contains common operations
|
54
|
+
# that programmer can perform on inflections. It keeps the
|
55
|
+
# database of {I18n::Inflector::InflectionData} instances
|
56
|
+
# and has methods to access them in an easy way.
|
57
|
+
#
|
58
|
+
# ==== Usage
|
59
|
+
# You can access the instance of this class attached to
|
60
|
+
# default I18n backend by entering:
|
61
|
+
# I18n.backend.inflector
|
62
|
+
# or in a short form:
|
63
|
+
# I18n.inflector
|
64
|
+
class Core
|
65
|
+
|
66
|
+
include I18n::Inflector::Util
|
67
|
+
|
68
|
+
# Options controlling the engine.
|
41
69
|
#
|
42
70
|
# @api public
|
43
|
-
# @
|
44
|
-
#
|
45
|
-
# @see I18n::Inflector
|
46
|
-
# @see #
|
47
|
-
# @
|
48
|
-
#
|
49
|
-
#
|
50
|
-
#
|
51
|
-
#
|
52
|
-
#
|
53
|
-
#
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
#
|
71
|
+
# @return [I18n::Inflector::InflectionOptions] the set of options
|
72
|
+
# controlling inflection engine
|
73
|
+
# @see I18n::Inflector::InflectionOptions#raises
|
74
|
+
# @see I18n::Inflector::InflectionOptions#unknown_defaults
|
75
|
+
# @see I18n::Inflector::InflectionOptions#excluded_defaults
|
76
|
+
# @see I18n::Inflector::InflectionOptions#aliased_patterns
|
77
|
+
# @example Usage of +options+:
|
78
|
+
# # globally set raises flag
|
79
|
+
# I18n.inflector.options.raises = true
|
80
|
+
#
|
81
|
+
# # globally set raises flag (the same meaning as the example above)
|
82
|
+
# I18n.backend.inflector.options.raises = true
|
83
|
+
#
|
84
|
+
# # set raises flag just for this translation
|
85
|
+
# I18n.translate('welcome', :inflector_raises => true)
|
86
|
+
attr_reader :options
|
87
|
+
|
88
|
+
# Initilizes inflector by creating internal databases for storing
|
89
|
+
# inflection hashes and options.
|
61
90
|
#
|
62
91
|
# @api public
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
# @see #inflector_unknown_defaults=
|
67
|
-
# @overload inflector_unknown_defaults?
|
68
|
-
# Checks the state of the switch that that enables falling back
|
69
|
-
# to the default token for a kind when the inflection option
|
70
|
-
# is unknown or empty.
|
71
|
-
# @return [Boolean] the value of the global switch
|
72
|
-
# @overload inflector_unknown_defaults?(value)
|
73
|
-
# Returns the given value.
|
74
|
-
# @param [Boolean] value the value to be returned
|
75
|
-
# @return [Boolean] +true+ if the passed +value+ is not +false+
|
76
|
-
def inflector_unknown_defaults?(option=nil)
|
77
|
-
option.nil? ? @inflector_unknown_defaults : option!=false
|
92
|
+
def initialize
|
93
|
+
@idb = {}
|
94
|
+
@options = I18n::Inflector::InflectionOptions.new
|
78
95
|
end
|
79
|
-
|
80
|
-
#
|
81
|
-
# to the default token when the inflection option is not found in a pattern.
|
96
|
+
|
97
|
+
# Adds database for the specified locale.
|
82
98
|
#
|
83
99
|
# @api public
|
84
|
-
# @
|
85
|
-
# @
|
86
|
-
# @
|
87
|
-
#
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
# the inflection option is not found in a pattern.
|
92
|
-
# @return [Boolean] the value of the global switch
|
93
|
-
# @overload inflector_excluded_defaults?(value)
|
94
|
-
# Returns the given value
|
95
|
-
# @param [Boolean] value the value to be returned
|
96
|
-
# @return [Boolean] +true+ if the passed +value+ is not +false+
|
97
|
-
def inflector_excluded_defaults?(option=nil)
|
98
|
-
option.nil? ? @inflector_excluded_defaults : option!=false
|
100
|
+
# @raise [I18n::InvalidLocale] if there is no proper locale name
|
101
|
+
# @param [Symbol] locale the locale for which the infleciton database is created
|
102
|
+
# @return [I18n::Inflector::InflectionData] the new object for keeping inflection data
|
103
|
+
# for the given +locale+
|
104
|
+
def new_database(locale)
|
105
|
+
locale = prep_locale(locale)
|
106
|
+
@idb[locale] = I18n::Inflector::InflectionData.new(locale)
|
99
107
|
end
|
100
|
-
|
101
|
-
#
|
102
|
-
#
|
108
|
+
|
109
|
+
# Attaches {I18n::Inflector::InflectionData} instance to the
|
110
|
+
# current collection.
|
111
|
+
#
|
103
112
|
# @api public
|
104
|
-
# @
|
105
|
-
# @
|
106
|
-
# @
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
113
|
+
# @raise [I18n::InvalidLocale] if there is no proper locale name
|
114
|
+
# @note It doesn't create copy of inflection data, it registers the given object.
|
115
|
+
# @param [I18n::Inflector::InflectionData] idb inflection data to add
|
116
|
+
# @return [I18n::Inflector::InflectionData] the given +idb+ or +nil+ if something
|
117
|
+
# went wrong (e.g. +nil+ was given as an argument)
|
118
|
+
def add_database(idb)
|
119
|
+
return nil if idb.nil?
|
120
|
+
locale = prep_locale(idb.locale)
|
121
|
+
delete_database(locale)
|
122
|
+
@idb[locale] = idb
|
112
123
|
end
|
113
124
|
|
114
|
-
#
|
125
|
+
# Deletes a database for the specified locale.
|
115
126
|
#
|
116
127
|
# @api public
|
117
|
-
# @
|
118
|
-
#
|
119
|
-
# @
|
120
|
-
# @
|
121
|
-
#
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
# @return [String] the translated string with interpolated patterns
|
127
|
-
def translate(locale, key, options = {})
|
128
|
-
translated_string = super
|
129
|
-
return translated_string if locale.to_s.empty?
|
130
|
-
|
131
|
-
unless translated_string.include?(I18n::Backend::Inflector::FAST_MATCHER)
|
132
|
-
return translated_string
|
133
|
-
end
|
134
|
-
|
135
|
-
inflection_tokens = @inflection_tokens[locale]
|
136
|
-
if (inflection_tokens.nil? || inflection_tokens.empty?)
|
137
|
-
return clear_inflection_patterns(translated_string)
|
138
|
-
end
|
139
|
-
|
140
|
-
interpolate_inflections(translated_string, locale, options.dup)
|
128
|
+
# @note It detaches the database from {I18n::Inflector::Core} instance.
|
129
|
+
# Other objects referring to it directly may still use it.
|
130
|
+
# @raise [I18n::InvalidLocale] if there is no proper locale name
|
131
|
+
# @param [Symbol] locale the locale for which the infleciton database is to be deleted.
|
132
|
+
# @return [void]
|
133
|
+
def delete_database(locale)
|
134
|
+
locale = prep_locale(locale)
|
135
|
+
return nil if @idb[locale].nil?
|
136
|
+
@idb[locale] = nil
|
141
137
|
end
|
142
|
-
|
138
|
+
|
143
139
|
# Reads default token for the given +kind+.
|
144
140
|
#
|
145
141
|
# @api public
|
146
142
|
# @return [Symbol,nil] the default token for the given kind or +nil+
|
147
|
-
# @raise [I18n::InvalidLocale] if
|
148
|
-
# @
|
149
|
-
# @overload inflection_default_token(kind)
|
143
|
+
# @raise [I18n::InvalidLocale] if there is no proper locale name
|
144
|
+
# @overload default_token(kind)
|
150
145
|
# This method reads default token for the given +kind+ and current locale.
|
151
|
-
# @param [Symbol] kind the kind of tokens
|
146
|
+
# @param [Symbol,String] kind the kind of tokens
|
152
147
|
# @return [Symbol,nil] the default token for the given kind or +nil+ if
|
153
148
|
# there is no default token
|
154
|
-
# @overload
|
149
|
+
# @overload default_token(kind, locale)
|
155
150
|
# This method reads default token for the given +kind+ and the given +locale+.
|
156
|
-
# @param [Symbol] kind the kind of tokens
|
151
|
+
# @param [Symbol,String] kind the kind of tokens
|
157
152
|
# @param [Symbol] locale the locale to use
|
158
153
|
# @return [Symbol,nil] the default token for the given kind or +nil+ if
|
159
154
|
# there is no default token
|
160
|
-
def
|
161
|
-
locale = inflector_prep_locale(locale)
|
155
|
+
def default_token(kind, locale=nil)
|
162
156
|
return nil if kind.to_s.empty?
|
163
|
-
|
164
|
-
inflections = @inflection_defaults[locale]
|
165
|
-
return nil if inflections.nil?
|
166
|
-
inflections[kind.to_sym]
|
157
|
+
data_safe(locale).get_default_token(kind)
|
167
158
|
end
|
168
159
|
|
169
160
|
# Checks if the given +token+ is an alias.
|
@@ -171,268 +162,320 @@ module I18n
|
|
171
162
|
# @api public
|
172
163
|
# @return [Boolean] +true+ if the given +token+ is an alias, +false+ otherwise
|
173
164
|
# @raise [I18n::InvalidLocale] if the given +locale+ is invalid
|
174
|
-
# @
|
175
|
-
# @overload
|
176
|
-
# Uses current locale to check if the given +token+ is an alias
|
177
|
-
#
|
165
|
+
# @raise [ArgumentError] if the count of arguments is invalid
|
166
|
+
# @overload has_alias?(token)
|
167
|
+
# Uses current locale to check if the given +token+ is an alias.
|
168
|
+
# @param [Symbol,String] token name of the checked token
|
169
|
+
# @return [Boolean] +true+ if the given +token+ is an alias, +false+ otherwise
|
170
|
+
# @overload has_alias?(token, locale)
|
171
|
+
# Uses the given +locale+ to check if the given +token+ is an alias.
|
178
172
|
# @param [Symbol,String] token name of the checked token
|
173
|
+
# @param [Symbol] locale the locale to use
|
179
174
|
# @return [Boolean] +true+ if the given +token+ is an alias, +false+ otherwise
|
180
|
-
# @overload
|
181
|
-
# Uses the given +locale+ to check if the given +token+ is an alias
|
182
|
-
# or a regular token.
|
175
|
+
# @overload has_alias?(token, kind, locale)
|
176
|
+
# Uses the given +locale+ and +kind+ to check if the given +token+ is an alias.
|
183
177
|
# @param [Symbol,String] token name of the checked token
|
178
|
+
# @param [Symbol,String] kind the kind used to narrow the check
|
184
179
|
# @param [Symbol] locale the locale to use
|
185
180
|
# @return [Boolean] +true+ if the given +token+ is an alias, +false+ otherwise
|
186
|
-
def
|
181
|
+
def has_alias?(*args)
|
182
|
+
token, kind, locale = tkl_args(args)
|
187
183
|
return false if token.to_s.empty?
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
aliases.has_key?(token.to_sym)
|
184
|
+
return false if (!kind.nil? && kind.to_s.empty?)
|
185
|
+
token = token.to_sym
|
186
|
+
kind = kind.to_sym unless kind.nil?
|
187
|
+
data_safe(locale).has_alias?(token, kind)
|
193
188
|
end
|
189
|
+
alias_method :token_has_alias?, :has_alias?
|
190
|
+
|
191
|
+
# Checks if the given +token+ is a true token (not alias).
|
192
|
+
#
|
193
|
+
# @api public
|
194
|
+
# @return [Boolean] +true+ if the given +token+ is a true token, +false+ otherwise
|
195
|
+
# @raise [I18n::InvalidLocale] if the given +locale+ is invalid
|
196
|
+
# @raise [ArgumentError] if the count of arguments is invalid
|
197
|
+
# @overload has_true_token?(token)
|
198
|
+
# Uses current locale to check if the given +token+ is a true token.
|
199
|
+
# @param [Symbol,String] token name of the checked token
|
200
|
+
# @return [Boolean] +true+ if the given +token+ is a true token, +false+ otherwise
|
201
|
+
# @overload has_true_token?(token, locale)
|
202
|
+
# Uses the given +locale+ to check if the given +token+ is a true token.
|
203
|
+
# @param [Symbol,String] token name of the checked token
|
204
|
+
# @param [Symbol] locale the locale to use
|
205
|
+
# @return [Boolean] +true+ if the given +token+ is a true token, +false+ otherwise
|
206
|
+
# @overload has_true_token?(token, kind, locale)
|
207
|
+
# Uses the given +locale+ and +kind+ to check if the given +token+ is a true token.
|
208
|
+
# @param [Symbol,String] token name of the checked token
|
209
|
+
# @param [Symbol,String] kind the kind used to narrow the check
|
210
|
+
# @param [Symbol] locale the locale to use
|
211
|
+
# @return [Boolean] +true+ if the given +token+ is a true token, +false+ otherwise
|
212
|
+
def has_true_token?(*args)
|
213
|
+
token, kind, locale = tkl_args(args)
|
214
|
+
return false if token.to_s.empty?
|
215
|
+
return false if (!kind.nil? && kind.to_s.empty?)
|
216
|
+
token = token.to_sym
|
217
|
+
kind = kind.to_sym unless kind.nil?
|
218
|
+
data_safe(locale).has_true_token?(token, kind)
|
219
|
+
end
|
220
|
+
alias_method :token_has_true?, :has_true_token?
|
221
|
+
|
222
|
+
# Checks if the given +token+ exists. It may be an alias or a true token.
|
223
|
+
#
|
224
|
+
# @api public
|
225
|
+
# @return [Boolean] +true+ if the given +token+ exists, +false+ otherwise
|
226
|
+
# @raise [I18n::InvalidLocale] if the given +locale+ is invalid
|
227
|
+
# @raise [ArgumentError] if the count of arguments is invalid
|
228
|
+
# @overload has_token?(token)
|
229
|
+
# Uses current locale to check if the given +token+ is a token.
|
230
|
+
# @param [Symbol,String] token name of the checked token
|
231
|
+
# @return [Boolean] +true+ if the given +token+ exists, +false+ otherwise
|
232
|
+
# @overload has_token?(token, locale)
|
233
|
+
# Uses the given +locale+ to check if the given +token+ exists.
|
234
|
+
# @param [Symbol,String] token name of the checked token
|
235
|
+
# @param [Symbol] locale the locale to use
|
236
|
+
# @return [Boolean] +true+ if the given +token+ exists, +false+ otherwise
|
237
|
+
# @overload has_token?(token, kind, locale)
|
238
|
+
# Uses the given +locale+ and +kind+ to check if the given +token+ exists.
|
239
|
+
# @param [Symbol,String] token name of the checked token
|
240
|
+
# @param [Symbol,String] kind the kind used to narrow the check
|
241
|
+
# @param [Symbol] locale the locale to use
|
242
|
+
# @return [Boolean] +true+ if the given +token+ exists, +false+ otherwise
|
243
|
+
def has_token?(*args)
|
244
|
+
token, kind, locale = tkl_args(args)
|
245
|
+
return false if token.to_s.empty?
|
246
|
+
return false if (!kind.nil? && kind.to_s.empty?)
|
247
|
+
token = token.to_sym
|
248
|
+
kind = kind.to_sym unless kind.nil?
|
249
|
+
data_safe(locale).has_token?(token, kind)
|
250
|
+
end
|
251
|
+
alias_method :token_exists?, :has_token?
|
194
252
|
|
195
253
|
# Gets true token for the given +token+ (which may be an alias).
|
196
254
|
#
|
197
255
|
# @api public
|
198
256
|
# @return [Symbol,nil] the true token if the given +token+ is an alias, token if
|
199
257
|
# the token is a real token or +nil+ otherwise
|
200
|
-
# @raise [I18n::InvalidLocale] if
|
201
|
-
# @
|
202
|
-
# @overload inflection_true_token(token)
|
258
|
+
# @raise [I18n::InvalidLocale] if there is no proper locale name
|
259
|
+
# @overload true_token(token)
|
203
260
|
# Uses current locale to get a real token for the given +token+.
|
204
261
|
# @param [Symbol,String] token name of the checked token
|
205
262
|
# @return [Symbol,nil] the true token if the given +token+ is an alias, token if
|
206
263
|
# the token is a real token or +nil+ otherwise
|
207
|
-
# @overload
|
264
|
+
# @overload true_token(token, locale)
|
208
265
|
# Uses the given +locale+ to get a real token for the given +token+.
|
209
266
|
# @param [Symbol,String] token name of the checked token
|
210
267
|
# @param [Symbol] locale the locale to use
|
211
268
|
# @return [Symbol,nil] the true token if the given +token+ is an alias, token if
|
212
269
|
# the token is a real token or +nil+ otherwise
|
213
|
-
|
270
|
+
# @overload true_token(token, kind, locale)
|
271
|
+
# Uses the given +locale+ and +kind+ to get a real token for the given +token+.
|
272
|
+
# @param [Symbol,String] token name of the checked token
|
273
|
+
# @param [Symbol,String] kind the kind used to narrow the check
|
274
|
+
# @param [Symbol] locale the locale to use
|
275
|
+
# @return [Symbol,nil] the true token if the given +token+ is an alias, token if
|
276
|
+
# the token is a real token or +nil+ otherwise
|
277
|
+
def true_token(*args)
|
278
|
+
token, kind, locale = tkl_args(args)
|
214
279
|
return nil if token.to_s.empty?
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
entry = inflections[token]
|
220
|
-
return token unless entry.nil?
|
221
|
-
inflections = @inflection_aliases[locale]
|
222
|
-
return nil if inflections.nil?
|
223
|
-
entry = inflections[token]
|
224
|
-
return nil if entry.nil?
|
225
|
-
entry[:target]
|
280
|
+
return nil if (!kind.nil? && kind.to_s.empty?)
|
281
|
+
token = token.to_sym
|
282
|
+
kind = kind.to_sym unless kind.nil?
|
283
|
+
data_safe(locale).get_true_token(token, kind)
|
226
284
|
end
|
285
|
+
alias_method :resolve_alias, :true_token
|
227
286
|
|
228
287
|
# Gets a kind for the given +token+ (which may be an alias).
|
229
288
|
#
|
230
289
|
# @api public
|
231
|
-
# @return [Symbol,nil] the kind of the given +token+ or
|
232
|
-
# @raise [I18n::InvalidLocale] if
|
233
|
-
# @
|
234
|
-
#
|
235
|
-
# Uses current locale to get a kind for the given +token+ which may be an alias.
|
290
|
+
# @return [Symbol,nil] the kind of the given +token+ or +nil+
|
291
|
+
# @raise [I18n::InvalidLocale] if there is no proper locale name
|
292
|
+
# @overload kind(token)
|
293
|
+
# Uses current locale to get a kind of the given +token+ (which may be an alias).
|
236
294
|
# @param [Symbol,String] token name of the token or alias
|
237
295
|
# @return [Symbol,nil] the kind of the given +token+
|
238
296
|
# for the current locale
|
239
|
-
# @overload
|
240
|
-
# Uses the given +locale+ to get a kind
|
297
|
+
# @overload kind(token, locale)
|
298
|
+
# Uses the given +locale+ to get a kind of the given +token+ (which may be an alias).
|
241
299
|
# @param [Symbol,String] token name of the token or alias
|
242
300
|
# @param [Symbol] locale the locale to use
|
243
301
|
# @return [Symbol,nil] the kind of the given +token+
|
244
302
|
# for the given +locale+
|
245
|
-
def
|
303
|
+
def kind(token, locale=nil)
|
246
304
|
return nil if token.to_s.empty?
|
247
|
-
|
248
|
-
init_translations unless initialized?
|
249
|
-
inflections = @inflection_tokens[locale]
|
250
|
-
return nil if inflections.nil?
|
251
|
-
entry = inflections[token]
|
252
|
-
return entry[:kind] unless entry.nil?
|
253
|
-
inflections = @inflection_aliases[locale]
|
254
|
-
return nil if inflections.nil?
|
255
|
-
entry = inflections[token]
|
256
|
-
return nil if entry.nil?
|
257
|
-
entry[:kind]
|
305
|
+
data_safe(locale).get_kind(token.to_sym)
|
258
306
|
end
|
259
307
|
|
260
308
|
# Gets available inflection tokens and their descriptions.
|
261
309
|
#
|
262
310
|
# @api public
|
263
|
-
# @
|
264
|
-
# @raise [I18n::InvalidLocale] if a used locale is invalid
|
311
|
+
# @raise [I18n::InvalidLocale] if there is no proper locale name
|
265
312
|
# @return [Hash] the hash containing available inflection tokens and descriptions
|
266
313
|
# @note You cannot deduce where aliases are pointing to, since the information
|
267
314
|
# about a target is replaced by the description. To get targets use the
|
268
315
|
# {#inflection_raw_tokens} method. To simply list aliases and their targets use
|
269
316
|
# the {#inflection_aliases} method.
|
270
|
-
# @overload
|
317
|
+
# @overload tokens
|
271
318
|
# Gets available inflection tokens and their descriptions.
|
272
319
|
# @return [Hash] the hash containing available inflection tokens as keys
|
273
320
|
# and their descriptions as values, including aliases,
|
274
321
|
# for all kinds and current locale.
|
275
|
-
# @overload
|
322
|
+
# @overload tokens(kind)
|
276
323
|
# Gets available inflection tokens and their descriptions for some +kind+.
|
277
|
-
# @param [Symbol] kind the kind of inflection tokens to be returned
|
324
|
+
# @param [Symbol,String] kind the kind of inflection tokens to be returned
|
278
325
|
# @return [Hash] the hash containing available inflection tokens as keys
|
279
326
|
# and their descriptions as values, including aliases, for current locale.
|
280
|
-
# @overload
|
327
|
+
# @overload tokens(kind, locale)
|
281
328
|
# Gets available inflection tokens and their descriptions for some +kind+ and +locale+.
|
282
|
-
# @param [Symbol] kind the kind of inflection tokens to be returned
|
329
|
+
# @param [Symbol,String] kind the kind of inflection tokens to be returned
|
283
330
|
# @param [Symbol] locale the locale to use
|
284
331
|
# @return [Hash] the hash containing available inflection tokens as keys
|
285
332
|
# and their descriptions as values, including aliases, for current locale
|
286
|
-
def
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
return true_tokens if aliases.nil?
|
291
|
-
aliases = aliases.reject{|k,v| v[:kind]!=kind} unless kind.nil?
|
292
|
-
aliases = aliases.merge(aliases){|k,v| v[:description]}
|
293
|
-
true_tokens.merge(aliases)
|
333
|
+
def tokens(kind=nil, locale=nil)
|
334
|
+
return {} if (!kind.nil? && kind.to_s.empty?)
|
335
|
+
kind = kind.to_sym unless kind.nil?
|
336
|
+
data_safe(locale).get_tokens(kind)
|
294
337
|
end
|
295
338
|
|
296
339
|
# Gets available inflection tokens and their values.
|
297
340
|
#
|
298
341
|
# @api public
|
299
|
-
# @see I18n::Inflector.raw_tokens Short name: I18n::Inflector.raw_tokens
|
300
342
|
# @return [Hash] the hash containing available inflection tokens and descriptions (or alias pointers)
|
301
|
-
# @raise [I18n::InvalidLocale] if
|
343
|
+
# @raise [I18n::InvalidLocale] if there is no proper locale name
|
302
344
|
# @note You may deduce whether the returned values are aliases or true tokens
|
303
|
-
#
|
304
|
-
# @overload
|
345
|
+
# by testing if a value is a type of Symbol or String.
|
346
|
+
# @overload tokens_raw
|
305
347
|
# Gets available inflection tokens and their values.
|
306
348
|
# @return [Hash] the hash containing available inflection tokens as keys
|
307
349
|
# and their descriptions as values. In case of aliases the returned
|
308
350
|
# values are Symbols
|
309
|
-
# @overload
|
351
|
+
# @overload tokens_raw(kind)
|
310
352
|
# Gets available inflection tokens and their values for the given +kind+.
|
311
|
-
# @param [Symbol] kind the kind of inflection tokens to be returned
|
353
|
+
# @param [Symbol,String] kind the kind of inflection tokens to be returned
|
312
354
|
# @return [Hash] the hash containing available inflection tokens as keys
|
313
355
|
# and their descriptions as values for the given +kind+. In case of
|
314
356
|
# aliases the returned values are Symbols
|
315
|
-
# @overload
|
357
|
+
# @overload tokens_raw(kind, locale)
|
316
358
|
# Gets available inflection tokens and their values for the given +kind+ and +locale+.
|
317
|
-
# @param [Symbol] kind the kind of inflection tokens to be returned
|
359
|
+
# @param [Symbol,String] kind the kind of inflection tokens to be returned
|
318
360
|
# @param [Symbol] locale the locale to use
|
319
361
|
# @return [Hash] the hash containing available inflection tokens as keys
|
320
362
|
# and their descriptions as values for the given +kind+ and +locale+.
|
321
363
|
# In case of aliases the returned values are Symbols
|
322
|
-
def
|
323
|
-
|
324
|
-
|
325
|
-
|
364
|
+
def tokens_raw(kind=nil, locale=nil)
|
365
|
+
return {} if (!kind.nil? && kind.to_s.empty?)
|
366
|
+
kind = kind.to_sym unless kind.nil?
|
367
|
+
data_safe(locale).get_raw_tokens(kind)
|
326
368
|
end
|
327
|
-
|
328
|
-
alias_method :inflection_raw_tokens, :inflection_tokens_raw
|
369
|
+
alias_method :raw_tokens, :tokens_raw
|
329
370
|
|
330
371
|
# Gets true inflection tokens and their values.
|
331
372
|
#
|
332
373
|
# @api public
|
333
374
|
# @return [Hash] the hash containing available inflection tokens and descriptions
|
334
|
-
# @
|
335
|
-
# @raise [I18n::InvalidLocale] if a used locale is invalid
|
375
|
+
# @raise [I18n::InvalidLocale] if there is no proper locale name
|
336
376
|
# @note It returns only true tokens, not aliases.
|
337
|
-
# @overload
|
377
|
+
# @overload tokens_true
|
338
378
|
# Gets true inflection tokens and their values.
|
339
379
|
# @return [Hash] the hash containing available inflection tokens as keys
|
340
380
|
# and their descriptions as values
|
341
|
-
# @overload
|
381
|
+
# @overload tokens_true(kind)
|
342
382
|
# Gets true inflection tokens and their values for the given +kind+.
|
343
|
-
# @param [Symbol] kind the kind of inflection tokens to be returned
|
383
|
+
# @param [Symbol,String] kind the kind of inflection tokens to be returned
|
344
384
|
# @return [Hash] the hash containing available inflection tokens as keys
|
345
385
|
# and their descriptions as values for the given +kind+
|
346
|
-
# @overload
|
386
|
+
# @overload tokens_true(kind, locale)
|
347
387
|
# Gets true inflection tokens and their values for the given +kind+ and +value+.
|
348
|
-
# @param [Symbol] kind the kind of inflection tokens to be returned
|
388
|
+
# @param [Symbol,String] kind the kind of inflection tokens to be returned
|
349
389
|
# @param [Symbol] locale the locale to use
|
350
390
|
# @return [Hash] the hash containing available inflection tokens as keys
|
351
391
|
# and their descriptions as values for the given +kind+ and +locale+
|
352
|
-
def
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
return {} if inflections.nil?
|
357
|
-
inflections = inflections.reject{|k,v| v[:kind]!=kind} unless kind.nil?
|
358
|
-
inflections.merge(inflections){|k,v| v[:description]}
|
392
|
+
def tokens_true(kind=nil, locale=nil)
|
393
|
+
return {} if (!kind.nil? && kind.to_s.empty?)
|
394
|
+
kind = kind.to_sym unless kind.nil?
|
395
|
+
data_safe(locale).get_true_tokens(kind)
|
359
396
|
end
|
360
|
-
|
361
|
-
alias_method :inflection_true_tokens, :inflection_tokens_true
|
397
|
+
alias_method :true_tokens, :tokens_true
|
362
398
|
|
363
399
|
# Gets inflection aliases and their pointers.
|
364
400
|
#
|
365
401
|
# @api public
|
366
|
-
# @
|
367
|
-
# @raise [I18n::InvalidLocale] if the given +locale+ is invalid
|
402
|
+
# @raise [I18n::InvalidLocale] if there is no proper locale name
|
368
403
|
# @return [Hash] the Hash containing available inflection aliases (<tt>alias => target</tt>)
|
369
|
-
# @overload
|
404
|
+
# @overload aliases
|
370
405
|
# Gets inflection aliases and their pointers.
|
371
406
|
# @return [Hash] the Hash containing available inflection aliases
|
372
|
-
# @overload
|
407
|
+
# @overload aliases(kind)
|
373
408
|
# Gets inflection aliases and their pointers for the given +kind+.
|
374
|
-
# @param [Symbol] kind the kind of aliases to get
|
409
|
+
# @param [Symbol,String] kind the kind of aliases to get
|
375
410
|
# @return [Hash] the Hash containing available inflection
|
376
411
|
# aliases for the given +kind+ and current locale
|
377
|
-
# @overload
|
412
|
+
# @overload aliases(kind, locale)
|
378
413
|
# Gets inflection aliases and their pointers for the given +kind+ and +locale+.
|
379
|
-
# @param [Symbol] kind the kind of aliases to get
|
414
|
+
# @param [Symbol,String] kind the kind of aliases to get
|
380
415
|
# @param [Symbol] locale the locale to use
|
381
416
|
# @return [Hash] the Hash containing available inflection
|
382
417
|
# aliases for the given +kind+ and +locale+
|
383
|
-
def
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
return {} if aliases.nil?
|
388
|
-
aliases = aliases.reject{|k,v| v[:kind]!=kind} unless kind.nil?
|
389
|
-
aliases.merge(aliases){|k,v| v[:target]}
|
418
|
+
def aliases(kind=nil, locale=nil)
|
419
|
+
return {} if (!kind.nil? && kind.to_s.empty?)
|
420
|
+
kind = kind.to_sym unless kind.nil?
|
421
|
+
data_safe(locale).get_aliases(kind)
|
390
422
|
end
|
391
423
|
|
392
424
|
# Gets known inflection kinds.
|
393
425
|
#
|
394
426
|
# @api public
|
395
|
-
# @see I18n::Inflector.kinds Short name: I18n::Inflector.kinds
|
396
427
|
# @return [Array<Symbol>] the array containing known inflection kinds
|
397
|
-
# @raise [I18n::InvalidLocale] if
|
398
|
-
# @overload
|
428
|
+
# @raise [I18n::InvalidLocale] if there is no proper locale name
|
429
|
+
# @overload kinds
|
399
430
|
# Gets known inflection kinds for the current locale.
|
400
431
|
# @return [Array<Symbol>] the array containing known inflection kinds
|
401
|
-
# @overload
|
432
|
+
# @overload kinds(locale)
|
402
433
|
# Gets known inflection kinds for the given +locale+.
|
403
434
|
# @param [Symbol] locale the locale for which operation has to be done
|
404
435
|
# @return [Array<Symbol>] the array containing known inflection kinds
|
405
|
-
def
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
436
|
+
def kinds(locale=nil)
|
437
|
+
data_safe(locale).get_kinds
|
438
|
+
end
|
439
|
+
alias_method :inflection_kinds, :kinds
|
440
|
+
|
441
|
+
# Tests if a kind exists.
|
442
|
+
#
|
443
|
+
# @api public
|
444
|
+
# @raise [I18n::InvalidLocale] if there is no proper locale name
|
445
|
+
# @return [Boolean] +true+ if the given +kind+ exists, +false+ otherwise
|
446
|
+
# @overload has_kind?(kind)
|
447
|
+
# @param [Symbol] kind the identifier of a kind
|
448
|
+
# @return [Boolean] +true+ if the given +kind+ exists for the current
|
449
|
+
# locale, +false+ otherwise
|
450
|
+
# @overload has_kind?(kind, locale)
|
451
|
+
# @param [Symbol,String] kind the identifier of a kind
|
452
|
+
# @param [Symbol] locale the locale identifier
|
453
|
+
# @return [Boolean] +true+ if the given +kind+ exists, +false+ otherwise
|
454
|
+
def has_kind?(kind, locale=nil)
|
455
|
+
return false if kind.to_s.empty?
|
456
|
+
data_safe(locale).has_kind?(kind)
|
411
457
|
end
|
412
458
|
|
413
459
|
# Gets locales which have configured inflection support.
|
414
460
|
#
|
415
461
|
# @api public
|
416
|
-
# @see I18n::Inflector.locales Short name: I18n::Inflector.locales
|
417
462
|
# @return [Array<Symbol>] the array containing locales that support inflection
|
418
463
|
# @note If +kind+ is given it returns only these locales
|
419
|
-
# that
|
464
|
+
# that support inflection by this kind.
|
420
465
|
def inflected_locales(kind=nil)
|
421
|
-
|
422
|
-
inflected_locales = (@
|
423
|
-
return inflected_locales if kind.
|
466
|
+
return [] if (!kind.nil? && kind.to_s.empty?)
|
467
|
+
inflected_locales = (@idb.keys || [])
|
468
|
+
return inflected_locales if kind.nil?
|
424
469
|
kind = kind.to_sym
|
425
|
-
inflected_locales.
|
426
|
-
kinds = inflection_subtree(loc)
|
427
|
-
kinds.respond_to?(:has_key?) && kinds.has_key?(kind)
|
428
|
-
end
|
470
|
+
inflected_locales.reject{|l| @idb[l].nil? || !@idb[l].has_kind?(kind)}
|
429
471
|
end
|
472
|
+
alias_method :locales, :inflected_locales
|
473
|
+
alias_method :supported_locales, :inflected_locales
|
430
474
|
|
431
|
-
# Checks if
|
475
|
+
# Checks if the given locale was configured to support inflection.
|
432
476
|
#
|
433
477
|
# @api public
|
434
|
-
# @
|
435
|
-
# @raise [I18n::InvalidLocale] if a used locale is invalid
|
478
|
+
# @raise [I18n::InvalidLocale] if there is no proper locale name
|
436
479
|
# @return [Boolean] +true+ if a locale supports inflection
|
437
480
|
# @overload inflected_locale?(locale)
|
438
481
|
# Checks if the given locale was configured to support inflection.
|
@@ -442,87 +485,31 @@ module I18n
|
|
442
485
|
# Checks if the current locale was configured to support inflection.
|
443
486
|
# @return [Boolean] +true+ if the current locale supports inflection
|
444
487
|
def inflected_locale?(locale=nil)
|
445
|
-
|
446
|
-
init_translations unless initialized?
|
447
|
-
@inflection_tokens.has_key?(locale)
|
448
|
-
end
|
449
|
-
|
450
|
-
# Stores translations in memory.
|
451
|
-
#
|
452
|
-
# @api public
|
453
|
-
# @raise [I18n::InvalidLocale] if the given +locale+ is invalid
|
454
|
-
# @raise [I18n::BadInflectionToken] if a name of some loaded token is invalid
|
455
|
-
# @raise [I18n::BadInflectionAlias] if a loaded alias points to a token that does not exists
|
456
|
-
# @raise [I18n::DuplicatedInflectionToken] if a token has already appeard in loaded configuration
|
457
|
-
# @note If inflections are changed it will regenerate proper internal
|
458
|
-
# structures.
|
459
|
-
# @return [Hash] the stored translations
|
460
|
-
def store_translations(locale, data, options = {})
|
461
|
-
r = super
|
462
|
-
locale = inflector_prep_locale(locale)
|
463
|
-
inflector_try_init
|
464
|
-
if data.respond_to?(:has_key?)
|
465
|
-
subdata = (data[:i18n] || data['i18n'])
|
466
|
-
unless subdata.nil?
|
467
|
-
subdata = (subdata[:inflections] || subdata['inflections'])
|
468
|
-
unless subdata.nil?
|
469
|
-
@inflection_tokens.delete locale
|
470
|
-
@inflection_aliases.delete locale
|
471
|
-
@inflection_defaults.delete locale
|
472
|
-
load_inflection_tokens(locale, r[:i18n][:inflections])
|
473
|
-
end
|
474
|
-
end
|
475
|
-
end
|
476
|
-
r
|
488
|
+
not @idb[prep_locale(locale)].nil? rescue false
|
477
489
|
end
|
490
|
+
alias_method :locale?, :inflected_locale?
|
491
|
+
alias_method :locale_supported?, :inflected_locale?
|
478
492
|
|
479
493
|
# Gets the description of the given inflection token.
|
480
494
|
#
|
481
495
|
# @api public
|
482
|
-
# @see I18n::Inflector.description Short name: I18n::Inflector.description
|
483
496
|
# @note If the given +token+ is really an alias it
|
484
497
|
# returns the description of the true token that
|
485
498
|
# it points to.
|
486
|
-
# @raise [I18n::InvalidLocale] if
|
499
|
+
# @raise [I18n::InvalidLocale] if there is no proper locale name
|
487
500
|
# @return [String,nil] the descriptive string or +nil+
|
488
|
-
# @overload
|
501
|
+
# @overload token_description(token)
|
489
502
|
# Uses current locale to get description of the given token.
|
490
503
|
# @return [String,nil] the descriptive string or +nil+ if something
|
491
504
|
# went wrong (e.g. token was not found)
|
492
|
-
# @overload
|
505
|
+
# @overload token_description(token, locale)
|
493
506
|
# Uses the given +locale+ to get description of the given inflection token.
|
494
507
|
# @param [Symbol] locale the locale to use
|
495
508
|
# @return [String,nil] the descriptive string or +nil+ if something
|
496
509
|
# went wrong (e.g. token was not found)
|
497
|
-
def
|
498
|
-
locale = inflector_prep_locale(locale)
|
510
|
+
def token_description(token, locale=nil)
|
499
511
|
return nil if token.to_s.empty?
|
500
|
-
|
501
|
-
inflections = @inflection_tokens[locale]
|
502
|
-
aliases = @inflection_aliases[locale]
|
503
|
-
return nil if (inflections.nil? || aliases.nil?)
|
504
|
-
token = token.to_sym
|
505
|
-
match = (inflections[token] || aliases[token])
|
506
|
-
return nil if match.nil?
|
507
|
-
match[:description]
|
508
|
-
end
|
509
|
-
|
510
|
-
protected
|
511
|
-
|
512
|
-
# Processes +locale+ name and validates
|
513
|
-
# if it's correct (not empty and not +nil+).
|
514
|
-
#
|
515
|
-
# @note If the +locale+ is not correct, it
|
516
|
-
# tries to use locale from {I18n.locale} and validates it
|
517
|
-
# as well.
|
518
|
-
# @param [Symbol,String] locale the locale identifier
|
519
|
-
# @raise [I18n::InvalidLocale] if there is no proper locale name
|
520
|
-
# @return [Symbol] the given locale or the global locale
|
521
|
-
# and usable or the global locale for I18n
|
522
|
-
def inflector_prep_locale(locale=nil)
|
523
|
-
locale ||= I18n.locale
|
524
|
-
raise I18n::InvalidLocale.new(locale) if locale.to_s.empty?
|
525
|
-
locale.to_sym
|
512
|
+
data_safe(locale).get_description(token.to_sym)
|
526
513
|
end
|
527
514
|
|
528
515
|
# Interpolates inflection values in a given +string+
|
@@ -533,39 +520,45 @@ module I18n
|
|
533
520
|
# @param [String,Symbol] locale the locale identifier
|
534
521
|
# @param [Hash] options the options
|
535
522
|
# @option options [Boolean] :inflector_excluded_defaults (false) local switch
|
536
|
-
# that overrides global setting (see: {#
|
523
|
+
# that overrides global setting (see: {I18n::Inflector::InflectionOptions#excluded_defaults})
|
537
524
|
# @option options [Boolean] :inflector_unknown_defaults (true) local switch
|
538
|
-
# that overrides global setting (see: {#
|
525
|
+
# that overrides global setting (see: {I18n::Inflector::InflectionOptions#unknown_defaults})
|
539
526
|
# @option options [Boolean] :inflector_raises (false) local switch
|
540
|
-
# that overrides global setting (see: {#
|
527
|
+
# that overrides global setting (see: {I18n::Inflector::InflectionOptions#raises})
|
528
|
+
# @option options [Boolean] :inflector_aliased_patterns (false) local switch
|
529
|
+
# that overrides global setting (see: {I18n::Inflector::InflectionOptions#aliased_patterns})
|
541
530
|
# @return [String] the string with interpolated patterns
|
542
|
-
def
|
543
|
-
used_kinds = options.except(*I18n::
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
|
550
|
-
|
551
|
-
|
531
|
+
def interpolate(string, locale, options = {})
|
532
|
+
used_kinds = options.except(*I18n::Inflector::INFLECTOR_RESERVED_KEYS)
|
533
|
+
sw, op = @options, options
|
534
|
+
raises = (s=op.delete :inflector_raises).nil? ? sw.raises : s
|
535
|
+
aliased_patterns = (s=op.delete :inflector_aliased_patterns).nil? ? sw.aliased_patterns : s
|
536
|
+
unknown_defaults = (s=op.delete :inflector_unknown_defaults).nil? ? sw.unknown_defaults : s
|
537
|
+
excluded_defaults = (s=op.delete :inflector_excluded_defaults).nil? ? sw.excluded_defaults : s
|
538
|
+
|
539
|
+
idb = @idb[locale]
|
540
|
+
|
541
|
+
string.gsub(I18n::Inflector::PATTERN) do
|
552
542
|
pattern_fix = $1
|
553
543
|
pattern_content = $2
|
554
544
|
ext_pattern = $&
|
555
545
|
parsed_kind = nil
|
546
|
+
default_token = nil
|
556
547
|
ext_value = nil
|
557
548
|
ext_freetext = ''
|
558
549
|
found = false
|
559
550
|
parsed_default_v= nil
|
560
551
|
|
561
552
|
# leave escaped pattern as is
|
562
|
-
next ext_pattern[1..-1] if I18n::
|
553
|
+
next ext_pattern[1..-1] if I18n::Inflector::ESCAPES.has_key?(pattern_fix)
|
563
554
|
|
564
555
|
# process pattern content's
|
565
|
-
pattern_content.scan(I18n::
|
556
|
+
pattern_content.scan(I18n::Inflector::TOKENS) do
|
566
557
|
ext_token = $1.to_s
|
567
558
|
ext_value = $2.to_s
|
568
559
|
ext_freetext = $3.to_s
|
560
|
+
tokens = Hash.new(false)
|
561
|
+
negatives = Hash.new(false)
|
569
562
|
kind = nil
|
570
563
|
option = nil
|
571
564
|
|
@@ -578,29 +571,54 @@ module I18n
|
|
578
571
|
next
|
579
572
|
end
|
580
573
|
|
581
|
-
#
|
582
|
-
|
583
|
-
|
584
|
-
|
585
|
-
|
586
|
-
|
587
|
-
|
588
|
-
next
|
589
|
-
end
|
574
|
+
# split tokens if comma is present and put into fast list
|
575
|
+
ext_token.split(I18n::Inflector::OPERATOR_MULTI).each do |t|
|
576
|
+
# token name corrupted
|
577
|
+
if t.empty?
|
578
|
+
raise I18n::InvalidInflectionToken.new(ext_pattern, t) if raises
|
579
|
+
next
|
580
|
+
end
|
590
581
|
|
591
|
-
|
592
|
-
|
582
|
+
# mark negative-matching tokens and put them to negatives fast list
|
583
|
+
if t[0..0] == I18n::Inflector::OPERATOR_NOT
|
584
|
+
t = t[1..-1]
|
585
|
+
if t.empty?
|
586
|
+
raise I18n::InvalidInflectionToken.new(ext_pattern, t) if raises
|
587
|
+
next
|
588
|
+
end
|
589
|
+
t = t.to_sym
|
590
|
+
t = idb.get_true_token(t) if aliased_patterns
|
591
|
+
negatives[t] = true
|
592
|
+
end
|
593
593
|
|
594
|
-
|
595
|
-
|
596
|
-
|
597
|
-
|
598
|
-
|
599
|
-
|
594
|
+
t = t.to_sym
|
595
|
+
t = idb.get_true_token(t) if aliased_patterns
|
596
|
+
|
597
|
+
# get kind for that token
|
598
|
+
kind = idb.get_kind(t)
|
599
|
+
if kind.nil?
|
600
|
+
raise I18n::InvalidInflectionToken.new(ext_pattern, t) if raises
|
601
|
+
next
|
602
|
+
end
|
603
|
+
|
604
|
+
# set processed kind after matching first token in a pattern
|
605
|
+
if parsed_kind.nil?
|
606
|
+
parsed_kind = kind
|
607
|
+
default_token = idb.get_default_token(parsed_kind)
|
608
|
+
elsif parsed_kind != kind
|
609
|
+
# different kinds in one pattern are prohibited
|
610
|
+
raise I18n::MisplacedInflectionToken.new(ext_pattern, t, parsed_kind) if raises
|
611
|
+
next
|
612
|
+
end
|
613
|
+
|
614
|
+
# use that token
|
615
|
+
tokens[t] = true unless negatives[t]
|
600
616
|
end
|
601
617
|
|
602
|
-
#
|
603
|
-
|
618
|
+
# self-explanatory
|
619
|
+
if (tokens.empty? && negatives.empty?)
|
620
|
+
raise I18n::InvalidInflectionToken.new(ext_pattern, ext_token) if raises
|
621
|
+
end
|
604
622
|
|
605
623
|
# fetch the kind's option or fetch default if an option does not exists
|
606
624
|
option = options.has_key?(kind) ? options[kind] : default_token
|
@@ -611,38 +629,38 @@ module I18n
|
|
611
629
|
option = unknown_defaults ? default_token : nil
|
612
630
|
else
|
613
631
|
# validate option and if it's unknown try in aliases
|
614
|
-
option = option.to_sym
|
615
|
-
|
616
|
-
|
617
|
-
|
618
|
-
|
619
|
-
|
620
|
-
option = unknown_defaults ? default_token : nil
|
621
|
-
else
|
622
|
-
option = option[:target]
|
623
|
-
end
|
632
|
+
option = idb.get_true_token(option.to_sym)
|
633
|
+
|
634
|
+
# if still nothing then fall back to default value
|
635
|
+
# for a kind in unknown_defaults switch is on
|
636
|
+
if option.nil?
|
637
|
+
option = unknown_defaults ? default_token : nil
|
624
638
|
end
|
625
639
|
end
|
626
640
|
|
627
641
|
# if the option is still unknown
|
628
642
|
if option.nil?
|
629
|
-
raise I18n::InvalidOptionForKind.new(ext_pattern, kind, ext_token,
|
643
|
+
raise I18n::InvalidOptionForKind.new(ext_pattern, kind, ext_token, nil) if raises
|
630
644
|
next
|
631
645
|
end
|
632
646
|
|
633
|
-
# memorize default
|
647
|
+
# memorize default value for further processing
|
634
648
|
# outside this block if excluded_defaults switch is on
|
635
|
-
parsed_default_v = ext_value if (excluded_defaults &&
|
649
|
+
parsed_default_v = ext_value if (excluded_defaults && !default_token.nil?)
|
636
650
|
|
637
|
-
# throw the value if a given option matches the
|
638
|
-
|
651
|
+
# throw the value if a given option matches one of the tokens from group
|
652
|
+
# or negatively matches one of the negated tokens
|
653
|
+
case negatives.count
|
654
|
+
when 0 then next unless tokens[option]
|
655
|
+
when 1 then next if negatives[option]
|
656
|
+
end
|
639
657
|
|
640
658
|
# skip further evaluation of the pattern
|
641
659
|
# since the right token has been found
|
642
660
|
found = true
|
643
661
|
break
|
644
662
|
|
645
|
-
end # single token
|
663
|
+
end # single token (or a group) processing
|
646
664
|
|
647
665
|
result = nil
|
648
666
|
|
@@ -653,222 +671,36 @@ module I18n
|
|
653
671
|
result = ext_value
|
654
672
|
elsif (excluded_defaults && !parsed_kind.nil?)
|
655
673
|
# if there is excluded_defaults switch turned on
|
656
|
-
# and a correct token was found in
|
674
|
+
# and a correct token was found in an inflection option but
|
657
675
|
# has not been found in a pattern then interpolate
|
658
676
|
# the pattern with a value picked for the default
|
659
677
|
# token for that kind if a default token was present
|
660
678
|
# in a pattern
|
661
679
|
kind = nil
|
662
680
|
token = options[parsed_kind]
|
663
|
-
kind =
|
664
|
-
result = parsed_default_v
|
681
|
+
kind = idb.get_kind(token)
|
682
|
+
result = parsed_default_v unless kind.nil?
|
665
683
|
end
|
666
684
|
|
667
685
|
pattern_fix + (result || ext_freetext)
|
668
686
|
|
669
687
|
end # single pattern processing
|
670
|
-
|
671
|
-
end
|
672
|
-
|
673
|
-
# Initializes internal hashes used for keeping inflections configuration.
|
674
|
-
#
|
675
|
-
# @return [void]
|
676
|
-
def inflector_try_init
|
677
|
-
return nil if defined? @inflector_initialized
|
678
|
-
@inflection_tokens ||= {}
|
679
|
-
@inflection_aliases ||= {}
|
680
|
-
@inflection_defaults ||= {}
|
681
|
-
@inflector_excluded_defaults = false
|
682
|
-
@inflector_unknown_defaults = true
|
683
|
-
@inflector_raises = false
|
684
|
-
@inflector_initialized = true
|
685
|
-
nil
|
686
|
-
end
|
687
688
|
|
688
|
-
# Takes care of loading inflection tokens
|
689
|
-
# for all languages (locales) that have them
|
690
|
-
# defined.
|
691
|
-
#
|
692
|
-
# @note It calls {I18n::Backend::Simple#init_translations I18n::Backend::Simple#init_translations}
|
693
|
-
# @raise [I18n::BadInflectionToken] if a name of some loaded token is invalid
|
694
|
-
# @raise [I18n::BadInflectionAlias] if a loaded alias points to a token that does not exists
|
695
|
-
# @raise [I18n::DuplicatedInflectionToken] if a token has already appeard in loaded configuration
|
696
|
-
# @return [Boolean] +true+ if everything went fine
|
697
|
-
def init_translations
|
698
|
-
inflector_try_init
|
699
|
-
super
|
700
689
|
end
|
701
690
|
|
702
|
-
|
703
|
-
#
|
704
|
-
# @param [String] translated_string the string that is translated
|
705
|
-
# @return [String] the translation with any inflection patterns removed
|
706
|
-
def clear_inflection_patterns(translated_string)
|
707
|
-
translated_string.gsub(I18n::Backend::Inflector::PATTERN,'')
|
708
|
-
end
|
691
|
+
protected
|
709
692
|
|
710
|
-
#
|
711
|
-
|
712
|
-
|
713
|
-
# @note Under some very rare conditions this method may be called while
|
714
|
-
# translation data is loading. It must always return when translations
|
715
|
-
# are not initialized. Otherwise it will cause loops and someone in Poland
|
716
|
-
# will eat a kittien!
|
717
|
-
# @param [Symbol] locale the locale to use
|
718
|
-
# @return [Hash,nil] part of the translation data that
|
719
|
-
# reflects inflections for a given locale or +nil+
|
720
|
-
# if translations are not initialized
|
721
|
-
def inflection_subtree(locale)
|
722
|
-
return nil unless initialized?
|
723
|
-
lookup(locale, :"i18n.inflections", [], :fallback => true, :raise => :false)
|
693
|
+
# @private
|
694
|
+
def data(locale=nil)
|
695
|
+
@idb[prep_locale(locale)]
|
724
696
|
end
|
725
697
|
|
726
|
-
#
|
727
|
-
|
728
|
-
|
729
|
-
# @raise [I18n::BadInflectionToken] if a name of the token that alias points to is corrupted
|
730
|
-
# @raise [I18n::BadInflectionAlias] if an alias points to token that does not exists
|
731
|
-
# @return [Symbol] the true token that alias points to if the given +token+
|
732
|
-
# is an alias or the given +token+ if it is a true token
|
733
|
-
# @overload shorten_inflection_alias(token, kind, locale)
|
734
|
-
# Resolves an alias for a token if the given +token+ is an alias for the given +locale+ and +kind+.
|
735
|
-
# @note This version uses internal subtree and needs the translation data to be initialized.
|
736
|
-
# @param [Symbol] token the token name
|
737
|
-
# @param [Symbol] kind the kind of the given token
|
738
|
-
# @param [Symbol] locale the locale to use
|
739
|
-
# @return [Symbol] the true token that alias points to if the given +token+
|
740
|
-
# is an alias or the given +token+ if it is a true token
|
741
|
-
# @overload shorten_inflection_alias(token, kind, locale, subtree)
|
742
|
-
# Resolves an alias for a token if the given +token+ is an alias for the given +locale+ and +kind+.
|
743
|
-
# @param [Symbol] token the token name
|
744
|
-
# @param [Symbol] kind the kind of the given token
|
745
|
-
# @param [Symbol] locale the locale to use
|
746
|
-
# @param [Hash] subtree the tree (in a form of nested Hashes) containing inflection tokens to scan
|
747
|
-
# @return [Symbol] the true token that alias points to if the given +token+
|
748
|
-
# is an alias or the given +token+ if it is a true token
|
749
|
-
def shorten_inflection_alias(token, kind, locale, subtree=nil, count=0)
|
750
|
-
count += 1
|
751
|
-
return nil if count > 64
|
752
|
-
|
753
|
-
inflections_tree = subtree || inflection_subtree(locale)
|
754
|
-
return nil if (inflections_tree.nil? || inflections_tree.empty?)
|
755
|
-
|
756
|
-
kind_subtree = inflections_tree[kind]
|
757
|
-
value = kind_subtree[token].to_s
|
758
|
-
|
759
|
-
if value.slice(0,1) != I18n::Backend::Inflector::ALIAS_MARKER
|
760
|
-
if kind_subtree.has_key?(token)
|
761
|
-
return token
|
762
|
-
else
|
763
|
-
# that should never happend but who knows
|
764
|
-
raise I18n::BadInflectionToken.new(locale, token, kind)
|
765
|
-
end
|
766
|
-
else
|
767
|
-
orig_token = token
|
768
|
-
token = value[1..-1]
|
769
|
-
if token.to_s.empty?
|
770
|
-
raise I18n::BadInflectionToken.new(locale, token, kind)
|
771
|
-
end
|
772
|
-
token = token.to_sym
|
773
|
-
if kind_subtree[token].nil?
|
774
|
-
raise BadInflectionAlias.new(locale, orig_token, kind, token)
|
775
|
-
else
|
776
|
-
shorten_inflection_alias(token, kind, locale, inflections_tree, count)
|
777
|
-
end
|
778
|
-
end
|
779
|
-
|
780
|
-
end
|
781
|
-
|
782
|
-
# Uses the inflections subtree and creates internal mappings
|
783
|
-
# to resolve kinds assigned to inflection tokens and aliases, including defaults.
|
784
|
-
# @return [Hash,nil] the internal Hash containing inflection tokens or +nil+ if something went wrong
|
785
|
-
# @raise [I18n::BadInflectionToken] if a name of some loaded token is invalid
|
786
|
-
# @raise [I18n::BadInflectionAlias] if a loaded alias points to a token that does not exists
|
787
|
-
# @raise [I18n::DuplicatedInflectionToken] if a token has already appeard in loaded configuration
|
788
|
-
# @overload load_inflection_tokens(locale)
|
789
|
-
# @note That version calls the {inflection_subtree} method to obtain internal translations data.
|
790
|
-
# Loads inflection tokens for the given locale using internal hash of stored translations. Requires
|
791
|
-
# translations to be initialized.
|
792
|
-
# @param [Symbol] locale the locale to use and work for
|
793
|
-
# @return [Hash,nil] the internal Hash containing inflection tokens (<tt>token => kind</tt>)
|
794
|
-
# or +nil+ if translations were not initialized
|
795
|
-
# @overload load_inflection_tokens(locale, subtree)
|
796
|
-
# Loads inflection tokens for the given locale using data given in an argument
|
797
|
-
# @param [Symbol] locale the locale to use and work for
|
798
|
-
# @param [Hash] subtree the tree (in a form of nested Hashes) containing inflection tokens to scan
|
799
|
-
# @return [Hash,nil] the internal Hash containing inflection tokens (<tt>token => kind</tt>)
|
800
|
-
# or +nil+ if the given subtree was wrong or empty
|
801
|
-
def load_inflection_tokens(locale, subtree=nil)
|
802
|
-
return @inflection_tokens[locale] if @inflection_tokens.has_key?(locale)
|
803
|
-
inflections_tree = subtree || inflection_subtree(locale)
|
804
|
-
return nil if (inflections_tree.nil? || inflections_tree.empty?)
|
805
|
-
ivars = @inflection_tokens[locale] = {}
|
806
|
-
aliases = @inflection_aliases[locale] = {}
|
807
|
-
defaults = @inflection_defaults[locale] = {}
|
808
|
-
|
809
|
-
inflections_tree.each_pair do |kind, tokens|
|
810
|
-
tokens.each_pair do |token, description|
|
811
|
-
|
812
|
-
# test for duplicate
|
813
|
-
if ivars.has_key?(token)
|
814
|
-
raise I18n::DuplicatedInflectionToken.new(ivars[token], kind, token)
|
815
|
-
end
|
816
|
-
|
817
|
-
# validate token's name
|
818
|
-
if token.nil?
|
819
|
-
raise I18n::BadInflectionToken.new(locale, token, kind)
|
820
|
-
end
|
821
|
-
|
822
|
-
# validate token's description
|
823
|
-
if description.nil?
|
824
|
-
raise I18n::BadInflectionToken.new(locale, token, kind, description)
|
825
|
-
end
|
826
|
-
|
827
|
-
# handle default token for a kind
|
828
|
-
if token == :default
|
829
|
-
if defaults.has_key?(kind) # should never happend unless someone is messing with @translations
|
830
|
-
raise I18n::DuplicatedInflectionToken.new(kind, nil, token)
|
831
|
-
end
|
832
|
-
defaults[kind] = description.to_sym
|
833
|
-
next
|
834
|
-
end
|
835
|
-
|
836
|
-
# handle alias
|
837
|
-
if description.slice(0,1) == I18n::Backend::Inflector::ALIAS_MARKER
|
838
|
-
real_token = shorten_inflection_alias(token, kind, locale, inflections_tree)
|
839
|
-
unless real_token.nil?
|
840
|
-
real_token = real_token.to_sym
|
841
|
-
aliases[token] = {}
|
842
|
-
aliases[token][:kind] = kind
|
843
|
-
aliases[token][:target] = real_token
|
844
|
-
aliases[token][:description] = inflections_tree[kind][real_token].to_s
|
845
|
-
end
|
846
|
-
next
|
847
|
-
end
|
848
|
-
|
849
|
-
ivars[token] = {}
|
850
|
-
ivars[token][:kind] = kind.to_sym
|
851
|
-
ivars[token][:description] = description.to_s
|
852
|
-
end
|
853
|
-
end
|
854
|
-
|
855
|
-
# validate defaults
|
856
|
-
defaults.each_pair do |kind, pointer|
|
857
|
-
unless ivars.has_key?(pointer)
|
858
|
-
# default may be an alias
|
859
|
-
target = aliases[pointer]
|
860
|
-
target = target[:target] unless target.nil?
|
861
|
-
real_token = (target || shorten_inflection_alias(:default, kind, locale, inflections_tree))
|
862
|
-
raise I18n::BadInflectionAlias.new(locale, :default, kind, pointer) if real_token.nil?
|
863
|
-
defaults[kind] = real_token.to_sym
|
864
|
-
end
|
865
|
-
end
|
866
|
-
|
867
|
-
ivars
|
698
|
+
# @private
|
699
|
+
def data_safe(locale=nil)
|
700
|
+
@idb[prep_locale(locale)] || I18n::Inflector::InflecitonData.new
|
868
701
|
end
|
869
702
|
|
870
703
|
end
|
704
|
+
|
871
705
|
end
|
872
|
-
|
873
|
-
|
874
706
|
end
|