# encoding: utf-8
module Sunrise
module Utils
# "Продвинутый" бекэнд для I18n.
#
# Наследует Simple бекэнд и полностью с ним совместим. Добаляет поддержку
# для отдельностоящих/контекстных названий дней недели и месяцев.
# Также позволяет каждому языку использовать собственные правила плюрализации,
# объявленные как Proc (lambda).
#
#
# Advanced I18n backend.
#
# Extends Simple backend. Allows usage of "standalone" keys
# for DateTime localization and usage of user-defined Proc (lambda) pluralization
# methods in translation tables.
class I18nBackend < ::I18n::Backend::Simple
include ::I18n::Backend::Pluralization
LOCALIZE_ABBR_MONTH_NAMES_MATCH = /(%d|%e)(.*)(%b)/
LOCALIZE_MONTH_NAMES_MATCH = /(%d|%e)(.*)(%B)/
LOCALIZE_STANDALONE_ABBR_DAY_NAMES_MATCH = /^%a/
LOCALIZE_STANDALONE_DAY_NAMES_MATCH = /^%A/
# Acts the same as +strftime+, but returns a localized version of the
# formatted date string. Takes a key from the date/time formats
# translations as a format argument (e.g., :short in :'date.formats').
#
#
# Метод отличается от localize в Simple бекэнде поддержкой
# отдельностоящих/контекстных названий дней недели и месяцев.
#
#
# Note that it differs from localize in Simple< backend by checking for
# "standalone" month name/day name keys in translation and using them if available.
#
# options parameter added for i18n-0.3 compliance.
def localize(locale, object, format = :default, options = nil)
raise ArgumentError, "Object must be a Date, DateTime or Time object. #{object.inspect} given." unless object.respond_to?(:strftime)
type = object.respond_to?(:sec) ? 'time' : 'date'
# TODO only translate these if format is a String?
formats = translate(locale, :"#{type}.formats")
format = formats[format.to_sym] if formats && formats[format.to_sym]
# TODO raise exception unless format found?
format = format.to_s.dup
# TODO only translate these if the format string is actually present
# TODO check which format strings are present, then bulk translate then, then replace them
if lookup(locale, :"date.standalone_abbr_day_names")
format.gsub!(LOCALIZE_STANDALONE_ABBR_DAY_NAMES_MATCH,
translate(locale, :"date.standalone_abbr_day_names")[object.wday])
end
format.gsub!(/%a/, translate(locale, :"date.abbr_day_names")[object.wday])
if lookup(locale, :"date.standalone_day_names")
format.gsub!(LOCALIZE_STANDALONE_DAY_NAMES_MATCH,
translate(locale, :"date.standalone_day_names")[object.wday])
end
format.gsub!(/%A/, translate(locale, :"date.day_names")[object.wday])
if lookup(locale, :"date.standalone_abbr_month_names")
format.gsub!(LOCALIZE_ABBR_MONTH_NAMES_MATCH) do
$1 + $2 + translate(locale, :"date.abbr_month_names")[object.mon]
end
format.gsub!(/%b/, translate(locale, :"date.standalone_abbr_month_names")[object.mon])
else
format.gsub!(/%b/, translate(locale, :"date.abbr_month_names")[object.mon])
end
if lookup(locale, :"date.standalone_month_names")
format.gsub!(LOCALIZE_MONTH_NAMES_MATCH) do
$1 + $2 + translate(locale, :"date.month_names")[object.mon]
end
format.gsub!(/%B/, translate(locale, :"date.standalone_month_names")[object.mon])
else
format.gsub!(/%B/, translate(locale, :"date.month_names")[object.mon])
end
format.gsub!(/%p/, translate(locale, :"time.#{object.hour < 12 ? :am : :pm}")) if object.respond_to? :hour
object.strftime(format)
end
end
end
end