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.
@@ -2,7 +2,7 @@
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-LICENSE GNU Lesser General Public License} or {file:COPYING Ruby License}.
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
7
  # This file contains inline documentation data
8
8
  # that would make the file with code less readable
@@ -10,414 +10,336 @@
10
10
  #
11
11
 
12
12
  module I18n
13
- module Backend
14
- # Overwrites the Simple backend translate method so that it will interpolate
15
- # additional inflection tokens present in translations. These tokens may
16
- # appear in *patterns* which are contained within <tt>@{</tt> and <tt>}</tt>
17
- # symbols.
18
- #
19
- # You can choose different kinds (gender, title, person, time, author, etc.)
20
- # of tokens to group them in a meaningful, semantical sets. That means you can
21
- # apply Inflector to do simple inflection by a gender or a person, when some
22
- # language requires it.
23
- #
24
- # To achieve similar functionality lambdas can be used but there might be
25
- # some areas of appliance that including proc objects in translations
26
- # is prohibited.
27
- # If you have a troop of happy translators that shouldn't have the
28
- # ability to execute any code yet you need some simple inflection
29
- # then you can make use of this module.
30
- # == Usage
31
- # require 'i18-inflector'
32
- #
33
- # i18n.translate('welcome')
34
- # # where welcome maps to: "Dear @{f:Madam|m:Sir}"
35
- #
36
- # == Inflection pattern
37
- # An example inflection pattern contained in a translation record looks like:
38
- # welcome: "Dear @{f:Madam|m:Sir|n:You|All}"
39
- #
40
- # The +f+, +m+ and +n+ are inflection *tokens* and +Madam+, +Sir+, +You+ and
41
- # +All+ are *values*. Only one value is going to replace the whole
42
- # pattern. To select which one an additional option is used. That option
43
- # must be passed to translate method.
44
- #
45
- # == Configuration
46
- # To recognize tokens present in patterns this module uses keys grouped
47
- # in the scope called `inflections` for a given locale. For instance
48
- # (YAML format):
49
- # en:
50
- # i18n:
51
- # inflections:
52
- # gender:
53
- # f: "female"
54
- # m: "male"
55
- # n: "neuter"
56
- # woman: @f
57
- # man: @m
58
- # default: n
59
- #
60
- # Elements in the example above are:
61
- # * +en+: language
62
- # * +i18n+: configuration scope
63
- # * +inflections+: inflections configuration scope
64
- # * +gender+: kind scope
65
- # * +f+, +m+, +n+: inflection tokens
66
- # * <tt>"male"</tt>, <tt>"female"</tt>, <tt>"neuter"</tt>: tokens' descriptions
67
- # * +woman+, +man+: inflection aliases
68
- # * <tt>@f</tt>, <tt>@m</tt>: pointers to real tokens
69
- # * +default+: default token for a kind +gender+
70
- #
71
- # === Kind
72
- # Note the fourth scope selector in the example above (+gender+). It's called
73
- # the *kind* and contains *tokens*. We have the kind
74
- # +gender+ to which the inflection tokens +f+, +m+ and +n+ are
75
- # assigned.
76
- #
77
- # You cannot assign the same token to more than one kind.
78
- # Trying to do that will raise DuplicatedInflectionToken exception.
79
- # This is required in order to keep patterns simple and tokens interpolation
80
- # fast.
81
- #
82
- # Kind is also used to instruct I18n.translate method which
83
- # token it should pick. This will be explained later.
84
- #
85
- # === Aliases
86
- # Aliases are special tokens that point to other tokens. They cannot
87
- # be used in inflection patterns but they are fully recognized values
88
- # of options while evaluating kinds.
89
- #
90
- # Aliases might be helpful in multilingual applications that are using
91
- # a fixed set of values passed through options to describe some properties
92
- # of messages, e.g. +masculine+ and +feminine+ for a grammatical gender.
93
- # Translators may then use their own tokens (like +f+ and +m+ for English)
94
- # to produce pretty and intuitive patterns.
95
- #
96
- # For example: if some application uses database with gender assigned
97
- # to a user which may be +male+, +female+ or +none+, then a translator
98
- # for some language may find it useful to map impersonal token (<tt>none</tt>)
99
- # to the +neuter+ token, since in translations for his language the
100
- # neuter gender is in use.
101
- #
102
- # Here is the example of such situation:
103
- #
104
- # en:
105
- # i18n:
106
- # inflections:
107
- # gender:
108
- # male: "male"
109
- # female: "female"
110
- # none: "impersonal form"
111
- # default: none
112
- #
113
- # pl:
114
- # i18n:
115
- # inflections:
116
- # gender:
117
- # k: "female"
118
- # m: "male"
119
- # n: "neuter"
120
- # male: @k
121
- # female: @m
122
- # none: @n
123
- # default: none
124
- #
125
- # In the case above Polish translator decided to use neuter
126
- # instead of impersonal form when +none+ token will be passed
127
- # through the option +:gender+ to the translate method. He
128
- # also decided that he will use +k+, +m+ or +n+ in patterns,
129
- # because the names are short and correspond to gender names in
130
- # Polish language.
131
- #
132
- # Aliases may point to other aliases. While loading inflections they
133
- # will be internally shortened and they will always point to real tokens,
134
- # not other aliases.
135
- #
136
- # === Default token
137
- # There is special token called the +default+, which points
138
- # to a token that should be used if translation routine cannot deduce
139
- # which one it should use because a proper option was not given.
140
- #
141
- # Default tokens may point to aliases and may use aliases' syntax, e.g.:
142
- # default: @man
143
- #
144
- # === Descriptions
145
- # The values of keys in the example (+female+, +male+ and +neuter+)
146
- # are *descriptions* which are not used by interpolation routines
147
- # but might be helpful (e.g. in UI). For obvious reasons you cannot
148
- # describe aliases.
149
- #
150
- # == Tokens
151
- # The token is an element of a pattern. A pattern may have many tokens
152
- # of the same kind separated by vertical bars. Each token name used in a
153
- # pattern should end with colon sign. After this colon a value should
154
- # appear (or an empty string).
155
- #
156
- # == Interpolation
157
- # The value of each token present in a pattern is to be picked by the interpolation
158
- # routine and will replace the whole pattern, when the token name from that
159
- # pattern matches the value of an option passed to {I18n.translate} method.
160
- # This option is called <b>the inflection option</b>. Its name should be
161
- # the same as a *kind* of tokens used within a pattern. The first token in a pattern
162
- # determines the kind of all tokens used in that pattern. You can pass
163
- # many inflection options, each one designated for keeping a token of a
164
- # different kind.
165
- #
166
- # ==== Examples:
167
- # # welcome is "Dear @{f:Madam|m:Sir|n:You|All}"
168
- #
169
- # I18n.translate('welcome', :gender => :m)
170
- # # => "Dear Sir"
171
- #
172
- # I18n.translate('welcome', :gender => :unknown)
173
- # # => "Dear All"
174
- #
175
- # I18n.translate('welcome')
176
- # # => "Dear You"
177
- #
178
- # In the second example the <b>fallback value</b> +All+ was interpolated
179
- # because the routine had been unable to find the token called +:unknown+.
180
- # That differs from the latest example, in which there was no option given,
181
- # so the default token for a kind had been applied (in this case +n+).
182
- #
183
- # == Local fallbacks (free text)
184
- # The fallback value will be used when any of the given tokens from
185
- # pattern cannot be interpolated.
186
- #
187
- # Be aware that enabling extended error reporting makes it unable
188
- # to use fallback values in most cases. Local fallbacks will then be
189
- # applied only when a given option contains a proper value for some
190
- # kind but it's just not present in a pattern, for example:
191
- #
192
- # I18n.locale = :en
193
- # I18n.backend.store_translations 'en', 'welcome' => 'Dear @{n:You|All}'
194
- # I18n.backend.store_translations 'en', :i18n => { :inflections => {
195
- # :gender => { :n => 'neuter', :o => 'other' }}}
196
- #
197
- # I18n.translate('welcome', :gender => :o, :inflector_raises => true)
198
- # # => "Dear All"
199
- #
200
- # # since the token :o was configured but not used in the pattern
201
- #
202
- # == Unknown and empty tokens in options
203
- # If an option containing token is not present at all then the interpolation
204
- # routine will try the default token for a processed kind if the default
205
- # token is present in a pattern. The same thing will happend if the option
206
- # is present but its value is unknown, empty or +nil+.
207
- # If the default token is not present in a pattern or is not defined in
208
- # a configuration data then the processed pattern will result in an empty
209
- # string or in a local fallback value if there is a free text placed
210
- # in a pattern.
211
- #
212
- # You can change this default behavior and force inflector
213
- # not to use a default token when a value of an option for a kind is unknown,
214
- # empty or +nil+ but only when it's not present.
215
- # To do that you should set option +:inflector_unknown_defaults+ to
216
- # +false+ and pass it to I18n.translate method. Other way is to set this
217
- # globally by using the method called inflector_unknown_defaults.
218
- # See #inflector_unknown_defaults for examples showing how the
219
- # translation results are changing when that switch is applied.
220
- #
221
- # == Mixing inflection and standard interpolation patterns
222
- # The Inflector module allows you to include standard <tt>%{}</tt>
223
- # patterns inside of inflection patterns. The value of a standard
224
- # interpolation variable will be evaluated and interpolated *before*
225
- # processing an inflection pattern. For example:
226
- #
227
- # I18n.backend.store_translations(:xx, 'hi' => 'Dear @{f:Lady|m:%{test}}!')
228
- #
229
- # I18n.t('hi', :gender => :m, :locale => :xx, :test => "Dude")
230
- # # => Dear Dude!
231
- #
232
- # == Escaping a pattern
233
- # If there is a need to translate something that matches an inflection
234
- # pattern the escape symbols can be used to disable the interpolation. These
235
- # symbols are <tt>\\</tt> and +@+ and they should be placed just before
236
- # a pattern that should be left untouched. For instance:
237
- #
238
- # I18n.backend.store_translations(:xx, 'hi' => 'This is the @@{pattern}!')
239
- #
240
- # I18n.t('hi', :gender => :m, :locale => :xx)
241
- # # => This is the @{pattern}!
242
- #
243
- # == Errors
244
- # By default the module will silently ignore any interpolation errors.
245
- # You can turn off this default behavior by passing +:inflector_raises+ option.
246
- #
247
- # === Usage of +:inflector_raises+ option
248
- #
249
- # I18n.locale = :en
250
- # I18n.backend.store_translations 'en', 'welcome' => 'Dear @{m:Sir|f:Madam|Fallback}'
251
- # I18n.backend.store_translations 'en', :i18n => { :inflections => {
252
- # :gender => {
253
- # :f => 'female',
254
- # :m => 'male'
255
- # }}}
256
- #
257
- # I18n.translate('welcome', :inflector_raises => true)
258
- #
259
- # # => I18n::InvalidOptionForKind: option :gender required by the pattern
260
- # # "@{m:Sir|f:Madam|Fallback}" was not found
261
- #
262
- # Here are the exceptions that may be raised when option +:inflector_raises+
263
- # is set to +true+:
264
- #
265
- # * {I18n::InvalidOptionForKind I18n::InvalidOptionForKind}
266
- # * {I18n::InvalidInflectionToken I18n::InvalidInflectionToken}
267
- # * {I18n::MisplacedInflectionToken I18n::MisplacedInflectionToken}
268
- #
269
- # There are also exceptions that are raised regardless of :+inflector_raises+
270
- # presence or value.
271
- # These are usually caused by critical errors encountered during processing
272
- # inflection data. Here is the list:
273
- #
274
- # * {I18n::InvalidLocale I18n::InvalidLocale}
275
- # * {I18n::DuplicatedInflectionToken I18n::DuplicatedInflectionToken}
276
- # * {I18n::BadInflectionToken I18n::BadInflectionToken}
277
- # * {I18n::BadInflectionAlias I18n::BadInflectionAlias}
278
- #
279
- module Inflector
280
- # When this switch is set to +true+ then inflector falls back to the default
281
- # token for a kind if an inflection option passed to the {#translate} is unknown
282
- # or +nil+. Note that the value of the default token will be
283
- # interpolated only when this token is present in a pattern. This switch
284
- # is by default set to +true+.
285
- #
286
- # @note Local option +:inflector_unknown_defaults+ passed to translation method
287
- # overrides this setting.
288
- #
289
- # @api public
290
- # @see #inflector_unknown_defaults?
291
- # @see I18n::Inflector.unknown_defaults Short name: I18n::Inflector.unknown_defaults
292
- # @return [Boolean] the state of the switch
293
- #
294
- # @example Usage of +:inflector_unknown_defaults+ option preparation
295
- #
296
- # I18n.locale = :en
297
- # I18n.backend.store_translations 'en', :i18n => { :inflections => {
298
- # :gender => {
299
- # :n => 'neuter',
300
- # :o => 'other',
301
- # :default => 'n' }}}
302
- #
303
- # I18n.backend.store_translations 'en', 'welcome' => 'Dear @{n:You|o:Other}'
304
- # I18n.backend.store_translations 'en', 'welcome_free' => 'Dear @{n:You|o:Other|Free}'
305
- #
306
- # @example Example 1
307
- #
308
- # # :gender option is not present,
309
- # # unknown tokens in options are falling back to default
310
- #
311
- # I18n.t('welcome')
312
- # # => "Dear You"
313
- #
314
- # # :gender option is not present,
315
- # # unknown tokens from options are not falling back to default
316
- #
317
- # I18n.t('welcome', :inflector_unknown_defaults => false)
318
- # # => "Dear You"
319
- #
320
- # # :gender option is not present, free text is present,
321
- # # unknown tokens from options are not falling back to default
322
- #
323
- # I18n.t('welcome_free', :inflector_unknown_defaults => false)
324
- # # => "Dear You"
325
- #
326
- # @example Example 2
327
- #
328
- # # :gender option is nil,
329
- # # unknown tokens from options are falling back to default token for a kind
330
- #
331
- # I18n.t('welcome', :gender => nil)
332
- # # => "Dear You"
333
- #
334
- # # :gender option is nil
335
- # # unknown tokens from options are not falling back to default token for a kind
336
- #
337
- # I18n.t('welcome', :gender => nil, :inflector_unknown_defaults => false)
338
- # # => "Dear "
339
- #
340
- # # :gender option is nil, free text is present
341
- # # unknown tokens from options are not falling back to default token for a kind
342
- #
343
- # I18n.t('welcome_free', :gender => nil, :inflector_unknown_defaults => false)
344
- # # => "Dear Free"
345
- #
346
- # @example Example 3
347
- #
348
- # # :gender option is unknown,
349
- # # unknown tokens from options are falling back to default token for a kind
350
- #
351
- # I18n.t('welcome', :gender => :unknown_blabla)
352
- # # => "Dear You"
353
- #
354
- # # :gender option is unknown,
355
- # # unknown tokens from options are not falling back to default token for a kind
356
- #
357
- # I18n.t('welcome', :gender => :unknown_blabla, :inflector_unknown_defaults => false)
358
- # # => "Dear "
359
- #
360
- # # :gender option is unknown, free text is present
361
- # # unknown tokens from options are not falling back to default token for a kind
362
- #
363
- # I18n.t('welcome_free', :gender => :unknown_blabla, :inflector_unknown_defaults => false)
364
- # # => "Dear Free"
365
- attr_accessor :inflector_unknown_defaults
13
+ # @version 2.0
14
+ # This module contains inflection classes and modules for enabling
15
+ # the inflection support in I18n translations.
16
+ # Its submodule overwrites the Simple backend translate method
17
+ # so that it will interpolate additional inflection tokens present
18
+ # in translations. These tokens may appear in *patterns* which
19
+ # are contained within <tt>@{</tt> and <tt>}</tt> symbols.
20
+ #
21
+ # == Usage
22
+ # require 'i18-inflector'
23
+ #
24
+ # i18n.translate('welcome', :gender => :f)
25
+ # # => Dear Madam
26
+ #
27
+ # i18n.inflector.kinds
28
+ # # => [:gender]
29
+ #
30
+ # i18n.inflector.true_tokens.keys
31
+ # # => [:f, :m, :n]
32
+ #
33
+ # == Inflection pattern
34
+ # An example inflection pattern contained in a translation record looks like:
35
+ # welcome: "Dear @{f:Madam|m:Sir|n:You|All}"
36
+ #
37
+ # The +f+, +m+ and +n+ are inflection *tokens* and +Madam+, +Sir+, +You+ and
38
+ # +All+ are *values*. Only one value is going to replace the whole
39
+ # pattern. To select which one an additional option is used. That option
40
+ # must be passed to translate method.
41
+ #
42
+ # == Configuration
43
+ # To recognize tokens present in patterns this module uses keys grouped
44
+ # in the scope called `inflections` for a given locale. For instance
45
+ # (YAML format):
46
+ # en:
47
+ # i18n:
48
+ # inflections:
49
+ # gender:
50
+ # f: "female"
51
+ # m: "male"
52
+ # n: "neuter"
53
+ # woman: @f
54
+ # man: @m
55
+ # default: n
56
+ #
57
+ # Elements in the example above are:
58
+ # * +en+: language
59
+ # * +i18n+: configuration scope
60
+ # * +inflections+: inflections configuration scope
61
+ # * +gender+: kind scope
62
+ # * +f+, +m+, +n+: inflection tokens
63
+ # * <tt>"male"</tt>, <tt>"female"</tt>, <tt>"neuter"</tt>: tokens' descriptions
64
+ # * +woman+, +man+: inflection aliases
65
+ # * <tt>@f</tt>, <tt>@m</tt>: pointers to real tokens
66
+ # * +default+: default token for a kind +gender+
67
+ #
68
+ # === Kind
69
+ # Note the fourth scope selector in the example above (+gender+). It's called
70
+ # the *kind* and contains *tokens*. We have the kind
71
+ # +gender+ to which the inflection tokens +f+, +m+ and +n+ are
72
+ # assigned.
73
+ #
74
+ # You cannot assign the same token to more than one kind.
75
+ # Trying to do that will raise DuplicatedInflectionToken exception.
76
+ # This is required in order to keep patterns simple and tokens interpolation
77
+ # fast.
78
+ #
79
+ # Kind is also used to instruct I18n.translate method which
80
+ # token it should pick. This will be explained later.
81
+ #
82
+ # === Tokens
83
+ # The token is an element of a pattern. A pattern may have many tokens
84
+ # of the same kind separated by vertical bars. Each token name used in a
85
+ # pattern should end with colon sign. After this colon a value should
86
+ # appear (or an empty string).
87
+ #
88
+ # === Aliases
89
+ # Aliases are special tokens that point to other tokens. They cannot
90
+ # be used in inflection patterns but they are fully recognized values
91
+ # of options while evaluating kinds.
92
+ #
93
+ # Aliases might be helpful in multilingual applications that are using
94
+ # a fixed set of values passed through options to describe some properties
95
+ # of messages, e.g. +masculine+ and +feminine+ for a grammatical gender.
96
+ # Translators may then use their own tokens (like +f+ and +m+ for English)
97
+ # to produce pretty and intuitive patterns.
98
+ #
99
+ # For example: if some application uses database with gender assigned
100
+ # to a user which may be +male+, +female+ or +none+, then a translator
101
+ # for some language may find it useful to map impersonal token (<tt>none</tt>)
102
+ # to the +neuter+ token, since in translations for his language the
103
+ # neuter gender is in use.
104
+ #
105
+ # Here is the example of such situation:
106
+ #
107
+ # en:
108
+ # i18n:
109
+ # inflections:
110
+ # gender:
111
+ # male: "male"
112
+ # female: "female"
113
+ # none: "impersonal form"
114
+ # default: none
115
+ #
116
+ # pl:
117
+ # i18n:
118
+ # inflections:
119
+ # gender:
120
+ # k: "female"
121
+ # m: "male"
122
+ # n: "neuter"
123
+ # male: @k
124
+ # female: @m
125
+ # none: @n
126
+ # default: none
127
+ #
128
+ # In the case above Polish translator decided to use neuter
129
+ # instead of impersonal form when +none+ token will be passed
130
+ # through the option +:gender+ to the translate method. He
131
+ # also decided that he will use +k+, +m+ or +n+ in patterns,
132
+ # because the names are short and correspond to gender names in
133
+ # Polish language.
134
+ #
135
+ # Aliases may point to other aliases. While loading inflections they
136
+ # will be internally shortened and they will always point to real tokens,
137
+ # not other aliases.
138
+ #
139
+ # === Default token
140
+ # There is special token called the +default+, which points
141
+ # to a token that should be used if translation routine cannot deduce
142
+ # which one it should use because a proper option was not given.
143
+ #
144
+ # Default tokens may point to aliases and may use aliases' syntax, e.g.:
145
+ # default: @man
146
+ #
147
+ # === Descriptions
148
+ # The values of keys in the example (+female+, +male+ and +neuter+)
149
+ # are *descriptions* which are not used by interpolation routines
150
+ # but might be helpful (e.g. in UI). For obvious reasons you cannot
151
+ # describe aliases.
152
+ #
153
+ # == Interpolation
154
+ # The value of each token present in a pattern is to be picked by the interpolation
155
+ # routine and will replace the whole pattern, when the token name from that
156
+ # pattern matches the value of an option passed to {I18n.translate} method.
157
+ # This option is called <b>the inflection option</b>. Its name should be
158
+ # the same as a *kind* of tokens used within a pattern. The first token in a pattern
159
+ # determines the kind of all tokens used in that pattern. You can pass
160
+ # many inflection options, each one designated for keeping a token of a
161
+ # different kind.
162
+ #
163
+ # === Examples:
164
+ #
165
+ # ===== YAML:
166
+ # Let's assume that the translation data in YAML format listed
167
+ # below is used in any later example, unless other inflections
168
+ # are given.
169
+ # en:
170
+ # i18n:
171
+ # inflections:
172
+ # gender:
173
+ # m: "male"
174
+ # f: "female"
175
+ # n: "neuter"
176
+ # default: n
177
+ #
178
+ # welcome: "Dear @{f:Madam|m:Sir|n:You|All}"
179
+ # ===== Code:
180
+ # I18n.translate('welcome', :gender => :m)
181
+ # # => "Dear Sir"
182
+ #
183
+ # I18n.translate('welcome', :gender => :unknown)
184
+ # # => "Dear All"
185
+ #
186
+ # I18n.translate('welcome')
187
+ # # => "Dear You"
188
+ #
189
+ # In the second example the <b>fallback value</b> +All+ was interpolated
190
+ # because the routine had been unable to find the token called +:unknown+.
191
+ # That differs from the latest example, in which there was no option given,
192
+ # so the default token for a kind had been applied (in this case +n+).
193
+ #
194
+ # === Local fallbacks (free text)
195
+ # The fallback value will be used when any of the given tokens from
196
+ # pattern cannot be interpolated.
197
+ #
198
+ # Be aware that enabling extended error reporting makes it unable
199
+ # to use fallback values in most cases. Local fallbacks will then be
200
+ # applied only when a given option contains a proper value for some
201
+ # kind but it's just not present in a pattern, for example:
202
+ #
203
+ # ===== YAML:
204
+ # en:
205
+ # i18n:
206
+ # inflections:
207
+ # gender:
208
+ # n: 'neuter'
209
+ # o: 'other'
210
+ #
211
+ # welcome: "Dear @{n:You|All}"
212
+ #
213
+ # ===== Code:
214
+ # I18n.translate('welcome', :gender => :o, :raises => true)
215
+ # # => "Dear All"
216
+ # # since the token :o was configured but not used in the pattern
217
+ #
218
+ # === Unknown and empty tokens in options
219
+ # If an option containing token is not present at all then the interpolation
220
+ # routine will try the default token for a processed kind if the default
221
+ # token is present in a pattern. The same thing will happend if the option
222
+ # is present but its value is unknown, empty or +nil+.
223
+ # If the default token is not present in a pattern or is not defined in
224
+ # a configuration data then the processed pattern will result in an empty
225
+ # string or in a local fallback value if there is a free text placed
226
+ # in a pattern.
227
+ #
228
+ # You can change this default behavior and force inflector
229
+ # not to use a default token when a value of an option for a kind is unknown,
230
+ # empty or +nil+ but only when it's not present.
231
+ # To do that you should set option +:unknown_defaults+ to
232
+ # +false+ and pass it to I18n.translate method. Other way is to set this
233
+ # globally by using the method called unknown_defaults.
234
+ # See #unknown_defaults for examples showing how the
235
+ # translation results are changing when that switch is applied.
236
+ #
237
+ # === Mixing inflection and standard interpolation patterns
238
+ # The Inflector module allows you to include standard <tt>%{}</tt>
239
+ # patterns inside of inflection patterns. The value of a standard
240
+ # interpolation variable will be evaluated and interpolated *before*
241
+ # processing an inflection pattern. For example:
242
+ #
243
+ # ===== YAML:
244
+ # Note: <em>Uses inflection configuration given in the first example.</em>
245
+ # en:
246
+ # hi: "Dear @{f:Lady|m:%{test}}!"
247
+ # ===== Code:
248
+ # I18n.t('hi', :gender => :m, :locale => :xx, :test => "Dude")
249
+ # # => Dear Dude!
250
+ #
251
+ # === Token groups
252
+ # It is possible to assign some value to more than one token.
253
+ # You can create group of tokens by separating them using commas.
254
+ # The comma has the meaning of logical OR in such a token group.
255
+ #
256
+ # ===== YAML:
257
+ # Note: <em>Uses inflection configuration given in the first example.</em>
258
+ # en:
259
+ # welcome: "Hello @{m,f:Ladies and Gentlemen|n:You}!"
260
+ # ===== Code:
261
+ # I18n.t('welcome', :gender => :f)
262
+ # # => Hello Ladies and Gentlemen!
263
+ #
264
+ # === Inverse matching of tokens
265
+ # You can place exclamation mark before a token that should be
266
+ # matched negatively. It's value will be used for a pattern
267
+ # <b>if the given inflection option contains other token</b>.
268
+ # You can use inversed matching tokens in token groups but
269
+ # note that using more than one inversed token separated
270
+ # by a comma will cause the expression to mach every time.
271
+ #
272
+ # ===== YAML:
273
+ # Note: <em>Uses inflection configuration given in the first example.</em>
274
+ # en:
275
+ # welcome: "Hello @{!m:Ladies|n:You}!"
276
+ # ===== Code:
277
+ # I18n.t('welcome', :gender => :n)
278
+ # # => Hello Ladies!
279
+ #
280
+ # I18n.t('welcome', :gender => :f)
281
+ # # => Hello Ladies!
282
+ #
283
+ # I18n.t('welcome', :gender => :m)
284
+ # # => Hello !
285
+ #
286
+ # === Aliases in a pattern
287
+ # Normally it possible to use only true tokens in patterns, not aliases.
288
+ # However, if you feel lucky and you're not affraid of messy patterns
289
+ # you can use the switch {I18n::Inflector::InflectionOptions#aliased_patterns}
290
+ # or corresponding +:inflector_aliased_patterns+ option passed to translation
291
+ # method.
292
+ #
293
+ # === Escaping a pattern
294
+ # If there is a need to translate something that matches an inflection
295
+ # pattern the escape symbols can be used to disable the interpolation. These
296
+ # symbols are <tt>\\</tt> and +@+ and they should be placed just before
297
+ # a pattern that should be left untouched. For instance:
298
+ #
299
+ # ===== YAML:
300
+ # Note: <em>Uses inflection configuration given in the first example.</em>
301
+ # en:
302
+ # welcome: "This is the @@{pattern}!"
303
+ # ===== Code:
304
+ # I18n.t('welcome', :gender => :m, :locale => :xx)
305
+ # # => This is the @{pattern}!
306
+ #
307
+ # == Errors
308
+ # By default the module will silently ignore any interpolation errors.
309
+ # You can turn off this default behavior by passing +:raises+ option.
310
+ #
311
+ # === Usage of +:raises+ option
312
+ #
313
+ # ===== YAML
314
+ # Note: <em>Uses inflection configuration given in the first example.</em>
315
+ # en:
316
+ # welcome: "Dear @{m:Sir|f:Madam|Fallback}"
317
+ # ===== Code:
318
+ # I18n.t('welcome', :raises => true)
319
+ # # => I18n::InvalidOptionForKind: option :gender required by the pattern
320
+ # # "@{m:Sir|f:Madam|Fallback}" was not found
321
+ #
322
+ # Here are the exceptions that may be raised when option +:raises+
323
+ # is set to +true+:
324
+ #
325
+ # * {I18n::InvalidOptionForKind I18n::InvalidOptionForKind}
326
+ # * {I18n::InvalidInflectionToken I18n::InvalidInflectionToken}
327
+ # * {I18n::MisplacedInflectionToken I18n::MisplacedInflectionToken}
328
+ #
329
+ # There are also exceptions that are raised regardless of :+raises+
330
+ # presence or value.
331
+ # These are usually caused by critical errors encountered during processing
332
+ # inflection data. Here is the list:
333
+ #
334
+ # * {I18n::InvalidLocale I18n::InvalidLocale}
335
+ # * {I18n::DuplicatedInflectionToken I18n::DuplicatedInflectionToken}
336
+ # * {I18n::BadInflectionToken I18n::BadInflectionToken}
337
+ # * {I18n::BadInflectionAlias I18n::BadInflectionAlias}
338
+ #
339
+ module Inflector
366
340
 
367
- # When this switch is set to +true+ then inflector falls back to the default
368
- # token for a kind if the given inflection option is correct but doesn't exist in a pattern.
369
- #
370
- # There might happend that the inflection option
371
- # given to {#translate} method will contain some proper token, but that token
372
- # will not be present in a processed pattern. Normally an empty string will
373
- # be generated from such a pattern or a free text (if a local fallback is present
374
- # in a pattern). You can change that behavior and tell interpolating routine to
375
- # use the default token for a processed kind in such cases.
376
- #
377
- # This switch is by default set to +false+.
378
- #
379
- # @note Local option +:inflector_excluded_defaults+ passed to the {#translate}
380
- # overrides this setting.
381
- #
382
- # @api public
383
- # @see #inflector_excluded_defaults?
384
- # @see I18n::Inflector.excluded_defaults Short name: I18n::Inflector.excluded_defaults
385
- # @return [Boolean] the state of the switch
386
- #
387
- # @example Usage of +:inflector_excluded_defaults+ option
388
- #
389
- # I18n.locale = :en
390
- # I18n.backend.store_translations 'en', :i18n => { :inflections => {
391
- # :gender => {
392
- # :n => 'neuter',
393
- # :m => 'male',
394
- # :o => 'other',
395
- # :default => 'n' }}}
396
- #
397
- # I18n.backend.store_translations 'en', 'welcome' => 'Dear @{n:You|m:Sir}'
398
- #
399
- # I18n.t('welcome', :gender => :o)
400
- # # => "Dear "
401
- #
402
- # I18n.t('welcome', :gender => :o, :inflector_excluded_defaults => true)
403
- # # => "Dear You"
404
- attr_accessor :inflector_excluded_defaults
405
-
406
- # This is a switch that enables extended error reporting. When it's enabled then
407
- # errors are raised in case of unknown or empty tokens present in a pattern
408
- # or in options. This switch is by default set to +false+.
409
- #
410
- # @note Local option +:inflector_raises+ passed to the {#translate} overrides this setting.
411
- #
412
- # @api public
413
- # @see #inflector_excluded_defaults?
414
- # @see I18n::Inflector.raises Short name: I18n::Inflector.raises
415
- # @return [Boolean] the state of the switch
416
- attr_accessor :inflector_raises
417
-
418
- end
419
341
  end
420
-
342
+
421
343
  # @abstract This exception class is defined in package I18n. It is raised when
422
344
  # the given and/or processed locale parameter is invalid.
423
345
  class InvalidLocale; end