class TwitterCldr::Formatters::PluralFormatter
Constants
- PLURALIZATION_REGEXP
Attributes
Public Class Methods
# File lib/twitter_cldr/formatters/plurals/plural_formatter.rb, line 18 def for_locale(locale) formatter_cache[locale] ||= PluralFormatter.new(locale) end
# File lib/twitter_cldr/formatters/plurals/plural_formatter.rb, line 31 def initialize(locale = TwitterCldr.locale) @locale = TwitterCldr.convert_locale(locale) end
Protected Class Methods
# File lib/twitter_cldr/formatters/plurals/plural_formatter.rb, line 24 def formatter_cache @formatter_cache ||= {} end
Public Instance Methods
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 thereplacements
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 examplereplacements
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}"
# 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
Private Instance Methods
# File lib/twitter_cldr/formatters/plurals/plural_formatter.rb, line 147 def interpolate_pattern(pattern, placeholder, number) pattern.gsub("%{#{placeholder}}", number.to_s) end
# File lib/twitter_cldr/formatters/plurals/plural_formatter.rb, line 123 def parse_inline_pluralization(captured_group) pluralization_hash = JSON.parse(captured_group) if pluralization_hash.is_a?(Hash) && pluralization_hash.size == 1 pluralization_hash.first else raise ArgumentError.new('expected a Hash with a single key') end end
# File lib/twitter_cldr/formatters/plurals/plural_formatter.rb, line 137 def pluralization_pattern(patterns, number) return unless number && patterns if patterns.is_a?(Hash) TwitterCldr::Utils.deep_symbolize_keys(patterns)[pluralization_rule(number)] else raise ArgumentError.new('expected patterns to be a Hash') end end
# File lib/twitter_cldr/formatters/plurals/plural_formatter.rb, line 133 def pluralization_rule(number) TwitterCldr::Formatters::Plurals::Rules.rule_for(number, locale) end