i18n-inflector 2.1.0 → 2.2.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.
@@ -10,14 +10,15 @@
10
10
  #
11
11
 
12
12
  module I18n
13
- # @version 2.1
13
+ # @version 2.2
14
14
  # This module contains inflection classes and modules for enabling
15
15
  # the inflection support in I18n translations.
16
16
  # It is used by the module called {I18n::Backend::Inflector}
17
17
  # that overwrites the Simple backend translate method
18
- # so that it will interpolate additional inflection tokens present
19
- # in translations. These tokens may appear in *patterns* which
20
- # are contained within <tt>@{</tt> and <tt>}</tt> symbols.
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*.
21
22
  #
22
23
  # == Usage
23
24
  # require 'i18-inflector'
@@ -168,133 +169,6 @@ module I18n
168
169
  # but might be helpful (e.g. in UI). For obvious reasons you cannot
169
170
  # describe aliases.
170
171
  #
171
- # == Named patterns
172
- #
173
- # A named pattern is a pattern that may contain special clause
174
- # containing name of a kind that tokens from a pattern
175
- # are assigned to. It looks like:
176
- #
177
- # welcome: "Dear @gender{f:Madam|m:Sir|n:You|All}"
178
- #
179
- # === Configuring named patterns
180
- #
181
- # To recognize tokens present in a named patterns,
182
- # inflector uses keys grouped in the scope called +inflections+
183
- # for the given locale. For instance (YAML format):
184
- # en:
185
- # i18n:
186
- # inflections:
187
- # @gender:
188
- # f: "female"
189
- # woman: @f
190
- # default: f
191
- #
192
- # Elements in the example above are:
193
- # * +en+: language
194
- # * +i18n+: configuration scope
195
- # * +inflections+: inflections configuration scope
196
- # * +gender+: <bb>strict kind</bb> scope
197
- # * +f+: inflection token
198
- # * <tt>"female"</tt>: token's description
199
- # * +woman+: inflection alias
200
- # * <tt>@f</tt>: pointer to real token
201
- # * +default+: default token for a strict kind +gender+
202
- #
203
- # === Strict kinds
204
- #
205
- # In order to handle named patterns properly a new data structure
206
- # is used. It is called the <b>strict kind</b>. Strict kinds are defined
207
- # in a configuration in a similar way the regular kinds are but
208
- # tokens assigned to them may have the same names across a whole
209
- # configuration. (Note that within a strict kind tokens should still
210
- # be unique.) That implies a requirement of passing the
211
- # identifier of a kind when referring to such tokens.
212
- #
213
- # Here is the example configuration using strict kinds:
214
- #
215
- # en:
216
- # i18n:
217
- # inflections:
218
- # @gender:
219
- # f: "female"
220
- # m: "male"
221
- # n: "neuter"
222
- # woman: @f
223
- # man: @m
224
- # default: n
225
- # @title:
226
- # s: "sir"
227
- # l: "lady"
228
- # u: "you"
229
- # m: @s
230
- # f: @l
231
- # default: u
232
- #
233
- # The only thing that syntactically distinguishes named kinds
234
- # from regular kinds is a presence of the +@+ symbol.
235
- #
236
- # You can mix regular and strict kinds having the same names.
237
- # The proper class of kind will be picked up by interpolation
238
- # method easily, since the first mentioned class uses
239
- # patterns that are not named, and the second uses named patterns.
240
- #
241
- # ==== Strict kinds in options
242
- #
243
- # The interpolation routine recognizes strict kinds passed as
244
- # options in almost the same way that it does it for regular
245
- # kinds. The only difference is that you can override usage
246
- # of a regular kind inflection option (if there is any) by
247
- # putting a strict kind option with name prefixed by +@+ symbol.
248
- # The inflection options starting with this symbol have
249
- # precedence over inflection options without it;
250
- # that is of course only true for strict kinds and has any effect
251
- # only when both options describing the same kind are present.
252
- #
253
- # In other words: interpolation routine is looking for
254
- # strict kinds in inflection options using their names
255
- # with +@+ in front. When that fails it falls back to
256
- # trying an option named like the strict kind but without
257
- # the +@+ symbol. Examples:
258
- #
259
- # I18n.translate(welcome, :gender => :m, :@gender => :f)
260
- # # the :f will be picked for the strict kind gender
261
- #
262
- # I18n.translate(welcome, :@gender => :f)
263
- # # the :f will be picked for the strict kind gender
264
- #
265
- # I18n.translate(welcome, :gender => :f)
266
- # # the :f will be picked for the strict kind gender
267
- #
268
- # In the example above we assume that +welcome+ is defined
269
- # like that:
270
- #
271
- # welcome: "Dear @gender{f:Madam|m:Sir|n:You|All}"
272
- #
273
- # Note that for regular kinds the option named <tt>:@gender</tt>
274
- # will have no meaning.
275
- #
276
- # ==== Note for developers
277
- #
278
- # Strict kinds that are used to handle named patterns
279
- # are internally stored in a different database and handled by
280
- # similar but different API methods than regular kinds. However
281
- # most of the {I18n::Inflector::API} methods are also aware of strict kinds
282
- # and will call proper methods oprating on strict inflections
283
- # data when the +@+ symbol is detected at the beginning of
284
- # the identifier of a kind passed as an argument. For example:
285
- #
286
- # I18n.inflector.has_token?(:m, :@gender)
287
- #
288
- # will effectively call:
289
- #
290
- # I18n.inflector.strict.has_token?(:m, :gender)
291
- #
292
- # As you can see above, to access {API_Strict} methods for strict kinds
293
- # (and strict kinds data) only, associated with default I18n backend,
294
- # use:
295
- #
296
- # I18n.inflector.strict
297
- #
298
172
  # == Interpolation
299
173
  # The value of each token present in a pattern is to be picked by the interpolation
300
174
  # routine and will replace the whole pattern, when the token name from that
@@ -356,28 +230,39 @@ module I18n
356
230
  # welcome: "Dear @{n:You|All}"
357
231
  #
358
232
  # ===== Code:
359
- # I18n.translate('welcome', :gender => :o, :raises => true)
233
+ # I18n.translate('welcome', :gender => :o, :inflector_raises => true)
360
234
  # # => "Dear All"
361
235
  # # since the token :o was configured but not used in the pattern
362
236
  #
363
- # === Unknown and empty tokens in options
237
+ # === Unknown, malformed and empty tokens in options
364
238
  # If an option containing token is not present at all then the interpolation
365
239
  # routine will try the default token for a processed kind if the default
366
240
  # token is present in a pattern. The same thing will happend if the option
367
- # is present but its value is unknown, empty or +nil+.
241
+ # is present but its value is malformed, unknown, empty or +nil+.
368
242
  # If the default token is not present in a pattern or is not defined in
369
- # a configuration data then the processed pattern will result in an empty
370
- # string or in a local fallback value if there is a free text placed
371
- # in a pattern.
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.
372
246
  #
373
247
  # You can change this default behavior and force inflector
374
- # not to use a default token when a value of an option for a kind is unknown,
375
- # empty or +nil+ but only when it's not present.
376
- # To do that you should set option +:unknown_defaults+ to
377
- # +false+ and pass it to I18n.translate method. Other way is to set this
378
- # globally by using the method called unknown_defaults.
379
- # See #unknown_defaults for examples showing how the
380
- # translation results are changing when that switch is applied.
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).
381
266
  #
382
267
  # === Mixing inflection and standard interpolation patterns
383
268
  # The Inflector module allows you to include standard <tt>%{}</tt>
@@ -418,6 +303,7 @@ module I18n
418
303
  # Note: <em>Uses inflection configuration given in the first example.</em>
419
304
  # en:
420
305
  # welcome: "Hello @{!m:Ladies|n:You}!"
306
+ #
421
307
  # ===== Code:
422
308
  # I18n.t('welcome', :gender => :n)
423
309
  # # => Hello Ladies!
@@ -428,11 +314,33 @@ module I18n
428
314
  # I18n.t('welcome', :gender => :m)
429
315
  # # => Hello !
430
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
+ #
431
339
  # === Aliases in a pattern
432
- # Normally it possible to use only true tokens in patterns, not aliases.
340
+ # Normally it is possible to use only true tokens in patterns, not aliases.
433
341
  # However, if you feel lucky and you're not affraid of messy patterns
434
342
  # you can use the switch {I18n::Inflector::InflectionOptions#aliased_patterns}
435
- # or corresponding <tt>:inflector_aliased_patterns</tt> option passed to translation
343
+ # or corresponding +:inflector_aliased_patterns+ option passed to translation
436
344
  # method.
437
345
  #
438
346
  # It may seem very easy and attractive to use aliased patterns, especially
@@ -444,7 +352,7 @@ module I18n
444
352
  # the aliases would be used. Note hovewer, that you can make use of
445
353
  # <tt>I18n.inflector.true_token</tt> method (see {I18n::Inflector::API#true_token}
446
354
  # that will resolve any alias and then use that data to feed some inflection option
447
- # (e.g. <tt>:gender</tt>). In such scenario you don't have to rely on aliases
355
+ # (e.g. +:gender+). In such scenario you don't have to rely on aliases
448
356
  # in patterns and you will gain some speed since resolving will occur just once,
449
357
  # not each time translated text is interpolated.
450
358
  #
@@ -462,37 +370,424 @@ module I18n
462
370
  # I18n.t('welcome', :gender => :m, :locale => :xx)
463
371
  # # => This is the @{pattern}!
464
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
+ #
465
624
  # == Errors
466
- # By default the module will silently ignore any interpolation errors.
467
- # You can turn off this default behavior by passing +:raises+ option.
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.
468
632
  #
469
- # === Usage of +:raises+ option
633
+ # === Usage of +:inflector_raises+ option
470
634
  #
471
635
  # ===== YAML
472
636
  # Note: <em>Uses inflection configuration given in the first example.</em>
473
637
  # en:
474
638
  # welcome: "Dear @{m:Sir|f:Madam|Fallback}"
475
639
  # ===== Code:
476
- # I18n.t('welcome', :raises => true)
477
- # # => I18n::InvalidOptionForKind: option :gender required by the pattern
478
- # # "@{m:Sir|f:Madam|Fallback}" was not found
640
+ # I18n.t('welcome', :inflector_raises => true)
641
+ # # => I18n::InflectionOptionNotFound: en.welcome:
642
+ # # @{m:Sir|f:Madam|Fallback}" - required option :gender was not found
479
643
  #
480
- # Here are the exceptions that may be raised when option +:raises+
644
+ # === Exception meanings
645
+ # Here are the exceptions that may be raised when the option +:inflector_raises+
481
646
  # is set to +true+:
482
647
  #
483
- # * {I18n::InvalidOptionForKind I18n::InvalidOptionForKind}
484
648
  # * {I18n::InvalidInflectionToken I18n::InvalidInflectionToken}
649
+ # * {I18n::InvalidInflectionKind I18n::InvalidInflectionKind}
650
+ # * {I18n::InvalidInflectionOption I18n::InvalidInflectionOption}
485
651
  # * {I18n::MisplacedInflectionToken I18n::MisplacedInflectionToken}
652
+ # * {I18n::InflectionOptionNotFound I18n::InflectionOptionNotFound}
653
+ # * {I18n::InflectionOptionIncorrect I18n::InflectionOptionIncorrect}
654
+ # * {I18n::ComplexPatternMalformed I18n::ComplexPatternMalformed}
486
655
  #
487
- # There are also exceptions that are raised regardless of :+raises+
656
+ # There are also exceptions that are raised regardless of :+inflector_raises+
488
657
  # presence or value.
489
658
  # These are usually caused by critical errors encountered during processing
490
- # inflection data. Here is the list:
659
+ # inflection data or exceptions raised by I18n. Note that the pure I18n's
660
+ # exceptions are not described here.
491
661
  #
662
+ # * {I18n::ArgumentError I18n::ArgumentError}
492
663
  # * {I18n::InvalidLocale I18n::InvalidLocale}
493
664
  # * {I18n::DuplicatedInflectionToken I18n::DuplicatedInflectionToken}
665
+ # * {I18n::BadInflectionKind I18n::BadInflectionKind}
494
666
  # * {I18n::BadInflectionToken I18n::BadInflectionToken}
495
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
496
791
  module Inflector
497
792
 
498
793
  class API
@@ -506,6 +801,12 @@ module I18n
506
801
  # database and operations for named patterns (strict kinds)
507
802
  attr_reader :strict
508
803
 
804
+ # This reader allows to reach internal configuration
805
+ # of the engine. It is shared among all instances of
806
+ # the Inflector and also available as
807
+ # {I18n::Inflector::Config I18n::Inflector::Config}.
808
+ attr_reader :config
809
+
509
810
  # Gets known regular inflection kinds.
510
811
  #
511
812
  # @api public
@@ -532,4 +833,9 @@ module I18n
532
833
  # @abstract This exception class is defined in package I18n. It is raised when
533
834
  # the given and/or processed locale parameter is invalid.
534
835
  class InvalidLocale; end
836
+
837
+ # @abstract This exception class is defined in package I18n. It is raised when
838
+ # the given and/or processed translation data or parameter are invalid.
839
+ class ArgumentError; end
840
+
535
841
  end