Class: TwitterCldr::Formatters::PluralFormatter

Inherits:
Object
  • 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

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(locale = TwitterCldr.locale) ⇒ PluralFormatter

Returns a new instance of PluralFormatter.



31
32
33
# File 'lib/twitter_cldr/formatters/plurals/plural_formatter.rb', line 31

def initialize(locale = TwitterCldr.locale)
  @locale = TwitterCldr.convert_locale(locale)
end

Instance Attribute Details

#localeObject (readonly)

Returns the value of attribute locale.



29
30
31
# File 'lib/twitter_cldr/formatters/plurals/plural_formatter.rb', line 29

def locale
  @locale
end

Class Method Details

.for_locale(locale) ⇒ Object



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

def for_locale(locale)
  formatter_cache[locale] ||= PluralFormatter.new(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}"


106
107
108
109
110
111
112
113
114
115
116
117
118
119
# File 'lib/twitter_cldr/formatters/plurals/plural_formatter.rb', line 106

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