cm-ru_propisju 2.4.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/Gemfile +7 -0
- data/History.txt +61 -0
- data/README.rdoc +52 -0
- data/Rakefile +33 -0
- data/cm-ru_propisju.gemspec +50 -0
- data/lib/ru_propisju.rb +766 -0
- data/test/test_ru_propisju.rb +513 -0
- metadata +93 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: 5c6ed9fd84239013e1f843a17b8d5e6659438553
|
|
4
|
+
data.tar.gz: 2acb17150b1b40198ef65540f8184490fb252ce1
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 034a7a27a9bc876b07fc5ee8337a7bf5b7665eee93ebfdf1cce3e335e2cfbcc1558bd9337c69d5a5d3b0ca36e28ca85900de4e48fac38948d787aa95e6e6e761
|
|
7
|
+
data.tar.gz: aa8aa75b1e4b500e963be6c62a015ce47a61020e194e046c4f504db97f950859c3e95b11f8f3d0b817b5293f73c666a1f4086ebd261b2d913f3b121299097842
|
data/Gemfile
ADDED
data/History.txt
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
=== 2.4.0
|
|
2
|
+
|
|
3
|
+
* Добавлен творительный падеж (только для русской локали) (https://github.com/julik/ru_propisju/pull/15)
|
|
4
|
+
|
|
5
|
+
=== 2.3.0
|
|
6
|
+
|
|
7
|
+
* Добавлена поддержка казахстанского тенге - nodkz
|
|
8
|
+
|
|
9
|
+
=== 2.2.3
|
|
10
|
+
|
|
11
|
+
* Более строгое форматирование долей (https://github.com/julik/ru_propisju/pull/12)
|
|
12
|
+
|
|
13
|
+
=== 2.2.2
|
|
14
|
+
|
|
15
|
+
* Форматирование долей могло вызвать ошибку (https://github.com/julik/ru_propisju/issues/10)
|
|
16
|
+
|
|
17
|
+
=== 2.2.1
|
|
18
|
+
|
|
19
|
+
* Опечатка в украинских числительных (https://github.com/julik/ru_propisju/pull/9)
|
|
20
|
+
|
|
21
|
+
=== 2.2.0
|
|
22
|
+
|
|
23
|
+
* Добавлены методы rublej_extended_format, digit_rublej
|
|
24
|
+
|
|
25
|
+
=== 2.1.4
|
|
26
|
+
|
|
27
|
+
* Правильная обработка нулей в суммах
|
|
28
|
+
|
|
29
|
+
=== 2.1.3
|
|
30
|
+
|
|
31
|
+
* Починен порядок тысячных долей на ruby 1.8x
|
|
32
|
+
|
|
33
|
+
=== 2.1.2
|
|
34
|
+
|
|
35
|
+
* Починено https://github.com/julik/ru_propisju/issues/5
|
|
36
|
+
|
|
37
|
+
=== 2.1.1
|
|
38
|
+
|
|
39
|
+
* Починено https://github.com/julik/ru_propisju/issues/3
|
|
40
|
+
|
|
41
|
+
=== 2.1.0
|
|
42
|
+
|
|
43
|
+
* Восстановлен старый API для choose_plural
|
|
44
|
+
* Добавлено исключение UnknownLocale
|
|
45
|
+
|
|
46
|
+
=== 2.0.0
|
|
47
|
+
|
|
48
|
+
* Добавлена поддержка украинского языка - iz65535
|
|
49
|
+
|
|
50
|
+
=== 1.2.0
|
|
51
|
+
|
|
52
|
+
* Добавлена поддержка И Еще Нескольких Валют (тм) - terraplane
|
|
53
|
+
|
|
54
|
+
=== 1.1.0
|
|
55
|
+
|
|
56
|
+
* На самом деле количество копеек пишется цифрами
|
|
57
|
+
|
|
58
|
+
=== 1.0.0
|
|
59
|
+
|
|
60
|
+
* Модуль вынут из RuTils
|
|
61
|
+
|
data/README.rdoc
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
= ru_propisju
|
|
2
|
+
|
|
3
|
+
* http://github.com/julik/ru_propisju
|
|
4
|
+
|
|
5
|
+
== DESCRIPTION:
|
|
6
|
+
|
|
7
|
+
Выводит сумму прописью и суммы копеек, рублей и гривен. Помогает в выборе правильного числительного.
|
|
8
|
+
|
|
9
|
+
== FEATURES/PROBLEMS:
|
|
10
|
+
|
|
11
|
+
Прекрасность.
|
|
12
|
+
|
|
13
|
+
== SYNOPSIS:
|
|
14
|
+
|
|
15
|
+
RuPropisju.rublej(123.78) #=> "сто двадцать три рубля 78 копеек"
|
|
16
|
+
RuPropisju.propisju_shtuk(212.40, 2, ["сволочь", "сволочи", "сволочей"]) #=> "двести двенадцать целых четыре десятых сволочи"
|
|
17
|
+
RuPropisju.rublej_extended_format(1000, :ru, fraction_formatter: '%02d', integrals_formatter: '+ %d', integrals_delimiter: ' ', always_show_fraction: true) #=> "+ 1 000 рублей 00 копеек (одна тысяча рублей 00 копеек)"
|
|
18
|
+
|
|
19
|
+
'Продается в ' + RuPropisju.propisju_shtuk(147, 1, ["городе", "городах", "городах"], :ru_in) #=> "Продается в ста сорока семи городах"
|
|
20
|
+
|
|
21
|
+
== REQUIREMENTS:
|
|
22
|
+
|
|
23
|
+
* Прямые руки
|
|
24
|
+
|
|
25
|
+
== INSTALL:
|
|
26
|
+
|
|
27
|
+
sudo gem install ru_propisju
|
|
28
|
+
|
|
29
|
+
== LICENSE:
|
|
30
|
+
|
|
31
|
+
(The MIT License)
|
|
32
|
+
|
|
33
|
+
Copyright (c) 2011 me@julik.nl
|
|
34
|
+
|
|
35
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
36
|
+
a copy of this software and associated documentation files (the
|
|
37
|
+
'Software'), to deal in the Software without restriction, including
|
|
38
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
39
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
40
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
41
|
+
the following conditions:
|
|
42
|
+
|
|
43
|
+
The above copyright notice and this permission notice shall be
|
|
44
|
+
included in all copies or substantial portions of the Software.
|
|
45
|
+
|
|
46
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
|
47
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
48
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
49
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
|
50
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
51
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
52
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
|
2
|
+
# -*- ruby -*-
|
|
3
|
+
$KCODE = 'u' if RUBY_VERSION < '1.9.0'
|
|
4
|
+
|
|
5
|
+
require 'rubygems'
|
|
6
|
+
require 'jeweler'
|
|
7
|
+
require './lib/ru_propisju'
|
|
8
|
+
|
|
9
|
+
Jeweler::Tasks.new do |gem|
|
|
10
|
+
gem.version = RuPropisju::VERSION
|
|
11
|
+
gem.name = "ru_propisju"
|
|
12
|
+
gem.summary = "Cумма прописью"
|
|
13
|
+
gem.email = "me@julik.nl"
|
|
14
|
+
gem.homepage = "http://github.com/julik/ru_propisju"
|
|
15
|
+
gem.authors = ["Julik Tarkhanov"]
|
|
16
|
+
gem.license = 'MIT'
|
|
17
|
+
|
|
18
|
+
# Do not package invisibles
|
|
19
|
+
gem.files.exclude ".*"
|
|
20
|
+
end
|
|
21
|
+
Jeweler::RubygemsDotOrgTasks.new
|
|
22
|
+
|
|
23
|
+
require 'rake/testtask'
|
|
24
|
+
desc "Run all tests"
|
|
25
|
+
Rake::TestTask.new("test") do |t|
|
|
26
|
+
t.libs << "test"
|
|
27
|
+
t.pattern = 'test/**/test_*.rb'
|
|
28
|
+
t.verbose = true
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
task :default => [ :test ]
|
|
32
|
+
|
|
33
|
+
# vim: syntax=ruby
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# Generated by jeweler
|
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
|
4
|
+
# -*- encoding: utf-8 -*-
|
|
5
|
+
|
|
6
|
+
Gem::Specification.new do |s|
|
|
7
|
+
s.name = %q{cm-ru_propisju}
|
|
8
|
+
s.version = "2.4.0"
|
|
9
|
+
|
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
|
11
|
+
s.authors = ["Julik Tarkhanov"]
|
|
12
|
+
s.date = %q{2015-04-13}
|
|
13
|
+
s.email = %q{me@julik.nl}
|
|
14
|
+
s.extra_rdoc_files = [
|
|
15
|
+
"README.rdoc"
|
|
16
|
+
]
|
|
17
|
+
s.files = [
|
|
18
|
+
"Gemfile",
|
|
19
|
+
"History.txt",
|
|
20
|
+
"README.rdoc",
|
|
21
|
+
"Rakefile",
|
|
22
|
+
"lib/ru_propisju.rb",
|
|
23
|
+
"cm-ru_propisju.gemspec",
|
|
24
|
+
"test/test_ru_propisju.rb"
|
|
25
|
+
]
|
|
26
|
+
s.homepage = %q{http://github.com/julik/ru_propisju}
|
|
27
|
+
s.licenses = ["MIT"]
|
|
28
|
+
s.require_paths = ["lib"]
|
|
29
|
+
s.rubygems_version = %q{1.6.2}
|
|
30
|
+
s.summary = %q{Cумма прописью}
|
|
31
|
+
|
|
32
|
+
if s.respond_to? :specification_version then
|
|
33
|
+
s.specification_version = 3
|
|
34
|
+
|
|
35
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
|
36
|
+
s.add_development_dependency(%q<jeweler>, ["= 1.8.4"])
|
|
37
|
+
s.add_development_dependency(%q<rake>, [">= 0"])
|
|
38
|
+
s.add_development_dependency(%q<test-unit>, [">= 0"])
|
|
39
|
+
else
|
|
40
|
+
s.add_dependency(%q<jeweler>, ["= 1.8.4"])
|
|
41
|
+
s.add_dependency(%q<rake>, [">= 0"])
|
|
42
|
+
s.add_dependency(%q<test-unit>, [">= 0"])
|
|
43
|
+
end
|
|
44
|
+
else
|
|
45
|
+
s.add_dependency(%q<jeweler>, ["= 1.8.4"])
|
|
46
|
+
s.add_dependency(%q<rake>, [">= 0"])
|
|
47
|
+
s.add_dependency(%q<test-unit>, [">= 0"])
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
data/lib/ru_propisju.rb
ADDED
|
@@ -0,0 +1,766 @@
|
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
|
2
|
+
$KCODE = 'u' if RUBY_VERSION < '1.9.0'
|
|
3
|
+
|
|
4
|
+
# Самый лучший, прекрасный, кривой и неотразимый суперпечататель суммы прописью для Ruby.
|
|
5
|
+
#
|
|
6
|
+
# RuPropisju.rublej(123) # "сто двадцать три рубля"
|
|
7
|
+
module RuPropisju
|
|
8
|
+
|
|
9
|
+
VERSION = '2.4.0'
|
|
10
|
+
|
|
11
|
+
# http://www.xe.com/symbols.php
|
|
12
|
+
# (лица, приближенные форексам и всяким там валютам и курсам)
|
|
13
|
+
# говорят, что код валюты российского рубля - rub
|
|
14
|
+
CURRENCIES = {
|
|
15
|
+
"rur" => :rublej,
|
|
16
|
+
"rub" => :rublej,
|
|
17
|
+
"usd" => :dollarov,
|
|
18
|
+
"uah" => :griven,
|
|
19
|
+
"eur" => :evro,
|
|
20
|
+
"kzt" => :tenge,
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
SUPPORTED_CURRENCIES = CURRENCIES.keys.join ','
|
|
24
|
+
|
|
25
|
+
TRANSLATIONS = {
|
|
26
|
+
'ru' => {
|
|
27
|
+
0 => "",
|
|
28
|
+
'0' => "ноль",
|
|
29
|
+
:thousands => ["тысяча", "тысячи", "тысяч"],
|
|
30
|
+
:millions => ["миллион", "миллиона", "миллионов"],
|
|
31
|
+
:billions => ["миллиард", "миллиарда", "миллиардов"],
|
|
32
|
+
100 => "сто",
|
|
33
|
+
200 => "двести",
|
|
34
|
+
300 => "триста",
|
|
35
|
+
400 => "четыреста",
|
|
36
|
+
500 => "пятьсот",
|
|
37
|
+
600 => "шестьсот",
|
|
38
|
+
700 => "семьсот",
|
|
39
|
+
800 => "восемьсот",
|
|
40
|
+
900 => "девятьсот",
|
|
41
|
+
|
|
42
|
+
10 => "десять",
|
|
43
|
+
11 => "одиннадцать",
|
|
44
|
+
12 => "двенадцать",
|
|
45
|
+
13 => "тринадцать",
|
|
46
|
+
14 => "четырнадцать",
|
|
47
|
+
15 => "пятнадцать",
|
|
48
|
+
16 => "шестнадцать",
|
|
49
|
+
17 => "семнадцать",
|
|
50
|
+
18 => "восемнадцать",
|
|
51
|
+
19 => "девятнадцать",
|
|
52
|
+
20 => "двадцать",
|
|
53
|
+
30 => "тридцать",
|
|
54
|
+
40 => "сорок",
|
|
55
|
+
50 => "пятьдесят",
|
|
56
|
+
60 => "шестьдесят",
|
|
57
|
+
70 => "семьдесят",
|
|
58
|
+
80 => "восемьдесят",
|
|
59
|
+
90 => "девяносто",
|
|
60
|
+
# единицы, местами - c учетом рода
|
|
61
|
+
1 => {1 => "один", 2 => 'одна', 3 => 'одно'},
|
|
62
|
+
2 => {1 => "два", 2 => 'две', 3 => 'два'},
|
|
63
|
+
3 => "три",
|
|
64
|
+
4 => "четыре",
|
|
65
|
+
5 => "пять",
|
|
66
|
+
6 => "шесть",
|
|
67
|
+
7 => "семь",
|
|
68
|
+
8 => "восемь",
|
|
69
|
+
9 => "девять",
|
|
70
|
+
:rub_integral => ["рубль", "рубля", "рублей"],
|
|
71
|
+
:rub_fraction => ['копейка', 'копейки', 'копеек'],
|
|
72
|
+
:uah_integral => ["гривна", "гривны", "гривен"],
|
|
73
|
+
:uah_fraction => ['копейка', 'копейки', 'копеек'],
|
|
74
|
+
:kzt_integral => ["тенге", "тенге", "тенге"],
|
|
75
|
+
:kzt_fraction => ['тиын', 'тиына', 'тиынов'],
|
|
76
|
+
:eur_integral => ["евро", "евро", "евро"],
|
|
77
|
+
# по опыту моей прошлой работы в банке
|
|
78
|
+
# центами называют дробную часть доллара
|
|
79
|
+
# а дробную часть евро называют евроцентом
|
|
80
|
+
:eur_fraction => ["цент", "цента", "центов"],
|
|
81
|
+
:usd_integral => ["доллар", "доллара", "долларов"],
|
|
82
|
+
:usd_fraction => ['цент', 'цента', 'центов'],
|
|
83
|
+
},
|
|
84
|
+
'ru_in' => { # Предложный падеж, например в 2 городах
|
|
85
|
+
0 => "",
|
|
86
|
+
'0' => "нуле",
|
|
87
|
+
:thousands => ["тысяче", "тысячах", "тысячах"],
|
|
88
|
+
:millions => ["миллионе", "миллионах", "миллионах"],
|
|
89
|
+
:billions => ["миллиарде", "миллиардах", "миллиардах"],
|
|
90
|
+
100 => "ста",
|
|
91
|
+
200 => "двухстах",
|
|
92
|
+
300 => "трёхстах",
|
|
93
|
+
400 => "четырёхстах",
|
|
94
|
+
500 => "пятистах",
|
|
95
|
+
600 => "шестистах",
|
|
96
|
+
700 => "семистах",
|
|
97
|
+
800 => "восьмистах",
|
|
98
|
+
900 => "девятистах",
|
|
99
|
+
|
|
100
|
+
10 => "десяти",
|
|
101
|
+
11 => "одиннадцати",
|
|
102
|
+
12 => "двенадцати",
|
|
103
|
+
13 => "тринадцати",
|
|
104
|
+
14 => "четырнадцати",
|
|
105
|
+
15 => "пятнадцати",
|
|
106
|
+
16 => "шестнадцати",
|
|
107
|
+
17 => "семнадцати",
|
|
108
|
+
18 => "восемнадцати",
|
|
109
|
+
19 => "девятнадцати",
|
|
110
|
+
20 => "двадцати",
|
|
111
|
+
30 => "тридцати",
|
|
112
|
+
40 => "сорока",
|
|
113
|
+
50 => "пятидесяти",
|
|
114
|
+
60 => "шестидесяти",
|
|
115
|
+
70 => "семидесяти",
|
|
116
|
+
80 => "восьмидесяти",
|
|
117
|
+
90 => "девяноста",
|
|
118
|
+
# единицы, местами - c учетом рода
|
|
119
|
+
1 => { 1 => 'одном', 2 => 'одной', 3 => 'одном' },
|
|
120
|
+
2 => { 1 => 'двух', 2 => 'двух', 3 => 'двух' },
|
|
121
|
+
3 => "трёх",
|
|
122
|
+
4 => "четырёх",
|
|
123
|
+
5 => "пяти",
|
|
124
|
+
6 => "шести",
|
|
125
|
+
7 => "семи",
|
|
126
|
+
8 => "восьми",
|
|
127
|
+
9 => "девяти",
|
|
128
|
+
:rub_integral => %w[рубле рублях рублях],
|
|
129
|
+
:rub_fraction => %w[копейке копейках копейках],
|
|
130
|
+
:uah_integral => %w[гривне гривнах гривнах],
|
|
131
|
+
:uah_fraction => %w[копейке копейках копейках],
|
|
132
|
+
:kzt_integral => %w[тенге тенге тенге],
|
|
133
|
+
:kzt_fraction => %w[тиыне тиынах тиынах],
|
|
134
|
+
:eur_integral => %w[евро евро евро],
|
|
135
|
+
# по опыту моей прошлой работы в банке
|
|
136
|
+
# центами называют дробную часть доллара
|
|
137
|
+
# а дробную часть евро называют евроцентом
|
|
138
|
+
:eur_fraction => %w[центе центах центах],
|
|
139
|
+
:usd_integral => %w[долларе долларах долларах],
|
|
140
|
+
:usd_fraction => %w[центе центах центах],
|
|
141
|
+
},
|
|
142
|
+
'ru_gen' => { # Родительный падеж, например в течение одного рабочего дня, пяти ночей (нуля рабочих дней)
|
|
143
|
+
0 => '',
|
|
144
|
+
'0' => 'нуля',
|
|
145
|
+
:thousands => %w[тысячи тысяч тысяч],
|
|
146
|
+
:millions => %w[миллиона миллионов миллионов],
|
|
147
|
+
:billions => %w[миллиарда миллиардов миллиардов],
|
|
148
|
+
100 => 'ста',
|
|
149
|
+
200 => 'двухсот',
|
|
150
|
+
300 => 'трёхсот',
|
|
151
|
+
400 => 'четырёхсот',
|
|
152
|
+
500 => 'пятисот',
|
|
153
|
+
600 => 'шестисот',
|
|
154
|
+
700 => 'семисот',
|
|
155
|
+
800 => 'восьмисот',
|
|
156
|
+
900 => 'девятисот',
|
|
157
|
+
|
|
158
|
+
10 => 'десяти',
|
|
159
|
+
11 => 'одиннадцати',
|
|
160
|
+
12 => 'двенадцати',
|
|
161
|
+
13 => 'тринадцати',
|
|
162
|
+
14 => 'четырнадцати',
|
|
163
|
+
15 => 'пятнадцати',
|
|
164
|
+
16 => 'шестнадцати',
|
|
165
|
+
17 => 'семнадцати',
|
|
166
|
+
18 => 'восемнадцати',
|
|
167
|
+
19 => 'девятнадцати',
|
|
168
|
+
20 => 'двадцати',
|
|
169
|
+
30 => 'тридцати',
|
|
170
|
+
40 => 'сорока',
|
|
171
|
+
50 => 'пятидесяти',
|
|
172
|
+
60 => 'шестидесяти',
|
|
173
|
+
70 => 'семидесяти',
|
|
174
|
+
80 => 'восьмидесяти',
|
|
175
|
+
90 => 'девяноста',
|
|
176
|
+
# единицы, местами - c учетом рода
|
|
177
|
+
1 => { 1 => 'одного', 2 => 'одной', 3 => 'одного' },
|
|
178
|
+
2 => { 1 => 'двух', 2 => 'двух', 3 => 'двух' },
|
|
179
|
+
3 => 'трёх',
|
|
180
|
+
4 => 'четырёх',
|
|
181
|
+
5 => 'пяти',
|
|
182
|
+
6 => 'шести',
|
|
183
|
+
7 => 'семи',
|
|
184
|
+
8 => 'восьми',
|
|
185
|
+
9 => 'девяти',
|
|
186
|
+
:rub_integral => %w[рубля рублей рублей],
|
|
187
|
+
:rub_fraction => %w[копейки копеек копеек],
|
|
188
|
+
:uah_integral => %w[гривны гривен гривен],
|
|
189
|
+
:uah_fraction => %w[копейки копеек копеек],
|
|
190
|
+
:kzt_integral => %w[тенге тенге тенге],
|
|
191
|
+
:kzt_fraction => %w[тиына тиынов тиынов],
|
|
192
|
+
:eur_integral => %w[евро евро евро],
|
|
193
|
+
# TODO: решить как же всё-таки звать дробную часть евро: "цент" или "евроцент"
|
|
194
|
+
:eur_fraction => %w[цента центов центов],
|
|
195
|
+
:usd_integral => %w[доллара долларов долларов],
|
|
196
|
+
:usd_fraction => %w[цента центов центов],
|
|
197
|
+
},
|
|
198
|
+
'ru_from' => {
|
|
199
|
+
0 => "",
|
|
200
|
+
'0' => "нулём",
|
|
201
|
+
:thousands => ["тысячю", "тысячами", "тысячами"],
|
|
202
|
+
:millions => ["миллионом", "миллионами", "миллионами"],
|
|
203
|
+
:billions => ["миллиардом", "миллиардами", "миллиардами"],
|
|
204
|
+
100 => "ста",
|
|
205
|
+
200 => "двумястами",
|
|
206
|
+
300 => "тремястами",
|
|
207
|
+
400 => "четырьмястами",
|
|
208
|
+
500 => "пятьюстами",
|
|
209
|
+
600 => "шестьюстами",
|
|
210
|
+
700 => "семьюстами",
|
|
211
|
+
800 => "восьмьюстами",
|
|
212
|
+
900 => "девятьюстами",
|
|
213
|
+
|
|
214
|
+
10 => "десятью",
|
|
215
|
+
11 => "одиннадцатью",
|
|
216
|
+
12 => "двенадцатью",
|
|
217
|
+
13 => "тринадцатью",
|
|
218
|
+
14 => "четырнадцатью",
|
|
219
|
+
15 => "пятнадцатью",
|
|
220
|
+
16 => "шестнадцатью",
|
|
221
|
+
17 => "семнадцатью",
|
|
222
|
+
18 => "восемнадцатью",
|
|
223
|
+
19 => "девятнадцатью",
|
|
224
|
+
20 => "двадцатью",
|
|
225
|
+
30 => "тридцатью",
|
|
226
|
+
40 => "сорока",
|
|
227
|
+
50 => "пятьюдесятью",
|
|
228
|
+
60 => "шестьюдесятью",
|
|
229
|
+
70 => "семьюдесятью",
|
|
230
|
+
80 => "восьмьюдесятью",
|
|
231
|
+
90 => "девяноста",
|
|
232
|
+
# единицы, местами - c учетом рода
|
|
233
|
+
1 => {1 => "одним", 2 => 'одной', 3 => 'одним'},
|
|
234
|
+
2 => {1 => "двумя", 2 => 'двумя', 3 => 'двумя'},
|
|
235
|
+
3 => "тремя",
|
|
236
|
+
4 => "четырьмя",
|
|
237
|
+
5 => "пятью",
|
|
238
|
+
6 => "шестью",
|
|
239
|
+
7 => "семью",
|
|
240
|
+
8 => "восьмью",
|
|
241
|
+
9 => "девятью",
|
|
242
|
+
:rub_integral => ["рублём", "рублями", "рублями"],
|
|
243
|
+
:rub_fraction => ['копейкой', 'копейками', 'копейками'],
|
|
244
|
+
:uah_integral => ["гривной", "гривнами", "гривнами"],
|
|
245
|
+
:uah_fraction => ['копейкой', 'копейками', 'копейками'],
|
|
246
|
+
:kzt_integral => ["тенге", "тенге", "тенге"],
|
|
247
|
+
:kzt_fraction => ['тиыной', 'тиынами', 'тиынами'],
|
|
248
|
+
:eur_integral => ["евро", "евро", "евро"],
|
|
249
|
+
# по опыту моей прошлой работы в банке
|
|
250
|
+
# центами называют дробную часть доллара
|
|
251
|
+
# а дробную часть евро называют евроцентом
|
|
252
|
+
:eur_fraction => ["центом", "центами", "центами"],
|
|
253
|
+
:usd_integral => ["долларом", "долларами", "долларами"],
|
|
254
|
+
:usd_fraction => ['центом', 'центами', 'центами'],
|
|
255
|
+
},
|
|
256
|
+
'ua' => {
|
|
257
|
+
0 => "",
|
|
258
|
+
'0' => "нуль",
|
|
259
|
+
:thousands => ["тисяча", "тисячі", "тисяч"],
|
|
260
|
+
:millions => ["мільйон", "мільйона", "мільйонів"],
|
|
261
|
+
:billions => ["мільярд", "мільярда", "мільярдів"],
|
|
262
|
+
100 => "сто",
|
|
263
|
+
200 => "двісті",
|
|
264
|
+
300 => "триста",
|
|
265
|
+
400 => "чотириста",
|
|
266
|
+
500 => "п'ятьсот",
|
|
267
|
+
600 => "шістсот",
|
|
268
|
+
700 => "сімсот",
|
|
269
|
+
800 => "вісімсот",
|
|
270
|
+
900 => "дев'ятсот",
|
|
271
|
+
|
|
272
|
+
10 => "десять",
|
|
273
|
+
11 => "одинадцять",
|
|
274
|
+
12 => "дванадцять",
|
|
275
|
+
13 => "тринадцять",
|
|
276
|
+
14 => "чотирнадцять",
|
|
277
|
+
15 => "п'ятнадцять",
|
|
278
|
+
16 => "шістнадцять",
|
|
279
|
+
17 => "сімнадцять",
|
|
280
|
+
18 => "вісімнадцять",
|
|
281
|
+
19 => "дев'ятнадцять",
|
|
282
|
+
20 => "двадцять",
|
|
283
|
+
30 => "тридцять",
|
|
284
|
+
40 => "сорок",
|
|
285
|
+
50 => "п'ятьдесят",
|
|
286
|
+
60 => "шістдесят",
|
|
287
|
+
70 => "сімдесят",
|
|
288
|
+
80 => "вісімдесят",
|
|
289
|
+
90 => "дев'яносто",
|
|
290
|
+
# единицы, местами - c учетом рода
|
|
291
|
+
1 => {1 => "один", 2 => 'одна', 3 => 'одне'},
|
|
292
|
+
2 => {1 => "два", 2 => 'дві', 3 => 'два'},
|
|
293
|
+
3 => "три",
|
|
294
|
+
4 => "чотири",
|
|
295
|
+
5 => "п'ять",
|
|
296
|
+
6 => "шість",
|
|
297
|
+
7 => "сім",
|
|
298
|
+
8 => "вісім",
|
|
299
|
+
9 => "дев'ять",
|
|
300
|
+
:rub_integral => ["рубль", "рубля", "рублів"],
|
|
301
|
+
:rub_fraction => ['копійка', 'копійки', 'копійок'],
|
|
302
|
+
:uah_integral => ["гривня", "гривні", "гривень"],
|
|
303
|
+
:uah_fraction => ["копійка", "копійки", "копійок"],
|
|
304
|
+
:kzt_integral => ["тенге", "тенге", "тенге"],
|
|
305
|
+
:kzt_fraction => ['тиын', 'тиына', 'тиынов'],
|
|
306
|
+
:eur_integral => ["євро", "євро", "євро"],
|
|
307
|
+
:eur_fraction => ["євроцент", "євроцента", "євроцентів"],
|
|
308
|
+
:usd_integral => ["долар", "долара", "доларів"],
|
|
309
|
+
:usd_fraction => ['цент', 'цента', 'центів'],
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
# Переименовал предложный падеж из _in в _pre (prepositional)
|
|
313
|
+
# Оставил 'ru_in' для обратной совместимости
|
|
314
|
+
TRANSLATIONS['ru_pre'] = TRANSLATIONS['ru_in']
|
|
315
|
+
|
|
316
|
+
MONEY_GENDERS = {
|
|
317
|
+
:rub => 1,
|
|
318
|
+
:usd => 1,
|
|
319
|
+
:uah => 2,
|
|
320
|
+
:eur => 1,
|
|
321
|
+
:kzt => 1,
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
|
|
325
|
+
# Кидается при запросе неизвестной валюты
|
|
326
|
+
class UnknownCurrency < ArgumentError
|
|
327
|
+
end
|
|
328
|
+
|
|
329
|
+
# Кидается при запросе неизвестного языка
|
|
330
|
+
class UnknownLocale < ArgumentError
|
|
331
|
+
end
|
|
332
|
+
|
|
333
|
+
# Выбирает нужный падеж существительного в зависимости от числа
|
|
334
|
+
#
|
|
335
|
+
# choose_plural(3, "штука", "штуки", "штук") #=> "штуки"
|
|
336
|
+
def choose_plural(amount, *variants)
|
|
337
|
+
variants = variants.flatten
|
|
338
|
+
|
|
339
|
+
mod_ten = amount % 10
|
|
340
|
+
mod_hundred = amount % 100
|
|
341
|
+
variant = if (mod_ten == 1 && mod_hundred != 11)
|
|
342
|
+
1
|
|
343
|
+
else
|
|
344
|
+
if mod_ten >= 2 && mod_ten <= 4 && (mod_hundred <10 || mod_hundred % 100>=20)
|
|
345
|
+
2
|
|
346
|
+
else
|
|
347
|
+
3
|
|
348
|
+
end
|
|
349
|
+
end
|
|
350
|
+
variants[variant-1]
|
|
351
|
+
end
|
|
352
|
+
|
|
353
|
+
# Выводит сумму прописью в зависимости от выбранной валюты.
|
|
354
|
+
# Поддерживаемые валюты: rur, usd, uah, eur
|
|
355
|
+
#
|
|
356
|
+
# amount_in_words(345.2, 'rur') #=> "триста сорок пять рублей 20 копеек"
|
|
357
|
+
def amount_in_words(amount, currency, locale = :ru, options = {})
|
|
358
|
+
currency = currency.to_s.downcase
|
|
359
|
+
unless CURRENCIES.has_key? currency
|
|
360
|
+
raise UnknownCurrency, "Unsupported currency #{currency}, the following are supported: #{SUPPORTED_CURRENCIES}"
|
|
361
|
+
end
|
|
362
|
+
method(CURRENCIES[currency]).call(amount, locale, options)
|
|
363
|
+
end
|
|
364
|
+
|
|
365
|
+
# Выводит целое или дробное число как сумму в рублях прописью
|
|
366
|
+
#
|
|
367
|
+
# rublej(345.2) #=> "триста сорок пять рублей 20 копеек"
|
|
368
|
+
#
|
|
369
|
+
def rublej(amount, locale = :ru, options = {})
|
|
370
|
+
integrals_key = :rub_integral
|
|
371
|
+
fractions_key = :rub_fraction
|
|
372
|
+
money_gender = MONEY_GENDERS[:rub]
|
|
373
|
+
|
|
374
|
+
money(amount, locale, integrals_key, fractions_key, money_gender, true, false, options)
|
|
375
|
+
end
|
|
376
|
+
|
|
377
|
+
# Выводит целое или дробное число как сумму в расширенном формате
|
|
378
|
+
#
|
|
379
|
+
# rublej_extended_format(345.2) #=> "345 рублей 20 копеек (триста сорок пять рублей 20 копеек)"
|
|
380
|
+
#
|
|
381
|
+
def rublej_extended_format(amount, locale = :ru, options = {})
|
|
382
|
+
"#{digit_rublej(amount, locale, options)} (#{rublej(amount, locale, options)})"
|
|
383
|
+
end
|
|
384
|
+
|
|
385
|
+
# Выводит целое или дробное число как сумму в рублях и копейках не прописью
|
|
386
|
+
#
|
|
387
|
+
# digit_rublej(345.2) #=> "345 рублей 20 копеек"
|
|
388
|
+
#
|
|
389
|
+
|
|
390
|
+
def digit_rublej(amount, locale = :ru, options = {})
|
|
391
|
+
integrals_key = :rub_integral
|
|
392
|
+
fractions_key = :rub_fraction
|
|
393
|
+
money_gender = MONEY_GENDERS[:rub]
|
|
394
|
+
|
|
395
|
+
money(amount, locale, integrals_key, fractions_key, money_gender, true, true, options)
|
|
396
|
+
end
|
|
397
|
+
# Выбирает корректный вариант числительного в зависимости от рода и числа и оформляет сумму прописью
|
|
398
|
+
#
|
|
399
|
+
# propisju(243, 1) => "двести сорок три"
|
|
400
|
+
# propisju(221, 2) => "двести двадцать одна"
|
|
401
|
+
def propisju(amount, gender, locale = :ru)
|
|
402
|
+
if amount.is_a?(Integer) || amount.is_a?(Bignum)
|
|
403
|
+
propisju_int(amount, gender, [], locale)
|
|
404
|
+
else # также сработает для Decimal, дробные десятичные числительные в долях поэтому женского рода
|
|
405
|
+
propisju_float(amount, locale)
|
|
406
|
+
end
|
|
407
|
+
end
|
|
408
|
+
|
|
409
|
+
# Выводит целое или дробное число как сумму в гривнах прописью
|
|
410
|
+
#
|
|
411
|
+
# griven(32) #=> "тридцать две гривны"
|
|
412
|
+
def griven(amount, locale = :ru, options = {})
|
|
413
|
+
integrals_key = :uah_integral
|
|
414
|
+
fractions_key = :uah_fraction
|
|
415
|
+
money_gender = MONEY_GENDERS[:uah]
|
|
416
|
+
|
|
417
|
+
money(amount, locale, integrals_key, fractions_key, money_gender, false, false, options)
|
|
418
|
+
end
|
|
419
|
+
|
|
420
|
+
# Выводит целое или дробное число как сумму в долларах прописью
|
|
421
|
+
#
|
|
422
|
+
# dollarov(32) #=> "тридцать два доллара"
|
|
423
|
+
def dollarov(amount, locale = :ru, options = {})
|
|
424
|
+
integrals_key = :usd_integral
|
|
425
|
+
fractions_key = :usd_fraction
|
|
426
|
+
money_gender = MONEY_GENDERS[:usd]
|
|
427
|
+
|
|
428
|
+
money(amount, locale, integrals_key, fractions_key, money_gender, false, false, options)
|
|
429
|
+
end
|
|
430
|
+
|
|
431
|
+
# Выводит целое или дробное число как сумму в евро прописью
|
|
432
|
+
#
|
|
433
|
+
# evro(32) #=> "тридцать два евро"
|
|
434
|
+
def evro(amount, locale = :ru, options = {})
|
|
435
|
+
integrals_key = :eur_integral
|
|
436
|
+
fractions_key = :eur_fraction
|
|
437
|
+
money_gender = MONEY_GENDERS[:eur]
|
|
438
|
+
|
|
439
|
+
money(amount, locale, integrals_key, fractions_key, money_gender, false, false, options)
|
|
440
|
+
end
|
|
441
|
+
|
|
442
|
+
# Выводит целое или дробное число как сумму в тенге прописью
|
|
443
|
+
#
|
|
444
|
+
# tenge(32) #=> "тридцать два тенге"
|
|
445
|
+
def tenge(amount, locale = :ru, options = {})
|
|
446
|
+
integrals_key = :kzt_integral
|
|
447
|
+
fractions_key = :kzt_fraction
|
|
448
|
+
money_gender = MONEY_GENDERS[:kzt]
|
|
449
|
+
|
|
450
|
+
money(amount, locale, integrals_key, fractions_key, money_gender, false, false, options)
|
|
451
|
+
end
|
|
452
|
+
|
|
453
|
+
# Выводит сумму прописью в рублях по количеству копеек
|
|
454
|
+
#
|
|
455
|
+
# kopeek(343) #=> "три рубля 43 копейки"
|
|
456
|
+
def kopeek(amount, locale = :ru, options = {})
|
|
457
|
+
rublej(amount / 100.0, locale, options)
|
|
458
|
+
end
|
|
459
|
+
|
|
460
|
+
# Выводит сумму данного существительного прописью и выбирает правильное число и падеж
|
|
461
|
+
#
|
|
462
|
+
# RuPropisju.propisju_shtuk(21, 3, "колесо", "колеса", "колес") #=> "двадцать одно колесо"
|
|
463
|
+
# RuPropisju.propisju_shtuk(21, 1, "мужик", "мужика", "мужиков") #=> "двадцать один мужик"
|
|
464
|
+
def propisju_shtuk(items, gender, forms, locale = :ru)
|
|
465
|
+
elements = if (items == items.to_i)
|
|
466
|
+
[propisju(items, gender, locale), choose_plural(items, forms)]
|
|
467
|
+
else
|
|
468
|
+
[propisju(items, gender, locale), forms[1]]
|
|
469
|
+
end
|
|
470
|
+
|
|
471
|
+
elements.join(" ")
|
|
472
|
+
end
|
|
473
|
+
|
|
474
|
+
def money(amount, locale, integrals_key, fractions_key, money_gender, fraction_as_number = false, integrals_as_number = false, options = {})
|
|
475
|
+
|
|
476
|
+
options[:integrals_formatter] ||= '%d'
|
|
477
|
+
options[:fraction_formatter] ||= '%d'
|
|
478
|
+
options[:integrals_delimiter] ||= ''
|
|
479
|
+
options[:always_show_fraction] ||= false
|
|
480
|
+
|
|
481
|
+
locale_data = pick_locale(TRANSLATIONS, locale)
|
|
482
|
+
integrals = locale_data[integrals_key]
|
|
483
|
+
fractions = locale_data[fractions_key]
|
|
484
|
+
return zero(locale_data, integrals, fractions, fraction_as_number, integrals_as_number, options) if amount.zero?
|
|
485
|
+
parts = []
|
|
486
|
+
|
|
487
|
+
unless amount.to_i == 0
|
|
488
|
+
if integrals_as_number
|
|
489
|
+
parts << format_integral(amount.to_i, options) << choose_plural(amount.to_i, integrals)
|
|
490
|
+
else
|
|
491
|
+
parts << propisju_int(amount.to_i, money_gender, integrals, locale)
|
|
492
|
+
end
|
|
493
|
+
end
|
|
494
|
+
|
|
495
|
+
if amount.kind_of?(Float)
|
|
496
|
+
remainder = (amount.divmod(1)[1]*100).round
|
|
497
|
+
if remainder == 100
|
|
498
|
+
parts = [propisju_int(amount.to_i + 1, money_gender, integrals, locale)]
|
|
499
|
+
parts << format(options[:fraction_formatter], 0) << choose_plural(0, fractions) if options[:always_show_fraction]
|
|
500
|
+
else
|
|
501
|
+
if fraction_as_number
|
|
502
|
+
kop = remainder.to_i
|
|
503
|
+
if (!kop.zero? || options[:always_show_fraction])
|
|
504
|
+
parts << format(options[:fraction_formatter], kop) << choose_plural(kop, fractions)
|
|
505
|
+
end
|
|
506
|
+
else
|
|
507
|
+
parts << propisju_int(remainder.to_i, money_gender, fractions, locale)
|
|
508
|
+
end
|
|
509
|
+
end
|
|
510
|
+
else
|
|
511
|
+
parts << format(options[:fraction_formatter], 0) << choose_plural(0, fractions) if options[:always_show_fraction]
|
|
512
|
+
end
|
|
513
|
+
|
|
514
|
+
parts.join(' ')
|
|
515
|
+
end
|
|
516
|
+
|
|
517
|
+
private
|
|
518
|
+
|
|
519
|
+
def zero(locale_data, integrals, fractions, fraction_as_number, integrals_as_number, options)
|
|
520
|
+
integ = integrals_as_number ? format(options[:integrals_formatter], 0) : locale_data['0']
|
|
521
|
+
frac = fraction_as_number ? format(options[:fraction_formatter], 0) : locale_data['0']
|
|
522
|
+
parts = [integ , integrals[-1], frac, fractions[-1]]
|
|
523
|
+
parts.join(' ')
|
|
524
|
+
end
|
|
525
|
+
|
|
526
|
+
# Cоставляет число прописью для чисел до тысячи
|
|
527
|
+
|
|
528
|
+
def compose_ordinal(remaining_amount_or_nil, gender, item_forms = [], locale = :ru)
|
|
529
|
+
|
|
530
|
+
remaining_amount = remaining_amount_or_nil.to_i
|
|
531
|
+
|
|
532
|
+
locale = locale.to_s
|
|
533
|
+
|
|
534
|
+
# Ноль чего-то
|
|
535
|
+
# return "ноль %s" % item_forms[3] if remaining_amount_or_nil.zero?
|
|
536
|
+
|
|
537
|
+
rest, rest1, chosen_ordinal, ones, tens, hundreds = [nil]*6
|
|
538
|
+
|
|
539
|
+
rest = remaining_amount % 1000
|
|
540
|
+
remaining_amount = remaining_amount / 1000
|
|
541
|
+
if rest.zero?
|
|
542
|
+
# последние три знака нулевые
|
|
543
|
+
return item_forms[2]
|
|
544
|
+
end
|
|
545
|
+
|
|
546
|
+
locale_root = pick_locale(TRANSLATIONS, locale)
|
|
547
|
+
|
|
548
|
+
# начинаем подсчет с Rest
|
|
549
|
+
# сотни
|
|
550
|
+
hundreds = locale_root[(rest / 100).to_i * 100]
|
|
551
|
+
|
|
552
|
+
# десятки
|
|
553
|
+
rest = rest % 100
|
|
554
|
+
rest1 = rest / 10
|
|
555
|
+
|
|
556
|
+
# единички
|
|
557
|
+
ones = ""
|
|
558
|
+
tens = locale_root[rest1 == 1 ? rest : rest1 * 10]
|
|
559
|
+
|
|
560
|
+
# индекс выбранной формы
|
|
561
|
+
chosen_ordinal = 2
|
|
562
|
+
if rest1 < 1 || rest1 > 1 # единицы
|
|
563
|
+
value = locale_root[rest % 10]
|
|
564
|
+
# если попался хэш, делаем выбор согласно рода
|
|
565
|
+
value = value[gender] if value.kind_of? Hash
|
|
566
|
+
ones = value
|
|
567
|
+
case rest % 10
|
|
568
|
+
when 1 then chosen_ordinal = 0 # индекс формы меняется
|
|
569
|
+
when 2..4 then chosen_ordinal = 1 # индекс формы меняется
|
|
570
|
+
end
|
|
571
|
+
end
|
|
572
|
+
plural = [
|
|
573
|
+
hundreds,
|
|
574
|
+
tens,
|
|
575
|
+
ones,
|
|
576
|
+
item_forms[chosen_ordinal],
|
|
577
|
+
].compact.reject(&:empty?).join(' ').strip
|
|
578
|
+
|
|
579
|
+
return plural
|
|
580
|
+
end
|
|
581
|
+
|
|
582
|
+
DECIMALS = {
|
|
583
|
+
'ru' =>{
|
|
584
|
+
:source_words => [
|
|
585
|
+
'целая',
|
|
586
|
+
'десятая',
|
|
587
|
+
'сотая',
|
|
588
|
+
'тысячная',
|
|
589
|
+
'десятитысячная',
|
|
590
|
+
'стотысячная',
|
|
591
|
+
'миллионная',
|
|
592
|
+
'десятимиллионная',
|
|
593
|
+
'стомиллионная',
|
|
594
|
+
'миллиардная',
|
|
595
|
+
'десятимиллиардная',
|
|
596
|
+
'стомиллиардная',
|
|
597
|
+
'триллионная'
|
|
598
|
+
],
|
|
599
|
+
:prefix => ["ая", 'ых'],
|
|
600
|
+
},
|
|
601
|
+
'ru_in' =>{
|
|
602
|
+
:source_words => [
|
|
603
|
+
'целой',
|
|
604
|
+
'десятой',
|
|
605
|
+
'сотой',
|
|
606
|
+
'тысячной',
|
|
607
|
+
'десятитысячной',
|
|
608
|
+
'стотысячной',
|
|
609
|
+
'миллионной',
|
|
610
|
+
'десятимиллионной',
|
|
611
|
+
'стомиллионной',
|
|
612
|
+
'миллиардной',
|
|
613
|
+
'десятимиллиардной',
|
|
614
|
+
'стомиллиардной',
|
|
615
|
+
'триллионной'
|
|
616
|
+
],
|
|
617
|
+
:prefix => ["ой", 'ых'],
|
|
618
|
+
},
|
|
619
|
+
'ru_from' =>{
|
|
620
|
+
:source_words => [
|
|
621
|
+
'целой',
|
|
622
|
+
'десятой',
|
|
623
|
+
'сотой',
|
|
624
|
+
'тысячной',
|
|
625
|
+
'десятитысячной',
|
|
626
|
+
'стотысячной',
|
|
627
|
+
'миллионной',
|
|
628
|
+
'десятимиллионной',
|
|
629
|
+
'стомиллионной',
|
|
630
|
+
'миллиардной',
|
|
631
|
+
'десятимиллиардной',
|
|
632
|
+
'стомиллиардной',
|
|
633
|
+
'триллионной'
|
|
634
|
+
],
|
|
635
|
+
:prefix => ["ой", 'ыми'],
|
|
636
|
+
},
|
|
637
|
+
'ua' => {
|
|
638
|
+
:source_words => [
|
|
639
|
+
'ціла',
|
|
640
|
+
'десята',
|
|
641
|
+
'сота',
|
|
642
|
+
'тисячна',
|
|
643
|
+
'десятитисячна',
|
|
644
|
+
'стотисячна',
|
|
645
|
+
'мільйонна',
|
|
646
|
+
'десятимільйонна',
|
|
647
|
+
'стомільйонна',
|
|
648
|
+
'мільярдна',
|
|
649
|
+
'десятимільярдна',
|
|
650
|
+
'стомільярдна',
|
|
651
|
+
'трильонна'
|
|
652
|
+
],
|
|
653
|
+
:prefix => ["а", 'их'],
|
|
654
|
+
},
|
|
655
|
+
}
|
|
656
|
+
# Добавляем новый префикс для предложного падежа и новые значения для родительного (совпадающие с предложным)
|
|
657
|
+
DECIMALS['ru_pre'] = DECIMALS['ru_in']
|
|
658
|
+
DECIMALS['ru_gen'] = DECIMALS['ru_in']
|
|
659
|
+
|
|
660
|
+
# Выдает сумму прописью с учетом дробной доли. Дробная доля округляется до миллионной, или (если
|
|
661
|
+
# дробная доля оканчивается на нули) до ближайшей доли или точки ( 500 тысячных округляется до 5 десятых, 30.0000 до 30).
|
|
662
|
+
def propisju_float(num, locale = :ru)
|
|
663
|
+
locale_root = pick_locale(DECIMALS, locale)
|
|
664
|
+
source_expression = locale_root[:prefix][0]
|
|
665
|
+
target_prefix = locale_root[:prefix][1]
|
|
666
|
+
words = locale_root[:source_words].map do |e|
|
|
667
|
+
[
|
|
668
|
+
e,
|
|
669
|
+
e.gsub(/#{source_expression}$/, target_prefix),
|
|
670
|
+
e.gsub(/#{source_expression}$/, target_prefix),
|
|
671
|
+
]
|
|
672
|
+
end.freeze
|
|
673
|
+
|
|
674
|
+
# Укорачиваем до триллионной доли
|
|
675
|
+
formatted = num.to_s[/^\d+(\.\d{0,#{words.length - 1}})?/].gsub(/0+$/, '')
|
|
676
|
+
wholes, decimals = formatted.split(".")
|
|
677
|
+
|
|
678
|
+
return propisju_int(wholes.to_i, 1, [], locale) if decimals.to_i.zero?
|
|
679
|
+
|
|
680
|
+
whole_st = propisju_shtuk(wholes.to_i, 2, words[0], locale)
|
|
681
|
+
|
|
682
|
+
rem_st = propisju_shtuk(decimals.to_i, 2, words[decimals.length], locale)
|
|
683
|
+
[whole_st, rem_st].compact.join(" ")
|
|
684
|
+
end
|
|
685
|
+
|
|
686
|
+
# Выполняет преобразование числа из цифрого вида в символьное
|
|
687
|
+
#
|
|
688
|
+
# amount - числительное
|
|
689
|
+
# gender = 1 - мужской, = 2 - женский, = 3 - средний
|
|
690
|
+
# one_item - именительный падеж единственного числа (= 1)
|
|
691
|
+
# two_items - родительный падеж единственного числа (= 2-4)
|
|
692
|
+
# five_items - родительный падеж множественного числа ( = 5-10)
|
|
693
|
+
#
|
|
694
|
+
# Примерно так:
|
|
695
|
+
# propisju(42, 1, ["сволочь", "сволочи", "сволочей"]) # => "сорок две сволочи"
|
|
696
|
+
def propisju_int(amount, gender = 1, item_forms = [], locale = :ru)
|
|
697
|
+
|
|
698
|
+
locale_root = pick_locale(TRANSLATIONS, locale)
|
|
699
|
+
|
|
700
|
+
# zero!
|
|
701
|
+
if amount.zero?
|
|
702
|
+
return [locale_root['0'], item_forms[-1]].compact.join(' ')
|
|
703
|
+
end
|
|
704
|
+
|
|
705
|
+
fractions = [
|
|
706
|
+
[:trillions, 1_000_000_000_000],
|
|
707
|
+
[:billions, 1_000_000_000],
|
|
708
|
+
[:millions, 1_000_000],
|
|
709
|
+
[:thousands, 1_000],
|
|
710
|
+
]
|
|
711
|
+
|
|
712
|
+
parts = fractions.map do | name, multiplier |
|
|
713
|
+
[name, fraction = (amount / multiplier) % 1000]
|
|
714
|
+
end
|
|
715
|
+
|
|
716
|
+
# Единицы обрабатываем отдельно
|
|
717
|
+
ones = amount % 1000
|
|
718
|
+
|
|
719
|
+
# Составляем простые тысячные доли
|
|
720
|
+
parts_in_writing = parts.reject do | part |
|
|
721
|
+
part[1].zero?
|
|
722
|
+
end.map do | name, fraction |
|
|
723
|
+
thousandth_gender = (name == :thousands) ? 2 : 1
|
|
724
|
+
compose_ordinal(fraction, thousandth_gender, locale_root[name], locale)
|
|
725
|
+
end
|
|
726
|
+
|
|
727
|
+
# И только единицы обрабатываем с переданными параметрами
|
|
728
|
+
parts_in_writing.push(compose_ordinal(ones, gender, item_forms, locale))
|
|
729
|
+
|
|
730
|
+
parts_in_writing.compact.join(' ')
|
|
731
|
+
end
|
|
732
|
+
|
|
733
|
+
def format_integral(number, options)
|
|
734
|
+
formatted_number = format(options[:integrals_formatter], number)
|
|
735
|
+
delimited_number(formatted_number, options[:integrals_delimiter])
|
|
736
|
+
end
|
|
737
|
+
|
|
738
|
+
def delimited_number(number, delimiter)
|
|
739
|
+
return number.to_s if delimiter == ''
|
|
740
|
+
|
|
741
|
+
number.to_s.gsub!(/(\d)(?=(\d\d\d)+(?!\d))/) do |digit_to_delimit|
|
|
742
|
+
"#{digit_to_delimit}#{delimiter}"
|
|
743
|
+
end || number.to_s
|
|
744
|
+
end
|
|
745
|
+
|
|
746
|
+
def pick_locale(from_hash, locale)
|
|
747
|
+
return from_hash[locale.to_s] if from_hash.has_key?(locale.to_s)
|
|
748
|
+
raise UnknownLocale, "Unknown locale #{locale.inspect}"
|
|
749
|
+
end
|
|
750
|
+
|
|
751
|
+
alias_method :rublja, :rublej
|
|
752
|
+
alias_method :rubl, :rublej
|
|
753
|
+
|
|
754
|
+
alias_method :kopeika, :kopeek
|
|
755
|
+
alias_method :kopeiki, :kopeek
|
|
756
|
+
|
|
757
|
+
alias_method :grivna, :griven
|
|
758
|
+
alias_method :grivny, :griven
|
|
759
|
+
|
|
760
|
+
alias_method :dollar, :dollarov
|
|
761
|
+
alias_method :dollary, :dollarov
|
|
762
|
+
|
|
763
|
+
public_instance_methods(true).map{|m| module_function(m) }
|
|
764
|
+
|
|
765
|
+
module_function :zero, :propisju_int, :propisju_float, :compose_ordinal, :pick_locale, :format_integral, :delimited_number
|
|
766
|
+
end
|