russian 0.2.7 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CHANGELOG.md +203 -0
- data/Gemfile +8 -0
- data/LICENSE +2 -2
- data/README.md +327 -0
- data/Rakefile +12 -50
- data/lib/russian/action_view_ext/helpers/date_helper.rb +136 -95
- data/lib/russian/active_model_ext/custom_error_message.rb +51 -0
- data/lib/russian/locale/actionview.yml +150 -83
- data/lib/russian/locale/activemodel.yml +57 -0
- data/lib/russian/locale/activerecord.yml +66 -61
- data/lib/russian/locale/activesupport.yml +5 -8
- data/lib/russian/locale/datetime.rb +49 -0
- data/lib/russian/locale/datetime.yml +90 -23
- data/lib/russian/locale/pluralization.rb +49 -0
- data/lib/russian/locale/transliterator.rb +18 -0
- data/lib/russian/russian_rails.rb +99 -0
- data/lib/russian/strptime.rb +166 -0
- data/lib/russian/transliteration.rb +87 -53
- data/lib/russian/version.rb +31 -0
- data/lib/russian.rb +382 -103
- data/russian.gemspec +43 -0
- data/sig/russian.rbs +46 -0
- metadata +197 -86
- data/CHANGELOG +0 -108
- data/README.textile +0 -298
- data/TODO +0 -10
- data/init.rb +0 -3
- data/lib/russian/active_record_ext/custom_error_message.rb +0 -163
- data/lib/russian/active_support_ext/parameterize.rb +0 -31
- data/lib/russian/backend/advanced.rb +0 -134
- data/lib/russian/locale/pluralize.rb +0 -25
- data/lib/vendor/i18n/MIT-LICENSE +0 -20
- data/lib/vendor/i18n/README.textile +0 -20
- data/lib/vendor/i18n/Rakefile +0 -5
- data/lib/vendor/i18n/i18n.gemspec +0 -27
- data/lib/vendor/i18n/lib/i18n/backend/simple.rb +0 -214
- data/lib/vendor/i18n/lib/i18n/exceptions.rb +0 -53
- data/lib/vendor/i18n/lib/i18n.rb +0 -199
- data/lib/vendor/i18n/test/all.rb +0 -5
- data/lib/vendor/i18n/test/i18n_exceptions_test.rb +0 -100
- data/lib/vendor/i18n/test/i18n_test.rb +0 -125
- data/lib/vendor/i18n/test/locale/en.rb +0 -1
- data/lib/vendor/i18n/test/locale/en.yml +0 -3
- data/lib/vendor/i18n/test/simple_backend_test.rb +0 -568
- data/lib/vendor/i18n_label/README.textile +0 -38
- data/lib/vendor/i18n_label/Rakefile +0 -11
- data/lib/vendor/i18n_label/init.rb +0 -1
- data/lib/vendor/i18n_label/install.rb +0 -1
- data/lib/vendor/i18n_label/lib/i18n_label.rb +0 -23
- data/lib/vendor/i18n_label/spec/i18n_label_spec.rb +0 -20
- data/lib/vendor/i18n_label/spec/spec_helper.rb +0 -10
- data/lib/vendor/i18n_label/tasks/i18n_label_tasks.rake +0 -4
- data/lib/vendor/i18n_label/uninstall.rb +0 -1
- data/spec/fixtures/en.yml +0 -4
- data/spec/fixtures/ru.yml +0 -4
- data/spec/i18n/locale/datetime_spec.rb +0 -99
- data/spec/i18n/locale/pluralization_spec.rb +0 -28
- data/spec/locale_spec.rb +0 -129
- data/spec/russian_spec.rb +0 -136
- data/spec/spec_helper.rb +0 -7
- data/spec/transliteration_spec.rb +0 -51
data/lib/russian.rb
CHANGED
|
@@ -1,119 +1,398 @@
|
|
|
1
|
-
#
|
|
1
|
+
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
$:.push File.join(File.dirname(__FILE__), 'russian')
|
|
8
|
-
require 'transliteration'
|
|
3
|
+
require "date"
|
|
4
|
+
require "i18n"
|
|
5
|
+
require "time"
|
|
9
6
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
end
|
|
15
|
-
# Advanced backend
|
|
16
|
-
require 'backend/advanced'
|
|
17
|
-
|
|
18
|
-
# Rails hacks
|
|
19
|
-
require 'active_record_ext/custom_error_message' if defined?(ActiveRecord)
|
|
20
|
-
if defined?(ActionView::Helpers)
|
|
21
|
-
require 'action_view_ext/helpers/date_helper'
|
|
22
|
-
require 'vendor/i18n_label/init'
|
|
23
|
-
end
|
|
24
|
-
require 'active_support_ext/parameterize' if defined?(ActiveSupport::Inflector)
|
|
7
|
+
require_relative "russian/russian_rails"
|
|
8
|
+
require_relative "russian/strptime"
|
|
9
|
+
require_relative "russian/transliteration"
|
|
10
|
+
require_relative "russian/version"
|
|
25
11
|
|
|
12
|
+
# Russian language support for Ruby: I18n helpers and Rails integration.
|
|
13
|
+
#
|
|
14
|
+
# The module wraps common gem `I18n` operations, adds its own helpers,
|
|
15
|
+
# and installs Rails-specific patches when Rails is detected.
|
|
16
|
+
#
|
|
17
|
+
# Don't forget to check `README`!
|
|
18
|
+
#
|
|
19
|
+
#
|
|
20
|
+
# Поддержка русского языка для Ruby: библиотеки I18n и интеграция с Rails.
|
|
21
|
+
#
|
|
22
|
+
# Модуль оборачивает типичные операции gem'а `I18n`, добавляет свои,
|
|
23
|
+
# и устанавливает Rails-специфичные патчи, если обнаружен Rails.
|
|
24
|
+
#
|
|
25
|
+
# Не забудьте прочитать `README`!
|
|
26
|
+
#
|
|
27
|
+
# @example
|
|
28
|
+
# require "russian"
|
|
29
|
+
# Russian.t(:"date.formats.default")
|
|
30
|
+
# Russian.l(Date.new(1985, 12, 1), format: :long)
|
|
31
|
+
# Russian.translit("Привет")
|
|
26
32
|
module Russian
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
# Russian locale
|
|
38
|
-
LOCALE = :'ru'
|
|
33
|
+
# Locale used by the gem.
|
|
34
|
+
#
|
|
35
|
+
#
|
|
36
|
+
# Локаль, которую использует gem.
|
|
37
|
+
#
|
|
38
|
+
# @return [Symbol] Russian locale identifier.
|
|
39
|
+
# Идентификатор русской локали.
|
|
40
|
+
LOCALE = :ru
|
|
39
41
|
|
|
40
|
-
#
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
#
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
# Init Russian i18n: set custom backend, set default locale to Russian locale, load all translations
|
|
53
|
-
# shipped with library.
|
|
54
|
-
def init_i18n
|
|
55
|
-
I18n.backend = Russian.i18n_backend_class.new
|
|
56
|
-
I18n.default_locale = LOCALE
|
|
57
|
-
I18n.load_path.unshift(*locale_files)
|
|
58
|
-
end
|
|
42
|
+
# @private
|
|
43
|
+
LOCALIZE_ABBR_MONTH_NAMES_MATCH = /(%[-_0^#:]*(\d+)*[EO]?d|%[-_0^#:]*(\d+)*[EO]?e)(.*)(%b)/
|
|
44
|
+
# @private
|
|
45
|
+
LOCALIZE_MONTH_NAMES_MATCH = /(%[-_0^#:]*(\d+)*[EO]?d|%[-_0^#:]*(\d+)*[EO]?e)(.*)(%B)/
|
|
46
|
+
# @private
|
|
47
|
+
LOCALIZE_STANDALONE_ABBR_DAY_NAMES_MATCH = /^%a/
|
|
48
|
+
# @private
|
|
49
|
+
LOCALIZE_STANDALONE_DAY_NAMES_MATCH = /^%A/
|
|
50
|
+
# @private
|
|
51
|
+
STRPTIME_DIRECTIVE_MODIFIERS = "-_0^#:"
|
|
59
52
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
end
|
|
76
|
-
|
|
77
|
-
# Simple pluralization proxy
|
|
78
|
-
#
|
|
79
|
-
# Usage:
|
|
80
|
-
# Russian.pluralize(1, "вещь", "вещи", "вещей")
|
|
81
|
-
# Russian.pluralize(3.14, "вещь", "вещи", "вещей", "вещи")
|
|
82
|
-
def pluralize(n, *variants)
|
|
83
|
-
raise ArgumentError, "Must have a Numeric as a first parameter" unless n.is_a?(Numeric)
|
|
84
|
-
raise ArgumentError, "Must have at least 3 variants for pluralization" if variants.size < 3
|
|
85
|
-
raise ArgumentError, "Must have at least 4 variants for pluralization" if (variants.size < 4 && n != n.round)
|
|
86
|
-
variants_hash = pluralization_variants_to_hash(*variants)
|
|
87
|
-
I18n.backend.send(:pluralize, LOCALE, variants_hash, n)
|
|
88
|
-
end
|
|
89
|
-
alias :p :pluralize
|
|
53
|
+
class << self
|
|
54
|
+
# Returns the locale used by the gem.
|
|
55
|
+
#
|
|
56
|
+
#
|
|
57
|
+
# Возвращает локаль, которую использует gem.
|
|
58
|
+
#
|
|
59
|
+
# @return [Symbol] Russian locale identifier.
|
|
60
|
+
# Идентификатор русской локали.
|
|
61
|
+
#
|
|
62
|
+
# @example
|
|
63
|
+
# Russian.locale
|
|
64
|
+
# # => :ru
|
|
65
|
+
def locale
|
|
66
|
+
LOCALE
|
|
67
|
+
end
|
|
90
68
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
#
|
|
69
|
+
# Installs Russian locale files into `I18n` and reloads the I18n backend.
|
|
70
|
+
#
|
|
71
|
+
# The method is safe to call repeatedly. It prepends this gem's locale
|
|
72
|
+
# files to `I18n.load_path`, enables pluralization and transliteration
|
|
73
|
+
# backends, and then calls `I18n.reload!`.
|
|
74
|
+
#
|
|
75
|
+
#
|
|
76
|
+
# Подключает файлы русской локали к `I18n` и перезагружает backend I18n.
|
|
77
|
+
#
|
|
78
|
+
# Метод безопасно вызывать повторно. Он добавляет locale-файлы gem'а в
|
|
79
|
+
# начало `I18n.load_path`, включает backend'ы pluralization и
|
|
80
|
+
# transliteration, а затем вызывает `I18n.reload!`.
|
|
81
|
+
#
|
|
82
|
+
# @return [void]
|
|
83
|
+
#
|
|
84
|
+
# @example
|
|
85
|
+
# I18n.load_path.clear
|
|
86
|
+
# Russian.init_i18n
|
|
87
|
+
# I18n.t(:"date.month_names", locale: :ru)
|
|
88
|
+
def init_i18n
|
|
89
|
+
backend = I18n::Backend::Simple
|
|
90
|
+
|
|
91
|
+
backend.include(I18n::Backend::Pluralization)
|
|
92
|
+
backend.include(I18n::Backend::Transliterator)
|
|
93
|
+
|
|
94
|
+
I18n.load_path = locale_files + (I18n.load_path - locale_files)
|
|
95
|
+
I18n.reload!
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
# Translates a key using the Russian locale by default.
|
|
99
|
+
#
|
|
100
|
+
# Both the legacy positional hash and modern keyword arguments are
|
|
101
|
+
# supported.
|
|
102
|
+
#
|
|
103
|
+
#
|
|
104
|
+
# Переводит ключ, по умолчанию используя русскую локаль.
|
|
105
|
+
#
|
|
106
|
+
# Поддерживаются и устаревший positional hash, и современные
|
|
107
|
+
# keyword-аргументы.
|
|
108
|
+
#
|
|
109
|
+
# @param key [String, Symbol] Translation key.
|
|
110
|
+
# Ключ перевода.
|
|
111
|
+
# @param options [Hash, nil] Legacy positional I18n options hash.
|
|
112
|
+
# Устаревший positional hash с опциями I18n.
|
|
113
|
+
# @param kwargs [Hash] Keyword I18n options.
|
|
114
|
+
# Keyword-опции I18n.
|
|
115
|
+
# @return [Object] Translation result returned by `I18n`.
|
|
116
|
+
# Результат перевода, возвращаемый `I18n`.
|
|
117
|
+
# @raise [ArgumentError] if `options` is not a hash.
|
|
118
|
+
# Если `options` не является hash'ем.
|
|
119
|
+
#
|
|
120
|
+
# @example
|
|
121
|
+
# Russian.translate(:"date.formats.default")
|
|
122
|
+
# Russian.translate(:"date.formats.default", scope: :foo)
|
|
123
|
+
# Russian.translate(:"date.formats.default", {scope: :foo})
|
|
124
|
+
def translate(key, options = nil, **kwargs)
|
|
125
|
+
I18n.translate(key, **normalize_i18n_options(options, kwargs, locale: LOCALE))
|
|
126
|
+
end
|
|
127
|
+
alias_method :t, :translate
|
|
128
|
+
|
|
129
|
+
# @!method t(key, options = nil, **kwargs)
|
|
130
|
+
# Alias for {.translate}.
|
|
131
|
+
#
|
|
132
|
+
#
|
|
133
|
+
# Псевдоним для {.translate}.
|
|
134
|
+
#
|
|
135
|
+
# @see .translate
|
|
136
|
+
|
|
137
|
+
# Localizes an object using the Russian locale by default.
|
|
138
|
+
#
|
|
139
|
+
# Both the legacy positional hash and modern keyword arguments are
|
|
140
|
+
# supported.
|
|
141
|
+
#
|
|
142
|
+
#
|
|
143
|
+
# Локализует объект, по умолчанию используя русскую локаль.
|
|
144
|
+
#
|
|
145
|
+
# Поддерживаются и устаревший positional hash, и современные
|
|
146
|
+
# keyword-аргументы.
|
|
147
|
+
#
|
|
148
|
+
# @param object [Object] Localizable object, usually `Date`, `Time`, or `DateTime`.
|
|
149
|
+
# Локализуемый объект, обычно `Date`, `Time` или `DateTime`.
|
|
150
|
+
# @param options [Hash, nil] Legacy positional I18n options hash.
|
|
151
|
+
# Устаревший positional hash с опциями I18n.
|
|
152
|
+
# @param kwargs [Hash] Keyword I18n options.
|
|
153
|
+
# Keyword-опции I18n.
|
|
154
|
+
# @return [String] Localized string.
|
|
155
|
+
# Локализованная строка.
|
|
156
|
+
# @raise [ArgumentError] if `options` is not a hash.
|
|
157
|
+
# Если `options` не является hash'ем.
|
|
158
|
+
#
|
|
159
|
+
# @example
|
|
160
|
+
# Russian.localize(Date.new(1985, 12, 1), format: :long)
|
|
161
|
+
# Russian.localize(Date.new(1985, 12, 1), {format: :long})
|
|
162
|
+
def localize(object, options = nil, **kwargs)
|
|
163
|
+
I18n.localize(object, **normalize_i18n_options(options, kwargs, locale: LOCALE))
|
|
164
|
+
end
|
|
165
|
+
alias_method :l, :localize
|
|
166
|
+
|
|
167
|
+
# @!method l(object, options = nil, **kwargs)
|
|
168
|
+
# Alias for {.localize}.
|
|
169
|
+
#
|
|
170
|
+
#
|
|
171
|
+
# Псевдоним для {.localize}.
|
|
172
|
+
#
|
|
173
|
+
# @see .localize
|
|
174
|
+
|
|
175
|
+
# Localizes an object using a `strftime`-style format identifier.
|
|
176
|
+
#
|
|
177
|
+
# `Russian.strftime(time, :long)` and
|
|
178
|
+
# `Russian.strftime(time, format: :long)` are both supported.
|
|
179
|
+
#
|
|
180
|
+
#
|
|
181
|
+
# Локализует объект, используя идентификатор формата в стиле `strftime`.
|
|
182
|
+
#
|
|
183
|
+
# Поддерживаются форматы `Russian.strftime(time, :long)` и
|
|
184
|
+
# `Russian.strftime(time, format: :long)`.
|
|
185
|
+
#
|
|
186
|
+
# @param object [Object] Localizable object.
|
|
187
|
+
# Локализуемый объект.
|
|
188
|
+
# @param format [Symbol, Hash] Format name or legacy options hash.
|
|
189
|
+
# Имя формата или устаревший hash с опциями.
|
|
190
|
+
# @param kwargs [Hash] Keyword I18n options.
|
|
191
|
+
# Keyword-опции I18n.
|
|
192
|
+
# @return [String] Localized string.
|
|
193
|
+
# Локализованная строка.
|
|
194
|
+
# @raise [ArgumentError] if a legacy options argument is not a hash.
|
|
195
|
+
# Если устаревший аргумент с опциями не является hash'ем.
|
|
196
|
+
#
|
|
197
|
+
# @example
|
|
198
|
+
# Russian.strftime(Time.new(2008, 9, 1, 11, 12, 43, "+03:00"), :long)
|
|
199
|
+
# Russian.strftime(Time.new(2008, 9, 1, 11, 12, 43, "+03:00"), format: :long)
|
|
200
|
+
def strftime(object, format = :default, **kwargs)
|
|
201
|
+
options =
|
|
202
|
+
if format.is_a?(Hash)
|
|
203
|
+
normalize_i18n_options(format, kwargs)
|
|
204
|
+
else
|
|
205
|
+
normalize_i18n_options({format: format}, kwargs)
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
localize(object, **options)
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
# Parses a localized Russian date string with `Date.strptime`.
|
|
212
|
+
#
|
|
213
|
+
# The method understands Russian month and weekday names, normalizes them
|
|
214
|
+
# to the English names expected by Ruby's parser, and then delegates to
|
|
215
|
+
# `Date.strptime`. All non-localized directives are still handled by the
|
|
216
|
+
# native Ruby parser.
|
|
217
|
+
#
|
|
218
|
+
#
|
|
219
|
+
# Разбирает локализованную русскую строку даты через `Date.strptime`.
|
|
220
|
+
#
|
|
221
|
+
# Метод понимает русские названия месяцев и дней недели, нормализует их
|
|
222
|
+
# к английским именам, которые ожидает стандартный parser Ruby, а затем
|
|
223
|
+
# делегирует работу в `Date.strptime`. Все остальные директивы по-прежнему
|
|
224
|
+
# обрабатываются нативным parser'ом Ruby.
|
|
225
|
+
#
|
|
226
|
+
# @param string [String] Localized date string.
|
|
227
|
+
# Локализованная строка даты.
|
|
228
|
+
# @param format [String] Optional `strptime` format string.
|
|
229
|
+
# Строка формата `strptime`.
|
|
230
|
+
# @return [Date] Parsed date.
|
|
231
|
+
# Разобранная дата.
|
|
232
|
+
#
|
|
233
|
+
# @example
|
|
234
|
+
# Russian.date_strptime("01 апреля 2011", "%d %B %Y")
|
|
235
|
+
# # => #<Date: 2011-04-01 ...>
|
|
236
|
+
def date_strptime(string, format = "%F")
|
|
237
|
+
Strptime.date_strptime(string, format)
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
# Parses a localized Russian date/time string with `Time.strptime`.
|
|
241
|
+
#
|
|
242
|
+
# The method uses the same Russian textual token normalization as
|
|
243
|
+
# {.date_strptime}, then delegates to `Time.strptime`.
|
|
244
|
+
#
|
|
245
|
+
#
|
|
246
|
+
# Разбирает локализованную русскую строку даты и времени через
|
|
247
|
+
# `Time.strptime`.
|
|
248
|
+
#
|
|
249
|
+
# Метод использует ту же нормализацию русских текстовых токенов, что и
|
|
250
|
+
# {.date_strptime}, а затем делегирует работу в `Time.strptime`.
|
|
251
|
+
#
|
|
252
|
+
# @param string [String] Localized date/time string.
|
|
253
|
+
# Локализованная строка даты и времени.
|
|
254
|
+
# @param format [String] `strptime` format string.
|
|
255
|
+
# Строка формата `strptime`.
|
|
256
|
+
# @param now [Time] Optional base time passed to `Time.strptime`.
|
|
257
|
+
# Базовое значение времени, передаваемое в `Time.strptime`.
|
|
258
|
+
# @return [Time] Parsed time.
|
|
259
|
+
# Разобранное время.
|
|
260
|
+
#
|
|
261
|
+
# @example
|
|
262
|
+
# Russian.time_strptime("01 апреля 2011 23:45:05 +0300", "%d %B %Y %H:%M:%S %z")
|
|
263
|
+
# # => 2011-04-01 23:45:05 +0300
|
|
264
|
+
def time_strptime(string, format, now = Time.now)
|
|
265
|
+
Strptime.time_strptime(string, format, now)
|
|
266
|
+
end
|
|
267
|
+
|
|
268
|
+
# Parses a localized Russian date/time string with `DateTime.strptime`.
|
|
269
|
+
#
|
|
270
|
+
# The method uses the same Russian textual token normalization as
|
|
271
|
+
# {.date_strptime}, then delegates to `DateTime.strptime`.
|
|
272
|
+
#
|
|
273
|
+
#
|
|
274
|
+
# Разбирает локализованную русскую строку даты и времени через
|
|
275
|
+
# `DateTime.strptime`.
|
|
276
|
+
#
|
|
277
|
+
# Метод использует ту же нормализацию русских текстовых токенов, что и
|
|
278
|
+
# {.date_strptime}, а затем делегирует работу в `DateTime.strptime`.
|
|
279
|
+
#
|
|
280
|
+
# @param string [String] Localized date/time string.
|
|
281
|
+
# Локализованная строка даты и времени.
|
|
282
|
+
# @param format [String] Optional `strptime` format string.
|
|
283
|
+
# Строка формата `strptime`.
|
|
284
|
+
# @return [DateTime] Parsed datetime.
|
|
285
|
+
# Разобранный `DateTime`.
|
|
286
|
+
#
|
|
287
|
+
# @example
|
|
288
|
+
# Russian.datetime_strptime("01 апреля 2011 23:45:05 +0300", "%d %B %Y %H:%M:%S %z")
|
|
289
|
+
# # => #<DateTime: 2011-04-01T23:45:05+03:00 ...>
|
|
290
|
+
def datetime_strptime(string, format = "%FT%T%z")
|
|
291
|
+
Strptime.datetime_strptime(string, format)
|
|
292
|
+
end
|
|
293
|
+
|
|
294
|
+
# Returns the correct Russian plural form for a numeric value.
|
|
295
|
+
#
|
|
296
|
+
# For integers, three variants are required: `one`, `few`, and `many`.
|
|
297
|
+
# For non-integer numbers, a fourth `other` variant is also required.
|
|
298
|
+
#
|
|
299
|
+
#
|
|
300
|
+
# Возвращает правильную русскую форму множественного числа для
|
|
301
|
+
# числового значения.
|
|
302
|
+
#
|
|
303
|
+
# Для целых чисел нужны три варианта: `one`, `few` и `many`.
|
|
304
|
+
# Для дробных чисел дополнительно нужен четвертый вариант `other`.
|
|
305
|
+
#
|
|
306
|
+
# @param n [Numeric] Number used for pluralization.
|
|
307
|
+
# Число для выбора формы.
|
|
308
|
+
# @param variants [Array<Object>] Pluralization variants in the order `one`, `few`, `many`, `other`.
|
|
309
|
+
# Варианты в порядке `one`, `few`, `many`, `other`.
|
|
310
|
+
# @return [Object] Selected pluralization variant.
|
|
311
|
+
# Выбранный вариант склонения.
|
|
312
|
+
# @raise [ArgumentError] if `n` is not numeric or required variants are missing.
|
|
313
|
+
# Если `n` не число или не переданы нужные варианты.
|
|
314
|
+
#
|
|
315
|
+
# @example
|
|
316
|
+
# Russian.pluralize(1, "вещь", "вещи", "вещей")
|
|
317
|
+
# # => "вещь"
|
|
318
|
+
# Russian.pluralize(3.14, "вещь", "вещи", "вещей", "вещи")
|
|
319
|
+
# # => "вещи"
|
|
320
|
+
def pluralize(n, *variants)
|
|
321
|
+
raise ArgumentError, "Must have a Numeric as a first parameter" unless n.is_a?(Numeric)
|
|
322
|
+
raise ArgumentError, "Must have at least 3 variants for pluralization" if variants.size < 3
|
|
323
|
+
raise ArgumentError, "Must have at least 4 variants for pluralization" if variants.size < 4 && n != n.round
|
|
324
|
+
|
|
325
|
+
variants_hash = pluralization_variants_to_hash(*variants)
|
|
326
|
+
I18n.backend.send(:pluralize, LOCALE, variants_hash, n)
|
|
327
|
+
end
|
|
328
|
+
alias_method :p, :pluralize
|
|
329
|
+
|
|
330
|
+
# @!method p(n, *variants)
|
|
331
|
+
# Alias for {.pluralize}.
|
|
332
|
+
#
|
|
333
|
+
#
|
|
334
|
+
# Псевдоним для {.pluralize}.
|
|
335
|
+
#
|
|
336
|
+
# @see .pluralize
|
|
337
|
+
|
|
338
|
+
# Transliterates a string from Cyrillic to Latin characters.
|
|
339
|
+
#
|
|
340
|
+
# The method delegates to {Transliteration.transliterate} and preserves the
|
|
341
|
+
# historical casing behavior of the gem.
|
|
342
|
+
#
|
|
343
|
+
#
|
|
344
|
+
# Транслитерирует строку из кириллицы в латиницу.
|
|
345
|
+
#
|
|
346
|
+
# Метод делегирует работу в {Transliteration.transliterate} и сохраняет
|
|
347
|
+
# историческое поведение gem'а по работе с регистром.
|
|
348
|
+
#
|
|
349
|
+
# @param str [String] String to transliterate.
|
|
350
|
+
# Строка для транслитерации.
|
|
351
|
+
# @return [String] Transliteration result.
|
|
352
|
+
# Результат транслитерации.
|
|
353
|
+
#
|
|
354
|
+
# @example
|
|
355
|
+
# Russian.transliterate("Юлия")
|
|
356
|
+
# # => "Yuliya"
|
|
357
|
+
def transliterate(str)
|
|
358
|
+
Transliteration.transliterate(str)
|
|
359
|
+
end
|
|
360
|
+
alias_method :translit, :transliterate
|
|
361
|
+
|
|
362
|
+
# @!method translit(str)
|
|
363
|
+
# Alias for {.transliterate}.
|
|
364
|
+
#
|
|
365
|
+
#
|
|
366
|
+
# Псевдоним для {.transliterate}.
|
|
367
|
+
#
|
|
368
|
+
# @see .transliterate
|
|
369
|
+
|
|
370
|
+
private
|
|
371
|
+
|
|
372
|
+
# @private
|
|
103
373
|
def locale_files
|
|
104
|
-
Dir[File.join(
|
|
374
|
+
Dir[File.join(__dir__, "russian", "locale", "**", "*")].select { |path| File.file?(path) }.sort
|
|
105
375
|
end
|
|
106
|
-
|
|
107
|
-
#
|
|
108
|
-
# with I18n pluralization.
|
|
376
|
+
|
|
377
|
+
# @private
|
|
109
378
|
def pluralization_variants_to_hash(*variants)
|
|
110
379
|
{
|
|
111
|
-
:
|
|
112
|
-
:
|
|
113
|
-
:
|
|
114
|
-
:
|
|
380
|
+
one: variants[0],
|
|
381
|
+
few: variants[1],
|
|
382
|
+
many: variants[2],
|
|
383
|
+
other: variants[3]
|
|
115
384
|
}
|
|
116
385
|
end
|
|
386
|
+
|
|
387
|
+
# @private
|
|
388
|
+
def normalize_i18n_options(options = nil, kwargs = {}, defaults = {})
|
|
389
|
+
legacy_options = options || {}
|
|
390
|
+
|
|
391
|
+
raise ArgumentError, "Options must be provided as a Hash or keyword arguments" unless legacy_options.is_a?(Hash)
|
|
392
|
+
|
|
393
|
+
defaults.merge(legacy_options).merge(kwargs)
|
|
394
|
+
end
|
|
395
|
+
end
|
|
117
396
|
end
|
|
118
397
|
|
|
119
398
|
Russian.init_i18n
|
data/russian.gemspec
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "lib/russian/version"
|
|
4
|
+
|
|
5
|
+
Gem::Specification.new do |spec|
|
|
6
|
+
spec.name = "russian"
|
|
7
|
+
spec.version = Russian::VERSION::STRING
|
|
8
|
+
|
|
9
|
+
spec.authors = ["Yaroslav Markin"]
|
|
10
|
+
spec.description = "Russian language support for Ruby and Rails"
|
|
11
|
+
spec.email = "yaroslav@markin.net"
|
|
12
|
+
spec.extra_rdoc_files = ["README.md", "LICENSE", "CHANGELOG.md"]
|
|
13
|
+
spec.files = Dir.glob([
|
|
14
|
+
"lib/**/*", "sig/**/*", "CHANGELOG.md", "Gemfile",
|
|
15
|
+
"LICENSE", "Rakefile", "README.md", "russian.gemspec"
|
|
16
|
+
])
|
|
17
|
+
spec.homepage = "https://github.com/yaroslav/russian"
|
|
18
|
+
spec.license = "MIT"
|
|
19
|
+
spec.metadata = {
|
|
20
|
+
"bug_tracker_uri" => "https://github.com/yaroslav/russian/issues",
|
|
21
|
+
"changelog_uri" => "https://github.com/yaroslav/russian/blob/master/CHANGELOG.md",
|
|
22
|
+
"documentation_uri" => "https://rubydoc.info/gems/russian",
|
|
23
|
+
"homepage_uri" => "https://github.com/yaroslav/russian",
|
|
24
|
+
"rubygems_mfa_required" => "true",
|
|
25
|
+
"source_code_uri" => "https://github.com/yaroslav/russian"
|
|
26
|
+
}
|
|
27
|
+
spec.platform = Gem::Platform::RUBY
|
|
28
|
+
spec.require_paths = ["lib"]
|
|
29
|
+
spec.required_ruby_version = ">= 3.2"
|
|
30
|
+
spec.summary = "Russian language support for Ruby and Rails"
|
|
31
|
+
|
|
32
|
+
spec.add_dependency("i18n", ">= 1.14.8", "< 2")
|
|
33
|
+
|
|
34
|
+
spec.add_development_dependency("bundler", ">= 2.4")
|
|
35
|
+
spec.add_development_dependency("irb", ">= 1.15")
|
|
36
|
+
spec.add_development_dependency("lefthook", "~> 2.1.4")
|
|
37
|
+
spec.add_development_dependency("rake", ">= 13.0", "< 14")
|
|
38
|
+
spec.add_development_dependency("rbs", "~> 3.10")
|
|
39
|
+
spec.add_development_dependency("rdoc", ">= 6.10")
|
|
40
|
+
spec.add_development_dependency("redcarpet", ">= 3.6")
|
|
41
|
+
spec.add_development_dependency("rspec", "~> 3.13")
|
|
42
|
+
spec.add_development_dependency("yard", "~> 0.9")
|
|
43
|
+
end
|
data/sig/russian.rbs
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
module Russian
|
|
2
|
+
LOCALE: :ru
|
|
3
|
+
|
|
4
|
+
def self.locale: () -> :ru
|
|
5
|
+
def self.init_i18n: () -> void
|
|
6
|
+
|
|
7
|
+
def self.translate: (String | Symbol key, ?Hash[untyped, untyped] options, **untyped) -> untyped
|
|
8
|
+
def self.t: (String | Symbol key, ?Hash[untyped, untyped] options, **untyped) -> untyped
|
|
9
|
+
|
|
10
|
+
def self.localize: (untyped object, ?Hash[untyped, untyped] options, **untyped) -> String
|
|
11
|
+
def self.l: (untyped object, ?Hash[untyped, untyped] options, **untyped) -> String
|
|
12
|
+
|
|
13
|
+
def self.strftime: (untyped object, ?Symbol format, **untyped) -> String
|
|
14
|
+
| (untyped object, Hash[untyped, untyped] format, **untyped) -> String
|
|
15
|
+
|
|
16
|
+
def self.date_strptime: (String string, ?String format) -> Date
|
|
17
|
+
def self.time_strptime: (String string, String format, ?Time now) -> Time
|
|
18
|
+
def self.datetime_strptime: (String string, ?String format) -> DateTime
|
|
19
|
+
|
|
20
|
+
def self.pluralize: (Numeric n, *untyped variants) -> untyped
|
|
21
|
+
def self.p: (Numeric n, *untyped variants) -> untyped
|
|
22
|
+
|
|
23
|
+
def self.transliterate: (String str) -> String
|
|
24
|
+
def self.translit: (String str) -> String
|
|
25
|
+
|
|
26
|
+
module RailsIntegration
|
|
27
|
+
def self.install!: () -> void
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
module Transliteration
|
|
31
|
+
def self.transliterate: (String str) -> String
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
module Strptime
|
|
35
|
+
def self.date_strptime: (String string, ?String format) -> Date
|
|
36
|
+
def self.time_strptime: (String string, String format, ?Time now) -> Time
|
|
37
|
+
def self.datetime_strptime: (String string, ?String format) -> DateTime
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
module VERSION
|
|
41
|
+
MAJOR: Integer
|
|
42
|
+
MINOR: Integer
|
|
43
|
+
TINY: Integer
|
|
44
|
+
STRING: String
|
|
45
|
+
end
|
|
46
|
+
end
|