julik-rutils 1.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +162 -0
- data/Manifest.txt +42 -0
- data/README.txt +234 -0
- data/Rakefile.rb +41 -0
- data/TODO.txt +6 -0
- data/WHAT_HAS_CHANGED.txt +44 -0
- data/bin/gilensize +22 -0
- data/bin/rutilize +38 -0
- data/init.rb +27 -0
- data/lib/countries/countries.rb +1773 -0
- data/lib/datetime/datetime.rb +83 -0
- data/lib/gilenson/bluecloth_extra.rb +7 -0
- data/lib/gilenson/gilenson.rb +665 -0
- data/lib/gilenson/helper.rb +34 -0
- data/lib/gilenson/maruku_extra.rb +19 -0
- data/lib/gilenson/rdiscount_extra.rb +7 -0
- data/lib/gilenson/redcloth_extra.rb +42 -0
- data/lib/integration/integration.rb +1 -0
- data/lib/integration/rails_date_helper_override.rb +127 -0
- data/lib/integration/rails_pre_filter.rb +4 -0
- data/lib/pluralizer/pluralizer.rb +261 -0
- data/lib/rutils.rb +54 -0
- data/lib/transliteration/bidi.rb +21 -0
- data/lib/transliteration/simple.rb +75 -0
- data/lib/transliteration/transliteration.rb +53 -0
- data/lib/version.rb +5 -0
- data/test/extras/integration_bluecloth.rb +13 -0
- data/test/extras/integration_maruku.rb +15 -0
- data/test/extras/integration_rails_filter.rb +29 -0
- data/test/extras/integration_rails_gilenson_helpers.rb +80 -0
- data/test/extras/integration_rails_helpers.rb +85 -0
- data/test/extras/integration_rdiscount.rb +15 -0
- data/test/extras/integration_redcloth3.rb +18 -0
- data/test/extras/integration_redcloth4.rb +19 -0
- data/test/run_tests.rb +4 -0
- data/test/test_datetime.rb +145 -0
- data/test/test_gilenson.rb +396 -0
- data/test/test_integration.rb +22 -0
- data/test/test_integration_flag.rb +18 -0
- data/test/test_pluralize.rb +84 -0
- data/test/test_rutils_base.rb +11 -0
- data/test/test_transliteration.rb +53 -0
- metadata +121 -0
@@ -0,0 +1,34 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
# Включается на правах хелпера в Rails-приложение
|
3
|
+
module RuTils::Gilenson::Helper
|
4
|
+
|
5
|
+
# Возвращает текст обработанный Гиленсоном
|
6
|
+
def gilensize(text, options = {})
|
7
|
+
return "" if text.blank?
|
8
|
+
f = RuTils::Gilenson::Formatter.new
|
9
|
+
f.configure!(options)
|
10
|
+
f.process(text)
|
11
|
+
end
|
12
|
+
|
13
|
+
# Возвращает текст обработанный Текстилем и Гиленсоном
|
14
|
+
# <i>Метод доступен только при включенном RedCloth</i>
|
15
|
+
def textilize(text)
|
16
|
+
return "" if text.blank?
|
17
|
+
if RuTils.overrides_enabled?
|
18
|
+
RuTils::Gilenson::RedClothExtra.new(text, [ :hard_breaks ]).to_html
|
19
|
+
else
|
20
|
+
super(text)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# Возвращает текст с кодом Markdown превращенным в HTML, попутно обработанный Гиленсоном
|
25
|
+
# <i>Метод доступен только при наличии BlueCloth</i>.
|
26
|
+
def markdown(text)
|
27
|
+
return "" if text.blank?
|
28
|
+
if RuTils.overrides_enabled?
|
29
|
+
RuTils::Gilenson::BlueClothExtra.new(text).to_html
|
30
|
+
else
|
31
|
+
super(text)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
# Maruku с поддержкой Gilenson
|
3
|
+
class RuTils::Gilenson::MarukuExtra < Maruku
|
4
|
+
def to_html(*anything)
|
5
|
+
suspended = super
|
6
|
+
|
7
|
+
# Return quotes to original state
|
8
|
+
[187, 171, 8220, 8221].map do |e|
|
9
|
+
suspended.gsub! /&\##{e};/, '"'
|
10
|
+
end
|
11
|
+
|
12
|
+
# Return spaces to original state
|
13
|
+
[160].map do |e|
|
14
|
+
suspended.gsub! /&\##{e};/, ' '
|
15
|
+
end
|
16
|
+
|
17
|
+
suspended.gilensize
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
if RedCloth.class == Module
|
3
|
+
# RedCloth 4 - частичная поддержка
|
4
|
+
class RuTils::Gilenson::RedClothExtra < RedCloth::TextileDoc
|
5
|
+
def to_html(*anything)
|
6
|
+
suspended = super(*anything)
|
7
|
+
|
8
|
+
# Return quotes to original state
|
9
|
+
[187, 171, 8220, 8221].map do |e|
|
10
|
+
suspended.gsub! /&\##{e};/, '"'
|
11
|
+
end
|
12
|
+
|
13
|
+
# Return spaces to original state
|
14
|
+
[160].map do |e|
|
15
|
+
suspended.gsub! /&\##{e};/, ' '
|
16
|
+
end
|
17
|
+
|
18
|
+
suspended.gilensize
|
19
|
+
end
|
20
|
+
end
|
21
|
+
else
|
22
|
+
# RedCloth 3 - RuTils выполняет перегрузку Textile Glyphs в RedCloth, перенося форматирование спецсимволов на Gilenson.
|
23
|
+
# Применять как стандартный RedCloth
|
24
|
+
# RuTils::Gilenson::RedClothExtra.new(some_text).to_html
|
25
|
+
class RuTils::Gilenson::RedClothExtra < RedCloth
|
26
|
+
# Этот метод в RedCloth при наличии Гиленсона становится заглушкой
|
27
|
+
def htmlesc(text, mode=0)
|
28
|
+
text
|
29
|
+
end
|
30
|
+
|
31
|
+
# А этот метод обрабатывает Textile Glyphs - ту самую типографицу.
|
32
|
+
# Вместо того чтобы влезать в чужие таблицы мы просто заменим Textile Glyphs на Gilenson - и все будут рады.
|
33
|
+
def pgl(text) #:nodoc:
|
34
|
+
# Подвешиваем пробелы в начале и в конце каждого блока. Тряпка требует чтобы эти пробелы приехали
|
35
|
+
# назад нетронутыми.
|
36
|
+
spaces = Array.new(2,'')
|
37
|
+
text.gsub!(/\A([\s]+)/) { spaces[0] = $1; '' }
|
38
|
+
text.gsub!(/(\s+)\Z/) { spaces[1] = $1; '' }
|
39
|
+
text.replace(spaces[0].to_s + RuTils::Gilenson::Formatter.new(text).to_html + spaces[1].to_s)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/rails_date_helper_override' if defined?(ActionView)
|
@@ -0,0 +1,127 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
module Object::ActionView::Helpers::DateHelper
|
3
|
+
# Несколько хаков для корректной работы модуля с Rails 1.2--2.0 одновременно с Rails 2.1 и выше.
|
4
|
+
|
5
|
+
# Хелперы DateHelper принимают параметр <tt>html_options</tt> (идет последним) начиная с Rails 2.1.
|
6
|
+
# Нужно понять, имеем ли мы дело с Rails 2.1+, для этого проверяем наличие классметода helper_modules у
|
7
|
+
# ActionView::Base, который появился как раз в версии 2.1.
|
8
|
+
DATE_HELPERS_RECEIVE_HTML_OPTIONS = ActionView::Base.respond_to?(:helper_modules) #:nodoc:
|
9
|
+
|
10
|
+
# В Rails Edge (2.1+) определяется <tt>Time.current</tt> для работы с временными зонами.
|
11
|
+
unless Time.respond_to? :current
|
12
|
+
class << ::Time # :nodoc:
|
13
|
+
def current; now; end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
# В Rails Edge (2.1+) определяется <tt>Date.current</tt> для работы с временными зонами.
|
18
|
+
unless Date.respond_to? :current
|
19
|
+
class << ::Date # :nodoc:
|
20
|
+
def current; now; end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# Заменяет <tt>ActionView::Helpers::DateHelper::distance_of_time_in_words</tt> на русское сообщение.
|
25
|
+
#
|
26
|
+
# Целые числа интерпретируются как секунды.
|
27
|
+
# <tt>distance_of_time_in_words(50)</tt> возвращает "меньше минуты".
|
28
|
+
alias :stock_distance_of_time_in_words :distance_of_time_in_words
|
29
|
+
def distance_of_time_in_words(*args)
|
30
|
+
RuTils::overrides_enabled? ? RuTils::DateTime::distance_of_time_in_words(*args) : stock_distance_of_time_in_words
|
31
|
+
end
|
32
|
+
|
33
|
+
# Заменяет ActionView::Helpers::DateHelper::select_month меню выбора русских месяцев.
|
34
|
+
#
|
35
|
+
# select_month(Date.today) # Использует ключи "Январь", "Март"
|
36
|
+
# select_month(Date.today, :use_month_numbers => true) # Использует ключи "1", "3"
|
37
|
+
# select_month(Date.today, :add_month_numbers => true) # Использует ключи "1 - Январь", "3 - Март"
|
38
|
+
def select_month(date, options = {}, html_options = {})
|
39
|
+
locale = options[:locale] unless RuTils::overrides_enabled?
|
40
|
+
|
41
|
+
val = date ? (date.kind_of?(Fixnum) ? date : date.month) : ''
|
42
|
+
if options[:use_hidden]
|
43
|
+
if self.class.private_instance_methods.include? "_date_hidden_html"
|
44
|
+
_date_hidden_html(options[:field_name] || 'month', val, options)
|
45
|
+
else
|
46
|
+
hidden_html(options[:field_name] || 'month', val, options)
|
47
|
+
end
|
48
|
+
else
|
49
|
+
month_options = []
|
50
|
+
if RuTils::overrides_enabled?
|
51
|
+
month_names = case true
|
52
|
+
when options[:use_short_month]
|
53
|
+
Date::RU_ABBR_MONTHNAMES
|
54
|
+
# использование в контексте date_select с днями требует родительный падеж
|
55
|
+
when options[:order] && options[:order].include?(:day)
|
56
|
+
Date::RU_INFLECTED_MONTHNAMES
|
57
|
+
else
|
58
|
+
Date::RU_MONTHNAMES
|
59
|
+
end
|
60
|
+
else
|
61
|
+
if defined? I18n
|
62
|
+
month_names = options[:use_month_names] || begin
|
63
|
+
key = options[:use_short_month] ? :'date.abbr_month_names' : :'date.month_names'
|
64
|
+
I18n.translate key, :locale => locale
|
65
|
+
end
|
66
|
+
else
|
67
|
+
month_names = options[:use_short_month] ? Date::ABBR_MONTHNAMES : Date::MONTHNAMES
|
68
|
+
end
|
69
|
+
end
|
70
|
+
month_names.unshift(nil) if month_names.size < 13
|
71
|
+
|
72
|
+
1.upto(12) do |month_number|
|
73
|
+
month_name = if options[:use_month_numbers]
|
74
|
+
month_number
|
75
|
+
elsif options[:add_month_numbers]
|
76
|
+
month_number.to_s + ' - ' + month_names[month_number]
|
77
|
+
else
|
78
|
+
month_names[month_number]
|
79
|
+
end
|
80
|
+
|
81
|
+
month_options << ((val == month_number) ?
|
82
|
+
content_tag(:option, month_name, :value => month_number, :selected => "selected") :
|
83
|
+
content_tag(:option, month_name, :value => month_number)
|
84
|
+
)
|
85
|
+
month_options << "\n"
|
86
|
+
end
|
87
|
+
|
88
|
+
if DATE_HELPERS_RECEIVE_HTML_OPTIONS
|
89
|
+
if self.class.private_instance_methods.include? "_date_select_html"
|
90
|
+
_date_select_html(options[:field_name] || 'month', month_options.join, options, html_options)
|
91
|
+
else
|
92
|
+
select_html(options[:field_name] || 'month', month_options.join, options, html_options)
|
93
|
+
end
|
94
|
+
else
|
95
|
+
select_html(options[:field_name] || 'month', month_options.join, options)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
alias :stock_select_date :select_date
|
101
|
+
# Заменяет ActionView::Helpers::DateHelper::select_date меню выбора русской даты.
|
102
|
+
def select_date(date = Date.current, options = {}, html_options = {})
|
103
|
+
options[:order] ||= [:day, :month, :year]
|
104
|
+
if DATE_HELPERS_RECEIVE_HTML_OPTIONS
|
105
|
+
stock_select_date(date, options, html_options)
|
106
|
+
else
|
107
|
+
stock_select_date(date, options)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
module Object::ActionView::Helpers
|
113
|
+
if defined?(InstanceTag) && InstanceTag.private_method_defined?(:date_or_time_select)
|
114
|
+
class InstanceTag #:nodoc:
|
115
|
+
private
|
116
|
+
alias :stock_date_or_time_select :date_or_time_select
|
117
|
+
def date_or_time_select(options, html_options = {})
|
118
|
+
options[:order] ||= [:day, :month, :year]
|
119
|
+
if DATE_HELPERS_RECEIVE_HTML_OPTIONS
|
120
|
+
stock_date_or_time_select(options, html_options)
|
121
|
+
else
|
122
|
+
stock_date_or_time_select(options)
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
@@ -0,0 +1,261 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
module RuTils
|
3
|
+
module Pluralization #:nodoc:
|
4
|
+
# Выбирает нужный падеж существительного в зависимости от числа
|
5
|
+
def self.choose_plural(amount, *variants)
|
6
|
+
variant = (amount%10==1 && amount%100!=11 ? 1 : amount%10>=2 && amount%10<=4 && (amount%100<10 || amount%100>=20) ? 2 : 3)
|
7
|
+
variants[variant-1]
|
8
|
+
end
|
9
|
+
|
10
|
+
# Выводит целое или дробное число как сумму в рублях прописью
|
11
|
+
def self.rublej(amount)
|
12
|
+
pts = []
|
13
|
+
|
14
|
+
pts << RuTils::Pluralization::sum_string(amount.to_i, 1, "рубль", "рубля", "рублей") unless amount.to_i == 0
|
15
|
+
if amount.kind_of?(Float)
|
16
|
+
remainder = (amount.divmod(1)[1]*100).round
|
17
|
+
if (remainder == 100)
|
18
|
+
pts = [RuTils::Pluralization::sum_string(amount.to_i+1, 1, 'рубль', 'рубля', 'рублей')]
|
19
|
+
else
|
20
|
+
pts << RuTils::Pluralization::sum_string(remainder.to_i, 2, 'копейка', 'копейки', 'копеек')
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
pts.join(' ')
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.kopeek(amount)
|
28
|
+
pts = []
|
29
|
+
r, k = (amount/100.0).floor, (amount - ((amount/100.0).floor * 100)).to_i
|
30
|
+
pts << RuTils::Pluralization::sum_string(r, 1, "рубль", "рубля", "рублей") unless r.zero?
|
31
|
+
pts << RuTils::Pluralization::sum_string(k, 2, 'копейка', 'копейки', 'копеек') unless k.zero?
|
32
|
+
pts.join(' ')
|
33
|
+
end
|
34
|
+
|
35
|
+
# Выполняет преобразование числа из цифрого вида в символьное
|
36
|
+
# amount - числительное
|
37
|
+
# gender = 1 - мужской, = 2 - женский, = 3 - средний
|
38
|
+
# one_item - именительный падеж единственного числа (= 1)
|
39
|
+
# two_items - родительный падеж единственного числа (= 2-4)
|
40
|
+
# five_items - родительный падеж множественного числа ( = 5-10)
|
41
|
+
def self.sum_string(amount, gender, one_item='', two_items='', five_items='')
|
42
|
+
into = ''
|
43
|
+
tmp_val ||= 0
|
44
|
+
|
45
|
+
return "ноль " + five_items if amount == 0
|
46
|
+
|
47
|
+
tmp_val = amount
|
48
|
+
|
49
|
+
# единицы
|
50
|
+
into, tmp_val = sum_string_fn(into, tmp_val, gender, one_item, two_items, five_items)
|
51
|
+
|
52
|
+
return into if tmp_val == 0
|
53
|
+
|
54
|
+
# тысячи
|
55
|
+
into, tmp_val = sum_string_fn(into, tmp_val, 2, "тысяча", "тысячи", "тысяч")
|
56
|
+
|
57
|
+
return into if tmp_val == 0
|
58
|
+
|
59
|
+
# миллионы
|
60
|
+
into, tmp_val = sum_string_fn(into, tmp_val, 1, "миллион", "миллиона", "миллионов")
|
61
|
+
|
62
|
+
return into if tmp_val == 0
|
63
|
+
|
64
|
+
# миллиардов
|
65
|
+
into, tmp_val = sum_string_fn(into, tmp_val, 1, "миллиард", "миллиарда", "миллиардов")
|
66
|
+
return into
|
67
|
+
end
|
68
|
+
|
69
|
+
private
|
70
|
+
def self.sum_string_fn(into, tmp_val, gender, one_item='', two_items='', five_items='')
|
71
|
+
rest, rest1, end_word, ones, tens, hundreds = [nil]*6
|
72
|
+
#
|
73
|
+
rest = tmp_val % 1000
|
74
|
+
tmp_val = tmp_val / 1000
|
75
|
+
if rest == 0
|
76
|
+
# последние три знака нулевые
|
77
|
+
into = five_items + " " if into == ""
|
78
|
+
return [into, tmp_val]
|
79
|
+
end
|
80
|
+
#
|
81
|
+
# начинаем подсчет с Rest
|
82
|
+
end_word = five_items
|
83
|
+
# сотни
|
84
|
+
hundreds = case rest / 100
|
85
|
+
when 0 then ""
|
86
|
+
when 1 then "сто "
|
87
|
+
when 2 then "двести "
|
88
|
+
when 3 then "триста "
|
89
|
+
when 4 then "четыреста "
|
90
|
+
when 5 then "пятьсот "
|
91
|
+
when 6 then "шестьсот "
|
92
|
+
when 7 then "семьсот "
|
93
|
+
when 8 then "восемьсот "
|
94
|
+
when 9 then "девятьсот "
|
95
|
+
end
|
96
|
+
|
97
|
+
# десятки
|
98
|
+
rest = rest % 100
|
99
|
+
rest1 = rest / 10
|
100
|
+
ones = ""
|
101
|
+
tens = case rest1
|
102
|
+
when 0 then ""
|
103
|
+
when 1 # особый случай
|
104
|
+
case rest
|
105
|
+
when 10 then "десять "
|
106
|
+
when 11 then "одиннадцать "
|
107
|
+
when 12 then "двенадцать "
|
108
|
+
when 13 then "тринадцать "
|
109
|
+
when 14 then "четырнадцать "
|
110
|
+
when 15 then "пятнадцать "
|
111
|
+
when 16 then "шестнадцать "
|
112
|
+
when 17 then "семнадцать "
|
113
|
+
when 18 then "восемнадцать "
|
114
|
+
when 19 then "девятнадцать "
|
115
|
+
end
|
116
|
+
when 2 then "двадцать "
|
117
|
+
when 3 then "тридцать "
|
118
|
+
when 4 then "сорок "
|
119
|
+
when 5 then "пятьдесят "
|
120
|
+
when 6 then "шестьдесят "
|
121
|
+
when 7 then "семьдесят "
|
122
|
+
when 8 then "восемьдесят "
|
123
|
+
when 9 then "девяносто "
|
124
|
+
end
|
125
|
+
#
|
126
|
+
if rest1 < 1 or rest1 > 1 # единицы
|
127
|
+
case rest % 10
|
128
|
+
when 1
|
129
|
+
ones = case gender
|
130
|
+
when 1 then "один "
|
131
|
+
when 2 then "одна "
|
132
|
+
when 3 then "одно "
|
133
|
+
end
|
134
|
+
end_word = one_item
|
135
|
+
when 2
|
136
|
+
if gender == 2
|
137
|
+
ones = "две "
|
138
|
+
else
|
139
|
+
ones = "два "
|
140
|
+
end
|
141
|
+
end_word = two_items
|
142
|
+
when 3
|
143
|
+
ones = "три " if end_word = two_items # TODO - WTF?
|
144
|
+
when 4
|
145
|
+
ones = "четыре " if end_word = two_items # TODO - WTF?
|
146
|
+
when 5
|
147
|
+
ones = "пять "
|
148
|
+
when 6
|
149
|
+
ones = "шесть "
|
150
|
+
when 7
|
151
|
+
ones = "семь "
|
152
|
+
when 8
|
153
|
+
ones = "восемь "
|
154
|
+
when 9
|
155
|
+
ones = "девять "
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
# сборка строки
|
160
|
+
plural = [hundreds, tens, ones, end_word, " ", into].join.strip
|
161
|
+
return [plural, tmp_val]
|
162
|
+
end
|
163
|
+
|
164
|
+
# Реализует вывод прописью любого объекта, реализующего Float
|
165
|
+
module FloatFormatting
|
166
|
+
|
167
|
+
# Выдает сумму прописью с учетом дробной доли. Дробная доля округляется до миллионной, или (если
|
168
|
+
# дробная доля оканчивается на нули) до ближайшей доли ( 500 тысячных округляется до 5 десятых).
|
169
|
+
# Дополнительный аргумент - род существительного (1 - мужской, 2- женский, 3-средний)
|
170
|
+
def propisju(gender = 2)
|
171
|
+
raise "Это не число!" if self.nan?
|
172
|
+
|
173
|
+
st = RuTils::Pluralization::sum_string(self.to_i, gender, "целая", "целых", "целых")
|
174
|
+
|
175
|
+
remainder = self.to_s.match(/\.(\d+)/)[1]
|
176
|
+
|
177
|
+
signs = remainder.to_s.size- 1
|
178
|
+
|
179
|
+
it = [["десятая", "десятых"]]
|
180
|
+
it << ["сотая", "сотых"]
|
181
|
+
it << ["тысячная", "тысячных"]
|
182
|
+
it << ["десятитысячная", "десятитысячных"]
|
183
|
+
it << ["стотысячная", "стотысячных"]
|
184
|
+
it << ["миллионная", "милллионных"]
|
185
|
+
it << ["десятимиллионная", "десятимилллионных", "десятимиллионных"]
|
186
|
+
it << ["стомиллионная", "стомилллионных", "стомиллионных"]
|
187
|
+
it << ["миллиардная", "миллиардных", "миллиардных"]
|
188
|
+
it << ["десятимиллиардная", "десятимиллиардных", "десятимиллиардных"]
|
189
|
+
it << ["стомиллиардная", "стомиллиардных", "стомиллиардных"]
|
190
|
+
it << ["триллионная", "триллионных", "триллионных"]
|
191
|
+
|
192
|
+
while it[signs].nil?
|
193
|
+
remainder = (remainder/10).round
|
194
|
+
signs = remainder.to_s.size- 1
|
195
|
+
end
|
196
|
+
|
197
|
+
suf1, suf2, suf3 = it[signs][0], it[signs][1], it[signs][2]
|
198
|
+
st + " " + RuTils::Pluralization::sum_string(remainder.to_i, 2, suf1, suf2, suf2)
|
199
|
+
end
|
200
|
+
|
201
|
+
def propisju_items(gender=1, *forms)
|
202
|
+
if self == self.to_i
|
203
|
+
return self.to_i.propisju_items(gender, *forms)
|
204
|
+
else
|
205
|
+
self.propisju(gender) + " " + forms[1]
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
end
|
210
|
+
|
211
|
+
# Реализует вывод прописью любого объекта, реализующего Numeric
|
212
|
+
module NumericFormatting
|
213
|
+
# Выбирает корректный вариант числительного в зависимости от рода и числа и оформляет сумму прописью
|
214
|
+
# 234.propisju => "двести сорок три"
|
215
|
+
# 221.propisju(2) => "двести двадцать одна"
|
216
|
+
def propisju(gender = 1)
|
217
|
+
RuTils::Pluralization::sum_string(self, gender, "")
|
218
|
+
end
|
219
|
+
|
220
|
+
def propisju_items(gender=1, *forms)
|
221
|
+
self.propisju(gender) + " " + RuTils::Pluralization::choose_plural(self.to_i, *forms)
|
222
|
+
end
|
223
|
+
|
224
|
+
# Выбирает корректный вариант числительного в зависимости от рода и числа. Например:
|
225
|
+
# * 4.items("колесо", "колеса", "колес") => "колеса"
|
226
|
+
def items(one_item, two_items, five_items)
|
227
|
+
RuTils::Pluralization::choose_plural(self, one_item, two_items, five_items)
|
228
|
+
end
|
229
|
+
|
230
|
+
# Выводит сумму в рублях прописью. Например:
|
231
|
+
# * (15.4).rublej => "пятнадцать рублей сорок копеек"
|
232
|
+
# * 1.rubl => "один рубль"
|
233
|
+
# * (3.14).rublja => "три рубля четырнадцать копеек"
|
234
|
+
def rublej
|
235
|
+
RuTils::Pluralization::rublej(self)
|
236
|
+
end
|
237
|
+
alias :rubl :rublej
|
238
|
+
alias :rublja :rublej
|
239
|
+
end
|
240
|
+
|
241
|
+
module FixnumFormatting
|
242
|
+
def kopeek
|
243
|
+
RuTils::Pluralization.kopeek(self)
|
244
|
+
end
|
245
|
+
alias :kopeika :kopeek
|
246
|
+
alias :kopeiki :kopeek
|
247
|
+
end
|
248
|
+
end
|
249
|
+
end
|
250
|
+
|
251
|
+
class Object::Numeric
|
252
|
+
include RuTils::Pluralization::NumericFormatting
|
253
|
+
end
|
254
|
+
|
255
|
+
class Object::Fixnum
|
256
|
+
include RuTils::Pluralization::FixnumFormatting
|
257
|
+
end
|
258
|
+
|
259
|
+
class Object::Float
|
260
|
+
include RuTils::Pluralization::FloatFormatting
|
261
|
+
end
|