class TwitterCldr::Formatters::NumberFormatter

Attributes

data_reader[R]

Public Class Methods

new(data_reader) click to toggle source
# File lib/twitter_cldr/formatters/numbers/number_formatter.rb, line 12
def initialize(data_reader)
  @data_reader = data_reader
end

Public Instance Methods

format(tokens, number, options = {}) click to toggle source
# File lib/twitter_cldr/formatters/numbers/number_formatter.rb, line 16
def format(tokens, number, options = {})
  options[:precision] ||= precision_from(number)
  options[:type] ||= :decimal

  prefix, suffix, integer_format, fraction_format = *partition_tokens(tokens)
  number = truncate_number(number, integer_format.format.length)

  int, fraction = parse_number(number, options)
  result =  integer_format.apply(int, options)
  result << fraction_format.apply(fraction, options) if fraction

  number_system.transliterate(
    "#{prefix.to_s}#{result}#{suffix.to_s}"
  )
end
truncate_number(number, decimal_digits) click to toggle source
# File lib/twitter_cldr/formatters/numbers/number_formatter.rb, line 32
def truncate_number(number, decimal_digits)
  if abbreviate?(number)
    factor = [0, number.to_i.abs.to_s.length - decimal_digits].max
    number / (10.0 ** factor)
  else
    number
  end
end

Protected Instance Methods

abbreviate?(number) click to toggle source
# File lib/twitter_cldr/formatters/numbers/number_formatter.rb, line 104
def abbreviate?(number)
  TwitterCldr::DataReaders::NumberDataReader.within_abbreviation_range?(number) && (
    data_reader.format == :short ||
    data_reader.format == :long
  )
end
number_system() click to toggle source
# File lib/twitter_cldr/formatters/numbers/number_formatter.rb, line 43
def number_system
  @number_system ||= TwitterCldr::Shared::NumberingSystem.for_name(
    data_reader.number_system
  )
end
parse_number(number, options = {}) click to toggle source
# File lib/twitter_cldr/formatters/numbers/number_formatter.rb, line 68
def parse_number(number, options = {})
  precision = options[:precision] || precision_from(number)
  rounding = options[:rounding] || 0

  if number.is_a? BigDecimal
    number = precision == 0 ?
      round_to(number, precision, rounding).abs.fix.to_s("F") :
      round_to(number, precision, rounding).abs.round(precision).to_s("F")
  else
    number = "%.#{precision}f" % round_to(number, precision, rounding).abs
  end
  number.split(".")
end
partition_tokens(tokens) click to toggle source
# File lib/twitter_cldr/formatters/numbers/number_formatter.rb, line 49
def partition_tokens(tokens)
  [
    token_val_from(tokens[0]),
    token_val_from(tokens[2]),
    Numbers::Integer.new(
      tokens[1],
      data_reader.symbols
    ),
    Numbers::Fraction.new(
      tokens[1],
      data_reader.symbols
    )
  ]
end
precision_from(num) click to toggle source
# File lib/twitter_cldr/formatters/numbers/number_formatter.rb, line 98
def precision_from(num)
  return 0 if num.is_a?(BigDecimal) && num.fix == num
  parts = (num.is_a?(BigDecimal) ? num.to_s("F") : num.to_s ).split(".")
  parts.size == 2 ? parts[1].size : 0
end
round_to(number, precision, rounding = 0) click to toggle source
# File lib/twitter_cldr/formatters/numbers/number_formatter.rb, line 82
def round_to(number, precision, rounding = 0)
  factor = 10 ** precision
  result = number.is_a?(BigDecimal) ?
    ((number * factor).fix / factor) :
    ((number * factor).round.to_f / factor)

  if rounding > 0
    rounding = rounding.to_f / factor
    result = number.is_a?(BigDecimal) ?
      ((result *  (1.0 / rounding)).fix / (1.0 / rounding)) :
      ((result *  (1.0 / rounding)).round.to_f / (1.0 / rounding))
  end

  result
end
token_val_from(token) click to toggle source
# File lib/twitter_cldr/formatters/numbers/number_formatter.rb, line 64
def token_val_from(token)
  token ? token.value : ""
end