i18n-inflector 2.2.0 → 2.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.yardopts +1 -1
- data/ChangeLog +156 -0
- data/Gemfile +0 -1
- data/Manifest.txt +1 -1
- data/README.rdoc +21 -8
- data/ci/i18n-inflector.gemspec +1 -1
- data/docs/EXAMPLES +2 -2
- data/docs/HISTORY +16 -0
- data/docs/TODO +1 -1
- data/docs/USAGE +939 -0
- data/lib/i18n-inflector/api.rb +14 -14
- data/lib/i18n-inflector/backend.rb +2 -2
- data/lib/i18n-inflector/config.rb +17 -11
- data/lib/i18n-inflector/errors.rb +2 -2
- data/lib/i18n-inflector/inflector.rb +11 -0
- data/lib/i18n-inflector/interpolate.rb +77 -10
- data/lib/i18n-inflector/long_comments.rb +3 -783
- data/lib/i18n-inflector/version.rb +1 -1
- data/test/inflector_test.rb +57 -2
- data.tar.gz.sig +0 -0
- metadata +5 -5
- metadata.gz.sig +0 -0
- data/docs/RELATIONS +0 -28
@@ -6,788 +6,10 @@
|
|
6
6
|
#
|
7
7
|
# This file contains inline documentation data
|
8
8
|
# that would make the file with code less readable
|
9
|
-
# if placed there.
|
10
|
-
#
|
9
|
+
# if placed there. Code from this file is not used
|
10
|
+
# by the library, it's just for documentation.
|
11
11
|
|
12
12
|
module I18n
|
13
|
-
# @version 2.2
|
14
|
-
# This module contains inflection classes and modules for enabling
|
15
|
-
# the inflection support in I18n translations.
|
16
|
-
# It is used by the module called {I18n::Backend::Inflector}
|
17
|
-
# that overwrites the Simple backend translate method
|
18
|
-
# so that it will interpolate additional inflection data present
|
19
|
-
# in translations. That data may appear in *patterns*
|
20
|
-
# contained within <tt>@{</tt> and <tt>}</tt> symbols. Each pattern
|
21
|
-
# consist of *tokens* and respective *values*.
|
22
|
-
#
|
23
|
-
# == Usage
|
24
|
-
# require 'i18-inflector'
|
25
|
-
#
|
26
|
-
# i18n.translate('welcome', :gender => :f)
|
27
|
-
# # => Dear Madam
|
28
|
-
#
|
29
|
-
# i18n.inflector.kinds
|
30
|
-
# # => [:gender]
|
31
|
-
#
|
32
|
-
# i18n.inflector.true_tokens.keys
|
33
|
-
# # => [:f, :m, :n]
|
34
|
-
#
|
35
|
-
# See the {file:EXAMPLES} for more information about real-life
|
36
|
-
# usage of Inflector.
|
37
|
-
#
|
38
|
-
# == Inflection pattern
|
39
|
-
# An example inflection pattern contained in a translation record looks like:
|
40
|
-
# welcome: "Dear @{f:Madam|m:Sir|n:You|All}"
|
41
|
-
#
|
42
|
-
# The +f+, +m+ and +n+ are inflection *tokens* and +Madam+, +Sir+, +You+ and
|
43
|
-
# +All+ are *values*. Only one value is going to replace the whole
|
44
|
-
# pattern. To select which one an additional option is used. That option
|
45
|
-
# must be passed to translate method.
|
46
|
-
#
|
47
|
-
# There are also so called <b>named patterns</b> that will be explained
|
48
|
-
# later.
|
49
|
-
#
|
50
|
-
# == Configuration
|
51
|
-
# To recognize tokens present in patterns keys grouped
|
52
|
-
# in the scope called +inflections+ for the given locale are used. For instance
|
53
|
-
# (YAML format):
|
54
|
-
# en:
|
55
|
-
# i18n:
|
56
|
-
# inflections:
|
57
|
-
# gender:
|
58
|
-
# f: "female"
|
59
|
-
# m: "male"
|
60
|
-
# n: "neuter"
|
61
|
-
# woman: @f
|
62
|
-
# man: @m
|
63
|
-
# default: n
|
64
|
-
#
|
65
|
-
# Elements in the example above are:
|
66
|
-
# * +en+: language
|
67
|
-
# * +i18n+: configuration scope
|
68
|
-
# * +inflections+: inflections configuration scope
|
69
|
-
# * +gender+: kind scope
|
70
|
-
# * +f+, +m+, +n+: inflection tokens
|
71
|
-
# * <tt>"male"</tt>, <tt>"female"</tt>, <tt>"neuter"</tt>: tokens' descriptions
|
72
|
-
# * +woman+, +man+: inflection aliases
|
73
|
-
# * <tt>@f</tt>, <tt>@m</tt>: pointers to real tokens
|
74
|
-
# * +default+: default token for a kind +gender+
|
75
|
-
#
|
76
|
-
# === Kind
|
77
|
-
# Note the fourth scope selector in the example above (+gender+). It's called
|
78
|
-
# the *kind* and contains *tokens*. We have the kind
|
79
|
-
# +gender+ to which the inflection tokens +f+, +m+ and +n+ are
|
80
|
-
# assigned.
|
81
|
-
#
|
82
|
-
# You cannot assign the same token to more than one kind.
|
83
|
-
# Trying to do that will raise DuplicatedInflectionToken exception.
|
84
|
-
# This is required in order to keep patterns simple and tokens interpolation
|
85
|
-
# fast.
|
86
|
-
#
|
87
|
-
# Kind is also used to instruct {I18n::Backend::Inflector#translate} method which
|
88
|
-
# token it should pick. This is done through options and
|
89
|
-
# will be explained later.
|
90
|
-
#
|
91
|
-
# There is also a class of kind called <b>strict kind</b> used by
|
92
|
-
# named patterns; that will be explained later.
|
93
|
-
#
|
94
|
-
# === Tokens
|
95
|
-
# The token is an element of a pattern. Any pattern may have many tokens
|
96
|
-
# of the same kind separated by vertical bars. Each token name used in a
|
97
|
-
# pattern should end with colon sign. After this colon a value should
|
98
|
-
# appear (or an empty string).
|
99
|
-
#
|
100
|
-
# Tokens also appear in a configuration data. They are assigned to kinds.
|
101
|
-
# Token names must be unique across all kinds, since it would be impossible
|
102
|
-
# for interpolation routine to guess a kind of a token present in a pattern.
|
103
|
-
# There is however a class of kinds called strict kinds, for which tokens
|
104
|
-
# must be unique only within a kind. The named patterns that are using
|
105
|
-
# strict kinds will be explained later.
|
106
|
-
#
|
107
|
-
# === Aliases
|
108
|
-
# Aliases are special tokens that point to other tokens. They cannot
|
109
|
-
# be used in inflection patterns but they are fully recognized options
|
110
|
-
# that can be passed to +translate+ method.
|
111
|
-
#
|
112
|
-
# Aliases might be helpful in multilingual applications that are using
|
113
|
-
# a fixed set of values passed through options to describe some properties
|
114
|
-
# of messages, e.g. +masculine+ and +feminine+ for a grammatical gender.
|
115
|
-
# Translators may then use their own tokens (like +f+ and +m+ for English)
|
116
|
-
# to produce pretty and intuitive patterns.
|
117
|
-
#
|
118
|
-
# For example: if some application uses database with gender assigned
|
119
|
-
# to a user which may be +male+, +female+ or +none+, then a translator
|
120
|
-
# for some language may find it useful to map impersonal token (<tt>none</tt>)
|
121
|
-
# to the +neuter+ token, since in translations for his language the
|
122
|
-
# neuter gender is in use.
|
123
|
-
#
|
124
|
-
# Here is the example of such situation:
|
125
|
-
#
|
126
|
-
# en:
|
127
|
-
# i18n:
|
128
|
-
# inflections:
|
129
|
-
# gender:
|
130
|
-
# male: "male"
|
131
|
-
# female: "female"
|
132
|
-
# none: "impersonal form"
|
133
|
-
# default: none
|
134
|
-
#
|
135
|
-
# pl:
|
136
|
-
# i18n:
|
137
|
-
# inflections:
|
138
|
-
# gender:
|
139
|
-
# k: "female"
|
140
|
-
# m: "male"
|
141
|
-
# n: "neuter"
|
142
|
-
# male: @k
|
143
|
-
# female: @m
|
144
|
-
# none: @n
|
145
|
-
# default: none
|
146
|
-
#
|
147
|
-
# In the case above Polish translator decided to use neuter
|
148
|
-
# instead of impersonal form when +none+ token will be passed
|
149
|
-
# through the option +:gender+ to the translate method. He
|
150
|
-
# also decided that he will use +k+, +m+ or +n+ in patterns,
|
151
|
-
# because the names are short and correspond to gender names in
|
152
|
-
# Polish language.
|
153
|
-
#
|
154
|
-
# Aliases may point to other aliases. While loading inflections they
|
155
|
-
# will be internally shortened and they will always point to real tokens,
|
156
|
-
# not other aliases.
|
157
|
-
#
|
158
|
-
# === Default token
|
159
|
-
# There is special token called the +default+, which points
|
160
|
-
# to a token that should be used if translation routine cannot deduce
|
161
|
-
# which one it should use because a proper option was not given.
|
162
|
-
#
|
163
|
-
# Default tokens may point to aliases and may use aliases' syntax, e.g.:
|
164
|
-
# default: @man
|
165
|
-
#
|
166
|
-
# === Descriptions
|
167
|
-
# The values of keys in the example (+female+, +male+ and +neuter+)
|
168
|
-
# are *descriptions* which are not used by interpolation routines
|
169
|
-
# but might be helpful (e.g. in UI). For obvious reasons you cannot
|
170
|
-
# describe aliases.
|
171
|
-
#
|
172
|
-
# == Interpolation
|
173
|
-
# The value of each token present in a pattern is to be picked by the interpolation
|
174
|
-
# routine and will replace the whole pattern, when the token name from that
|
175
|
-
# pattern matches the value of an option passed to {I18n.translate} method.
|
176
|
-
# This option is called <b>the inflection option</b>. Its name should be
|
177
|
-
# the same as a *kind* of tokens used within a pattern. The first token in a pattern
|
178
|
-
# determines the kind of all tokens used in that pattern. You can pass
|
179
|
-
# many inflection options, each one designated for keeping a token of a
|
180
|
-
# different kind.
|
181
|
-
#
|
182
|
-
# === Examples:
|
183
|
-
#
|
184
|
-
# ===== YAML:
|
185
|
-
# Let's assume that the translation data in YAML format listed
|
186
|
-
# below is used in any later example, unless other inflections
|
187
|
-
# are given.
|
188
|
-
# en:
|
189
|
-
# i18n:
|
190
|
-
# inflections:
|
191
|
-
# gender:
|
192
|
-
# m: "male"
|
193
|
-
# f: "female"
|
194
|
-
# n: "neuter"
|
195
|
-
# default: n
|
196
|
-
#
|
197
|
-
# welcome: "Dear @{f:Madam|m:Sir|n:You|All}"
|
198
|
-
# ===== Code:
|
199
|
-
# I18n.translate('welcome', :gender => :m)
|
200
|
-
# # => "Dear Sir"
|
201
|
-
#
|
202
|
-
# I18n.translate('welcome', :gender => :unknown)
|
203
|
-
# # => "Dear All"
|
204
|
-
#
|
205
|
-
# I18n.translate('welcome')
|
206
|
-
# # => "Dear You"
|
207
|
-
#
|
208
|
-
# In the second example the <b>fallback value</b> +All+ was interpolated
|
209
|
-
# because the routine had been unable to find the token called +:unknown+.
|
210
|
-
# That differs from the latest example, in which there was no option given,
|
211
|
-
# so the default token for a kind had been applied (in this case +n+).
|
212
|
-
#
|
213
|
-
# === Local fallbacks (free text)
|
214
|
-
# The fallback value will be used when any of the given tokens from
|
215
|
-
# pattern cannot be interpolated.
|
216
|
-
#
|
217
|
-
# Be aware that enabling extended error reporting makes it unable
|
218
|
-
# to use fallback values in most cases. Local fallbacks will then be
|
219
|
-
# applied only when the given option contains a proper value for some
|
220
|
-
# kind but it's just not present in a pattern, for example:
|
221
|
-
#
|
222
|
-
# ===== YAML:
|
223
|
-
# en:
|
224
|
-
# i18n:
|
225
|
-
# inflections:
|
226
|
-
# gender:
|
227
|
-
# n: 'neuter'
|
228
|
-
# o: 'other'
|
229
|
-
#
|
230
|
-
# welcome: "Dear @{n:You|All}"
|
231
|
-
#
|
232
|
-
# ===== Code:
|
233
|
-
# I18n.translate('welcome', :gender => :o, :inflector_raises => true)
|
234
|
-
# # => "Dear All"
|
235
|
-
# # since the token :o was configured but not used in the pattern
|
236
|
-
#
|
237
|
-
# === Unknown, malformed and empty tokens in options
|
238
|
-
# If an option containing token is not present at all then the interpolation
|
239
|
-
# routine will try the default token for a processed kind if the default
|
240
|
-
# token is present in a pattern. The same thing will happend if the option
|
241
|
-
# is present but its value is malformed, unknown, empty or +nil+.
|
242
|
-
# If the default token is not present in a pattern or is not defined in
|
243
|
-
# a configuration data then the processing of a pattern will result
|
244
|
-
# in an empty string or in a local fallback value if there is
|
245
|
-
# a free text placed in a pattern.
|
246
|
-
#
|
247
|
-
# You can change this default behavior and force inflector
|
248
|
-
# not to use a default token when a value of an option for
|
249
|
-
# a kind is malformed, unknown, empty or +nil+ but only when
|
250
|
-
# it's not present. To do that you should set option +:inflector_unknown_defaults+
|
251
|
-
# to +false+ and pass it to I18n.translate method. Other way is to set this
|
252
|
-
# switch globally using the {I18n::Inflector::InflectionOptions#unknown_defaults}.
|
253
|
-
#
|
254
|
-
# === Unmatched tokens in options
|
255
|
-
# It might happend that there is a default token present in a pattern
|
256
|
-
# but the inflection option causes other token to be picked up
|
257
|
-
# which however is not present in this pattern although it's
|
258
|
-
# correct and assigned to the currently processed kind. In such
|
259
|
-
# situation the free text or an empty string will be generated.
|
260
|
-
# You may change that behavior by passing +:inflector_excluded_defaults+
|
261
|
-
# option set to +true+ or by setting the global option called
|
262
|
-
# {I18n::Inflector::InflectionOptions#excluded_defaults}. If this
|
263
|
-
# option is set then any unmatched (excluded) but correct token
|
264
|
-
# given in an inflection option will cause the default token
|
265
|
-
# to be picked up (if present in a pattern of course).
|
266
|
-
#
|
267
|
-
# === Mixing inflection and standard interpolation patterns
|
268
|
-
# The Inflector module allows you to include standard <tt>%{}</tt>
|
269
|
-
# patterns inside of inflection patterns. The value of a standard
|
270
|
-
# interpolation variable will be evaluated and interpolated *before*
|
271
|
-
# processing an inflection pattern. For example:
|
272
|
-
#
|
273
|
-
# ===== YAML:
|
274
|
-
# Note: <em>Uses inflection configuration given in the first example.</em>
|
275
|
-
# en:
|
276
|
-
# hi: "Dear @{f:Lady|m:%{test}}!"
|
277
|
-
# ===== Code:
|
278
|
-
# I18n.t('hi', :gender => :m, :locale => :xx, :test => "Dude")
|
279
|
-
# # => Dear Dude!
|
280
|
-
#
|
281
|
-
# === Token groups
|
282
|
-
# It is possible to assign some value to more than one token.
|
283
|
-
# You can create group of tokens by separating them using commas.
|
284
|
-
# The comma has the meaning of logical OR in such a token group.
|
285
|
-
#
|
286
|
-
# ===== YAML:
|
287
|
-
# Note: <em>Uses inflection configuration given in the first example.</em>
|
288
|
-
# en:
|
289
|
-
# welcome: "Hello @{m,f:Ladies and Gentlemen|n:You}!"
|
290
|
-
# ===== Code:
|
291
|
-
# I18n.t('welcome', :gender => :f)
|
292
|
-
# # => Hello Ladies and Gentlemen!
|
293
|
-
#
|
294
|
-
# === Inverse matching of tokens
|
295
|
-
# You can place exclamation mark before a token that should be
|
296
|
-
# matched negatively. It's value will be used for a pattern
|
297
|
-
# <b>if the given inflection option contains other token</b>.
|
298
|
-
# You can use inversed matching tokens in token groups but
|
299
|
-
# note that using more than one inversed token separated
|
300
|
-
# by a comma will cause the expression to mach every time.
|
301
|
-
#
|
302
|
-
# ===== YAML:
|
303
|
-
# Note: <em>Uses inflection configuration given in the first example.</em>
|
304
|
-
# en:
|
305
|
-
# welcome: "Hello @{!m:Ladies|n:You}!"
|
306
|
-
#
|
307
|
-
# ===== Code:
|
308
|
-
# I18n.t('welcome', :gender => :n)
|
309
|
-
# # => Hello Ladies!
|
310
|
-
#
|
311
|
-
# I18n.t('welcome', :gender => :f)
|
312
|
-
# # => Hello Ladies!
|
313
|
-
#
|
314
|
-
# I18n.t('welcome', :gender => :m)
|
315
|
-
# # => Hello !
|
316
|
-
#
|
317
|
-
# === Loud tokens
|
318
|
-
# Sometimes there might be a need to use descriptions of
|
319
|
-
# matching tokens instead of some given values. Use <b>loud tokens</b>
|
320
|
-
# to achieve that. Any matching token in a pattern that has tilde symbol (+~+)
|
321
|
-
# set as its value will be replaced by its description. In case of
|
322
|
-
# undescribed aliases, the description from a target token will be used.
|
323
|
-
#
|
324
|
-
# ===== YAML:
|
325
|
-
# Note: <em>Uses inflection configuration given in the first example.</em>
|
326
|
-
# en:
|
327
|
-
# welcome: "Hello @{m:~|n:~}!"
|
328
|
-
#
|
329
|
-
# ===== Code:
|
330
|
-
# I18n.t('welcome', :gender => :n)
|
331
|
-
# # => Hello neuter!
|
332
|
-
#
|
333
|
-
# I18n.t('welcome', :gender => :f)
|
334
|
-
# # => Hello female!
|
335
|
-
#
|
336
|
-
# To use tilde symbol as the only value of a token you may esape it
|
337
|
-
# by putting a backslash in front of the symbol.
|
338
|
-
#
|
339
|
-
# === Aliases in a pattern
|
340
|
-
# Normally it is possible to use only true tokens in patterns, not aliases.
|
341
|
-
# However, if you feel lucky and you're not affraid of messy patterns
|
342
|
-
# you can use the switch {I18n::Inflector::InflectionOptions#aliased_patterns}
|
343
|
-
# or corresponding +:inflector_aliased_patterns+ option passed to translation
|
344
|
-
# method.
|
345
|
-
#
|
346
|
-
# It may seem very easy and attractive to use aliased patterns, especially
|
347
|
-
# in the environments where token comes from a user. In such cases aliases
|
348
|
-
# may be used as database that translates common words to inflection tokens
|
349
|
-
# that have meanings. For example user may enter a gender in some text
|
350
|
-
# field and it will be used as inflection token. To map different names
|
351
|
-
# (e.g. male, boy, sir, female, girl, lady) to exact inflection tokens
|
352
|
-
# the aliases would be used. Note hovewer, that you can make use of
|
353
|
-
# <tt>I18n.inflector.true_token</tt> method (see {I18n::Inflector::API#true_token}
|
354
|
-
# that will resolve any alias and then use that data to feed some inflection option
|
355
|
-
# (e.g. +:gender+). In such scenario you don't have to rely on aliases
|
356
|
-
# in patterns and you will gain some speed since resolving will occur just once,
|
357
|
-
# not each time translated text is interpolated.
|
358
|
-
#
|
359
|
-
# === Escaping a pattern
|
360
|
-
# If there is a need to translate something that matches an inflection
|
361
|
-
# pattern the escape symbols can be used to disable the interpolation. These
|
362
|
-
# symbols are <tt>\\</tt> and +@+ and they should be placed just before
|
363
|
-
# a pattern that should be left untouched. For instance:
|
364
|
-
#
|
365
|
-
# ===== YAML:
|
366
|
-
# Note: <em>Uses inflection configuration given in the first example.</em>
|
367
|
-
# en:
|
368
|
-
# welcome: "This is the @@{pattern}!"
|
369
|
-
# ===== Code:
|
370
|
-
# I18n.t('welcome', :gender => :m, :locale => :xx)
|
371
|
-
# # => This is the @{pattern}!
|
372
|
-
#
|
373
|
-
# == Named patterns
|
374
|
-
#
|
375
|
-
# A named pattern is a pattern that contains name of a kind
|
376
|
-
# that tokens from a pattern are assigned to. It looks like:
|
377
|
-
#
|
378
|
-
# welcome: "Dear @gender{f:Madam|m:Sir|n:You|All}"
|
379
|
-
#
|
380
|
-
# === Configuring named patterns
|
381
|
-
# To recognize tokens present in named patterns,
|
382
|
-
# inflector uses keys grouped in the scope called +inflections+
|
383
|
-
# for the given locale. For instance (YAML format):
|
384
|
-
# en:
|
385
|
-
# i18n:
|
386
|
-
# inflections:
|
387
|
-
# @gender:
|
388
|
-
# f: "female"
|
389
|
-
# woman: @f
|
390
|
-
# default: f
|
391
|
-
#
|
392
|
-
# Elements in the example above are:
|
393
|
-
# * +en+: language
|
394
|
-
# * +i18n+: configuration scope
|
395
|
-
# * +inflections+: inflections configuration scope
|
396
|
-
# * +gender+: <bb>strict kind</bb> scope
|
397
|
-
# * +f+: inflection token
|
398
|
-
# * <tt>"female"</tt>: token's description
|
399
|
-
# * +woman+: inflection alias
|
400
|
-
# * <tt>@f</tt>: pointer to real token
|
401
|
-
# * +default+: default token for a strict kind +gender+
|
402
|
-
#
|
403
|
-
# === Strict kinds
|
404
|
-
#
|
405
|
-
# In order to handle named patterns properly a new data structure
|
406
|
-
# is used. It is called the <b>strict kind</b>. Strict kinds are defined
|
407
|
-
# in a configuration in a similar way the regular kinds are but
|
408
|
-
# tokens assigned to them may have the same names across a whole
|
409
|
-
# configuration. (Note that tokens of the same strict kind should still
|
410
|
-
# be unique.) That implies a requirement of passing the
|
411
|
-
# identifier of a kind when referring to such tokens.
|
412
|
-
#
|
413
|
-
# Here is the example configuration using strict kinds:
|
414
|
-
#
|
415
|
-
# en:
|
416
|
-
# i18n:
|
417
|
-
# inflections:
|
418
|
-
# @gender:
|
419
|
-
# f: "female"
|
420
|
-
# m: "male"
|
421
|
-
# n: "neuter"
|
422
|
-
# woman: @f
|
423
|
-
# man: @m
|
424
|
-
# default: n
|
425
|
-
# @title:
|
426
|
-
# s: "sir"
|
427
|
-
# l: "lady"
|
428
|
-
# u: "you"
|
429
|
-
# m: @s
|
430
|
-
# f: @l
|
431
|
-
# default: u
|
432
|
-
#
|
433
|
-
# The only thing that syntactically distinguishes strict kinds
|
434
|
-
# from regular kinds is a presence of the +@+ symbol.
|
435
|
-
#
|
436
|
-
# You can mix regular and strict kinds having the same names.
|
437
|
-
# The proper class of kind will be picked up by interpolation
|
438
|
-
# method easily, since the first mentioned class uses
|
439
|
-
# patterns that are not named, and the second uses named patterns.
|
440
|
-
#
|
441
|
-
# ==== Strict kinds in options
|
442
|
-
#
|
443
|
-
# The interpolation routine recognizes strict kinds passed as
|
444
|
-
# options in almost the same way that it does it for regular
|
445
|
-
# kinds. The only difference is that you can override usage
|
446
|
-
# of a regular kind inflection option (if there is any) by
|
447
|
-
# putting a strict kind option with name prefixed by +@+ symbol.
|
448
|
-
# The inflection options starting with this symbol have
|
449
|
-
# precedence over inflection options without it;
|
450
|
-
# that is of course only true for strict kinds and has any effect
|
451
|
-
# only when both options describing the same kind are present.
|
452
|
-
#
|
453
|
-
# In other words: interpolation routine is looking for
|
454
|
-
# strict kinds in inflection options using their names
|
455
|
-
# with +@+ in front. When that fails it falls back to
|
456
|
-
# trying an option named like the strict kind but without
|
457
|
-
# the +@+ symbol. Examples:
|
458
|
-
#
|
459
|
-
# I18n.translate(welcome, :gender => :m, :@gender => :f)
|
460
|
-
# # the :f will be picked for the strict kind gender
|
461
|
-
#
|
462
|
-
# I18n.translate(welcome, :@gender => :f)
|
463
|
-
# # the :f will be picked for the strict kind gender
|
464
|
-
#
|
465
|
-
# I18n.translate(welcome, :gender => :f)
|
466
|
-
# # the :f will be picked for the strict kind gender
|
467
|
-
#
|
468
|
-
# In the example above we assume that +welcome+ is defined
|
469
|
-
# like that:
|
470
|
-
#
|
471
|
-
# welcome: "Dear @gender{f:Madam|m:Sir|n:You|All}"
|
472
|
-
#
|
473
|
-
# Note that for regular kinds the option named +:@gender+
|
474
|
-
# will have no meaning.
|
475
|
-
#
|
476
|
-
# ==== Note for developers
|
477
|
-
#
|
478
|
-
# Strict kinds that are used to handle named patterns
|
479
|
-
# are internally stored in a different database and handled by
|
480
|
-
# similar but different API methods than regular kinds. However
|
481
|
-
# most of the {I18n::Inflector::API} methods are also aware of strict kinds
|
482
|
-
# and will call proper methods oprating on strict inflections
|
483
|
-
# data when the +@+ symbol is detected at the beginning of
|
484
|
-
# the identifier of a kind passed as an argument. For example:
|
485
|
-
#
|
486
|
-
# I18n.inflector.has_token?(:m, :@gender)
|
487
|
-
#
|
488
|
-
# will effectively call:
|
489
|
-
#
|
490
|
-
# I18n.inflector.strict.has_token?(:m, :gender)
|
491
|
-
#
|
492
|
-
# As you can see above, to access {API_Strict} methods for strict kinds
|
493
|
-
# (and strict kinds data) only, associated with default I18n backend,
|
494
|
-
# use:
|
495
|
-
#
|
496
|
-
# I18n.inflector.strict
|
497
|
-
#
|
498
|
-
# == Multiple patterns
|
499
|
-
# You can make use of some syntactic sugar when having more than
|
500
|
-
# one pattern (regular or named) in your string. To not repeat
|
501
|
-
# a kind identifier(s) you may join pattern contents as in the
|
502
|
-
# following example:
|
503
|
-
#
|
504
|
-
# welcome: "You are @gender{f:pretty|m,n:handsome}{ }{f:lady|m:sir|n:human}"
|
505
|
-
#
|
506
|
-
# As you can see there should be no spaces or any other characters
|
507
|
-
# between successive patterns. That's why in this example an
|
508
|
-
# empty pattern's content is used. This is in fact a pattern
|
509
|
-
# containing no tokens but just a free text consisting
|
510
|
-
# of single space character.
|
511
|
-
#
|
512
|
-
# == Complex patterns
|
513
|
-
# A <bb>complex pattern</bb> is a named pattern that uses more than
|
514
|
-
# one inflection kind and sets of a respective tokens. The given identifiers
|
515
|
-
# of kinds should be separated by the plus sign and instead of single
|
516
|
-
# tokens there should be token sets (a tokens separated by the plus
|
517
|
-
# sign too).
|
518
|
-
#
|
519
|
-
# Example:
|
520
|
-
#
|
521
|
-
# welcome: "Dear @gender+number{f+s:Lady|f+p:Ladies|m+s:Sir|m+p:Gentlemen|All}"
|
522
|
-
#
|
523
|
-
# In the example above the complex pattern uses +gender+ and +number+
|
524
|
-
# inflection kinds and a token set (e.g. <tt>f+s</tt>) matches when
|
525
|
-
# both tokens match interpolation options (e.g. <tt>:gender => :f</tt>,
|
526
|
-
# <tt>:number => :s</tt>). The order of tokens in sets has meaning
|
527
|
-
# and should reflect the order of declared kinds.
|
528
|
-
#
|
529
|
-
# Note, that the count of tokens in each set should reflect the count
|
530
|
-
# of kinds that are used. Otherwise the interpolation routine will
|
531
|
-
# interpolate a free text (if given) or an empty string. If the switch
|
532
|
-
# {InflectionOptions#raises} is on then the {I18n::ComplexPatternMalformed}
|
533
|
-
# exception will be raised.
|
534
|
-
#
|
535
|
-
# The inflection tokens used in sets may make use of any features mentioned
|
536
|
-
# before (defaults, excluded defaults, negative matching, token groups,
|
537
|
-
# aliases, aliased patterns, loud tokens).
|
538
|
-
#
|
539
|
-
# === Loud tokens in complex patterns
|
540
|
-
#
|
541
|
-
# In case of loud tokens (having values taken from their
|
542
|
-
# descriptions), the complex pattern will be replaced by
|
543
|
-
# the descriptions of matching tokens joined with a single space
|
544
|
-
# character. So, for instance, when the translation data looks like:
|
545
|
-
#
|
546
|
-
# i18n:
|
547
|
-
# inflections:
|
548
|
-
# @person:
|
549
|
-
# i: 'I'
|
550
|
-
# u: 'You'
|
551
|
-
# @tense:
|
552
|
-
# now: 'am'
|
553
|
-
# past: 'were'
|
554
|
-
# welcome: "@person+tense{i+now:~|u+past:~}"
|
555
|
-
#
|
556
|
-
# the translate method will give the following results:
|
557
|
-
#
|
558
|
-
# I18n.translate('welcome', :person => :i, :tense => :now)
|
559
|
-
# # => "I am"
|
560
|
-
#
|
561
|
-
# I18n.translate('welcome', :person => :you, :tense => :past)
|
562
|
-
# # => "You were"
|
563
|
-
#
|
564
|
-
# This example is abstract, since the combination of +:i+
|
565
|
-
# and +:past+ will result in <tt>i were</tt> string, which is
|
566
|
-
# probably something unexpected. To achieve that kind of logic
|
567
|
-
# simply use combined patterns with the given values instead
|
568
|
-
# of loud tokens.
|
569
|
-
#
|
570
|
-
# == Inflection keys
|
571
|
-
# There is a way of storing inflected strings in keys instead
|
572
|
-
# of patterns. To use it you should simply assign subkeys to
|
573
|
-
# some translation key instead of string containing a pattern.
|
574
|
-
# The key-based inflection group is contained within a key
|
575
|
-
# which name begins with the +@+ symbol.
|
576
|
-
#
|
577
|
-
# The translation key containing a pattern:
|
578
|
-
#
|
579
|
-
# welcome: "Dear @{f:Lady|m:Sir|n:You|All}!"
|
580
|
-
#
|
581
|
-
# Can be easily written as:
|
582
|
-
#
|
583
|
-
# @welcome:
|
584
|
-
# f: "Lady"
|
585
|
-
# m: "Sir"
|
586
|
-
# n: "You"
|
587
|
-
# @free: "All"
|
588
|
-
# @prefix: "Dear "
|
589
|
-
# @suffix: "!"
|
590
|
-
#
|
591
|
-
# You can also use strict kind or even the inflection sets, token
|
592
|
-
# groups, etc.:
|
593
|
-
#
|
594
|
-
# welcome: "@gender+tense{f+past:She was|m+present:He is|n+future:You will be}"
|
595
|
-
#
|
596
|
-
# Can be written as:
|
597
|
-
#
|
598
|
-
# @welcome:
|
599
|
-
# f+past: "She was"
|
600
|
-
# m+present: "He is"
|
601
|
-
# n+future: "You will be"
|
602
|
-
# @kind: "gender+tense"
|
603
|
-
#
|
604
|
-
# There are special, optional subkeys that may give you
|
605
|
-
# more control over inflection process. These are:
|
606
|
-
#
|
607
|
-
# * +@kind+: a kind or kinds in case of strict kinds
|
608
|
-
# * +@prefix+: a prefix to be put before the interpolated data
|
609
|
-
# * +@suffix+: a suffix to be put after the interpolated data
|
610
|
-
# * +@free+: a free text that is to be used when no token will match
|
611
|
-
#
|
612
|
-
# === Limitations
|
613
|
-
#
|
614
|
-
# Inflection keys look compact and clean but obviously
|
615
|
-
# you cannot use the key-based inflection to simply replace
|
616
|
-
# a string containing more than one inflection pattern.
|
617
|
-
#
|
618
|
-
# Also, <b>you have to be very careful when using this method
|
619
|
-
# with Ruby 1.8</b> because the order of processed token sets
|
620
|
-
# may change. That may break the logic in case of inflection
|
621
|
-
# sets where order has meaning (e.g. tokens with inverted
|
622
|
-
# matching).
|
623
|
-
#
|
624
|
-
# == Errors
|
625
|
-
# By default the module will silently ignore non-critical interpolation
|
626
|
-
# errors. You can turn off this default behavior by passing +:inflector_raises+
|
627
|
-
# option set to +true+. Note that most errors is reported because of
|
628
|
-
# wrong data in patterns or in configuration. In case of inflection
|
629
|
-
# options only malformed, empty or +nil+ values are reported
|
630
|
-
# when the mentioned switch is turned on. For inflection options
|
631
|
-
# containing unknown tokens no errors are generated.
|
632
|
-
#
|
633
|
-
# === Usage of +:inflector_raises+ option
|
634
|
-
#
|
635
|
-
# ===== YAML
|
636
|
-
# Note: <em>Uses inflection configuration given in the first example.</em>
|
637
|
-
# en:
|
638
|
-
# welcome: "Dear @{m:Sir|f:Madam|Fallback}"
|
639
|
-
# ===== Code:
|
640
|
-
# I18n.t('welcome', :inflector_raises => true)
|
641
|
-
# # => I18n::InflectionOptionNotFound: en.welcome:
|
642
|
-
# # @{m:Sir|f:Madam|Fallback}" - required option :gender was not found
|
643
|
-
#
|
644
|
-
# === Exception meanings
|
645
|
-
# Here are the exceptions that may be raised when the option +:inflector_raises+
|
646
|
-
# is set to +true+:
|
647
|
-
#
|
648
|
-
# * {I18n::InvalidInflectionToken I18n::InvalidInflectionToken}
|
649
|
-
# * {I18n::InvalidInflectionKind I18n::InvalidInflectionKind}
|
650
|
-
# * {I18n::InvalidInflectionOption I18n::InvalidInflectionOption}
|
651
|
-
# * {I18n::MisplacedInflectionToken I18n::MisplacedInflectionToken}
|
652
|
-
# * {I18n::InflectionOptionNotFound I18n::InflectionOptionNotFound}
|
653
|
-
# * {I18n::InflectionOptionIncorrect I18n::InflectionOptionIncorrect}
|
654
|
-
# * {I18n::ComplexPatternMalformed I18n::ComplexPatternMalformed}
|
655
|
-
#
|
656
|
-
# There are also exceptions that are raised regardless of :+inflector_raises+
|
657
|
-
# presence or value.
|
658
|
-
# These are usually caused by critical errors encountered during processing
|
659
|
-
# inflection data or exceptions raised by I18n. Note that the pure I18n's
|
660
|
-
# exceptions are not described here.
|
661
|
-
#
|
662
|
-
# * {I18n::ArgumentError I18n::ArgumentError}
|
663
|
-
# * {I18n::InvalidLocale I18n::InvalidLocale}
|
664
|
-
# * {I18n::DuplicatedInflectionToken I18n::DuplicatedInflectionToken}
|
665
|
-
# * {I18n::BadInflectionKind I18n::BadInflectionKind}
|
666
|
-
# * {I18n::BadInflectionToken I18n::BadInflectionToken}
|
667
|
-
# * {I18n::BadInflectionAlias I18n::BadInflectionAlias}
|
668
|
-
#
|
669
|
-
# === Exception hierarchy
|
670
|
-
# I18n::ArgumentError
|
671
|
-
# |
|
672
|
-
# `-- I18n::InvalidLocale
|
673
|
-
# |
|
674
|
-
# `-- I18n::InflectionException
|
675
|
-
# |
|
676
|
-
# `-- I18n::InflectionPatternException
|
677
|
-
# | |
|
678
|
-
# | |-- I18n::InvalidInflectionToken
|
679
|
-
# | |-- I18n::InvalidInflectionKind
|
680
|
-
# | |-- I18n::MisplacedInflectionToken
|
681
|
-
# | |-- I18n::ComplexPatternMalformed
|
682
|
-
# | `-- I18n::InvalidOptionForKind
|
683
|
-
# | |-- I18n::InflectionOptionNotFound
|
684
|
-
# | `-- I18n::InflectionOptionIncorrect
|
685
|
-
# |
|
686
|
-
# `-- I18n::InflectionConfigurationException
|
687
|
-
# |
|
688
|
-
# |-- I18n::DuplicatedInflectionToken
|
689
|
-
# |-- I18n::BadInflectionAlias
|
690
|
-
# |-- I18n::BadInflectionToken
|
691
|
-
# `-- I18n::BadInflectionKind
|
692
|
-
#
|
693
|
-
# == Reserved names and characters
|
694
|
-
# Some strings cannot be used as names and/or identifiers of
|
695
|
-
# kinds and tokens. There are also some reserved characters
|
696
|
-
# that cannot be used within them.
|
697
|
-
#
|
698
|
-
# === Reserved keys
|
699
|
-
# Reserved keys, that cannot be used as names of inflection
|
700
|
-
# options and as names of kinds in the configuration
|
701
|
-
# are available after issuing:
|
702
|
-
#
|
703
|
-
# puts I18n.inflector.config::Reserved::KEYS.to_a
|
704
|
-
#
|
705
|
-
# Here is the current list: <tt>:scope, :default, :separator,
|
706
|
-
# :resolve, :object, :fallback, :format, :cascade,
|
707
|
-
# :raise, :rescue_format, :inflector_cache_aware,
|
708
|
-
# :inflector_raises, :inflector_aliased_patterns,
|
709
|
-
# :inflector_unknown_defaults, :inflector_excluded_defaults</tt>.
|
710
|
-
#
|
711
|
-
# Additionally all Symbols or Strings beginning with
|
712
|
-
# +inflector_+ are prohibited, since they are reserved as
|
713
|
-
# controlling options.
|
714
|
-
#
|
715
|
-
# === Reserved characters
|
716
|
-
# All characters that have special meaning (operators and
|
717
|
-
# markers) are not allowed in patterns, in configuration
|
718
|
-
# and in options.
|
719
|
-
#
|
720
|
-
# ==== Reserved characters in kinds
|
721
|
-
# ===== Passed as inflection options
|
722
|
-
# ====== Code
|
723
|
-
# puts I18n.inflector.config::Reserved::Kinds::OPTION
|
724
|
-
# ====== List
|
725
|
-
# <tt>+ | : ! { }</tt> and <tt>,</tt> (comma).
|
726
|
-
#
|
727
|
-
# ===== Given in a configuration
|
728
|
-
# ====== Code
|
729
|
-
# puts I18n.inflector.config::Reserved::Kinds::DB
|
730
|
-
# ====== List
|
731
|
-
# <tt>+ | : ! { }</tt> and <tt>,</tt> (comma).
|
732
|
-
#
|
733
|
-
# ===== Placed in patterns
|
734
|
-
# ====== Code
|
735
|
-
# puts I18n.inflector.config::Reserved::Kinds::PATTERN
|
736
|
-
# ====== List
|
737
|
-
# <tt>+ | : , ! @ { }</tt> and <tt>,</tt> (comma).
|
738
|
-
#
|
739
|
-
# ==== Reserved characters in tokens
|
740
|
-
# ===== Passed as values of inflection options
|
741
|
-
# ====== Code
|
742
|
-
# puts I18n.inflector.config::Reserved::Tokens::OPTION
|
743
|
-
# ====== List
|
744
|
-
# <tt>+ | : ! @ { }</tt> and <tt>,</tt> (comma).
|
745
|
-
#
|
746
|
-
# ===== Given in a configuration
|
747
|
-
# ====== Code
|
748
|
-
# puts I18n.inflector.config::Reserved::Tokens::DB
|
749
|
-
# ====== List
|
750
|
-
# <tt>+ | : ! @ { }</tt> and <tt>,</tt> (comma).
|
751
|
-
#
|
752
|
-
# ===== Placed in patterns
|
753
|
-
# ====== Code
|
754
|
-
# puts I18n.inflector.config::Reserved::Tokens::PATTERN
|
755
|
-
# ====== List
|
756
|
-
# <tt>+ | : ! @ { }</tt> and <tt>,</tt> (comma).
|
757
|
-
#
|
758
|
-
# == Operators and markers
|
759
|
-
# Here is more formal definition of operators and markers used in patterns.
|
760
|
-
#
|
761
|
-
# === Pattern
|
762
|
-
# @[kind][+kind ...]{token_set[|token_set ...][|free_text]}
|
763
|
-
#
|
764
|
-
# * +@+ is the pattern marker
|
765
|
-
# * +{+ and +}+ are pattern delimiters
|
766
|
-
# * +free_text+ is an optional free text value
|
767
|
-
# * +kind+ is a kind identifier
|
768
|
-
# * <tt>+</tt> is the +AND+ operator that joins kinds (produces complex kinds)
|
769
|
-
# ==== +token_set+
|
770
|
-
# token_group[+token_group ...]:value
|
771
|
-
#
|
772
|
-
# * +:+ is the +ASSIGNMENT+ operator
|
773
|
-
# * +value+ is a value to be picked up then a token set matches; value may also
|
774
|
-
# be the loud marker (+~+)
|
775
|
-
# * <tt>+</tt> is the +AND+ operator that joins many token groups into a set
|
776
|
-
# ===== +token_group+
|
777
|
-
# [!]token[,[!]token ...]
|
778
|
-
#
|
779
|
-
# * +token+ is a token identifier
|
780
|
-
# * +!+ is the +NOT+ operator
|
781
|
-
# * +,+ is the +OR+ operator
|
782
|
-
#
|
783
|
-
# === Operator precedence
|
784
|
-
# * +NOT+ operators for inversed matching of tokens (<tt>!</tt>)
|
785
|
-
# * +OR+ operators for joining tokens into token groups (<tt>,</tt>)
|
786
|
-
# * +AND+ operators for joining token groups into sets (<tt>+</tt>)
|
787
|
-
# * +ASSIGNMENT+ operator for assigning values to token sets (<tt>:</tt>)
|
788
|
-
# * +OR+ operators for token sets or for free texts (<tt>|</tt>)
|
789
|
-
# * +AND+ operators for kind identifiers (<tt>+</tt>)
|
790
|
-
# * Pattern marker and pattern delimiters
|
791
13
|
module Inflector
|
792
14
|
|
793
15
|
class API
|
@@ -821,9 +43,7 @@ module I18n
|
|
821
43
|
# Gets known inflection kinds for the given +locale+.
|
822
44
|
# @param [Symbol] locale the locale for which operation has to be done
|
823
45
|
# @return [Array<Symbol>] the array containing known inflection kinds
|
824
|
-
def kinds(locale=nil)
|
825
|
-
super
|
826
|
-
end
|
46
|
+
def kinds(locale=nil); super end
|
827
47
|
alias_method :inflection_kinds, :kinds
|
828
48
|
|
829
49
|
end
|