i18n-inflector-3 3.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.
- checksums.yaml +7 -0
- data/ChangeLog +1674 -0
- data/LGPL-LICENSE +169 -0
- data/README.md +259 -0
- data/docs/COPYING +57 -0
- data/docs/EXAMPLES +357 -0
- data/docs/HISTORY +280 -0
- data/docs/LEGAL +10 -0
- data/docs/LGPL +166 -0
- data/docs/TODO +8 -0
- data/docs/USAGE +967 -0
- data/docs/rdoc.css +20 -0
- data/lib/i18n-inflector/api.rb +753 -0
- data/lib/i18n-inflector/api_strict.rb +671 -0
- data/lib/i18n-inflector/backend.rb +352 -0
- data/lib/i18n-inflector/config.rb +289 -0
- data/lib/i18n-inflector/errors.rb +226 -0
- data/lib/i18n-inflector/hset.rb +24 -0
- data/lib/i18n-inflector/inflection_data.rb +357 -0
- data/lib/i18n-inflector/inflection_data_strict.rb +300 -0
- data/lib/i18n-inflector/inflector.rb +38 -0
- data/lib/i18n-inflector/interpolate.rb +546 -0
- data/lib/i18n-inflector/lazy_enum.rb +267 -0
- data/lib/i18n-inflector/long_comments.rb +57 -0
- data/lib/i18n-inflector/options.rb +329 -0
- data/lib/i18n-inflector/version.rb +27 -0
- data/lib/i18n-inflector.rb +19 -0
- metadata +87 -0
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
#
|
|
4
|
+
# Author:: Paweł Wilk (mailto:pw@gnu.org)
|
|
5
|
+
# Copyright:: (c) 2011,2012,2013 by Paweł Wilk
|
|
6
|
+
# License:: This program is licensed under the terms of {file:docs/LGPL GNU Lesser General Public License} or {file:docs/COPYING Ruby License}.
|
|
7
|
+
#
|
|
8
|
+
# This file contains lazy enumerators.
|
|
9
|
+
|
|
10
|
+
module I18n
|
|
11
|
+
module Inflector
|
|
12
|
+
if RUBY_VERSION.gsub(/\D/, '')[0..1].to_i < 19
|
|
13
|
+
|
|
14
|
+
class LazyEnumerator < Object.const_defined?(:Enumerator) ? Enumerator : Enumerable::Enumerator
|
|
15
|
+
# This class allows to initialize the Enumerator with a block
|
|
16
|
+
class Yielder
|
|
17
|
+
def initialize(&block)
|
|
18
|
+
@main_block = block
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def each(&block)
|
|
22
|
+
@final_block = block
|
|
23
|
+
@main_block.call(self)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
if Proc.method_defined?(:yield)
|
|
27
|
+
def yield(*arg)
|
|
28
|
+
@final_block.yield(*arg)
|
|
29
|
+
end
|
|
30
|
+
else
|
|
31
|
+
def yield(*arg)
|
|
32
|
+
@final_block.call(*arg)
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
alias_method :<<, :yield if method_defined?(:yield) && !method_defined?(:<<)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
unless begin
|
|
40
|
+
new {}
|
|
41
|
+
rescue StandardError
|
|
42
|
+
false
|
|
43
|
+
end
|
|
44
|
+
def initialize(*args, &)
|
|
45
|
+
args.empty? ? super(Yielder.new(&)) : super
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
if method_defined?(:with_object) && !method_defined?(:each_with_object)
|
|
50
|
+
alias_method :each_with_object,
|
|
51
|
+
:with_object
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
else # if RUBY_VERSION >= 1.9.0
|
|
56
|
+
|
|
57
|
+
class LazyEnumerator < Enumerator
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# This class adds some lazy operations for collections
|
|
63
|
+
class LazyEnumerator
|
|
64
|
+
# Create a new instance that iterates over the passed Enumerable
|
|
65
|
+
# @return [I18n::Inflector::LazyEnumerator] the enumerator
|
|
66
|
+
def self.for(enumerable)
|
|
67
|
+
new do |y|
|
|
68
|
+
enumerable.each do |e|
|
|
69
|
+
y << e
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# Addition operator for collections
|
|
75
|
+
# @return [I18n::Inflector::LazyEnumerator] the enumerator
|
|
76
|
+
def +(other)
|
|
77
|
+
self.class.new do |yielder|
|
|
78
|
+
each do |v|
|
|
79
|
+
yielder << v
|
|
80
|
+
end
|
|
81
|
+
other.each do |v|
|
|
82
|
+
yielder << v
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# Insertion operator for collections
|
|
88
|
+
# @return [I18n::Inflector::LazyEnumerator] the enumerator
|
|
89
|
+
def insert(value)
|
|
90
|
+
self.class.new do |yielder|
|
|
91
|
+
yielder << value
|
|
92
|
+
each do |v|
|
|
93
|
+
yielder << v
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
# Appending operator for collections
|
|
99
|
+
# @return [I18n::Inflector::LazyEnumerator] the enumerator
|
|
100
|
+
def append(value)
|
|
101
|
+
self.class.new do |yielder|
|
|
102
|
+
each do |v|
|
|
103
|
+
yielder << v
|
|
104
|
+
end
|
|
105
|
+
yielder << value
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
# Mapping enumerator
|
|
110
|
+
# @return [I18n::Inflector::LazyEnumerator] the enumerator
|
|
111
|
+
def map(&block)
|
|
112
|
+
self.class.new do |yielder|
|
|
113
|
+
each do |v|
|
|
114
|
+
yielder << block[v]
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
# Selecting enumerator
|
|
120
|
+
# @return [I18n::Inflector::LazyEnumerator] the enumerator
|
|
121
|
+
def select(&block)
|
|
122
|
+
self.class.new do |yielder|
|
|
123
|
+
each do |v|
|
|
124
|
+
yielder << v if block[v]
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
# Rejecting enumerator
|
|
130
|
+
# @return [I18n::Inflector::LazyEnumerator] the enumerator
|
|
131
|
+
def reject(&block)
|
|
132
|
+
self.class.new do |yielder|
|
|
133
|
+
each do |v|
|
|
134
|
+
yielder << v unless block[v]
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
# Checks if a collection is empty
|
|
140
|
+
# @return [Boolean] +true+ if collection is empty, +false+ otherwise
|
|
141
|
+
def empty?
|
|
142
|
+
self.class.new do |_yielder|
|
|
143
|
+
each do |_k, _v|
|
|
144
|
+
return false
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
true
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
# This class implements simple enumerators for arrays
|
|
152
|
+
# that allow to do lazy operations on them.
|
|
153
|
+
class LazyArrayEnumerator < LazyEnumerator
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
# This class implements simple enumerators for hashes
|
|
157
|
+
# that allow to do lazy operations on them.
|
|
158
|
+
class LazyHashEnumerator < LazyEnumerator
|
|
159
|
+
# Creates a Hash kind of object by collecting all
|
|
160
|
+
# data from enumerated collection.
|
|
161
|
+
# @return [Hash] the resulting hash
|
|
162
|
+
def to_h
|
|
163
|
+
h = {}
|
|
164
|
+
each { |k, v| h[k] = v }
|
|
165
|
+
h
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
# Insertion operator for Hash enumerators
|
|
169
|
+
# @return [I18n::Inflector::LazyHashEnumerator] the enumerator
|
|
170
|
+
def insert(key, value)
|
|
171
|
+
self.class.new do |yielder|
|
|
172
|
+
yielder.yield(key, value)
|
|
173
|
+
each do |k, v|
|
|
174
|
+
yielder.yield(k, v)
|
|
175
|
+
end
|
|
176
|
+
end
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
# Appending operator for Hash enumerators
|
|
180
|
+
# @return [I18n::Inflector::LazyHashEnumerator] the enumerator
|
|
181
|
+
def append(key, value)
|
|
182
|
+
self.class.new do |yielder|
|
|
183
|
+
each do |k, v|
|
|
184
|
+
yielder.yield(k, v)
|
|
185
|
+
end
|
|
186
|
+
yielder.yield(key, value)
|
|
187
|
+
end
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
# Hash mapping enumerator
|
|
191
|
+
# @return [I18n::Inflector::LazyHashEnumerator] the enumerator
|
|
192
|
+
def map(&block)
|
|
193
|
+
LazyHashEnumerator.new do |yielder|
|
|
194
|
+
each do |k, v|
|
|
195
|
+
yielder.yield(k, block[k, v])
|
|
196
|
+
end
|
|
197
|
+
end
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
# Hash to Array mapping enumerator
|
|
201
|
+
# @return [I18n::Inflector::LazyHashEnumerator] the enumerator
|
|
202
|
+
def ary_map(&block)
|
|
203
|
+
LazyHashEnumerator.new do |yielder|
|
|
204
|
+
each do |value|
|
|
205
|
+
yielder << block[value]
|
|
206
|
+
end
|
|
207
|
+
end
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
# This method converts resulting keys
|
|
211
|
+
# to an array.
|
|
212
|
+
def keys
|
|
213
|
+
ary = []
|
|
214
|
+
each { |k, _v| ary << k }
|
|
215
|
+
ary
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
# This method converts resulting values
|
|
219
|
+
# to an array.
|
|
220
|
+
def values
|
|
221
|
+
ary = []
|
|
222
|
+
each { |_k, v| ary << v }
|
|
223
|
+
ary
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
# Keys enumerator
|
|
227
|
+
# @return [I18n::Inflector::LazyArrayEnumerator.new] the enumerator
|
|
228
|
+
def each_key
|
|
229
|
+
LazyArrayEnumerator.new do |yielder|
|
|
230
|
+
each do |k, _v|
|
|
231
|
+
yielder << k
|
|
232
|
+
end
|
|
233
|
+
end
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
# Values enumerator
|
|
237
|
+
# @return [I18n::Inflector::LazyArrayEnumerator.new] the enumerator
|
|
238
|
+
def each_value
|
|
239
|
+
LazyArrayEnumerator.new do |yielder|
|
|
240
|
+
each do |_k, v|
|
|
241
|
+
yielder << v
|
|
242
|
+
end
|
|
243
|
+
end
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
# Hash selecting enumerator
|
|
247
|
+
# @return [I18n::Inflector::LazyHashEnumerator] the enumerator
|
|
248
|
+
def select(&block)
|
|
249
|
+
self.class.new do |yielder|
|
|
250
|
+
each do |k, v|
|
|
251
|
+
yielder.yield(k, v) if block[k, v]
|
|
252
|
+
end
|
|
253
|
+
end
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
# Hash rejecting enumerator
|
|
257
|
+
# @return [I18n::Inflector::LazyHashEnumerator] the enumerator
|
|
258
|
+
def reject(&block)
|
|
259
|
+
self.class.new do |yielder|
|
|
260
|
+
each do |k, v|
|
|
261
|
+
yielder.yield(k, v) unless block[k, v]
|
|
262
|
+
end
|
|
263
|
+
end
|
|
264
|
+
end
|
|
265
|
+
end
|
|
266
|
+
end
|
|
267
|
+
end
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
#
|
|
4
|
+
# Author:: Paweł Wilk (mailto:pw@gnu.org)
|
|
5
|
+
# Copyright:: (c) 2011,2012,2013 by Paweł Wilk
|
|
6
|
+
# License:: This program is licensed under the terms of {file:docs/LGPL GNU Lesser General Public License} or {file:docs/COPYING Ruby License}.
|
|
7
|
+
#
|
|
8
|
+
# This file contains inline documentation data
|
|
9
|
+
# that would make the file with code less readable
|
|
10
|
+
# if placed there. Code from this file is not used
|
|
11
|
+
# by the library, it's just for documentation.
|
|
12
|
+
|
|
13
|
+
module I18n
|
|
14
|
+
module Inflector
|
|
15
|
+
class API
|
|
16
|
+
# This reader allows to reach a reference of the
|
|
17
|
+
# object that is a kind of {I18n::Inflector::API_Strict}
|
|
18
|
+
# and handles inflections for named patterns (strict kinds).
|
|
19
|
+
#
|
|
20
|
+
# @api public
|
|
21
|
+
# @return [I18n::Inflector::API_Strict] the object containing
|
|
22
|
+
# database and operations for named patterns (strict kinds)
|
|
23
|
+
attr_reader :strict
|
|
24
|
+
|
|
25
|
+
# This reader allows to reach internal configuration
|
|
26
|
+
# of the engine. It is shared among all instances of
|
|
27
|
+
# the Inflector and also available as
|
|
28
|
+
# {I18n::Inflector::Config I18n::Inflector::Config}.
|
|
29
|
+
attr_reader :config
|
|
30
|
+
|
|
31
|
+
# Gets known regular inflection kinds.
|
|
32
|
+
#
|
|
33
|
+
# @api public
|
|
34
|
+
# @note To get all inflection kinds (regular and strict) for default inflector
|
|
35
|
+
# use: <tt>I18n.inflector.kinds + I18n.inflector.strict.kinds</tt>
|
|
36
|
+
# @return [Array<Symbol>] the array containing known inflection kinds
|
|
37
|
+
# @raise [I18n::InvalidLocale] if there is no proper locale name
|
|
38
|
+
# @overload kinds
|
|
39
|
+
# Gets known inflection kinds for the current locale.
|
|
40
|
+
# @return [Array<Symbol>] the array containing known inflection kinds
|
|
41
|
+
# @overload kinds(locale)
|
|
42
|
+
# Gets known inflection kinds for the given +locale+.
|
|
43
|
+
# @param [Symbol] locale the locale for which operation has to be done
|
|
44
|
+
# @return [Array<Symbol>] the array containing known inflection kinds
|
|
45
|
+
def kinds(locale = nil) = super
|
|
46
|
+
alias_method :inflection_kinds, :kinds
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# @abstract This exception class is defined in package I18n. It is raised when
|
|
51
|
+
# the given and/or processed locale parameter is invalid.
|
|
52
|
+
class InvalidLocale; end
|
|
53
|
+
|
|
54
|
+
# @abstract This exception class is defined in package I18n. It is raised when
|
|
55
|
+
# the given and/or processed translation data or parameter are invalid.
|
|
56
|
+
class ArgumentError; end
|
|
57
|
+
end
|
|
@@ -0,0 +1,329 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
#
|
|
4
|
+
# Author:: Paweł Wilk (mailto:pw@gnu.org)
|
|
5
|
+
# Copyright:: (c) 2011,2012,2013 by Paweł Wilk
|
|
6
|
+
# License:: This program is licensed under the terms of {file:docs/LGPL GNU Lesser General Public License} or {file:docs/COPYING Ruby License}.
|
|
7
|
+
#
|
|
8
|
+
# This file contains a class used to set up some options,
|
|
9
|
+
# for engine.
|
|
10
|
+
|
|
11
|
+
module I18n
|
|
12
|
+
module Inflector
|
|
13
|
+
# This class contains structures for keeping parsed translation data
|
|
14
|
+
# and basic operations.
|
|
15
|
+
#
|
|
16
|
+
# All global options are available for current backend's inflector by
|
|
17
|
+
# calling:
|
|
18
|
+
# I18n.backend.inflector.options.<option_name>
|
|
19
|
+
# or just:
|
|
20
|
+
# I18n.inflector.options.<option_name>
|
|
21
|
+
# A global option may be overriden by passing a proper option to
|
|
22
|
+
# the translation method. Such option should have the name of a
|
|
23
|
+
# global option but prefixed with +inflector_+:
|
|
24
|
+
# translate('welcome', :inflector_<option_name> => value)
|
|
25
|
+
# @note This class uses modified version of +attr_accessor+ that
|
|
26
|
+
# memorizes any added method name as an option name. These options
|
|
27
|
+
# (with +inflector_+ prefix added) are accessible through
|
|
28
|
+
# {#known} method. The last method is used by options preparing
|
|
29
|
+
# routine when the interpolation is performed.
|
|
30
|
+
class InflectionOptions
|
|
31
|
+
# Prefix used to mark option as a controlling option.
|
|
32
|
+
OPTION_PREFIX = 'inflector_'
|
|
33
|
+
|
|
34
|
+
class << self
|
|
35
|
+
# @private
|
|
36
|
+
attr_reader :known
|
|
37
|
+
|
|
38
|
+
# @private
|
|
39
|
+
alias_method :old_attr_accessor, :attr_accessor
|
|
40
|
+
def attr_accessor(*args)
|
|
41
|
+
r = old_attr_accessor(*args)
|
|
42
|
+
@known ||= {}
|
|
43
|
+
args.each do |arg|
|
|
44
|
+
key = "@#{arg}"
|
|
45
|
+
@known[key.to_sym] = (OPTION_PREFIX + arg.to_s).to_sym
|
|
46
|
+
end
|
|
47
|
+
r
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# This switch enables cache-aware mode. In that mode inflection
|
|
52
|
+
# options and flags are evaluated before calling original translate
|
|
53
|
+
# method and all options are passed to that method. Because options
|
|
54
|
+
# preparation for inflection methods is explicit (any missing switches
|
|
55
|
+
# and their default values are added to options) then original
|
|
56
|
+
# translate (or proxy caching method) will receive even those options
|
|
57
|
+
# that might have been changed globally.
|
|
58
|
+
#
|
|
59
|
+
# Caching modules for I18n may use options passed to the translate
|
|
60
|
+
# method (if they are plugged in before inflector) for key
|
|
61
|
+
# transformation since the inflection options may influence
|
|
62
|
+
# the interpolation process and therefore the resulting string.
|
|
63
|
+
#
|
|
64
|
+
# If however, the caching variant of the translate method is
|
|
65
|
+
# positioned before inflected variant in methods chain, then
|
|
66
|
+
# the only way of knowing all the settings by caching routine is to call
|
|
67
|
+
# <tt>options.options.prepare_options!(options)</tt> on the used backend,
|
|
68
|
+
# for example:
|
|
69
|
+
# I18n.backend.inflector.options.prepare(options)
|
|
70
|
+
# That will alter the +options+ data so they will contain all switches
|
|
71
|
+
# and values.
|
|
72
|
+
#
|
|
73
|
+
# @api public
|
|
74
|
+
# @return [Boolean] state of the switch
|
|
75
|
+
# @param [Boolean] state +true+ enables, +false+ disables this switch
|
|
76
|
+
attr_accessor :cache_aware
|
|
77
|
+
|
|
78
|
+
# This is a switch that enables extended error reporting. When it's enabled then
|
|
79
|
+
# errors are raised in case of unknown or empty tokens present in a pattern
|
|
80
|
+
# or in options. This switch is by default set to +false+.
|
|
81
|
+
#
|
|
82
|
+
# @note Local option +:inflector_raises+ passed
|
|
83
|
+
# to the {I18n::Backend::Inflector#translate} overrides this setting.
|
|
84
|
+
#
|
|
85
|
+
# @api public
|
|
86
|
+
# @return [Boolean] state of the switch
|
|
87
|
+
# @param [Boolean] state +true+ enables, +false+ disables this switch
|
|
88
|
+
attr_accessor :raises
|
|
89
|
+
|
|
90
|
+
# This is a switch that enables you to use aliases in patterns. When it's enabled then
|
|
91
|
+
# aliases may be used in inflection patterns, not only true tokens. This operation
|
|
92
|
+
# may make your translation data a bit messy if you're not alert.
|
|
93
|
+
# That's why this switch is by default set to +false+.
|
|
94
|
+
#
|
|
95
|
+
# @note Local option +:inflector_aliased_patterns+ passed to the
|
|
96
|
+
# {I18n::Backend::Inflector#translate} overrides this setting.
|
|
97
|
+
#
|
|
98
|
+
# @api public
|
|
99
|
+
# @return [Boolean] state of the switch
|
|
100
|
+
# @param [Boolean] state +true+ enables, +false+ disables this switch
|
|
101
|
+
attr_accessor :aliased_patterns
|
|
102
|
+
|
|
103
|
+
# This is a switch that enables you to interpolate patterns contained
|
|
104
|
+
# in resulting nested Hashes. It is used when the original translation
|
|
105
|
+
# method returns a subtree of translation data because the given key
|
|
106
|
+
# is not pointing to a leaf of the data but to some collection.
|
|
107
|
+
#
|
|
108
|
+
# This switch is by default set to +true+. When you turn it off then
|
|
109
|
+
# the Inflector won't touch nested results and will return them as they are.
|
|
110
|
+
#
|
|
111
|
+
# @note Local option +:inflector_traverses+ passed to the
|
|
112
|
+
# {I18n::Backend::Inflector#translate} overrides this setting.
|
|
113
|
+
#
|
|
114
|
+
# @api public
|
|
115
|
+
# @return [Boolean] state of the switch
|
|
116
|
+
# @param [Boolean] state +true+ enables, +false+ disables this switch
|
|
117
|
+
attr_accessor :traverses
|
|
118
|
+
|
|
119
|
+
# This is a switch that enables interpolation of symbols. Whenever
|
|
120
|
+
# interpolation method will receive a collection of symbols as a result
|
|
121
|
+
# of calling underlying translation method
|
|
122
|
+
# it won't process them, returning as they are, unless
|
|
123
|
+
# this switch is enabled.
|
|
124
|
+
#
|
|
125
|
+
# Note that using symbols as values in translation data creates
|
|
126
|
+
# I18n aliases. This option is intended to work with arrays of
|
|
127
|
+
# symbols or hashes with symbols as values, if the original translation
|
|
128
|
+
# method returns such structures.
|
|
129
|
+
#
|
|
130
|
+
# This switch is by default set to +false+.
|
|
131
|
+
#
|
|
132
|
+
# @note Local option +:inflector_interpolate_symbols+ passed to the
|
|
133
|
+
# {I18n::Backend::Inflector#translate} overrides this setting.
|
|
134
|
+
#
|
|
135
|
+
# @api public
|
|
136
|
+
# @return [Boolean] state of the switch
|
|
137
|
+
# @param [Boolean] state +true+ enables, +false+ disables this switch
|
|
138
|
+
attr_accessor :interpolate_symbols
|
|
139
|
+
|
|
140
|
+
# When this switch is set to +true+ then inflector falls back to the default
|
|
141
|
+
# token for a kind if an inflection option passed to the
|
|
142
|
+
# {I18n::Backend::Inflector#translate} is unknown or +nil+.
|
|
143
|
+
# Note that the value of the default token will be
|
|
144
|
+
# interpolated only when this token is present in a pattern. This switch
|
|
145
|
+
# is by default set to +true+.
|
|
146
|
+
#
|
|
147
|
+
# @note Local option +:inflector_unknown_defaults+ passed
|
|
148
|
+
# to the {I18n::Backend::Inflector#translate} overrides this setting.
|
|
149
|
+
#
|
|
150
|
+
# @api public
|
|
151
|
+
# @return [Boolean] state of the switch
|
|
152
|
+
# @param [Boolean] state +true+ enables, +false+ disables this switch
|
|
153
|
+
#
|
|
154
|
+
# @example YAML:
|
|
155
|
+
# en:
|
|
156
|
+
# i18n:
|
|
157
|
+
# inflections:
|
|
158
|
+
# gender:
|
|
159
|
+
# n: 'neuter'
|
|
160
|
+
# o: 'other'
|
|
161
|
+
# default: n
|
|
162
|
+
#
|
|
163
|
+
# welcome: "Dear @{n:You|o:Other}"
|
|
164
|
+
# welcome_free: "Dear @{n:You|o:Other|Free}"
|
|
165
|
+
#
|
|
166
|
+
# @example Example 1
|
|
167
|
+
#
|
|
168
|
+
# # :gender option is not present,
|
|
169
|
+
# # unknown tokens in options are falling back to default
|
|
170
|
+
#
|
|
171
|
+
# I18n.t('welcome')
|
|
172
|
+
# # => "Dear You"
|
|
173
|
+
#
|
|
174
|
+
# # :gender option is not present,
|
|
175
|
+
# # unknown tokens from options are not falling back to default
|
|
176
|
+
#
|
|
177
|
+
# I18n.t('welcome', inflector_unknown_defaults: false)
|
|
178
|
+
# # => "Dear You"
|
|
179
|
+
#
|
|
180
|
+
# # other way of setting an option – globally
|
|
181
|
+
#
|
|
182
|
+
# I18n.inflector.options.unknown_defaults = false
|
|
183
|
+
# I18n.t('welcome')
|
|
184
|
+
# # => "Dear You"
|
|
185
|
+
#
|
|
186
|
+
# # :gender option is not present, free text is present,
|
|
187
|
+
# # unknown tokens from options are not falling back to default
|
|
188
|
+
#
|
|
189
|
+
# I18n.t('welcome_free', inflector_unknown_defaults: false)
|
|
190
|
+
# # => "Dear You"
|
|
191
|
+
#
|
|
192
|
+
# @example Example 2
|
|
193
|
+
#
|
|
194
|
+
# # :gender option is nil,
|
|
195
|
+
# # unknown tokens from options are falling back to default token for a kind
|
|
196
|
+
#
|
|
197
|
+
# I18n.t('welcome', gender: nil)
|
|
198
|
+
# # => "Dear You"
|
|
199
|
+
#
|
|
200
|
+
# # :gender option is nil
|
|
201
|
+
# # unknown tokens from options are not falling back to default token for a kind
|
|
202
|
+
#
|
|
203
|
+
# I18n.t('welcome', gender: nil, inflector_unknown_defaults: false)
|
|
204
|
+
# # => "Dear "
|
|
205
|
+
#
|
|
206
|
+
# # :gender option is nil, free text is present
|
|
207
|
+
# # unknown tokens from options are not falling back to default token for a kind
|
|
208
|
+
#
|
|
209
|
+
# I18n.t('welcome_free', gender: nil, inflector_unknown_defaults: false)
|
|
210
|
+
# # => "Dear Free"
|
|
211
|
+
#
|
|
212
|
+
# @example Example 3
|
|
213
|
+
#
|
|
214
|
+
# # :gender option is unknown,
|
|
215
|
+
# # unknown tokens from options are falling back to default token for a kind
|
|
216
|
+
#
|
|
217
|
+
# I18n.t('welcome', gender: :unknown_blabla)
|
|
218
|
+
# # => "Dear You"
|
|
219
|
+
#
|
|
220
|
+
# # :gender option is unknown,
|
|
221
|
+
# # unknown tokens from options are not falling back to default token for a kind
|
|
222
|
+
#
|
|
223
|
+
# I18n.t('welcome', gender: :unknown_blabla, inflector_unknown_defaults: false)
|
|
224
|
+
# # => "Dear "
|
|
225
|
+
#
|
|
226
|
+
# # :gender option is unknown, free text is present
|
|
227
|
+
# # unknown tokens from options are not falling back to default token for a kind
|
|
228
|
+
#
|
|
229
|
+
# I18n.t('welcome_free', gender: :unknown_blabla, inflector_unknown_defaults: false)
|
|
230
|
+
# # => "Dear Free"
|
|
231
|
+
attr_accessor :unknown_defaults
|
|
232
|
+
|
|
233
|
+
# When this switch is set to +true+ then inflector falls back to the default
|
|
234
|
+
# token for a kind if the given inflection option is correct but doesn't exist
|
|
235
|
+
# in a pattern.
|
|
236
|
+
#
|
|
237
|
+
# There might happen that the inflection option
|
|
238
|
+
# given to {#translate} method will contain some proper token, but that token
|
|
239
|
+
# will not be present in a processed pattern. Normally an empty string will
|
|
240
|
+
# be generated from such a pattern or a free text (if a local fallback is present
|
|
241
|
+
# in a pattern). You can change that behavior and tell interpolating routine to
|
|
242
|
+
# use the default token for a processed kind in such cases.
|
|
243
|
+
#
|
|
244
|
+
# This switch is by default set to +false+.
|
|
245
|
+
#
|
|
246
|
+
# @note Local option +:inflector_excluded_defaults+ passed to the {I18n::Backend::Inflector#translate}
|
|
247
|
+
# overrides this setting.
|
|
248
|
+
#
|
|
249
|
+
# @api public
|
|
250
|
+
# @return [Boolean] state of the switch
|
|
251
|
+
# @param [Boolean] state +true+ enables, +false+ disables this switch
|
|
252
|
+
#
|
|
253
|
+
# @example YAML:
|
|
254
|
+
# en:
|
|
255
|
+
# i18n:
|
|
256
|
+
# inflections:
|
|
257
|
+
# gender:
|
|
258
|
+
# o: "other"
|
|
259
|
+
# m: "male"
|
|
260
|
+
# n: "neuter"
|
|
261
|
+
# default: n
|
|
262
|
+
#
|
|
263
|
+
# welcome: 'Dear @{n:You|m:Sir}'
|
|
264
|
+
# @example Usage of +:inflector_excluded_defaults+ option
|
|
265
|
+
# I18n.t('welcome', gender: :o)
|
|
266
|
+
# # => "Dear "
|
|
267
|
+
#
|
|
268
|
+
# I18n.t('welcome', gender: :o, inflector_excluded_defaults: true)
|
|
269
|
+
# # => "Dear You"
|
|
270
|
+
attr_accessor :excluded_defaults
|
|
271
|
+
|
|
272
|
+
# This method initializes all internal structures.
|
|
273
|
+
def initialize
|
|
274
|
+
reset
|
|
275
|
+
end
|
|
276
|
+
|
|
277
|
+
# This method resets all options to their default values.
|
|
278
|
+
#
|
|
279
|
+
# @return [void]
|
|
280
|
+
def reset
|
|
281
|
+
@unknown_defaults = true
|
|
282
|
+
@traverses = true
|
|
283
|
+
@interpolate_symbols = false
|
|
284
|
+
@excluded_defaults = false
|
|
285
|
+
@aliased_patterns = false
|
|
286
|
+
@cache_aware = false
|
|
287
|
+
@raises = false
|
|
288
|
+
nil
|
|
289
|
+
end
|
|
290
|
+
|
|
291
|
+
# This method processes the given argument
|
|
292
|
+
# in a way that it will use default values
|
|
293
|
+
# for options that are missing.
|
|
294
|
+
#
|
|
295
|
+
# @api public
|
|
296
|
+
# @note It modifies the given object.
|
|
297
|
+
# @param [Hash] options the options
|
|
298
|
+
# @return [Hash] the given options
|
|
299
|
+
def prepare_options!(options)
|
|
300
|
+
self.class.known
|
|
301
|
+
.reject { |_name, long| options.key?(long) }
|
|
302
|
+
.each { |name, long| options[long] = instance_variable_get(name) }
|
|
303
|
+
options
|
|
304
|
+
end
|
|
305
|
+
|
|
306
|
+
# This method prepares options for translate method.
|
|
307
|
+
# That means removal of all kind-related options
|
|
308
|
+
# and all options that are flags.
|
|
309
|
+
#
|
|
310
|
+
# @api public
|
|
311
|
+
# @note It modifies the given object.
|
|
312
|
+
# @param [Hash] options the given options
|
|
313
|
+
# @return [Hash] the given options
|
|
314
|
+
def clean_for_translate!(options)
|
|
315
|
+
self.class.known.each_value { |long| options.delete long }
|
|
316
|
+
options
|
|
317
|
+
end
|
|
318
|
+
|
|
319
|
+
# Lists all known options in a long format
|
|
320
|
+
# (each name preceeded by <tt>inflector_</tt>).
|
|
321
|
+
#
|
|
322
|
+
# @api public
|
|
323
|
+
# @return [Array<Symbol>] the known options
|
|
324
|
+
def known
|
|
325
|
+
self.class.known.values
|
|
326
|
+
end
|
|
327
|
+
end
|
|
328
|
+
end
|
|
329
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
#
|
|
4
|
+
# Author:: Paweł Wilk (mailto:pw@gnu.org)
|
|
5
|
+
# Copyright:: (c) 2011,2012,2013 by Paweł Wilk
|
|
6
|
+
# License:: This program is licensed under the terms of {file:docs/LGPL GNU Lesser General Public License} or {file:docs/COPYING Ruby License}.
|
|
7
|
+
#
|
|
8
|
+
# This file contains version information.
|
|
9
|
+
|
|
10
|
+
module I18n
|
|
11
|
+
module Inflector
|
|
12
|
+
# @private
|
|
13
|
+
DEVELOPER = 'Paweł Wilk'
|
|
14
|
+
# @private
|
|
15
|
+
EMAIL = 'pw@gnu.org'
|
|
16
|
+
# @private
|
|
17
|
+
VERSION = '3.0.0'
|
|
18
|
+
# @private
|
|
19
|
+
NAME = 'i18n-inflector'
|
|
20
|
+
# @private
|
|
21
|
+
SUMMARY = 'Inflection module for I18n'
|
|
22
|
+
# @private
|
|
23
|
+
URL = 'https://rubygems.org/gems/i18n-inflector/'
|
|
24
|
+
# @private
|
|
25
|
+
DESCRIPTION = 'Enhances simple I18n backend in a way that it inflects translation data using pattern interpolation.'
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'i18n'
|
|
4
|
+
|
|
5
|
+
require 'i18n-inflector/version'
|
|
6
|
+
require 'i18n-inflector/hset'
|
|
7
|
+
require 'i18n-inflector/lazy_enum'
|
|
8
|
+
require 'i18n-inflector/inflection_data_strict'
|
|
9
|
+
require 'i18n-inflector/inflection_data'
|
|
10
|
+
require 'i18n-inflector/options'
|
|
11
|
+
require 'i18n-inflector/inflector'
|
|
12
|
+
require 'i18n-inflector/config'
|
|
13
|
+
require 'i18n-inflector/backend'
|
|
14
|
+
require 'i18n-inflector/errors'
|
|
15
|
+
require 'i18n-inflector/interpolate'
|
|
16
|
+
require 'i18n-inflector/api_strict'
|
|
17
|
+
require 'i18n-inflector/api'
|
|
18
|
+
|
|
19
|
+
I18n::Backend::Simple.include I18n::Backend::Inflector
|