runumerals 1.0.2
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/.yardopts +6 -0
- data/LICENSE +21 -0
- data/README.md +109 -0
- data/Rakefile +17 -0
- data/lib/ru_numerals.rb +929 -0
- data/lib/version.rb +4 -0
- metadata +92 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 50737e4e66677d78dffb87b75fde135d380ed37e
|
4
|
+
data.tar.gz: 6cfb02594f54885cee13bc1769dadf83f3b61d2b
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 452e30f74ae5357d46c5faa11de415b5e0c7627100b35334c84342d0683a935eb432da79b2a8e1f39212941fb12c37cae6bc52cdb338d81b27b86812a4c070ea
|
7
|
+
data.tar.gz: 8ce338635748f9910500993aec7525ee81dff3dd200d56e3574531dd66e176a3d58ccedcf3e33f7cc2e36fc7e83aa7dc8c12f5dc07887fe0f27230ff3388d01e
|
data/.yardopts
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2018 Boris Fifelin
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,109 @@
|
|
1
|
+
Runumerals: Convertation of numeric values to russian numerals
|
2
|
+
========
|
3
|
+
**Authors**: Sergey Abel, Boris Fifelin
|
4
|
+
|
5
|
+
**Copyright**: 1996 - 2018
|
6
|
+
|
7
|
+
**License**: MIT License
|
8
|
+
|
9
|
+
**Latest Version**: 1.0.2
|
10
|
+
|
11
|
+
**Ruby Version**: >= 1.9.2
|
12
|
+
|
13
|
+
Synopsis
|
14
|
+
--------
|
15
|
+
Runumerals is a Ruby module providing methods that convert numeric values to russian numerals.
|
16
|
+
|
17
|
+
The rest of this file is in Russian as the use of this module implies the knowledge of the Russian language.
|
18
|
+
|
19
|
+
Модуль RuNumerals содержит функции для работы с русскими числительными.
|
20
|
+
Основное предназначение - преобразование числительных для финансовых документов (не забудьте про capitalize ;-).
|
21
|
+
Также иногда требуют нумерацию листов в виде "лист 2 из 35 листов", здесь будет полезна способность правильно давать склонение сущесвительного в зависимости от количества.
|
22
|
+
Если найдете ещё какие-либо применения, буду только рад.
|
23
|
+
|
24
|
+
|
25
|
+
Возможности
|
26
|
+
--------
|
27
|
+
1. Преобразование в количественные числительные
|
28
|
+
2. Преобразование в порядковые числительные
|
29
|
+
3. Преобразование числовых предствалений дат, времени, денежных единиц, дробей
|
30
|
+
4. Согласование по роду, падежу; возможность задать свою грамматику
|
31
|
+
5. Возможность расширения классов Ruby методами модуля RuNumerals (Ruby way?)
|
32
|
+
|
33
|
+
Feci quod potui, faciant meliora potentes :-)
|
34
|
+
|
35
|
+
Установка
|
36
|
+
---------
|
37
|
+
|
38
|
+
$ gem install runumerals
|
39
|
+
|
40
|
+
Примеры
|
41
|
+
---------
|
42
|
+
|
43
|
+
```
|
44
|
+
|
45
|
+
require 'ru_numerals'
|
46
|
+
RuNumerals::ru_numeral(154,'д') #=> "ста пятидесяти четырём"
|
47
|
+
RuNumerals::ru_numeral(101,'','с',1) #=> "ноль тысяч сто одно"
|
48
|
+
RuNumerals::ru_numeral(1,'',RuNumerals::RUBGRAM,-1) #=> "рубль"
|
49
|
+
RuNumerals::ru_numeral(2,'',RuNumerals::RUBGRAM,-1) #=> "рубля"
|
50
|
+
RuNumerals::ru_ordinal(1) #=> "первый"
|
51
|
+
RuNumerals::ru_ordinal(2) #=> "второй"
|
52
|
+
RuNumerals::ru_ordinal(250000000,'в','ж') #=> "двухсотпятидесятимиллионную"
|
53
|
+
RuNumerals::ru_ordinal(5,'т','ж',true) #=> "пятыми"
|
54
|
+
RuNumerals::ru_ordinal(-5,'в','о') #=> "минус пятого"
|
55
|
+
RuNumerals::ru_date(Time.now) #=> "девятое ноября две тысячи шестнадцатого года"
|
56
|
+
RuNumerals::ru_date(Time.now,"д",spellyy: false) #=> "девятому ноября 2016 года"
|
57
|
+
RuNumerals::ru_date(Time.now,spelldd: false, spellyy: false) #=> "9 ноября 2016 года"
|
58
|
+
RuNumerals::ru_time(Time.now) #=> "восемнадцать часов пятьдесят две минуты двадцать секунд"
|
59
|
+
RuNumerals::ru_time(Time.now,"д",spellhh: false , spellmm: false , spellss: false)
|
60
|
+
#=> "18 часам 52 минутам 20 секундам"
|
61
|
+
RuNumerals::ru_time(Time.now,'',spellhh: false , spellmm: false , noseconds: false)
|
62
|
+
#=> "18 часов 52 минуты"
|
63
|
+
RuNumerals::ru_money(123.029,"и",RuNumerals::RUBGRAM,RuNumerals::KOPGRAM) #=> "сто двадцать три рубля три копейки"
|
64
|
+
RuNumerals::ru_money(123.029,"р",RuNumerals::RUBGRAM,RuNumerals::KOPGRAM, spellkop: false) #=> "ста двадцати трёх рублей 03 копеек"
|
65
|
+
RuNumerals::ru_money(123.029,"т",nil,RuNumerals::KOPGRAM) #=> "двенадцатью тысячами тремястами тремя копейками"
|
66
|
+
RuNumerals::ru_fractional(Rational(8,7)) #=> "одна целая одна седьмая"
|
67
|
+
RuNumerals::ru_fractional(Rational(8,7),"",improper: true) #=> "восемь седьмых"
|
68
|
+
RuNumerals::ru_fractional(Rational(6,2),"т") #=> "тремя"
|
69
|
+
RuNumerals::ru_fractional(1001.02) #=> "одна тысяча одна целая две сотых"
|
70
|
+
RuNumerals::extend(Integer) #=> nil
|
71
|
+
1.ru_numeral #=> "один"
|
72
|
+
1.ru_ordinal("д") #=> "первому"
|
73
|
+
RuNumerals::extend(Float,:ru_rubleskopecks) #=> nil
|
74
|
+
1.25.ru_rubleskopecks("и",spellkop: false) #=> "один рубль 25 копеек"
|
75
|
+
```
|
76
|
+
|
77
|
+
Замечания
|
78
|
+
---------
|
79
|
+
Общие параметры для ряда функций:
|
80
|
+
|
81
|
+
* gr_casus (<tt>String</tt>), значение по умолчанию: "и" - падеж числительного
|
82
|
+
Может принимать значения "и","р","д","в","т" или "п" (первая буква названия падежа)
|
83
|
+
|
84
|
+
* grammar (<tt>String</tt>), значение по умолчанию: "мн",
|
85
|
+
описывает грамматику (род, одушевлённость/неодушевлённость, склонение по падежам).
|
86
|
+
|
87
|
+
Имеет вид: <tt>"[мжс][но]|И1|Р1|Д1|В1|Т1|П1|И2|Р2|Д2|В2|Т2|П2"</tt> где
|
88
|
+
|
89
|
+
1. \[мжс\] указывет род ("м" - мужской, "ж" - женский, "с" - средний)
|
90
|
+
2. \[но\] указывет одушевлённость: "н" для неодушевлённых, "о" для одушевлённых
|
91
|
+
3. склонение по падежам (знак | - разделитель между падежными формами):
|
92
|
+
"И1" - форма для именительного падежа ед. ч., ... , "П2" - форма предложного падежа мн. ч.
|
93
|
+
|
94
|
+
Если в грамматике не указаны падежные формы, то, соответсвенно, склоняемое с числительным слово не выводится.
|
95
|
+
|
96
|
+
Примеры грамматик:
|
97
|
+
|
98
|
+
```
|
99
|
+
|
100
|
+
"мн|этаж|этажа|этажу|этаж|этажом|этаже|этажи|этажей|этажам|этажи|этажами|этажах"
|
101
|
+
"мо|человек|человека|человеку|человека|человеком|человеке|человеки|человек|человекам|человеков|человеками|человеках"
|
102
|
+
"жн" # только согласование числительного по роду
|
103
|
+
```
|
104
|
+
|
105
|
+
* Будьте осторожны с грамматиками. Например, множественное число слова <i>человек</i> - <i>люди</i> (супплетивная форма).
|
106
|
+
Но с числительными употрбеляется именно <i>человеки</i> (не в именительном падеже, разумеется)
|
107
|
+
|
108
|
+
* Также могут возникнуть проблемы с предложным падежом - в некоторых случаях требуется его другая форма (местный падеж).
|
109
|
+
Например, "в 1965 <i>году</i>", а не "<i>годе</i>", "в третьем <i>ряду</i>", "в первом <i>часу</i>" и т.п.
|
data/Rakefile
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/lib/version.rb')
|
2
|
+
|
3
|
+
task :build => :gendoc do
|
4
|
+
system "gem build runumerals.gemspec"
|
5
|
+
end
|
6
|
+
|
7
|
+
|
8
|
+
task :gendoc do
|
9
|
+
system "yardoc"
|
10
|
+
end
|
11
|
+
|
12
|
+
|
13
|
+
task :release => :build do
|
14
|
+
system "gem push axlsx-#{RuNumerals::VERSION}.gem"
|
15
|
+
end
|
16
|
+
|
17
|
+
task :default => :build
|
data/lib/ru_numerals.rb
ADDED
@@ -0,0 +1,929 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
# Russian nurerals
|
3
|
+
#
|
4
|
+
# Copyright (c) 1996 Sergey Abel, (c) 2016 Boris Fifelin
|
5
|
+
#
|
6
|
+
# Licensed under the same terms as Ruby. No warranty is provided.
|
7
|
+
#
|
8
|
+
# Feci quod potui, faciant meliora potentes :-)
|
9
|
+
#
|
10
|
+
# RuNumerals contains methods that convert numeric values to russian numerals.
|
11
|
+
# The description and comments are in Russian as the use of this module implies
|
12
|
+
# the knowledge of the Russian language.
|
13
|
+
#
|
14
|
+
# Модуль RuNumerals содержит функции для работы с русскими числительными.
|
15
|
+
# Основное предназначение - преобразование числительных для финансовых документов (не забудьте про capitalize ;-).
|
16
|
+
# Также иногда требуют нумерацию листов в виде "лист 2 из 35 листов", здесь будет полезна
|
17
|
+
# способность правильно давать склонение сущесвительного в зависимости от количества.
|
18
|
+
# Если найдете ещё какие-либо применения, буду только рад.
|
19
|
+
#
|
20
|
+
# Общие параметры для ряда функций:
|
21
|
+
#
|
22
|
+
# * grammatical_case (+String+), значение по умолчанию: "и" - падеж числительного
|
23
|
+
# Может принимать значения "и","р","д","в","т" или "п" (первая буква названия падежа)
|
24
|
+
# * grammar (+String+), значение по умолчанию: "мн",
|
25
|
+
# описывает грамматику (род, одушевлённость/неодушевлённость, склонение по падежам).
|
26
|
+
#
|
27
|
+
# Имеет вид: <tt>"[мжс][но]|И1|Р1|Д1|В1|Т1|П1|И2|Р2|Д2|В2|Т2|П2"</tt> где
|
28
|
+
# 1. \[мжс\] указывет род ("м" - мужской, "ж" - женский, "с" - средний)
|
29
|
+
# 2. \[но\] указывет одушевлённость: "н" для неодушевлённых, "о" для одушевлённых
|
30
|
+
# 3. склонение по падежам (знак | - разделитель между падежными формами):
|
31
|
+
# "И1" - форма для именительного падежа ед. ч., ... , "П2" - форма предложного падежа мн. ч.
|
32
|
+
# Если в грамматике не указаны падежные формы, то, соответсвенно, склоняемое с числительным слово не выводится.
|
33
|
+
#
|
34
|
+
# Примеры грамматик:
|
35
|
+
#
|
36
|
+
# "мн|этаж|этажа|этажу|этаж|этажом|этаже|этажи|этажей|этажам|этажи|этажами|этажах"
|
37
|
+
# "мо|человек|человека|человеку|человека|человеком|человеке|человеки|человек|человекам|человеков|человеками|человеках"
|
38
|
+
# "жн" # только согласование числительного по роду
|
39
|
+
#
|
40
|
+
# Замечания:
|
41
|
+
# - Будьте осторожны с грамматиками, например, множественное число слова <i>человек</i> - <i>люди</i> (супплетивная форма).
|
42
|
+
# Но с числительными употрбеляется именно <i>человеки</i> (не в именительном падеже, разумеется)
|
43
|
+
# - Также могут возникнуть проблемы с предложным падежом - в некоторых случаях требуется его другая форма (местный падеж).
|
44
|
+
# Например, "в 1961 <i>году</i>", а не <i>годе</i>, "в третьем <i>ряду</i>", "в первом <i>часу</i>" и т.п.
|
45
|
+
|
46
|
+
require 'version.rb'
|
47
|
+
|
48
|
+
module RuNumerals
|
49
|
+
# RuNumerals contains methods that convert numeric values to russian numerals.
|
50
|
+
# The description and comments are in Russian as the use of this module implies the knowledge of the Russian language.
|
51
|
+
|
52
|
+
EXTEND_MAP={Integer => [:ru_numeral, :ru_ordinal],
|
53
|
+
Float => [:ru_fractional, :ru_money, :ru_rubles, :ru_kopecks, :ru_rubleskopecks,
|
54
|
+
:ru_dollars, :ru_cents, :ru_dollarscents, :ru_euros, :ru_eurocents, :ru_euroseurocents],
|
55
|
+
Rational => [:ru_fractional],
|
56
|
+
Time => [:ru_date, :ru_time]}
|
57
|
+
private_constant :EXTEND_MAP
|
58
|
+
CASUS_STR="ирдвтп"
|
59
|
+
private_constant :CASUS_STR
|
60
|
+
ORDWORD=[nil,"тысяч","миллион","миллиард","триллион","квадриллион","квинтиллион","секстиллион","септиллион","октиллион","нониллион",
|
61
|
+
"дециллион","ундециллион","додециллион","тредециллион","кваттуордециллион",
|
62
|
+
"квиндециллион","седециллион","септдециллион","октодециллион","новемдециллион",
|
63
|
+
"вигинтиллион","анвигинтиллион","дуовигинтиллион","тревигинтиллион","кватторвигинтиллион",
|
64
|
+
"квинвигинтиллион","сексвигинтиллион","септемвигинтиллион","октовигинтиллион","новемвигинтиллион",
|
65
|
+
"тригинтиллион","антригинтиллион","дуотригинтиллион","третригинтиллион","кваттортригинтиллион",
|
66
|
+
"квинтригинтиллион","секстригинтиллион","септемтригинтиллион","октотригинтиллион","новемтригинтиллион",
|
67
|
+
"квадрагинтиллион","анквадрагинтиллион","дуоквадрагинтиллион","треквадрагинтиллион","кватторквадрагинтиллион",
|
68
|
+
"квинквадрагинтиллион","сексквадрагинтиллион","септемквадрагинтиллион","октоквадрагинтиллион","новемквадрагинтиллион",
|
69
|
+
"квинквагинтиллион","анквинквагинтиллион","дуоквинквагинтиллион","треквинквагинтиллион","кватторквинквагинтиллион",
|
70
|
+
"квинквинквагинтиллион","сексквинквагинтиллион","септемквинквагинтиллион","октоквинквагинтиллион","новемквинквагинтиллион",
|
71
|
+
"сексагинтиллион","ансексагинтиллион","дуосексагинтиллион","тресексагинтиллион","кватторсексагинтиллион",
|
72
|
+
"квинсексагинтиллион","секссексагинтиллион","септемсексагинтиллион","октосексагинтиллион","новемсексагинтиллион",
|
73
|
+
"септуагинтиллион","ансептуагинтиллион","дуосептуагинтиллион","тресептуагинтиллион","кватторсептуагинтиллион",
|
74
|
+
"квинсептуагинтиллион","секссептуагинтиллион","септемсептуагинтиллион","октосептуагинтиллион","новемсептуагинтиллион",
|
75
|
+
"октогинтиллион","аноктогинтиллион","дуооктогинтиллион","треоктогинтиллион","кваттороктогинтиллион",
|
76
|
+
"квиноктогинтиллион","сексоктогинтиллион","септемоктогинтиллион","октооктогинтиллион","новемоктогинтиллион",
|
77
|
+
"нонагинтиллион","аннонагинтиллион","дуононагинтиллион","тренонагинтиллион","кватторнонагинтиллион",
|
78
|
+
"квиннонагинтиллион","секснонагинтиллион","септемнонагинтиллион","октононагинтиллион","новемнонагинтиллион","центиллион"]
|
79
|
+
private_constant :ORDWORD
|
80
|
+
THOU_ENDING=[["а","и","е","у","ей","е"],["и","","ам","и","ами","ах"]]
|
81
|
+
private_constant :THOU_ENDING
|
82
|
+
MILLI_ENDING=[["","а","у","","ом","е"],["ы","ов","ам","ы","ами","ах"]]
|
83
|
+
private_constant :MILLI_ENDING
|
84
|
+
HUNDREDS=[nil,["сто","ста","ста","сто","ста","ста"],
|
85
|
+
["двести","двухсот","двумстам","двести","двумястами","двухстах"],
|
86
|
+
["триста","трёхсот","трёмстам","триста","тремястами","трёхстах"],
|
87
|
+
["четыреста","четырёхсот","четырёмстам","четыреста","четырьмястами","четырёхстах"],
|
88
|
+
["пятьсот","пятисот","пятистам","пятьсот","пятьюстами","пятистах"],
|
89
|
+
["шестьсот","шестисот","шестистам","шестьсот","шестьюстами","шестистах"],
|
90
|
+
["семьсот","семисот","семистам","семьсот","семьюстами","семистах"],
|
91
|
+
["восемьсот","восьмисот","восьмистам","восемьсот","восьмьюстами","восьмистах"],
|
92
|
+
["девятьсот","девятисот","девятистам","девятьсот","девятьюстами","девятистах"]]
|
93
|
+
private_constant :HUNDREDS
|
94
|
+
TWENTIES=[nil,nil,
|
95
|
+
["двадцать","двадцати","двадцати","двадцать","двадцатью","двадцати"],
|
96
|
+
["тридцать","тридцати","тридцати","тридцать","тридцатью","тридцати"],
|
97
|
+
["сорок","сорока","сорока","сорок","сорока","сорока"],
|
98
|
+
["пятьдесят","пятидесяти","пятидесяти","пятьдесят","пятьюдесятью","пятидесяти"],
|
99
|
+
["шестьдесят","шестидесяти","шестидесяти","шестьдесят","шестьюдесятью","шестидесяти"],
|
100
|
+
["семьдесят","семидесяти","семидесяти","семьдесят","семьюдесятью","семидесяти"],
|
101
|
+
["восемьдесят","восьмидесяти","восьмидесяти","восемьдесят","восьмьюдесятью","восьмидесяти"],
|
102
|
+
["девяносто","девяноста","девяноста","девяносто","девяноста","девяноста"]]
|
103
|
+
private_constant :TWENTIES
|
104
|
+
TEENCASES=["ь","и","и","ь","ью","и"]
|
105
|
+
private_constant :TEENCASES
|
106
|
+
ONES=[["ноль","нуля","нулю","ноль","нулём","нуле"],
|
107
|
+
["один","одного","одному","один","одним","одном"],
|
108
|
+
["два","двух","двум","два","двумя","двух"],
|
109
|
+
["три","трёх","трём","три","тремя","трёх"],
|
110
|
+
["четыре","четырёх","четырём","четыре","четырьмя","четырёх"],
|
111
|
+
["пять","пяти","пяти","пять","пятью","пяти"],
|
112
|
+
["шесть","шести","шести","шесть","шестью","шести"],
|
113
|
+
["семь","семи","семи","семь","семью","семи"],
|
114
|
+
["восемь","восьми","восьми","восемь","восемью","восьми"],
|
115
|
+
["девять","девяти","девяти","девять","девятью","девяти"]]
|
116
|
+
private_constant :ONES
|
117
|
+
ONES1=[nil,["одна","одной","одной","одну","одной","одной"],
|
118
|
+
["одно","одного","одному","одно","одним","одном"]]
|
119
|
+
private_constant :ONES1
|
120
|
+
ONES2=[nil,["две","двух","двум","две","двумя","двух"],
|
121
|
+
["два","двух","двум","два","двумя","двух"]]
|
122
|
+
private_constant :ONES2
|
123
|
+
ENDING02678=[["ой","ого","ому","ой","ым","ом"],
|
124
|
+
["ая","ой","ой","ую","ой","ой"],
|
125
|
+
["ое","ого","ому","ое","ым","ом"],
|
126
|
+
["ые","ых","ым","ые","ыми","ых"]]
|
127
|
+
private_constant :ENDING02678
|
128
|
+
ENDING1459=[["ый","ого","ому","ый","ым","ом"],
|
129
|
+
["ая","ой","ой","ую","ой","ой"],
|
130
|
+
["ое","ого","ому","ое","ым","ом"],
|
131
|
+
["ые","ых","ым","ые","ыми","ых"]]
|
132
|
+
private_constant :ENDING1459
|
133
|
+
ENDING3=[["ий","ьего","ьему","ий","ьим","ьем"],
|
134
|
+
["ья","ьей","ьей","ью","ьей","ьей"],
|
135
|
+
["ье","ьего","ьему","ье","ьим","ьем"],
|
136
|
+
["ьи","ьих","ьим","ьи","ьими","ьих"]]
|
137
|
+
private_constant :ENDING3
|
138
|
+
ACCUSATIVE=["ого","ую","ое","ых"]
|
139
|
+
private_constant :ACCUSATIVE
|
140
|
+
ACCUSATIVE3=["ьего","ью","ье","ьих"]
|
141
|
+
private_constant :ACCUSATIVE3
|
142
|
+
COMPOUNDS=["одно","двух","трёх","четырёх","пяти","шести","семи","восьми","девяти"]
|
143
|
+
private_constant :COMPOUNDS
|
144
|
+
TEENS=["десят","одиннадцат","двенадцат","тринадцат","четырнадцат","пятнадцат","шестнадцат","семнадцат","восемнадцат","девятнадцат"]
|
145
|
+
private_constant :TEENS
|
146
|
+
TIES=[nil,nil,"двадцат","тридцат","сороков","пятидесят","шестидесят","семидесят","восьмидесят","девяност"]
|
147
|
+
private_constant :TIES
|
148
|
+
ORDINALS=["нулев","перв","втор","трет","четвёрт","пят","шест","седьм","восьм","девят"]
|
149
|
+
private_constant :ORDINALS
|
150
|
+
MONTAB=["января","февраля","марта","апреля","мая","июня","июля","августа","сентября","октября","ноября","декабря"]
|
151
|
+
private_constant :MONTAB
|
152
|
+
YEARGRAM="мн|год|года|году|год|годом|годе|годы|годов|годам|годы|годами|годах"
|
153
|
+
private_constant :YEARGRAM
|
154
|
+
HOURGRAM="мн|час|часа|часу|час|часом|часе|часы|часов|часам|часы|часами|часах"
|
155
|
+
private_constant :HOURGRAM
|
156
|
+
MINGRAM="жн|минута|минуты|минуте|минуту|минутой|минуте|минуты|минут|минутам|минуты|минутами|минутах"
|
157
|
+
private_constant :MINGRAM
|
158
|
+
SECGRAM="жн|секунда|секунды|секунде|секунду|секундой|секунде|секунды|секунд|секундам|секунды|секундами|секундах"
|
159
|
+
private_constant :SECGRAM
|
160
|
+
WHOLEGRAM="жн|целая|целой|целой|целую|целой|целой|целые|целых|целым|целые|целыми|целых"
|
161
|
+
private_constant :WHOLEGRAM
|
162
|
+
# Грамматика слова "рубль"
|
163
|
+
RUBGRAM="мн|рубль|рубля|рублю|рубль|рублём|рубле|рубли|рублей|рублям|рубли|рублями|рублях"
|
164
|
+
# Грамматика слова "копейка"
|
165
|
+
KOPGRAM="жн|копейка|копейки|копейке|копейку|копейкой|копейке|копейки|копеек|копейкам|копейки|копейками|копейках"
|
166
|
+
# Грамматика слова "доллар"
|
167
|
+
DOLLARGRAM="мн|доллар|доллара|доллару|доллар|долларом|долларе|доллары|долларов|долларам|доллары|долларами|долларах"
|
168
|
+
# Грамматика слова "цент"
|
169
|
+
CENTGRAM="мн|цент|цента|центу|цент|центом|центе|центы|центов|центам|центы|центами|центах"
|
170
|
+
# Грамматика слова "евро"
|
171
|
+
EUROGRAM="мн|евро|евро|евро|евро|евро|евро|евро|евро|евро|евро|евро|евро"
|
172
|
+
# Грамматика слова "евроцент"
|
173
|
+
EUROCENTGRAM="мн|евроцент|евроцента|евроценту|евроцент|евроцентом|евроценте|евроценты|евроцентов|евроцентам|евроценты|евроцентами|центах"
|
174
|
+
class << self
|
175
|
+
private
|
176
|
+
def get_grammar(order, plural, casus)
|
177
|
+
if order == 0 then
|
178
|
+
@usergram[plural][casus]
|
179
|
+
elsif order == 1 then
|
180
|
+
ORDWORD[order] + THOU_ENDING[plural][casus]
|
181
|
+
else
|
182
|
+
ORDWORD[order] + MILLI_ENDING[plural][casus]
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
def get_order(n)
|
187
|
+
order=1
|
188
|
+
order+=1 until n < 10 ** (3*order)
|
189
|
+
order-1
|
190
|
+
end
|
191
|
+
|
192
|
+
def set_grammar(grammar)
|
193
|
+
@gender=0
|
194
|
+
@animate=false
|
195
|
+
@usergram = [["","","","","",""],["","","","","",""]]
|
196
|
+
t_ar=grammar.to_s.split("|")
|
197
|
+
return if t_ar.empty?
|
198
|
+
t_ar[0].downcase.each_char do |c|
|
199
|
+
case c
|
200
|
+
when "м" then
|
201
|
+
@gender=0
|
202
|
+
when "ж" then
|
203
|
+
@gender=1
|
204
|
+
when "с" then
|
205
|
+
@gender=2
|
206
|
+
when "н"
|
207
|
+
@animate=false
|
208
|
+
when "о"
|
209
|
+
@animate=true
|
210
|
+
else
|
211
|
+
raise ArgumentError, %Q/Invalid grammar specified "#{s}"/, caller
|
212
|
+
end
|
213
|
+
end
|
214
|
+
0.upto(1) do |i|
|
215
|
+
0.upto(5) do |j|
|
216
|
+
c_gr=t_ar[6*i + j + 1]
|
217
|
+
@usergram[i][j] = c_gr ? c_gr : ""
|
218
|
+
end
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
def get_tail(n, casus, animate, order)
|
223
|
+
return get_grammar(order,1,1) if n.zero?
|
224
|
+
t_n=n
|
225
|
+
tail=get_grammar(order,1, casus == 0 || casus == 3 ? 1 : casus )
|
226
|
+
t_n = t_n%100
|
227
|
+
t_n = t_n%10 if t_n >= 20
|
228
|
+
return tail if t_n == 0 || t_n >= 10
|
229
|
+
if t_n == 1 then
|
230
|
+
tail=get_grammar(order,0,casus)
|
231
|
+
elsif ( t_n >=2 && t_n <=4 ) && ( casus == 0 || casus == 3 ) then
|
232
|
+
tail = get_grammar(order, animate && casus == 3 ? 1 : 0 , 1 )
|
233
|
+
else
|
234
|
+
tail = get_grammar(order, 1, casus == 0 || casus == 3 ? 1 : casus)
|
235
|
+
end
|
236
|
+
tail
|
237
|
+
end
|
238
|
+
|
239
|
+
def milli(n, casus, gender, animate, order)
|
240
|
+
t_n=n
|
241
|
+
if order != 0 then
|
242
|
+
t_gender=(order == 1 ? 1 : 0)
|
243
|
+
t_animate=false
|
244
|
+
else
|
245
|
+
t_gender=gender
|
246
|
+
t_animate=animate
|
247
|
+
end
|
248
|
+
tail=get_tail(t_n,casus,t_animate,order)
|
249
|
+
return ONES[0][casus] + " " + tail if t_n.zero?
|
250
|
+
t_str=""
|
251
|
+
if t_n >= 100 then
|
252
|
+
t_str+=HUNDREDS[t_n/100][casus]
|
253
|
+
t_n=t_n%100
|
254
|
+
end
|
255
|
+
if t_n >=20 then
|
256
|
+
t_str << " " if not t_str.empty?
|
257
|
+
t_str << TWENTIES[t_n/10][casus]
|
258
|
+
t_n = t_n%10
|
259
|
+
end
|
260
|
+
if t_n >=10 then
|
261
|
+
t_str << " " if not t_str.empty?
|
262
|
+
t_str << TEENS[t_n%10] + TEENCASES[casus]
|
263
|
+
t_n = 0
|
264
|
+
end
|
265
|
+
return t_str + " " + tail if t_n == 0
|
266
|
+
t_str << " " if not t_str.empty?
|
267
|
+
if t_n == 1 then
|
268
|
+
if t_animate && casus == 3 then
|
269
|
+
t_str << (t_gender == 0 ? ONES[1][1] : ONES1[t_gender][3])
|
270
|
+
else
|
271
|
+
t_str << (t_gender == 0 ? ONES[1][casus] : ONES1[t_gender][casus])
|
272
|
+
end
|
273
|
+
elsif t_n == 2 then
|
274
|
+
if t_animate && casus == 3 then
|
275
|
+
t_str << (t_gender == 0 ? ONES[2][1] : ONES2[t_gender][1])
|
276
|
+
else
|
277
|
+
t_str << (t_gender == 0 ? ONES[2][casus] : ONES2[t_gender][casus])
|
278
|
+
end
|
279
|
+
elsif t_animate && t_n <=4 && casus == 3 then
|
280
|
+
t_str << ONES[t_n][1]
|
281
|
+
else
|
282
|
+
t_str << ONES[t_n][casus]
|
283
|
+
end
|
284
|
+
t_str << " " + tail
|
285
|
+
end
|
286
|
+
|
287
|
+
def get_ending(n, animate, gender, casus)
|
288
|
+
if ( animate || gender == 1 ) && casus == 3 then
|
289
|
+
return n == 3 ? ACCUSATIVE3[gender] : ACCUSATIVE[gender]
|
290
|
+
end
|
291
|
+
case n
|
292
|
+
when 0,2,6,7,8 then
|
293
|
+
return ENDING02678[gender][casus]
|
294
|
+
when 1,4,5,9 then
|
295
|
+
return ENDING1459[gender][casus]
|
296
|
+
when 3
|
297
|
+
return ENDING3[gender][casus]
|
298
|
+
end
|
299
|
+
end
|
300
|
+
|
301
|
+
def first_ordinal(n, animate, gender, casus )
|
302
|
+
return "" if n.zero?
|
303
|
+
t_str=""
|
304
|
+
digit=n/100
|
305
|
+
if digit.nonzero? then
|
306
|
+
if (n%100).zero? then
|
307
|
+
if digit > 1 then
|
308
|
+
t_str=ONES[digit][1]
|
309
|
+
end
|
310
|
+
return t_str + "сот" + get_ending(1,animate,gender,casus)
|
311
|
+
end
|
312
|
+
t_str=HUNDREDS[digit][0] + " "
|
313
|
+
end
|
314
|
+
digit=(n%100)/10
|
315
|
+
return t_str + TEENS[n%10] + get_ending(1,animate,gender,casus) if digit == 1
|
316
|
+
if digit !=0 then
|
317
|
+
if (n%10).zero? then
|
318
|
+
return t_str + TIES[digit] + (digit == 4 ? get_ending(0,animate,gender,casus) : get_ending(1,animate,gender,casus))
|
319
|
+
else
|
320
|
+
t_str << TWENTIES[digit][0] + " "
|
321
|
+
end
|
322
|
+
end
|
323
|
+
digit=n%10
|
324
|
+
t_str + ORDINALS[digit] + get_ending(digit,animate,gender,casus)
|
325
|
+
end
|
326
|
+
|
327
|
+
def second_ordinal(n,order,animate, gender, casus )
|
328
|
+
return "" if n.zero?
|
329
|
+
t_str=""
|
330
|
+
if n != 1 then
|
331
|
+
digit=n/100
|
332
|
+
if digit.nonzero? then
|
333
|
+
if digit == 1
|
334
|
+
t_str= (n%100).zero? ? "сто" : "ста"
|
335
|
+
else
|
336
|
+
t_str= ONES[digit][1] + "сот"
|
337
|
+
end
|
338
|
+
end
|
339
|
+
digit=(n%100)/10
|
340
|
+
if digit == 1 then
|
341
|
+
t_str << TEENS[n%10] + TEENCASES[1]
|
342
|
+
else
|
343
|
+
t_str << TWENTIES[digit][1] if digit != 0
|
344
|
+
digit=n%10
|
345
|
+
t_str << COMPOUNDS[digit] if digit != 0
|
346
|
+
end
|
347
|
+
end
|
348
|
+
t_str + ORDWORD[order] + "н" + get_ending(1,animate,gender,casus)
|
349
|
+
end
|
350
|
+
|
351
|
+
public
|
352
|
+
###
|
353
|
+
# Преобразует число в количественное числительное
|
354
|
+
#
|
355
|
+
# @param [Integer] n число для преобразования
|
356
|
+
# @param gr_casus [String] падеж числительного
|
357
|
+
# @param grammar [String] грамматика
|
358
|
+
# @param minorder [Integer] минимальный порядок тысяч (см. примеры). Если минимальный порядок < 0, то собственно числительное не выводится
|
359
|
+
# @return [String]
|
360
|
+
# @raise [ArgumentError]
|
361
|
+
# @example
|
362
|
+
# RuNumerals::ru_numeral(154,'д') #=> "ста пятидесяти четырём"
|
363
|
+
# RuNumerals::ru_numeral(101,'','с',1) #=> "ноль тысяч сто одно"
|
364
|
+
# RuNumerals::ru_numeral(1,'',RuNumerals::RUBGRAM,-1) #=> "рубль"
|
365
|
+
# RuNumerals::ru_numeral(2,'',RuNumerals::RUBGRAM,-1) #=> "рубля"
|
366
|
+
#
|
367
|
+
def ru_numeral(n,gr_casus = "и", grammar = "мн", minorder = 0)
|
368
|
+
if not n.kind_of?(Integer) then
|
369
|
+
raise ArgumentError, %Q/The number must be Integer. Argument has class "#{n.class}", value "#{n}"/, caller
|
370
|
+
end
|
371
|
+
gr_casus="и" if gr_casus.nil? || gr_casus.empty?
|
372
|
+
minorder=minorder.to_i
|
373
|
+
set_grammar(grammar)
|
374
|
+
@animate=false if n > 10 and n%10 != 1
|
375
|
+
casus=CASUS_STR.index(gr_casus.downcase)
|
376
|
+
if not casus
|
377
|
+
raise ArgumentError, %Q/The grammatical case must be one of "ирдвтп". Current value of argument is "#{gr_casus}"/, caller
|
378
|
+
end
|
379
|
+
if n < 0 then
|
380
|
+
is_negative=true
|
381
|
+
n=-n
|
382
|
+
else
|
383
|
+
is_negative=false
|
384
|
+
end
|
385
|
+
order=get_order(n)
|
386
|
+
if order > ORDWORD.length then
|
387
|
+
raise ArgumentError, %Q/Too big number #{n}. Max number supported is #{10**((ORDWORD.length+1)*3) - 1}/, caller
|
388
|
+
end
|
389
|
+
triad=0
|
390
|
+
return get_tail(n%1000,casus,@animate,0) if minorder < 0
|
391
|
+
t_str= is_negative ? "минус " : ""
|
392
|
+
[[minorder,ORDWORD.length].min,order].max.downto(0) do |i|
|
393
|
+
triad=(n/(10**(3*i)))%1000
|
394
|
+
t_str << milli(triad,casus,@gender,@animate,i) + " " if triad.nonzero? || t_str.empty?
|
395
|
+
end
|
396
|
+
t_str << get_grammar(0,1,1) if triad.zero? && n.nonzero?
|
397
|
+
t_str.rstrip
|
398
|
+
end
|
399
|
+
|
400
|
+
###
|
401
|
+
#Преобразует число в порядковое числительное
|
402
|
+
#
|
403
|
+
# @param [Integer] n число для преобразования
|
404
|
+
# @param gr_casus [String] падеж числительного
|
405
|
+
# @param grammar [String] грамматика
|
406
|
+
# @param plural [true,false] множественное число
|
407
|
+
# @return [String]
|
408
|
+
# @raise [ArgumentError]
|
409
|
+
# @example
|
410
|
+
#
|
411
|
+
# RuNumerals::ru_ordinal(1) #=> "первый"
|
412
|
+
# RuNumerals::ru_ordinal(2) #=> "второй"
|
413
|
+
# RuNumerals::ru_ordinal(250000000,'в','ж') #=> "двухсотпятидесятимиллионную"
|
414
|
+
# RuNumerals::ru_ordinal(5,'т','ж',true) #=> "пятыми"
|
415
|
+
# RuNumerals::ru_ordinal(-5,'в','о') #=> "минус пятого"
|
416
|
+
#
|
417
|
+
def ru_ordinal(n, gr_casus = "и", grammar = "мн", plural = false)
|
418
|
+
if not n.kind_of?(Integer) then
|
419
|
+
raise ArgumentError, %Q/The number must be Integer. Argument has class "#{n.class}", value "#{n}"/, caller
|
420
|
+
end
|
421
|
+
gr_casus="и" if gr_casus.nil? || gr_casus.empty?
|
422
|
+
set_grammar(grammar)
|
423
|
+
casus=CASUS_STR.index(gr_casus.downcase)
|
424
|
+
if not casus
|
425
|
+
raise ArgumentError, %Q/The grammatical case must be one of "ирдвтп". Current value of argument is "#{gr_casus}"/, caller
|
426
|
+
end
|
427
|
+
if n < 0 then
|
428
|
+
is_negative=true
|
429
|
+
n=-n
|
430
|
+
else
|
431
|
+
is_negative=false
|
432
|
+
end
|
433
|
+
order=get_order(n)
|
434
|
+
if order > ORDWORD.length then
|
435
|
+
raise ArgumentError, %Q/Too big number #{n}. Max number supported is #{10**((ORDWORD.length+1)*3) - 1}/, caller
|
436
|
+
end
|
437
|
+
@gender=3 if plural
|
438
|
+
if n.zero? then
|
439
|
+
return (ORDINALS[0] + get_ending(0,@animate, @gender, casus) + " " + get_grammar(0, plural ? 1 : 0 , casus)).rstrip
|
440
|
+
end
|
441
|
+
t_str = first_ordinal(n%1000,@animate,@gender,casus)
|
442
|
+
1.upto(get_order(n)) do |i|
|
443
|
+
triad=(n/(10**(3*i)))%1000
|
444
|
+
if triad.nonzero? then
|
445
|
+
if not t_str.empty? then
|
446
|
+
t_str = (triad == 1 ? get_grammar(i,0,0) : milli(triad,0,0,false,i)) + " " + t_str
|
447
|
+
else
|
448
|
+
t_str = second_ordinal(triad, i, @animate, @gender, casus)
|
449
|
+
end
|
450
|
+
end
|
451
|
+
end
|
452
|
+
(( is_negative ? "минус " : "" ) + t_str + " " + get_grammar(0, plural ? 1 : 0, casus)).rstrip
|
453
|
+
end
|
454
|
+
###
|
455
|
+
#Преобразует объект класса +Time+ в текстовое представление даты
|
456
|
+
#
|
457
|
+
# @param [Time] d объект для преобразования
|
458
|
+
# @param gr_casus [String] падеж числительного
|
459
|
+
# @param [Hash] options опции
|
460
|
+
# @option options [true,false] :spelldd (true) преобразовать в числительное число месяца
|
461
|
+
# @option options [true,false] :spellyy (true) преобразовать в числительное год
|
462
|
+
# @return [String]
|
463
|
+
# @raise [ArgumentError]
|
464
|
+
# @example
|
465
|
+
#
|
466
|
+
# RuNumerals::ru_date(Time.now) #=> "девятое ноября две тысячи шестнадцатого года"
|
467
|
+
# RuNumerals::ru_date(Time.now, "д",spellyy: false) #=> "девятому ноября 2016 года"
|
468
|
+
# RuNumerals::ru_date(Time.now, spelldd: false, spellyy: false) #=> "9 ноября 2016 года"
|
469
|
+
#
|
470
|
+
def ru_date(d, gr_casus="и", **options )
|
471
|
+
if not d.kind_of?(Time) then
|
472
|
+
raise ArgumentError, %Q/The argument must be Time class. Argument has class "#{d.class}", value "#{d}"/, caller
|
473
|
+
end
|
474
|
+
spelldd=true
|
475
|
+
spellyy=true
|
476
|
+
options.each do |k,v|
|
477
|
+
case k
|
478
|
+
when :spelldd then spelldd=v
|
479
|
+
when :spellyy then spellyy=v
|
480
|
+
else raise ArgumentError, %Q/Invalid option key #{k} value "#{v}"/, caller
|
481
|
+
end
|
482
|
+
end
|
483
|
+
if spelldd then
|
484
|
+
day_part=ru_ordinal(d.day,gr_casus,"с")
|
485
|
+
else
|
486
|
+
day_part=d.day.to_s
|
487
|
+
end
|
488
|
+
day_part + " " + MONTAB[d.mon-1] + " " + (spellyy ? ru_ordinal(d.year,"р",YEARGRAM) : (d.year.to_s + " года"))
|
489
|
+
end
|
490
|
+
###
|
491
|
+
#Преобразует объект класса +Time+ в текстовое представление времени
|
492
|
+
#
|
493
|
+
# @param [Time] d объект для преобразования
|
494
|
+
# @param gr_casus [String] падеж числительного
|
495
|
+
# @param [Hash] options опции
|
496
|
+
# @option options [true,false] :spellhh (true) преобразовать в числительное часы
|
497
|
+
# @option options [true,false] :spellmm (true) преобразовать в числительное минуты
|
498
|
+
# @option options [true,false] :spellss (true) преобразовать в числительное секунды
|
499
|
+
# @option options [true,false] :seconds (true) показывать секунды
|
500
|
+
# @return [String]
|
501
|
+
# @raise [ArgumentError]
|
502
|
+
# @example
|
503
|
+
#
|
504
|
+
# RuNumerals::ru_time(Time.now)
|
505
|
+
# #=> "восемнадцать часов пятьдесят две минуты двадцать секунд"
|
506
|
+
# RuNumerals::ru_time(Time.now,"д",spellhh: false , spellmm: false , spellss: false)
|
507
|
+
# #=> "18 часам 52 минутам 20 секундам"
|
508
|
+
# RuNumerals::ru_time(Time.now,'',spellhh: false , spellmm: false , noseconds: false)
|
509
|
+
# #=> "18 часов 52 минуты"
|
510
|
+
#
|
511
|
+
def ru_time(d, gr_casus="и", **options)
|
512
|
+
if not d.kind_of?(Time) then
|
513
|
+
raise ArgumentError, %Q/The argument must be Time class. Argument has class "#{d.class}", value "#{d}"/, caller
|
514
|
+
end
|
515
|
+
spellhh=true
|
516
|
+
spellmm=true
|
517
|
+
spellss=true
|
518
|
+
seconds=true
|
519
|
+
options.each do |k,v|
|
520
|
+
case k
|
521
|
+
when :spellhh then spellhh=v
|
522
|
+
when :spellmm then spellmm=v
|
523
|
+
when :spellss then spellss=v
|
524
|
+
when :seconds then seconds=v
|
525
|
+
else raise ArgumentError, %Q/Invalid option key #{k} value "#{v}"/, caller
|
526
|
+
end
|
527
|
+
end
|
528
|
+
(spellhh ? ru_numeral(d.hour, gr_casus, HOURGRAM ) : (d.hour.to_s + " " + ru_numeral(d.hour, gr_casus, HOURGRAM, -1 ))) + " " +
|
529
|
+
(spellmm ? ru_numeral(d.min, gr_casus, MINGRAM ) : (d.min.to_s + " "+ ru_numeral(d.min, gr_casus, MINGRAM, -1 ))) +
|
530
|
+
(seconds ? ( " " + (spellss ? ru_numeral(d.sec, gr_casus, SECGRAM ) : (d.sec.to_s + " " + ru_numeral(d.sec, gr_casus, SECGRAM, -1 )))) : "")
|
531
|
+
end
|
532
|
+
###
|
533
|
+
#Преобразует число в текстовое представление денежной суммы
|
534
|
+
#
|
535
|
+
# @param [Integer,Float] n объект для преобразования
|
536
|
+
# @param gr_casus [String] падеж числительного
|
537
|
+
# @param rub_gram [String] грамматика "рублей", если nil или "", то выводятся только "копейки" со значением n*100
|
538
|
+
# @param kop_gram [String] грамматика "копеек", если nil или "", то "копейки" не выводятся и их значение отбрасывается
|
539
|
+
# @param [Hash] options опции
|
540
|
+
# @option options [true,false] :spellrub (true) преобразовать в числительное число "рублей"
|
541
|
+
# @option options [true,false] :spellkop (true) преобразовать в числительное число "копеек", значение выводится в формате "%02d"
|
542
|
+
# @return [String]
|
543
|
+
# @raise [ArgumentError]
|
544
|
+
# @example
|
545
|
+
#
|
546
|
+
# RuNumerals::ru_money(123.029,"и",RuNumerals::RUBGRAM,RuNumerals::KOPGRAM)
|
547
|
+
# #=> "сто двадцать три рубля три копейки"
|
548
|
+
# RuNumerals::ru_money(123.029,"р",RuNumerals::RUBGRAM,RuNumerals::KOPGRAM, spellkop: false)
|
549
|
+
# #=> "ста двадцати трёх рублей 03 копеек"
|
550
|
+
# RuNumerals::ru_money(123.029,"т",nil,RuNumerals::KOPGRAM)
|
551
|
+
# #=> "двенадцатью тысячами тремястами тремя копейками"
|
552
|
+
#
|
553
|
+
def ru_money(n,gr_casus,rub_gram, kop_gram, **options)
|
554
|
+
if not (n.kind_of?(Integer) || n.kind_of?(Float)) then
|
555
|
+
raise ArgumentError, %Q/The number must be Integer or Float. Argument has class "#{n.class}", value "#{n}"/, caller
|
556
|
+
end
|
557
|
+
n=n.to_f
|
558
|
+
spellrub=true
|
559
|
+
spellkop=true
|
560
|
+
options.each do |k,v|
|
561
|
+
case k
|
562
|
+
when :spellrub then spellrub=v
|
563
|
+
when :spellkop then spellkop=v
|
564
|
+
else raise ArgumentError, %Q/Invalid option key #{k} value "#{v}"/, caller
|
565
|
+
end
|
566
|
+
end
|
567
|
+
if (rub_gram.nil? || rub_gram.empty?) && (kop_gram.nil? || kop_gram.empty? ) then
|
568
|
+
raise ArgumentError, %Q/Both grammars are nil/, caller
|
569
|
+
end
|
570
|
+
if rub_gram.nil? || rub_gram.empty? then
|
571
|
+
kops=(n*100).round
|
572
|
+
if spellkop then
|
573
|
+
return ru_numeral(kops,gr_casus,kop_gram)
|
574
|
+
else
|
575
|
+
return kops.to_s + " " + ru_numeral(kops,gr_casus,kop_gram,-1)
|
576
|
+
end
|
577
|
+
end
|
578
|
+
rubs=n.truncate
|
579
|
+
kops=((n*100)%100).round
|
580
|
+
if spellrub then
|
581
|
+
rub_s=ru_numeral(rubs,gr_casus,rub_gram)
|
582
|
+
else
|
583
|
+
rub_s=rubs.to_s + " " + ru_numeral(rubs,gr_casus,rub_gram,-1)
|
584
|
+
end
|
585
|
+
return rub_s if ( kop_gram.nil? || kop_gram.empty? )
|
586
|
+
if spellkop then
|
587
|
+
kop_s=ru_numeral(kops,gr_casus,kop_gram)
|
588
|
+
else
|
589
|
+
kop_s=("%02d" % kops.to_s) + " " + ru_numeral(kops,gr_casus,kop_gram,-1)
|
590
|
+
end
|
591
|
+
rub_s + " " + kop_s
|
592
|
+
end
|
593
|
+
###
|
594
|
+
#Преобразует дробное число в его текстовое представление
|
595
|
+
#
|
596
|
+
# @param [Rational, Float, Integer] n объект для преобразования
|
597
|
+
# @param gr_casus [String] падеж числительного
|
598
|
+
# @param grammar [String] грамматика
|
599
|
+
# @param [Hash] options опции
|
600
|
+
# @option options [true,false] :improper (false) не преобразовать в правильную дробь
|
601
|
+
# @return [String]
|
602
|
+
# @raise [ArgumentError]
|
603
|
+
# Если знаменатель равен единице (аргумент типа +Integer+ как частный случай),
|
604
|
+
# то результатом будет количественное числительное (будет осуществлен вызов ru_numeral)
|
605
|
+
#
|
606
|
+
# @example
|
607
|
+
#
|
608
|
+
# RuNumerals::ru_fractional(Rational(8,7)) #=> "одна целая одна седьмая"
|
609
|
+
# RuNumerals::ru_fractional(Rational(8,7),"",improper: true) #=> "восемь седьмых"
|
610
|
+
# RuNumerals::ru_fractional(Rational(8,7),improper: true) #=> "восемь седьмых"
|
611
|
+
# RuNumerals::ru_fractional(Rational(6,2),"т") #=> "тремя"
|
612
|
+
# RuNumerals::ru_fractional(1001.02) #=> "одна тысяча одна целая две сотых"
|
613
|
+
#
|
614
|
+
def ru_fractional(n,gr_casus="и",grammar=nil, **options)
|
615
|
+
improper=false
|
616
|
+
options.each do |k,v|
|
617
|
+
case k
|
618
|
+
when :improper then improper=v
|
619
|
+
else raise ArgumentError, %Q/Invalid option key #{k} value "#{v}"/, caller
|
620
|
+
end
|
621
|
+
end
|
622
|
+
if n.kind_of?(Integer) then
|
623
|
+
numer=n
|
624
|
+
denom=1
|
625
|
+
elsif n.kind_of?(Float) then
|
626
|
+
m=n.to_s.match('([-+]?[0-9]+)\.([0-9]+)([eE]([-+][0-9]+))?')
|
627
|
+
numer=(m[1] + m[2]).to_i
|
628
|
+
denom_order=(m[2].length - (m[3].nil? ? 0 : m[4].to_i))
|
629
|
+
while denom_order < 0
|
630
|
+
numer*=10
|
631
|
+
denom_order+=1
|
632
|
+
end
|
633
|
+
while numer%10 == 0 && denom_order > 0
|
634
|
+
numer/=10
|
635
|
+
denom_order-=1
|
636
|
+
end
|
637
|
+
denom=10**denom_order
|
638
|
+
elsif n.kind_of?(Rational) then
|
639
|
+
numer=n.numerator
|
640
|
+
denom=n.denominator
|
641
|
+
else
|
642
|
+
raise ArgumentError, %Q/The number must be one of Rational, Float or Integer. Argument has class "#{n.class}", value "#{n}"/, caller
|
643
|
+
end
|
644
|
+
if denom == 1 then
|
645
|
+
return ru_numeral(numer, gr_casus, grammar)
|
646
|
+
end
|
647
|
+
if (not improper) && numer.abs >= denom then
|
648
|
+
t_str=ru_numeral((numer < 0 ? -(numer.abs/denom) : numer/denom),gr_casus,WHOLEGRAM)
|
649
|
+
numer=numer.abs%denom
|
650
|
+
else
|
651
|
+
t_str=""
|
652
|
+
end
|
653
|
+
if not numer.zero? then
|
654
|
+
t_str << " " if not t_str.empty?
|
655
|
+
t_str << ru_numeral(numer,gr_casus,"ж") + " "
|
656
|
+
if numer%10 == 1 then
|
657
|
+
t_str << ru_ordinal(denom,gr_casus,"ж")
|
658
|
+
elsif gr_casus == "и" then
|
659
|
+
t_str << ru_ordinal(denom,"р","ж",true)
|
660
|
+
else
|
661
|
+
t_str << ru_ordinal(denom,gr_casus,"ж",true)
|
662
|
+
end
|
663
|
+
end
|
664
|
+
t_str + (grammar.nil? ? "" : (" " + ru_numeral(1,"р",grammar,-1)))
|
665
|
+
end
|
666
|
+
###
|
667
|
+
#Преобразует число в текстовое представление денежной суммы в рублях. Дробная часть отбрасываются.
|
668
|
+
# @param [Integer,Float] n объект для преобразования
|
669
|
+
# @param gr_casus [String] падеж числительного
|
670
|
+
# @param [Hash] options опции
|
671
|
+
# @option options [true,false] :spellrub (true) преобразовать в числительное число рублей
|
672
|
+
# @return [String]
|
673
|
+
# @raise [ArgumentError]
|
674
|
+
# @example
|
675
|
+
#
|
676
|
+
# RuNumerals::ru_rubles(2123.29) #=> "две тысячи сто двадцать три рубля"
|
677
|
+
# RuNumerals::ru_rubles(3,"т", spellrub: false) #=> "3 рублями"
|
678
|
+
#
|
679
|
+
def ru_rubles(n,gr_casus="и",**options)
|
680
|
+
ru_money(n,gr_casus,RUBGRAM,nil,options)
|
681
|
+
end
|
682
|
+
###
|
683
|
+
#Преобразует число в текстовое представление денежной суммы в копейках (n*100)
|
684
|
+
# @param [Integer,Float] n объект для преобразования
|
685
|
+
# @param gr_casus [String] падеж числительного
|
686
|
+
# @param [Hash] options опции
|
687
|
+
# @option options [true,false] :spellkop (true) преобразовать в числительное число копеек, значение выводится в формате "%02d"
|
688
|
+
# @return [String]
|
689
|
+
# @raise [ArgumentError]
|
690
|
+
# @example
|
691
|
+
#
|
692
|
+
# RuNumerals::ru_kopecks(2123.29) #=> "двести двенадцать тысяч триста двадцать девять копеек"
|
693
|
+
# RuNumerals::ru_kopecks(3,"т",spellkop: false) #=> "300 копейками"
|
694
|
+
#
|
695
|
+
def ru_kopecks(n,gr_casus="и",**options)
|
696
|
+
ru_money(n,gr_casus,nil,KOPGRAM,options)
|
697
|
+
end
|
698
|
+
###
|
699
|
+
#Преобразует число в текстовое представление денежной суммы в рублях и копейках
|
700
|
+
# @param [Integer,Float] n объект для преобразования
|
701
|
+
# @param gr_casus [String] падеж числительного
|
702
|
+
# @param [Hash] options опции
|
703
|
+
# @option options [true,false] :spellrub (true) преобразовать в числительное число рублей
|
704
|
+
# @option options [true,false] :spellkop (true) преобразовать в числительное число копеек, значение выводится в формате "%02d"
|
705
|
+
# @return [String]
|
706
|
+
# @raise [ArgumentError]
|
707
|
+
# @example
|
708
|
+
#
|
709
|
+
# RuNumerals::ru_rubleskopecks(2123.29) #=> "две тысячи сто двадцать три рубля двадцать девять копеек"
|
710
|
+
# RuNumerals::ru_rubleskopecks(3,"т",spellkop: false) #=> "тремя рублями 00 копеек"
|
711
|
+
#
|
712
|
+
def ru_rubleskopecks(n,gr_casus="и",**options)
|
713
|
+
ru_money(n,gr_casus,RUBGRAM,KOPGRAM,options)
|
714
|
+
end
|
715
|
+
###
|
716
|
+
#Преобразует число в текстовое представление денежной суммы в долларах. Дробная часть отбрасываются.
|
717
|
+
# @param [Integer,Float] n объект для преобразования
|
718
|
+
# @param gr_casus [String] падеж числительного
|
719
|
+
# @param [Hash] options опции
|
720
|
+
# @option options [true,false] :spellrub (true) преобразовать в числительное число долларов
|
721
|
+
# @return [String]
|
722
|
+
# @raise [ArgumentError]
|
723
|
+
# @example
|
724
|
+
#
|
725
|
+
# RuNumerals::ru_dollars(2123.29) #=> "две тысячи сто двадцать три доллара"
|
726
|
+
# RuNumerals::ru_dollars(3,"т",spellrub: false) #=> "3 долларами"
|
727
|
+
#
|
728
|
+
def ru_dollars(n,gr_casus="и",**options)
|
729
|
+
ru_money(n,gr_casus,DOLLARGRAM,nil,options)
|
730
|
+
end
|
731
|
+
###
|
732
|
+
#Преобразует число в текстовое представление денежной суммы в центах (n*100)
|
733
|
+
# @param [Integer,Float] n объект для преобразования
|
734
|
+
# @param gr_casus [String] падеж числительного
|
735
|
+
# @param [Hash] options опции
|
736
|
+
# @option options [true,false] :spellkop (true) преобразовать в числительное число центов, значение выводится в формате "%02d"
|
737
|
+
# @return [String]
|
738
|
+
# @raise [ArgumentError]
|
739
|
+
# @example
|
740
|
+
#
|
741
|
+
# RuNumerals::ru_cents(2123.29) #=> "двести двенадцать тысяч триста двадцать девять центов"
|
742
|
+
# RuNumerals::ru_cents(3,"т",spellkop: false) #=> "300 центами"
|
743
|
+
#
|
744
|
+
def ru_cents(n,gr_casus="и",**options)
|
745
|
+
ru_money(n,gr_casus,nil,CENTGRAM,options)
|
746
|
+
end
|
747
|
+
###
|
748
|
+
#Преобразует число в текстовое представление денежной суммы в долларах и центах
|
749
|
+
# @param [Integer,Float] n объект для преобразования
|
750
|
+
# @param gr_casus [String] падеж числительного
|
751
|
+
# @param [Hash] options опции
|
752
|
+
# @option options [true,false] :spellrub (true) преобразовать в числительное число долларов
|
753
|
+
# @option options [true,false] :spellkop (true) преобразовать в числительное число центов, значение выводится в формате "%02d"
|
754
|
+
# @return [String]
|
755
|
+
# @raise [ArgumentError]
|
756
|
+
# @example
|
757
|
+
#
|
758
|
+
# RuNumerals::ru_dollarscents(2123.29) #=> "две тысячи сто двадцать три доллара двадцать девять центов"
|
759
|
+
# RuNumerals::ru_dollarscents(3,"т",spellkop: false) #=> "тремя долларами 00 центов"
|
760
|
+
#
|
761
|
+
def ru_dollarscents(n,gr_casus="и",**options)
|
762
|
+
ru_money(n,gr_casus,DOLLARGRAM,CENTGRAM,options)
|
763
|
+
end
|
764
|
+
###
|
765
|
+
#Преобразует число в текстовое представление денежной суммы в евро. Дробная часть отбрасываются.
|
766
|
+
# @param [Integer,Float] n объект для преобразования
|
767
|
+
# @param gr_casus [String] падеж числительного
|
768
|
+
# @param [Hash] options опции
|
769
|
+
# @option options [true,false] :spellrub (true) преобразовать в числительное число евро
|
770
|
+
# @return [String]
|
771
|
+
# @raise [ArgumentError]
|
772
|
+
# @example
|
773
|
+
#
|
774
|
+
# RuNumerals::ru_euros(2123.29) #=> "две тысячи сто двадцать три евро"
|
775
|
+
# RuNumerals::ru_euros(3,"т",spellrub: false) #=> "3 евро"
|
776
|
+
#
|
777
|
+
def ru_euros(n,gr_casus="и",**options)
|
778
|
+
ru_money(n,gr_casus,EUROGRAM,nil,options)
|
779
|
+
end
|
780
|
+
###
|
781
|
+
#Преобразует число в текстовое представление денежной суммы в евроцентах (n*100)
|
782
|
+
# @param [Integer,Float] n объект для преобразования
|
783
|
+
# @param gr_casus [String] падеж числительного
|
784
|
+
# @param [Hash] options опции
|
785
|
+
# @option options [true,false] :spellkop (true) преобразовать в числительное число евроцентов, значение выводится в формате "%02d"
|
786
|
+
# @return [String]
|
787
|
+
# @raise [ArgumentError]
|
788
|
+
# @example
|
789
|
+
#
|
790
|
+
# RuNumerals::ru_eurocents(2123.29) #=> "двести двенадцать тысяч триста двадцать девять евроцентов"
|
791
|
+
# RuNumerals::ru_eurocents(3,"т",spellkop: false) #=> "300 евроцентами"
|
792
|
+
#
|
793
|
+
def ru_eurocents(n,gr_casus="и",**options)
|
794
|
+
ru_money(n,gr_casus,nil,EUROCENTGRAM,options)
|
795
|
+
end
|
796
|
+
###
|
797
|
+
#Преобразует число в текстовое представление денежной суммы в евро и евроцентах
|
798
|
+
# @param [Integer,Float] n объект для преобразования
|
799
|
+
# @param gr_casus [String] падеж числительного
|
800
|
+
# @param [Hash] options опции
|
801
|
+
# @option options [true,false] :spellrub (true) преобразовать в числительное число евро
|
802
|
+
# @option options [true,false] :spellkop (true) преобразовать в числительное число евроцентов, значение выводится в формате "%02d"
|
803
|
+
# @return [String]
|
804
|
+
# @raise [ArgumentError]
|
805
|
+
# @example
|
806
|
+
#
|
807
|
+
# RuNumerals::ru_euroseurocents(2123.29) #=> "две тысячи сто двадцать три евро двадцать девять евроцентов"
|
808
|
+
# RuNumerals::ru_euroseurocents(3,"т",spellkop: false) #=> "тремя долларами 00 евроцентов"
|
809
|
+
#
|
810
|
+
def ru_euroseurocents(n,gr_casus="и",**options)
|
811
|
+
ru_money(n,gr_casus,EUROGRAM,EUROCENTGRAM,options)
|
812
|
+
end
|
813
|
+
###
|
814
|
+
#Добавляет метод или методы RuNumerals классу.
|
815
|
+
# @param [Class] cls объект для преобразования
|
816
|
+
# @param [Array] methods методы
|
817
|
+
# - :ru_numeral (+Symbol+) - добавить метод ru_numeral (только для +Integer+)
|
818
|
+
# - :ru_ordinal (+Symbol+) - добавить метод ru_ordinal (только для +Integer+)
|
819
|
+
# - :ru_date (+Symbol+) - добавить метод ru_date (только для +Time+)
|
820
|
+
# - :ru_time (+Symbol+) - добавить метод ru_time (только для +Time+)
|
821
|
+
# - :ru_fractional (+Symbol+) - добавить метод ru_fractional (только для +Float+ и +Rational+)
|
822
|
+
# - :ru_money (+Symbol+) - добавить метод ru_money (только для +Float+)
|
823
|
+
# - :ru_rubles (+Symbol+) - добавить метод ru_rubles (только для +Float+)
|
824
|
+
# - :ru_kopecks (+Symbol+) - добавить метод ru_kopecks (только для +Float+)
|
825
|
+
# - :ru_rubleskopecks (+Symbol+) - добавить метод ru_rubleskopecks (только для +Float+)
|
826
|
+
# - :ru_dollars (+Symbol+) - добавить метод ru_dollars (только для +Float+)
|
827
|
+
# - :ru_cents (+Symbol+) - добавить метод ru_cents (только для +Float+)
|
828
|
+
# - :ru_dollarscents (+Symbol+) - добавить метод ru_dollarscents (только для +Float+)
|
829
|
+
# - :ru_euros (+Symbol+) - добавить метод ru_euros (только для +Float+)
|
830
|
+
# - :ru_eurocents (+Symbol+) - добавить метод ru_eurocents (только для +Float+)
|
831
|
+
# - :ru_euroseurocents (+Symbol+) - добавить метод ru_euroseurocents (только для +Float+)
|
832
|
+
#
|
833
|
+
#Если опции не указаны, то классу добавляются все подходящие функции.
|
834
|
+
# @return [nil]
|
835
|
+
# @raise [ArgumentError]
|
836
|
+
# @example
|
837
|
+
#
|
838
|
+
# RuNumerals::extend(Integer) #=> nil
|
839
|
+
# 1.ru_numeral #=> "один"
|
840
|
+
# 1.ru_ordinal("д") #=> "первому"
|
841
|
+
# RuNumerals::extend(Float,:ru_rubleskopecks) #=> nil
|
842
|
+
# 1.25.ru_rubleskopecks("и",:nospellkop) #=> "один рубль 25 копеек"
|
843
|
+
#
|
844
|
+
def extend(cls,*methods)
|
845
|
+
if ( cls.class != Class ) then
|
846
|
+
raise ArgumentError, %Q/Argument must be Class, current argument class is "#{cls.Class}, "/, caller
|
847
|
+
end
|
848
|
+
if not EXTEND_MAP.keys.include?(cls) then
|
849
|
+
raise ArgumentError, %Q/Class "#{cls}" is not supported/, caller
|
850
|
+
end
|
851
|
+
if methods.nil? or methods.empty? then
|
852
|
+
all_methods=true
|
853
|
+
else
|
854
|
+
all_methods=false
|
855
|
+
methods.each do |i|
|
856
|
+
if not EXTEND_MAP[cls].include?(i) then
|
857
|
+
raise ArgumentError, %Q/Method "#{i}" is not supported for class "#{cls}"/, caller
|
858
|
+
end
|
859
|
+
end
|
860
|
+
end
|
861
|
+
methods_to_ext= (all_methods ? EXTEND_MAP[cls] : methods)
|
862
|
+
methods_to_ext.each do |i|
|
863
|
+
case i
|
864
|
+
when :ru_numeral then
|
865
|
+
cls.send(:define_method,i) do |gr_casus='и', grammar='мн', min_order=0|
|
866
|
+
RuNumerals::ru_numeral(self, gr_casus, grammar, min_order)
|
867
|
+
end
|
868
|
+
when :ru_ordinal then
|
869
|
+
cls.send(:define_method,i) do |gr_casus='и', grammar='мн', plural=false|
|
870
|
+
RuNumerals::ru_ordinal(self, gr_casus, grammar, plural)
|
871
|
+
end
|
872
|
+
when :ru_money then
|
873
|
+
cls.send(:define_method,i) do |gr_casus='и', r_gram=nil,k_gram=nil, **opts|
|
874
|
+
RuNumerals::ru_money(self, gr_casus,r_gram,k_gram,opts)
|
875
|
+
end
|
876
|
+
when :ru_date then
|
877
|
+
cls.send(:define_method,i) do |gr_casus='и', **opts|
|
878
|
+
RuNumerals::ru_date(self, gr_casus, opts)
|
879
|
+
end
|
880
|
+
when :ru_time then
|
881
|
+
cls.send(:define_method,i) do |gr_casus='и', **opts|
|
882
|
+
RuNumerals::ru_time(self, gr_casus, opts)
|
883
|
+
end
|
884
|
+
when :ru_rubles then
|
885
|
+
cls.send(:define_method,i) do |gr_casus='и', **opts|
|
886
|
+
RuNumerals::ru_rubles(self, gr_casus, opts)
|
887
|
+
end
|
888
|
+
when :ru_kopecks then
|
889
|
+
cls.send(:define_method,i) do |gr_casus='и', **opts|
|
890
|
+
RuNumerals::ru_kopecks(self, gr_casus, opts)
|
891
|
+
end
|
892
|
+
when :ru_rubleskopecks then
|
893
|
+
cls.send(:define_method,i) do |gr_casus='и', **opts|
|
894
|
+
RuNumerals::ru_rubleskopecks(self, gr_casus, opts)
|
895
|
+
end
|
896
|
+
when :ru_dollars then
|
897
|
+
cls.send(:define_method,i) do |gr_casus='и', **opts|
|
898
|
+
RuNumerals::ru_dollars(self, gr_casus, opts)
|
899
|
+
end
|
900
|
+
when :ru_cents
|
901
|
+
cls.send(:define_method,i) do |gr_casus='и', **opts|
|
902
|
+
RuNumerals::ru_cents(self, gr_casus, opts)
|
903
|
+
end
|
904
|
+
when :ru_dollarscents then
|
905
|
+
cls.send(:define_method,i) do |gr_casus='и', **opts|
|
906
|
+
RuNumerals::ru_dollarscents(self, gr_casus, opts)
|
907
|
+
end
|
908
|
+
when :ru_euros then
|
909
|
+
cls.send(:define_method,i) do |gr_casus='и', **opts|
|
910
|
+
RuNumerals::ru_euros(self, gr_casus, opts)
|
911
|
+
end
|
912
|
+
when :ru_eurocents then
|
913
|
+
cls.send(:define_method,i) do |gr_casus='и', **opts|
|
914
|
+
RuNumerals::ru_eurocents(self, gr_casus, opts)
|
915
|
+
end
|
916
|
+
when :ru_euroseurocents then
|
917
|
+
cls.send(:define_method,i) do |gr_casus='и', **opts|
|
918
|
+
RuNumerals::ru_euroseurocents(self, gr_casus, opts)
|
919
|
+
end
|
920
|
+
when :ru_fractional then
|
921
|
+
cls.send(:define_method,i) do |gr_casus='и', grammar=nil, **opts|
|
922
|
+
RuNumerals::ru_fractional(self, gr_casus, grammar, opts)
|
923
|
+
end
|
924
|
+
end
|
925
|
+
end
|
926
|
+
nil
|
927
|
+
end
|
928
|
+
end
|
929
|
+
end
|
data/lib/version.rb
ADDED
metadata
ADDED
@@ -0,0 +1,92 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: runumerals
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Sergey Abel
|
8
|
+
- Boris Fifelin
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2018-05-15 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: yard
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - ">="
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: '0'
|
21
|
+
type: :development
|
22
|
+
prerelease: false
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - ">="
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: '0'
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: rake
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - ">="
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '0'
|
35
|
+
type: :development
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - ">="
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '0'
|
42
|
+
- !ruby/object:Gem::Dependency
|
43
|
+
name: test-unit
|
44
|
+
requirement: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - ">="
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: '0'
|
49
|
+
type: :development
|
50
|
+
prerelease: false
|
51
|
+
version_requirements: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - ">="
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '0'
|
56
|
+
description: Convertation of numeric values to russian numerals
|
57
|
+
email: bfifelin@gmail.com
|
58
|
+
executables: []
|
59
|
+
extensions: []
|
60
|
+
extra_rdoc_files: []
|
61
|
+
files:
|
62
|
+
- ".yardopts"
|
63
|
+
- LICENSE
|
64
|
+
- README.md
|
65
|
+
- Rakefile
|
66
|
+
- lib/ru_numerals.rb
|
67
|
+
- lib/version.rb
|
68
|
+
homepage: https://github.com/bfifelin/runumerals
|
69
|
+
licenses:
|
70
|
+
- MIT
|
71
|
+
metadata: {}
|
72
|
+
post_install_message:
|
73
|
+
rdoc_options: []
|
74
|
+
require_paths:
|
75
|
+
- lib
|
76
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
77
|
+
requirements:
|
78
|
+
- - ">="
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
version: 1.9.2
|
81
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
82
|
+
requirements:
|
83
|
+
- - ">="
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
86
|
+
requirements: []
|
87
|
+
rubyforge_project:
|
88
|
+
rubygems_version: 2.6.11
|
89
|
+
signing_key:
|
90
|
+
specification_version: 4
|
91
|
+
summary: Russian numerals
|
92
|
+
test_files: []
|