yaroslav-russian 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2008 Yaroslav Markin
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.textile ADDED
@@ -0,0 +1,44 @@
1
+ h1. Russian
2
+
3
+ Russian language support for Ruby and Rails, using I18n library.
4
+
5
+ Поддержка русского языка для Ruby и Rails при помощи библиотеки I18n.
6
+
7
+ h3. If you don't speak Russian
8
+
9
+ This code may still be useful for you. You can learn how to create custom backends for I18n and how to
10
+ provide support of "standalone" (as defined in "Unicode CLDR":http://unicode.org/cldr/) month names with I18n and Rails, and also how to add dead simple pluralization rules into your translation tables.
11
+
12
+ h1. Что это
13
+
14
+ Russian -- это библиотека для полноценной поддержки русского языка (форматирование даты и времени, плюрализация, локализация в целом) для Ruby и Ruby on Rails.
15
+
16
+ Для этого используется библиотека I18n, несколько хаков поверх нее и файлы переводов.
17
+
18
+ I18n входит в состав Ruby on Rails начиная с версии 2.2, но на момент публикации нормальная поддержка русского языка отсутствовала.
19
+
20
+ h1. Установка
21
+
22
+ TODO: пути на GitHub, публикация на RubyForge
23
+
24
+ * gem rubyforge
25
+ * gem github
26
+
27
+ h2. Ruby on Rails
28
+
29
+ * gem
30
+ * plugin github
31
+
32
+ h1. Использование
33
+
34
+ * Прозрачное: локаль по умолчанию, свой бекенд (недеструктивный)
35
+ * Хелперы Russian.*
36
+
37
+ h2. Ruby on Rails
38
+
39
+ * Стандартный язык для I18n
40
+ * Перегрузка хелперов
41
+
42
+ h1. Автор
43
+
44
+ Ярослав Маркин ("yaroslav@markin.net":mailto:yaroslav@markin.net)
data/Rakefile ADDED
@@ -0,0 +1,55 @@
1
+ require 'rubygems'
2
+ require 'rake/gempackagetask'
3
+ require 'spec/rake/spectask'
4
+ require 'rubygems/specification'
5
+ require 'date'
6
+
7
+ GEM = "russian"
8
+ GEM_VERSION = "0.0.1"
9
+ AUTHOR = "Yaroslav Markin"
10
+ EMAIL = "yaroslav@markin.net"
11
+ HOMEPAGE = "http://github.com/yaroslav/russian/"
12
+ SUMMARY = "Russian language support for Ruby and Rails"
13
+
14
+ spec = Gem::Specification.new do |s|
15
+ s.name = GEM
16
+ s.version = GEM_VERSION
17
+ s.platform = Gem::Platform::RUBY
18
+ s.has_rdoc = true
19
+ s.extra_rdoc_files = ["README.textile", "LICENSE", 'TODO']
20
+ s.summary = SUMMARY
21
+ s.description = s.summary
22
+ s.author = AUTHOR
23
+ s.email = EMAIL
24
+ s.homepage = HOMEPAGE
25
+
26
+ # Uncomment this to add a dependency
27
+ # s.add_dependency "foo"
28
+
29
+ s.require_path = 'lib'
30
+ s.autorequire = GEM
31
+ s.files = %w(LICENSE README.textile Rakefile TODO init.rb) + Dir.glob("{lib,spec}/**/*")
32
+ end
33
+
34
+ Rake::GemPackageTask.new(spec) do |pkg|
35
+ pkg.gem_spec = spec
36
+ end
37
+
38
+ task :default => :spec
39
+ desc "Run specs"
40
+ Spec::Rake::SpecTask.new do |t|
41
+ t.spec_files = FileList['spec/**/*_spec.rb']
42
+ t.spec_opts = %w(-fs --color)
43
+ end
44
+
45
+ desc "install the gem locally"
46
+ task :install => [:package] do
47
+ sh %{sudo gem install pkg/#{GEM}-#{GEM_VERSION}}
48
+ end
49
+
50
+ desc "create a gemspec file"
51
+ task :make_spec do
52
+ File.open("#{GEM}.gemspec", "w") do |file|
53
+ file.puts spec.to_ruby
54
+ end
55
+ end
data/TODO ADDED
@@ -0,0 +1,11 @@
1
+ TODO
2
+ ====
3
+ * docs and README (english - brief, full russian doc)
4
+ * check Unicode CLDR to ensure all datetime formats are correct
5
+ * refactor Advanced backend localize method (looks ugly)
6
+
7
+ Questionable
8
+ ============
9
+ * integration spec coverage for actionview locale
10
+ * integration spec coverage for activerecord locale
11
+ * integration spec coverage for activesupport locale
data/init.rb ADDED
@@ -0,0 +1,3 @@
1
+ # Rails plugin init
2
+ require 'russian'
3
+
@@ -0,0 +1,90 @@
1
+ # Replaces Rails select_month helper and translated_month_names private method to provide
2
+ # "standalone month names" feature.
3
+ #
4
+ # It is now possible to use both abbreviated and full month names in two variants (if current locale provides them).
5
+ # All date helpers support <tt>:use_standalone_month_names</tt> key now, <tt>select_month</tt> helper sets
6
+ # it to true by default.
7
+ # Standalone month names are also used when <tt>:discard_day</tt> key is provided.
8
+ if defined?(ActionView::Helpers::DateTimeSelector) && ActionView::Helpers::DateTimeSelector.private_instance_methods.include?("translated_month_names")
9
+ module ActionView
10
+ module Helpers
11
+ module DateHelper
12
+ # Returns a select tag with options for each of the months January through December with the current month
13
+ # selected. The month names are presented as keys (what's shown to the user) and the month numbers (1-12) are
14
+ # used as values (what's submitted to the server). It's also possible to use month numbers for the presentation
15
+ # instead of names -- set the <tt>:use_month_numbers</tt> key in +options+ to true for this to happen. If you
16
+ # want both numbers and names, set the <tt>:add_month_numbers</tt> key in +options+ to true. If you would prefer
17
+ # to show month names as abbreviations, set the <tt>:use_short_month</tt> key in +options+ to true. If you want
18
+ # to use your own month names, set the <tt>:use_month_names</tt> key in +options+ to an array of 12 month names.
19
+ # You can also choose if you want to use i18n standalone month names or default month names -- you can
20
+ # force standalone month names usage by using <tt>:use_standalone_month_names</tt> key.
21
+ # Override the field name using the <tt>:field_name</tt> option, 'month' by default.
22
+ #
23
+ # ==== Examples
24
+ # # Generates a select field for months that defaults to the current month that
25
+ # # will use keys like "January", "March".
26
+ # select_month(Date.today)
27
+ #
28
+ # # Generates a select field for months that defaults to the current month that
29
+ # # is named "start" rather than "month"
30
+ # select_month(Date.today, :field_name => 'start')
31
+ #
32
+ # # Generates a select field for months that defaults to the current month that
33
+ # # will use keys like "1", "3".
34
+ # select_month(Date.today, :use_month_numbers => true)
35
+ #
36
+ # # Generates a select field for months that defaults to the current month that
37
+ # # will use keys like "1 - January", "3 - March".
38
+ # select_month(Date.today, :add_month_numbers => true)
39
+ #
40
+ # # Generates a select field for months that defaults to the current month that
41
+ # # will use keys like "Jan", "Mar".
42
+ # select_month(Date.today, :use_short_month => true)
43
+ #
44
+ # # Generates a select field for months that defaults to the current month that
45
+ # # will use keys like "Januar", "Marts."
46
+ # select_month(Date.today, :use_month_names => %w(Januar Februar Marts ...))
47
+ #
48
+ def select_month(date, options = {}, html_options = {})
49
+ DateTimeSelector.new(date, options.merge(:use_standalone_month_names => true), html_options).select_month
50
+ end
51
+ end
52
+
53
+ class DateTimeSelector #:nodoc:
54
+ private
55
+ # Returns translated month names
56
+ # => [nil, "January", "February", "March",
57
+ # "April", "May", "June", "July",
58
+ # "August", "September", "October",
59
+ # "November", "December"]
60
+ #
61
+ # If :use_short_month option is set
62
+ # => [nil, "Jan", "Feb", "Mar", "Apr", "May", "Jun",
63
+ # "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
64
+ #
65
+ # Also looks up if <tt>:discard_day</tt> or <tt>:use_standalone_month_names</tt> option is set
66
+ # and uses i18n standalone month names if so.
67
+ def translated_month_names
68
+ begin
69
+ if @options[:use_short_month]
70
+ if (@options[:discard_day] || @options[:use_standalone_month_names]) && I18n.translate(:'date.standalone_abbr_month_names')
71
+ key = :'date.standalone_abbr_month_names'
72
+ else
73
+ key = :'date.abbr_month_names'
74
+ end
75
+ else
76
+ if (@options[:discard_day] || @options[:use_standalone_month_names]) && I18n.translate(:'date.standalone_month_names')
77
+ key = :'date.standalone_month_names'
78
+ else
79
+ key = :'date.month_names'
80
+ end
81
+ end
82
+
83
+ I18n.translate(key, :locale => @options[:locale])
84
+ end
85
+ end
86
+
87
+ end
88
+ end
89
+ end
90
+ end # if defined?
@@ -0,0 +1,33 @@
1
+ if defined?(ActiveRecord::Errors)
2
+ # The following is taken from custom_error_message plugin by David Easley
3
+ # (http://rubyforge.org/projects/custom-err-msg/)
4
+ module ActiveRecord
5
+ class Errors
6
+
7
+ # Redefine the ActiveRecord::Errors::full_messages method:
8
+ # Returns all the full error messages in an array. 'Base' messages are handled as usual.
9
+ # Non-base messages are prefixed with the attribute name as usual UNLESS they begin with '^'
10
+ # in which case the attribute name is omitted.
11
+ # E.g. validates_acceptance_of :accepted_terms, :message => '^Please accept the terms of service'
12
+ def full_messages
13
+ full_messages = []
14
+
15
+ @errors.each_key do |attr|
16
+ @errors[attr].each do |msg|
17
+ next if msg.nil?
18
+
19
+ if attr == "base"
20
+ full_messages << msg
21
+ elsif msg =~ /^\^/
22
+ full_messages << msg[1..-1]
23
+ else
24
+ full_messages << @base.class.human_attribute_name(attr) + " " + msg
25
+ end
26
+ end
27
+ end
28
+
29
+ return full_messages
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,104 @@
1
+ module I18n
2
+ module Backend
3
+ # Advanced I18n backend.
4
+ #
5
+ # Extends <tt>Simple</tt> backend. Allows usage of <tt>standalone_*</tt> keys
6
+ # for DateTime localization and usage of user-defined <tt>Proc</tt> (lambda) pluralization
7
+ # methods in translation tables.
8
+ class Advanced < Simple
9
+ LOCALIZE_ABBR_MONTH_NAMES_MATCH = /(%d|%e)?(\s*)(%b)/
10
+ LOCALIZE_MONTH_NAMES_MATCH = /(%d|%e)?(\s*)(%B)/
11
+ LOCALIZE_STANDALONE_ABBR_DAY_NAMES_MATCH = /^%a/
12
+ LOCALIZE_STANDALONE_DAY_NAMES_MATCH = /^%A/
13
+
14
+ # Acts the same as +strftime+, but returns a localized version of the
15
+ # formatted date string. Takes a key from the date/time formats
16
+ # translations as a format argument (<em>e.g.</em>, <tt>:short</tt> in <tt>:'date.formats'</tt>).
17
+ #
18
+ # Note that it differs from <tt>localize</tt> in <tt>Simple</tt> backend by checking for
19
+ # <tt>standalone_*</tt> month name/day name keys in translation and using them if available.
20
+ def localize(locale, object, format = :default)
21
+ raise ArgumentError, "Object must be a Date, DateTime or Time object. #{object.inspect} given." unless object.respond_to?(:strftime)
22
+
23
+ type = object.respond_to?(:sec) ? 'time' : 'date'
24
+ # TODO only translate these if format is a String?
25
+ formats = translate(locale, :"#{type}.formats")
26
+ format = formats[format.to_sym] if formats && formats[format.to_sym]
27
+ # TODO raise exception unless format found?
28
+ format = format.to_s.dup
29
+
30
+ # TODO only translate these if the format string is actually present
31
+ # TODO check which format strings are present, then bulk translate then, then replace them
32
+
33
+ if lookup(locale, :"date.standalone_abbr_day_names")
34
+ format.gsub!(LOCALIZE_STANDALONE_ABBR_DAY_NAMES_MATCH,
35
+ translate(locale, :"date.standalone_abbr_day_names")[object.wday])
36
+ end
37
+ format.gsub!(/%a/, translate(locale, :"date.abbr_day_names")[object.wday])
38
+
39
+ if lookup(locale, :"date.standalone_day_names")
40
+ format.gsub!(LOCALIZE_STANDALONE_DAY_NAMES_MATCH,
41
+ translate(locale, :"date.standalone_day_names")[object.wday])
42
+ end
43
+ format.gsub!(/%A/, translate(locale, :"date.day_names")[object.wday])
44
+
45
+ if lookup(locale, :"date.standalone_abbr_month_names")
46
+ format.gsub!(LOCALIZE_ABBR_MONTH_NAMES_MATCH) do
47
+ $1 ? $1 + $2 + translate(locale, :"date.abbr_month_names")[object.mon] :
48
+ $2 + translate(locale, :"date.standalone_abbr_month_names")[object.mon]
49
+ end
50
+ else
51
+ format.gsub!(/%b/, translate(locale, :"date.abbr_month_names")[object.mon])
52
+ end
53
+
54
+ if lookup(locale, :"date.standalone_month_names")
55
+ format.gsub!(LOCALIZE_MONTH_NAMES_MATCH) do
56
+ $1 ? $1 + $2 + translate(locale, :"date.month_names")[object.mon] :
57
+ $2 + translate(locale, :"date.standalone_month_names")[object.mon]
58
+ end
59
+ else
60
+ format.gsub!(/%B/, translate(locale, :"date.month_names")[object.mon])
61
+ end
62
+
63
+ format.gsub!(/%p/, translate(locale, :"time.#{object.hour < 12 ? :am : :pm}")) if object.respond_to? :hour
64
+ object.strftime(format)
65
+ end
66
+
67
+ protected
68
+ # Picks a pluralization rule specified in translation tables for a language or
69
+ # uses default pluralization rules.
70
+ #
71
+ # This is how pluralization rules are defined in translation tables, English
72
+ # language for example:
73
+ #
74
+ # store_translations :'en-US', {
75
+ # :pluralize => lambda { |n| n == 1 ? :one : :other }
76
+ # }
77
+ #
78
+ # Rule must return a symbol to use with pluralization, it must be one of:
79
+ # :zero, :one, :two, :few, :many, :other
80
+ def pluralize(locale, entry, count)
81
+ return entry unless entry.is_a?(Hash) and count
82
+
83
+ key = :zero if count == 0 && entry.has_key?(:zero)
84
+ locale_pluralize = lookup(locale, :pluralize)
85
+ if locale_pluralize && locale_pluralize.respond_to?(:call)
86
+ key ||= locale_pluralize.call(count)
87
+ else
88
+ key ||= default_pluralizer(count)
89
+ end
90
+ raise InvalidPluralizationData.new(entry, count) unless entry.has_key?(key)
91
+
92
+ entry[key]
93
+ end
94
+
95
+ # Default pluralizer, used if pluralization rule is not defined in translations.
96
+ #
97
+ # Uses English pluralization rules -- it will pick the first translation if count is not equal to 1
98
+ # and the second translation if it is equal to 1.
99
+ def default_pluralizer(count)
100
+ count == 1 ? :one : :other
101
+ end
102
+ end
103
+ end
104
+ end
@@ -0,0 +1,113 @@
1
+ ru-RU:
2
+ number:
3
+ # Used in number_with_delimiter()
4
+ # These are also the defaults for 'currency', 'percentage', 'precision', and 'human'
5
+ format:
6
+ # Sets the separator between the units, for more precision (e.g. 1.0 / 2.0 == 0.5)
7
+ separator: "."
8
+ # Delimets thousands (e.g. 1,000,000 is a million) (always in groups of three)
9
+ delimiter: " "
10
+ # Number of decimals, behind the separator (the number 1 with a precision of 2 gives: 1.00)
11
+ precision: 3
12
+
13
+ # Used in number_to_currency()
14
+ currency:
15
+ format:
16
+ # Where is the currency sign? %u is the currency unit, %n the number (default: $5.00)
17
+ format: "%n %u"
18
+ unit: "руб."
19
+ # These three are to override number.format and are optional
20
+ separator: "."
21
+ delimiter: " "
22
+ precision: 2
23
+
24
+ # Used in number_to_percentage()
25
+ percentage:
26
+ format:
27
+ # These three are to override number.format and are optional
28
+ # separator:
29
+ delimiter: ""
30
+ precision: 2
31
+
32
+ # Used in number_to_precision()
33
+ precision:
34
+ format:
35
+ # These three are to override number.format and are optional
36
+ # separator:
37
+ delimiter: ""
38
+ # precision:
39
+
40
+ # Used in number_to_human_size()
41
+ human:
42
+ format:
43
+ # These three are to override number.format and are optional
44
+ # separator:
45
+ delimiter: ""
46
+ precision: 1
47
+
48
+ # Used in distance_of_time_in_words(), distance_of_time_in_words_to_now(), time_ago_in_words()
49
+ datetime:
50
+ distance_in_words:
51
+ half_a_minute: "меньше минуты"
52
+ less_than_x_seconds:
53
+ one: "меньше секунды"
54
+ few: "меньше {{count}} секунд"
55
+ many: "меньше {{count}} секунд"
56
+ other: "меньше {{count}} секунд"
57
+ x_seconds:
58
+ one: "1 секунда"
59
+ few: "{{count}} секунды"
60
+ many: "{{count}} секунд"
61
+ other: "{{count}} секунды"
62
+ less_than_x_minutes:
63
+ one: "меньше минуты"
64
+ few: "меньше {{count}} минут"
65
+ many: "меньше {{count}} минут"
66
+ other: "меньше {{count}} минут"
67
+ x_minutes:
68
+ one: "1 минуту"
69
+ few: "{{count}} минуты"
70
+ many: "{{count}} минут"
71
+ other: "{{count}} минуты"
72
+ about_x_hours:
73
+ one: "около часа"
74
+ few: "около {{count}} часов"
75
+ many: "около {{count}} часов"
76
+ other: "около {{count}} часов"
77
+ x_days:
78
+ one: "1 день"
79
+ few: "{{count}} дня"
80
+ many: "{{count}} дней"
81
+ other: "{{count}} дня"
82
+ about_x_months:
83
+ one: "около 1 месяца"
84
+ few: "около {{count}} месяцев"
85
+ many: "около {{count}} месяцев"
86
+ other: "около {{count}} месяцев"
87
+ x_months:
88
+ one: "1 месяц"
89
+ few: "{{count}} месяца"
90
+ many: "{{count}} месяцев"
91
+ other: "{{count}} месяца"
92
+ about_x_years:
93
+ one: "около 1 года"
94
+ few: "около {{count}} лет"
95
+ many: "около {{count}} лет"
96
+ other: "около {{count}} лет"
97
+ over_x_years:
98
+ one: "больше 1 года"
99
+ few: "больше {{count}} лет"
100
+ many: "больше {{count}} лет"
101
+ other: "больше {{count}} лет"
102
+
103
+ activerecord:
104
+ errors:
105
+ template:
106
+ header:
107
+ one: "{{model}} не удалось сохранить из-за 1 ошибки"
108
+ few: "{{model}} не удалось сохранить из-за {{count}} ошибок"
109
+ many: "{{model}} не удалось сохранить из-за {{count}} ошибок"
110
+ other: "{{model}} не удалось сохранить из-за {{count}} ошибок"
111
+ # The variable :count is also available
112
+ body: "Проблемы возникли со следующими полями:"
113
+
@@ -0,0 +1,48 @@
1
+ ru-RU:
2
+ activerecord:
3
+ errors:
4
+ # The values :model, :attribute and :value are always available for interpolation
5
+ # The value :count is available when applicable. Can be used for pluralization.
6
+ #
7
+ # You can use ^-prefixed messages as well to get rid of human attribute name appearing
8
+ # before your message in validation messages.
9
+ messages:
10
+ inclusion: "имеет непредусмотренное значение"
11
+ exclusion: "имеет зарезервированное значение"
12
+ invalid: "имеет неверное значение"
13
+ confirmation: "не совпадает с подтверждением"
14
+ accepted: "нужно подтвердить"
15
+ empty: "не может быть пустым"
16
+ blank: "не может быть пустым"
17
+ too_long:
18
+ one: "слишком большой длины (допустимая длина - менее 1 символа)"
19
+ few: "слишком большой длины (допустимая длина - менее {{count}} символов)"
20
+ many: "слишком большой длины (допустимая длина - менее {{count}} символов)"
21
+ other: "слишком большой длины (допустимая длина - менее {{count}} символов)"
22
+ too_short:
23
+ one: "недостаточной длины (допустимая длина - более 1 символа)"
24
+ few: "недостаточной длины (допустимая длина - более {{count}} символов)"
25
+ many: "недостаточной длины (допустимая длина - более {{count}} символов)"
26
+ other: "недостаточной длины (допустимая длина - более {{count}} символов)"
27
+ wrong_length:
28
+ one: "неверной длины (допустимая длина - ровно 1 символ)"
29
+ few: "неверной длины (допустимая длина - ровно {{count}} символа)"
30
+ many: "неверной длины (допустимая длина - ровно {{count}} символов)"
31
+ other: "неверной длины (допустимая длина - ровно {{count}} символа)"
32
+ taken: "уже существует"
33
+ not_a_number: "не является числом"
34
+ greater_than: "может иметь значение большее {{count}}"
35
+ greater_than_or_equal_to: "может иметь значение большее или равное {{count}}"
36
+ equal_to: "может иметь лишь значение, равное {{count}}"
37
+ less_than: "может иметь значение меньше чем {{count}}"
38
+ less_than_or_equal_to: "может иметь значение меньшее или равное {{count}}"
39
+ odd: "может иметь лишь четное значение"
40
+ even: "может иметь лишь нечетное значение"
41
+ # Append your own errors here or at the model/attributes scope.
42
+
43
+ models:
44
+ # Overrides default messages
45
+
46
+ attributes:
47
+ # Overrides model and default messages.
48
+
@@ -0,0 +1,5 @@
1
+ ru-RU:
2
+ # Used in array.to_sentence.
3
+ support:
4
+ array:
5
+ sentence_connector: "и"
@@ -0,0 +1,29 @@
1
+ ru-RU:
2
+ date:
3
+ formats:
4
+ # Use the strftime parameters for formats.
5
+ # When no format has been given, it uses default.
6
+ # You can provide other formats here if you like!
7
+ default: "%d.%m.%Y"
8
+ short: "%d %b"
9
+ long: "%d %B %Y"
10
+
11
+ day_names: [воскресенье, понедельник, вторник, среда, четверг, пятница, суббота]
12
+ standalone_day_names: [Воскресенье, Понедельник, Вторник, Среда, Четверг, Пятница, Суббота]
13
+ abbr_day_names: [Вс, Пн, Вт, Ср, Чт, Пт, Сб]
14
+
15
+ # Don't forget the nil at the beginning; there's no such thing as a 0th month
16
+ month_names: [~, января, февраля, марта, апреля, мая, июня, июля, августа, сентября, октября, ноября, декабря]
17
+ standalone_month_names: [~, Январь, Февраль, Март, Апрель, Май, Июнь, Июль, Август, Сентябрь, Октябрь, Ноябрь, Декабрь]
18
+ abbr_month_names: [~, янв., февр., марта, апр., мая, июня, июля, авг., сент., окт., нояб., дек.]
19
+ standalone_abbr_month_names: [~, янв., февр., март, апр., май, июнь, июль, авг., сент., окт., нояб., дек.]
20
+ # Used in date_select and datime_select.
21
+ order: [ :day, :month, :year ]
22
+
23
+ time:
24
+ formats:
25
+ default: "%a, %d %b %Y, %H:%M:%S %z"
26
+ short: "%d %b, %H:%M"
27
+ long: "%d %B %Y, %H:%M"
28
+ am: "утра"
29
+ pm: "вечера"
@@ -0,0 +1,22 @@
1
+ {
2
+ :'ru-RU' => {
3
+ :pluralize => lambda { |n|
4
+ # Russian language pluralization rules, taken from CLDR project, http://unicode.org/cldr/
5
+ #
6
+ # one -> n mod 10 is 1 and n mod 100 is not 11;
7
+ # few -> n mod 10 in 2..4 and n mod 100 not in 12..14;
8
+ # many -> n mod 10 is 0 or n mod 10 in 5..9 or n mod 100 in 11..14;
9
+ # other -> everything else
10
+ if n.modulo(10) == 1 && n.modulo(100) != 11
11
+ :one
12
+ elsif (n.modulo(10) >=2 && n.modulo(10) <= 4) && (n.modulo(100) >=12 && n.modulo(100) <= 14)
13
+ :few
14
+ elsif n.modulo(10) == 0 || (n.modulo(10) >=5 && n.modulo(10) <= 9) ||
15
+ (n.modulo(100) >= 11 && n.modulo(100) <= 14)
16
+ :many
17
+ else
18
+ :other
19
+ end
20
+ }
21
+ }
22
+ }