Class: TwitterCldr::Formatters::PluralFormatter

Inherits:
Base
  • Object
show all
Defined in:
lib/twitter_cldr/formatters/plurals/plural_formatter.rb

Constant Summary collapse

PLURALIZATION_REGEXP =
Regexp.union(
    /%\{(\w+?):(\w+?)\}/,   # regular pluralization pattern
    /%<(\{.*?\})>/          # inline pluralization pattern
)

Instance Attribute Summary collapse

Attributes inherited from Base

#tokenizer

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ PluralFormatter

Returns a new instance of PluralFormatter.


19
20
21
# File 'lib/twitter_cldr/formatters/plurals/plural_formatter.rb', line 19

def initialize(options = {})
  self.locale = extract_locale(options)
end

Instance Attribute Details

#localeObject

Returns the value of attribute locale


17
18
19
# File 'lib/twitter_cldr/formatters/plurals/plural_formatter.rb', line 17

def locale
  @locale
end

Instance Method Details

#format(string, replacements) ⇒ Object

Replaces every pluralization token in the string with a phrase formed using a number and a pluralization pattern from the replacements hash.

Two types of formatting are supported for pluralization.

  • Regular pluralization:

    Format of a pluralization group is '%number:objects'. When pluralization group like that is encountered in the string, replacements hash is expected to contain a number and pluralization patterns at keys :number and :objects respectively (note, keys of the replacements hash should be symbols).

    Pluralization patterns are specified as a hash containing a pattern for every plural category of the language. Keys of this hash should be symbols. If necessary, pluralization pattern can contain placeholder for the number. Syntax for the placeholder is similar to the hash-based string interpolation: '%number.

  • Inline pluralization:

    Pluralization group if formatted as '%<{ “number”: { “one”: “one horse” } }>'. Content inside '%<…>' is expected to be a valid string representation of a JSON object with a single key-value pair (JSON property), where key matches key in the replacements hash (e.g., in this example replacements hash can be something like { :number => 3 }), and value is a hash (JSON object) of pluralization rules to be used with this number. No space is allowed inside opening '%<and closing '>' sequences. As pluralization group is parsed as JSON all keys and string values inside it should be enclosed in double quotes.

Examples:

f.format('%{count:horses}', :count => 1, :horses => { :one => 'one horse', :other => '%{count} horses' })
# => "one horse"

f.format('%{count:horses}', :count => 2, :horses => { :one => 'one horse', :other => '%{count} horses' })
# => "2 horses"

f.format('%<{ "count": {"one": "one horse", "other": "%{count} horses"} }>', :count => 2)
# => "2 horses"

Multiple pluralization groups can be present in the same string.

Examples:

f.format(
    '%{ponies_count:ponies} and %{unicorns_count:unicorns}',
    :ponies_count   => 2, :ponies   => { :one => 'one pony',    :other => '%{ponies_count} ponies' },
    :unicorns_count => 1, :unicorns => { :one => 'one unicorn', :other => '%{unicorns_count} unicorns' }
)
# => "2 ponies and one unicorn"

The same applies to inline pluralization.

Mixed styles of pluralization (both regular and inline) can be used in the same string, but it's better to avoid that as it might bring more confusion than real benefit.

If a number or required pluralization pattern is missing in the replacements hash, corresponding pluralization token is ignored.

Examples:

f.format('%{count:horses}', :horses => { :one => 'one horse', :other => '%{count} horses' })
# => "%{count:horses}"

f.format('%<{"count": {"one": "one horse", "other": "%{count} horses"}}>', {})
# => '%<{"count": {"one": "one horse", "other": "%{count} horses"}}>'

f.format('%{count:horses}', :count => 10, :horses => { :one => 'one horse' })
# => "%{count:horses}"

f.format('%<{"count": {"one": "one horse"}}>', :count => 2)
# => '%<{"count": {"one": "one horse"}}>'

f.format('%{count:horses}', {})
# => "%{count:horses}"

94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/twitter_cldr/formatters/plurals/plural_formatter.rb', line 94

def format(string, replacements)
  string.gsub(PLURALIZATION_REGEXP) do |match|
    number_placeholder, patterns = if $3
      parse_inline_pluralization($3)
    else
      [$1, replacements[$2.to_sym]]
    end

    number  = replacements[number_placeholder.to_sym]
    pattern = pluralization_pattern(patterns, number)

    pattern && interpolate_pattern(pattern, number_placeholder, number) || match
  end
end