num2words 0.1.2 → 0.1.4

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.
Files changed (59) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +98 -0
  3. data/README.md +1 -1
  4. data/config/locales/en.yml +29 -0
  5. data/config/locales/ru.yml +44 -0
  6. data/lib/num2words/converter.rb +154 -33
  7. data/lib/num2words/core_ext.rb +16 -0
  8. data/lib/num2words/locales/ar.rb +2 -2
  9. data/lib/num2words/locales/be.rb +2 -2
  10. data/lib/num2words/locales/bg.rb +2 -2
  11. data/lib/num2words/locales/bn.rb +2 -2
  12. data/lib/num2words/locales/cs.rb +2 -2
  13. data/lib/num2words/locales/da.rb +2 -2
  14. data/lib/num2words/locales/de.rb +2 -2
  15. data/lib/num2words/locales/el.rb +2 -2
  16. data/lib/num2words/locales/en.rb +10 -2
  17. data/lib/num2words/locales/es.rb +2 -2
  18. data/lib/num2words/locales/et.rb +2 -2
  19. data/lib/num2words/locales/fa.rb +2 -2
  20. data/lib/num2words/locales/fi.rb +2 -2
  21. data/lib/num2words/locales/fr.rb +2 -2
  22. data/lib/num2words/locales/gu.rb +2 -2
  23. data/lib/num2words/locales/he.rb +2 -2
  24. data/lib/num2words/locales/hi.rb +2 -2
  25. data/lib/num2words/locales/hr.rb +2 -2
  26. data/lib/num2words/locales/hu.rb +2 -2
  27. data/lib/num2words/locales/id.rb +2 -2
  28. data/lib/num2words/locales/it.rb +2 -2
  29. data/lib/num2words/locales/ja.rb +2 -2
  30. data/lib/num2words/locales/kn.rb +2 -2
  31. data/lib/num2words/locales/ko.rb +2 -2
  32. data/lib/num2words/locales/kz.rb +2 -2
  33. data/lib/num2words/locales/lt.rb +2 -2
  34. data/lib/num2words/locales/lv.rb +2 -2
  35. data/lib/num2words/locales/ml.rb +2 -2
  36. data/lib/num2words/locales/mr.rb +2 -2
  37. data/lib/num2words/locales/ms.rb +2 -2
  38. data/lib/num2words/locales/nl.rb +2 -2
  39. data/lib/num2words/locales/no.rb +2 -2
  40. data/lib/num2words/locales/pa.rb +2 -2
  41. data/lib/num2words/locales/pl.rb +2 -2
  42. data/lib/num2words/locales/pt.rb +2 -2
  43. data/lib/num2words/locales/ro.rb +2 -2
  44. data/lib/num2words/locales/ru.rb +10 -2
  45. data/lib/num2words/locales/sk.rb +2 -2
  46. data/lib/num2words/locales/sl.rb +2 -2
  47. data/lib/num2words/locales/sr.rb +2 -2
  48. data/lib/num2words/locales/sv.rb +2 -2
  49. data/lib/num2words/locales/sw.rb +2 -2
  50. data/lib/num2words/locales/ta.rb +2 -2
  51. data/lib/num2words/locales/te.rb +2 -2
  52. data/lib/num2words/locales/th.rb +2 -2
  53. data/lib/num2words/locales/tr.rb +2 -2
  54. data/lib/num2words/locales/uk.rb +2 -2
  55. data/lib/num2words/locales/ur.rb +2 -2
  56. data/lib/num2words/locales/vi.rb +2 -2
  57. data/lib/num2words/locales/zh.rb +2 -2
  58. data/lib/num2words/version.rb +1 -1
  59. metadata +3 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: aa5b9caee063d530f67b6c582ec33a27e3af6e8d5128d5fdcabbe0203156f4e9
4
- data.tar.gz: 76a4d77f82d271c7139e34ffa54fb8e9c79841a0027ae5d14997941e50b27031
3
+ metadata.gz: 1809289bec98157e0b78b8bbe9f18b5fab8fa5f111293105e89b5747d866e43d
4
+ data.tar.gz: 1e5cfdd50831c7e9f75a8216488268564cda27b7972c70feca0a9d34c05c907b
5
5
  SHA512:
6
- metadata.gz: b890bbf4084a1390703166991d3a518ef6576c28cc950b096d4f9f8155d6bd2ea9f85df031673d8ed1e38f1764d42ee3af62dce895d15d91ca71642032f2489d
7
- data.tar.gz: 6492214777cf0cfecbbf4d4d7518d2bc1ebebfbab93906165e7d764a2afc710e11b246bf1c490b40f450f295376661a35b9132bfedf862eb26c382d5a628f7f1
6
+ metadata.gz: 353353c876466e244bf2748073d7a3534a5ead257bc8d7f70f35d975a45762f4d2e0023d2cbf6e55136587974278093987fd2bba4d20ec972f33bedc9a1820c2
7
+ data.tar.gz: 8037de95f9896db0f4b00aa16710836de2337416c646dfc40900f3021a019aba9c04ae7f06842ebc6be73904aca9156258ee766992a861196a3274008ca13ab4
data/CHANGELOG.md ADDED
@@ -0,0 +1,98 @@
1
+ # Changelog
2
+
3
+ Все заметные изменения в этом проекте будут документироваться в этом файле.
4
+
5
+ Формат основан на [Keep a Changelog](https://keepachangelog.com/ru/1.0.0/),
6
+ и этот проект использует [Semantic Versioning](https://semver.org/lang/ru/).
7
+
8
+ ---
9
+
10
+ ## [Unreleased]
11
+
12
+ - Добавление новых локалей (планируется расширение поддерживаемых языков).
13
+ - Оптимизация производительности при больших числах.
14
+ - Улучшения документации.
15
+
16
+ ---
17
+
18
+ ## [0.1.4] - 2025-08-21
19
+ ### Added
20
+ - Расширение `String#to_words`, возможность преобразовать строки с датами
21
+ ```ruby
22
+ "21.08.2025".to_words(:ru)
23
+ # => "двадцать первое августа две тысячи двадцать пятого года"
24
+
25
+ "21.08.2025".to_words(:en)
26
+ # => "the twenty-first of August, two thousand twenty five"
27
+ ```
28
+ - Расширение `Date#to_words`, добавлена возможность преобразовывать объекты Date и DateTime
29
+ ```ruby
30
+ Date.new(2025, 8, 21).to_words(:ru)
31
+ # => "двадцать первого августа две тысячи двадцать пятого года"
32
+
33
+ Date.new(2025, 8, 21).to_words(:en)
34
+ # => "the twenty-first of August, two thousand twenty-five"
35
+ ```
36
+ - Поддержка параметра `format: :nominative`, можно получать даты в именительном падеже.
37
+ ```ruby
38
+ Date.new(2025, 8, 21).to_words(:ru, format: :nominative)
39
+ # => "двадцать первое августа две тысячи двадцать пятый год"
40
+
41
+ "19.07.2012".to_words(:ru, format: :nominative)
42
+ # => "девятнадцатое июля две тысячи двенадцатый год"
43
+ ```
44
+
45
+ ## [0.1.3] – 2025-08-20
46
+ ### Added
47
+ - Параметр **`word_case:`** для методов `to_words`, `to_currency` со значениями:
48
+ - `:upper`, `:capitalize`, `:title`, `:downcase`.
49
+ - В английской локали:
50
+ - Поддержка опции **`style: :decimal`**, которая выводит дробную часть через `point` по-цифровому (например: `"twelve point one two"`).
51
+ - Улучшена поддержка стиля **`:fraction`** — дроби преобразуются в слова с корректными окончаниями (`"tenths"`, `"hundredths"` и т.д.).
52
+ - Улучшена читаемость кода:
53
+ - Унифицированные имена переменных (`major_value`, `minor_value`).
54
+ - Вынес функционал `apply_case` для управления регистром.
55
+
56
+ ### Examples after 0.1.3
57
+
58
+ ```ruby
59
+ 10.1.to_words(locale: :ru, word_case: :capitalize)
60
+ # => "Десять целых одна десятая"
61
+
62
+ 5.5.to_words(locale: :en, style: :fraction) # По умолчанию: style = fraction
63
+ # => "five and five tenths"
64
+
65
+ 123.01.to_words(:en, style: :decimal, word_case: :upper)
66
+ # => "ONE HUNDRED TWENTY THREE POINT ZERO ONE"
67
+
68
+ 99.99.to_currency(locale: :ru, word_case: :upper)
69
+ # => "ДЕВЯНОСТО ДЕВЯТЬ РУБЛЕЙ ДЕВЯНОСТО ДЕВЯТЬ КОПЕЕК"
70
+
71
+ 42.to_words(locale: :en, word_case: :title)
72
+ # => "Forty Two"
73
+
74
+ 76.03.to_words(word_case: :downcase) # По умолчанию: word_case = downcase
75
+ "семьдесят шесть целых три сотые"
76
+ ```
77
+
78
+ ## [0.1.2] - 2025-08-19
79
+ ### Fixed
80
+ - Исправлена ошибка с локалью `no` → заменена на корректную `nb` (Norwegian Bokmål).
81
+
82
+ ---
83
+
84
+ ## [0.1.1] - 2025-08-18
85
+ ### Added
86
+ - Добавлены переводы для новых языков (Swahili, Punjabi и др.).
87
+ - В README.md добавлена Markdown-таблица языков с ISO-кодами и валютами.
88
+
89
+ ### Fixed
90
+ - Исправлены ошибки в конфигурации валют для некоторых локалей.
91
+
92
+ ---
93
+
94
+ ## [0.1.0] - 2025-08-17
95
+ ### Added
96
+ - Первая публичная версия гема `num2words`.
97
+ - Поддержка перевода чисел в слова для нескольких языков.
98
+ - Поддержка валют (RUB, USD, EUR и др.).
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # num2words
1
+ # num2words [![Gem Version](https://badge.fury.io/rb/num2words.svg)](https://badge.fury.io/rb/num2words)
2
2
 
3
3
  📦 **num2words** — Ruby-гем для преобразования чисел в строковое представление (прописью).
4
4
 
@@ -24,3 +24,32 @@ en:
24
24
  fractional:
25
25
  name: ["cent", "cents", "cents"]
26
26
  feminine: false
27
+
28
+ grammar:
29
+ minus: "minus"
30
+ conjunction: "and"
31
+ default_fraction: "parts"
32
+ fractions:
33
+ 10: ["tenth", "tenths", "tenths"]
34
+ 100: ["hundredth", "hundredths", "hundredths"]
35
+ 1000: ["thousandth", "thousandths", "thousandths"]
36
+ 10000: ["ten-thousandth", "ten-thousandths", "ten-thousandths"]
37
+ 100000: ["hundred-thousandth", "hundred-thousandths", "hundred-thousandths"]
38
+ 1000000: ["millionth", "millionths", "millionths"]
39
+ 10000000: ["ten-millionth", "ten-millionths", "ten-millionths"]
40
+ 100000000: ["hundred-millionth", "hundred-millionths", "hundred-millionths"]
41
+ 1000000000: ["billionth", "billionths", "billionths"]
42
+
43
+ date:
44
+ template:
45
+ default: "the %{day} of %{month}, %{year}"
46
+ months:
47
+ default: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]
48
+
49
+ numbers:
50
+ ordinals:
51
+ default:
52
+ masculine: ["first", "second", "third", "fourth", "fifth", "sixth", "seventh", "eighth", "ninth",
53
+ "tenth", "eleventh", "twelfth", "thirteenth", "fourteenth" ,"fifteenth", "sixteenth", "seventeenth", "eighteenth", "nineteenth",
54
+ "twentieth", "twenty-first", "twenty-second", "twenty-third", "twenty-fourth", "twenty-fifth", "twenty-sixth", "twenty-seventh", "twenty-eighth", "twenty-ninth",
55
+ "thirtieth","thirty-first"]
@@ -19,3 +19,47 @@ ru:
19
19
  fractional:
20
20
  name: ["копейка", "копейки", "копеек"]
21
21
  feminine: true
22
+
23
+ grammar:
24
+ minus: "минус"
25
+ conjunction: "целых"
26
+ default_fraction: "дробных"
27
+ fractions:
28
+ 10: ["десятая", "десятые", "десятых"]
29
+ 100: ["сотая", "сотые", "сотых"]
30
+ 1000: ["тысячная", "тысячные", "тысячных"]
31
+ 10000: ["десятитысячная", "десятитысячные", "десятитысячных"]
32
+ 100000: ["стотысячная", "стотысячные", "стотысячных"]
33
+ 1000000: ["миллионная", "миллионные", "миллионных"]
34
+ 10000000: ["десятимиллионная", "десятимиллионные", "десятимиллионных"]
35
+ 100000000: ["стомиллионная", "стомиллионные", "стомиллионных"]
36
+ 1000000000: ["миллиардная", "миллиардные", "миллиардных"]
37
+
38
+ date:
39
+ template:
40
+ default: "%{day} %{month} %{year} года"
41
+ nominative: "%{day} %{month} %{year} год"
42
+ months:
43
+ default: ["января", "февраля", "марта", "апреля", "мая", "июня", "июля", "августа", "сентября", "октября", "ноября", "декабря"]
44
+ nominative: ["января", "февраля", "марта", "апреля", "мая", "июня", "июля", "августа", "сентября", "октября", "ноября", "декабря"]
45
+
46
+ numbers:
47
+ ordinals:
48
+ nominative:
49
+ masculine: ["первый", "второй", "третий", "четвёртый", "пятый", "шестой", "седьмой", "восьмой", "девятый", "десятый",
50
+ "одиннадцатый", "двенадцатый", "тринадцатый", "четырнадцатый", "пятнадцатый", "шестнадцатый", "семнадцатый", "восемнадцатый", "девятнадцатый",
51
+ "двадцатый", "двадцать первый", "двадцать второй", "двадцать третий", "двадцать четвёртый", "двадцать пятый", "двадцать шестой", "двадцать седьмой", "двадцать восьмой", "двадцать девятый",
52
+ "тридцатый", "тридцать первый"]
53
+ feminine: ["первая", "вторая", "третья", "четвёртая", "пятая", "шестая", "седьмая", "восьмая", "девятая",
54
+ "десятая", "одиннадцатая", "двенадцатая", "тринадцатая", "четырнадцатая", "пятнадцатая", "шестнадцатая", "семнадцатая", "восемнадцатая", "девятнадцатая",
55
+ "двадцатая", "двадцать первая", "двадцать вторая", "двадцать третья", "двадцать четвёртая", "двадцать пятая", "двадцать шестая", "двадцать седьмая", "двадцать восьмая", "двадцать девятая",
56
+ "тридцатая", "тридцать первая"]
57
+ neuter: ["первое", "второе", "третье", "четвёртое", "пятое", "шестое", "седьмое", "восьмое", "девятое",
58
+ "десятое", "одиннадцатое", "двенадцатое", "тринадцатое", "четырнадцатое", "пятнадцатое", "шестнадцатое", "семнадцатое", "восемнадцатое", "девятнадцатое",
59
+ "двадцатое", "двадцать первое", "двадцать второе", "двадцать третье", "двадцать четвёртое", "двадцать пятое", "двадцать шестое", "двадцать седьмое", "двадцать восьмое", "двадцать девятое",
60
+ "тридцатое", "тридцать первое"]
61
+ default:
62
+ masculine: ["первого", "второго", "третьего", "четвёртого", "пятого", "шестого", "седьмого", "восьмого", "девятого",
63
+ "десятого", "одиннадцатого", "двенадцатого", "тринадцатого", "четырнадцатого", "пятнадцатого", "шестнадцатого", "семнадцатого", "восемнадцатого", "девятнадцатого",
64
+ "двадцатого", "двадцать первого", "двадцать второго", "двадцать третьего", "двадцать четвёртого", "двадцать пятого", "двадцать шестого", "двадцать седьмого", "двадцать восьмого", "двадцать девятого",
65
+ "тридцатого", "тридцать первого"]
@@ -1,59 +1,58 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "date"
4
+
3
5
  module Num2words
4
6
  class Converter
5
7
  class << self
6
- # number — целое число (0..10^12-1)
7
8
  def to_words(number, *args, **opts)
8
- locale = args.first.is_a?(Symbol) ? args.first : opts[:locale] || :ru
9
- feminine = opts.delete(:feminine) || false
10
-
9
+ locale = args.first.is_a?(Symbol) ? args.first : opts[:locale] || I18n.default_locale
10
+ feminine = opts[:feminine] || false
11
+ style = opts[:style] || :fraction
12
+ word_case = opts[:word_case] || :default
13
+ date_format = opts[:format] || :default
11
14
  locale_data = Locales[locale]
12
15
 
13
- number = Integer(number)
14
- return (feminine ? locale_data::ONES_FEM[0] : locale_data::ONES_MASC[0]) if number.zero?
16
+ result = case detect_type(number)
17
+ when :float then to_words_fractional(number, locale, feminine, locale_data, style: style)
18
+ when :integer then to_words_integer(number, locale, feminine, locale_data)
19
+ when :date then to_words_date(number, locale, locale_data, format: date_format)
20
+ else nil
21
+ end
15
22
 
16
- groups = number.to_s
17
- .chars.reverse.each_slice(3).map(&:reverse)
18
- .map(&:join).map!(&:to_i).reverse
23
+ raise ArgumentError, "Unsupported input type: #{number.inspect}" if result.nil?
19
24
 
20
- words = []
21
- groups.each_with_index do |grp, idx|
22
- scale_idx = groups.size - idx - 1
23
- fem = (scale_idx == 1) || feminine # тысячи — жен. род
24
- words.concat triple_to_words(grp, scale_idx, locale_data, feminine: fem)
25
- end
26
- words.join(" ")
25
+ apply_case(result, word_case)
27
26
  end
28
27
 
29
- # amount может быть String, Integer, Float, BigDecimal
30
28
  def to_currency(amount, *args, **opts)
31
- locale = args.first.is_a?(Symbol) ? args.first : opts[:locale] || :ru
29
+ locale = args.first.is_a?(Symbol) ? args.first : opts[:locale] || I18n.default_locale
30
+ word_case = opts[:word_case] || :downcase
32
31
  locale_data = Locales[locale]
33
32
 
34
- str = amount.to_s
35
- rub_str, kop_str = str.split(".")
36
- rub = Integer(rub_str)
37
- # всегда 2 знака для копеек; обрезаем лишние, дополняем недостающие
38
- kop = (kop_str || "0")[0, 2].ljust(2, "0").to_i
33
+ major_str, minor_str = sprintf('%.2f', amount).split('.')
34
+ major_value = major_str.to_i
35
+ minor_value = minor_str.to_i
39
36
 
40
- rub_words = to_words(rub, locale: locale)
41
- rub_name = pluralize(rub, *locale_data::RUB)
37
+ major_words = to_words(major_value, locale: locale)
38
+ major_name = pluralize(major_value, *locale_data::MAJOR_UNIT)
42
39
 
43
- kop_words = to_words(kop, locale: locale, feminine: true)
44
- kop_name = pluralize(kop, *locale_data::KOP)
40
+ minor_words = to_words(minor_value, locale: locale, feminine: true)
41
+ minor_name = pluralize(minor_value, *locale_data::MINOR_UNIT)
45
42
 
46
- "#{rub_words} #{rub_name} #{kop_words} #{kop_name}"
43
+ result = [major_words, major_name, minor_words, minor_name].join(" ")
44
+ apply_case(result, word_case)
47
45
  end
48
46
 
49
47
  private
50
48
 
51
- def pluralize(n, one, few, many)
52
- return many if (11..14).include?(n % 100)
53
- case n % 10
54
- when 1 then one
49
+ def pluralize(number, singular, few, plural)
50
+ return plural if (11..14).include?(number % 100)
51
+
52
+ case number % 10
53
+ when 1 then singular
55
54
  when 2..4 then few
56
- else many
55
+ else plural
57
56
  end
58
57
  end
59
58
 
@@ -77,6 +76,128 @@ module Num2words
77
76
  words << pluralize(n, *local_data::SCALES[scale_idx]) unless scale_idx.zero?
78
77
  words.compact
79
78
  end
79
+
80
+ def to_words_fractional(number, locale, feminine, locale_data, style: :fraction)
81
+ minus_word = locale_data::GRAMMAR[:minus] || "minus"
82
+ conjunction_word = locale_data::GRAMMAR[:conjunction] || "and"
83
+ default_fraction = locale_data::GRAMMAR[:default_fraction] || "parts"
84
+ fractions_data = locale_data::FRACTIONS || {}
85
+
86
+ sign_word = number.negative? ? minus_word : ""
87
+
88
+ integer_string, fraction_string = number.abs.to_s.split('.', 2)
89
+ integer_value = integer_string.to_i
90
+
91
+ return to_words_integer(integer_value, locale, feminine, locale_data) if fraction_string.to_i.zero?
92
+
93
+ fraction_string = fraction_string.sub(/0+\z/, "")
94
+ numerator = fraction_string.to_i
95
+ denominator = 10 ** fraction_string.length
96
+
97
+ integer_words = to_words_integer(integer_value, locale, feminine, locale_data)
98
+
99
+ if locale.to_sym == :en && style == :decimal
100
+ fraction_digits = fraction_string.chars.map { |d| to_words_integer(d.to_i, locale, feminine, locale_data) }
101
+ full_string = [sign_word, integer_words, "point", fraction_digits.join(" ")].reject(&:empty?).join(" ")
102
+ return full_string
103
+ end
104
+
105
+ numerator_words = to_words_integer(numerator, locale, (locale.to_sym == :ru ? true : feminine), locale_data)
106
+
107
+ denom_forms = fractions_data[denominator] || fractions_data[denominator.to_s] # массив склонений
108
+ denominator_words = denom_forms.is_a?(Array) ? pluralize(numerator, *denom_forms) : default_fraction
109
+
110
+ [sign_word, integer_words, conjunction_word, numerator_words, denominator_words].reject(&:empty?).join(" ")
111
+ end
112
+
113
+ def to_words_integer(number, locale, feminine, locale_data)
114
+ integer_value = Integer(number)
115
+
116
+ return (feminine ? locale_data::ONES_FEM[0] : locale_data::ONES_MASC[0]) if integer_value.zero?
117
+
118
+ groups = integer_value.to_s
119
+ .chars.reverse.each_slice(3).map(&:reverse)
120
+ .map(&:join).map!(&:to_i).reverse
121
+
122
+ words = []
123
+ groups.each_with_index do |group_value, index|
124
+ scale_index = groups.size - index - 1
125
+ group_feminine = (scale_index == 1) || feminine
126
+ words.concat triple_to_words(group_value, scale_index, locale_data, feminine: group_feminine)
127
+ end
128
+
129
+ words.join(" ")
130
+ end
131
+
132
+ def to_words_date(date, locale, locale_data, format: :default)
133
+ date = Date.parse(date.to_s) unless date.is_a?(Date)
134
+
135
+ day, month, year = [date.day, date.month, date.year]
136
+
137
+ months = locale_data::DATE[:months][format] || locale_data::DATE[:months][:default]
138
+ template = locale_data::TEMPLATE[format] || locale_data::TEMPLATE[:default]
139
+
140
+ raise ArgumentError, "Months not found for locale #{locale}" unless months
141
+ raise ArgumentError, "Template not found for locale #{locale}" unless template
142
+
143
+ day_words = to_words_ordinal(day, locale, format, locale_data, gender: :neuter)
144
+ month_words = months[month - 1]
145
+ year_words = to_words_ordinal(year, locale, format, locale_data)
146
+
147
+ template % { day: day_words, month: month_words, year: year_words }
148
+ end
149
+
150
+ def to_words_ordinal(value, locale, format, locale_data, gender: :masculine)
151
+ ordinals = locale_data::ORDINALS[format] rescue nil
152
+ raise ArgumentError, "Ordinals not found for locale #{locale}, format #{format}" unless ordinals
153
+
154
+ gender_data = ordinals[gender] || ordinals[:masculine]
155
+ raise ArgumentError, "Gender #{gender} not found for locale #{locale}, format #{format}" unless gender_data
156
+
157
+ return gender_data[value - 1] if gender_data[value]
158
+
159
+ if value > 31
160
+ thousands = (value / 100) * 100
161
+ last_two = value % 100
162
+
163
+ base_year = to_words_integer(thousands, locale, false, locale_data)
164
+ last_ordinal = gender_data[last_two - 1] || to_words_integer(last_two, locale, false, locale_data)
165
+ last_ordinal = to_words_integer(last_two, locale, false, locale_data) if locale == :en
166
+
167
+ return [base_year, last_ordinal].join(" ")
168
+ end
169
+
170
+ to_words_integer(value, locale, false, locale_data)
171
+ end
172
+
173
+ def apply_case(text, word_case)
174
+ case word_case
175
+ when :upper then text.upcase
176
+ when :capitalize then text.capitalize
177
+ when :title then text.split.map(&:capitalize).join(" ")
178
+ when :downcase then text.downcase
179
+ else text
180
+ end
181
+ end
182
+
183
+ def detect_type(value)
184
+ case value
185
+ when Integer then :integer
186
+ when Float then :float
187
+ when Date, Time, ::DateTime then :date
188
+ when String
189
+ return :integer if /\A-?\d+\z/.match?(value)
190
+ return :float if /\A-?\d+\.\d+\z/.match?(value)
191
+
192
+ begin
193
+ Date.parse(value)
194
+ :date
195
+ rescue ArgumentError
196
+ :string
197
+ end
198
+ else :unknown
199
+ end
200
+ end
80
201
  end
81
202
  end
82
203
  end
@@ -11,7 +11,23 @@ class Integer
11
11
  end
12
12
 
13
13
  class Float
14
+ def to_words(*args, **opts)
15
+ Num2words::Converter.to_words(self, *args, **opts)
16
+ end
17
+
14
18
  def to_currency(*args, **opts)
15
19
  Num2words::Converter.to_currency(self, *args, **opts)
16
20
  end
17
21
  end
22
+
23
+ class String
24
+ def to_words(*args, **opts)
25
+ Num2words::Converter.to_words(self, *args, **opts)
26
+ end
27
+ end
28
+
29
+ class Date
30
+ def to_words(*args, **opts)
31
+ Num2words::Converter.to_words(self.strftime("%d.%m.%Y"), *args, **opts)
32
+ end
33
+ end
@@ -10,8 +10,8 @@ module Num2words
10
10
  HUNDREDS = I18n.t("num2words.hundreds", locale: :ar)
11
11
  SCALES = I18n.t("num2words.scales", locale: :ar)
12
12
 
13
- RUB = I18n.t("num2words.currencies.SAR.name", locale: :ar)
14
- KOP = I18n.t("num2words.currencies.SAR.fractional.name", locale: :ar)
13
+ MAJOR_UNIT = I18n.t("num2words.currencies.SAR.name", locale: :ar)
14
+ MINOR_UNIT = I18n.t("num2words.currencies.SAR.fractional.name", locale: :ar)
15
15
  end
16
16
 
17
17
  register :ar, AR
@@ -10,8 +10,8 @@ module Num2words
10
10
  HUNDREDS = I18n.t("num2words.hundreds", locale: :be)
11
11
  SCALES = I18n.t("num2words.scales", locale: :be)
12
12
 
13
- RUB = I18n.t("num2words.currencies.BYN.name", locale: :be)
14
- KOP = I18n.t("num2words.currencies.BYN.fractional.name", locale: :be)
13
+ MAJOR_UNIT = I18n.t("num2words.currencies.BYN.name", locale: :be)
14
+ MINOR_UNIT = I18n.t("num2words.currencies.BYN.fractional.name", locale: :be)
15
15
  end
16
16
 
17
17
  register :be, BE
@@ -10,8 +10,8 @@ module Num2words
10
10
  HUNDREDS = I18n.t("num2words.hundreds", locale: :bg)
11
11
  SCALES = I18n.t("num2words.scales", locale: :bg)
12
12
 
13
- RUB = I18n.t("num2words.currencies.BGN.name", locale: :bg)
14
- KOP = I18n.t("num2words.currencies.BGN.fractional.name", locale: :bg)
13
+ MAJOR_UNIT = I18n.t("num2words.currencies.BGN.name", locale: :bg)
14
+ MINOR_UNIT = I18n.t("num2words.currencies.BGN.fractional.name", locale: :bg)
15
15
  end
16
16
 
17
17
  register :bg, BG
@@ -10,8 +10,8 @@ module Num2words
10
10
  HUNDREDS = I18n.t("num2words.hundreds", locale: :bn)
11
11
  SCALES = I18n.t("num2words.scales", locale: :bn)
12
12
 
13
- RUB = I18n.t("num2words.currencies.BDT.name", locale: :bn)
14
- KOP = I18n.t("num2words.currencies.BDT.fractional.name", locale: :bn)
13
+ MAJOR_UNIT = I18n.t("num2words.currencies.BDT.name", locale: :bn)
14
+ MINOR_UNIT = I18n.t("num2words.currencies.BDT.fractional.name", locale: :bn)
15
15
  end
16
16
 
17
17
  register :bn, BN
@@ -10,8 +10,8 @@ module Num2words
10
10
  HUNDREDS = I18n.t("num2words.hundreds", locale: :cs)
11
11
  SCALES = I18n.t("num2words.scales", locale: :cs)
12
12
 
13
- RUB = I18n.t("num2words.currencies.CZK.name", locale: :cs)
14
- KOP = I18n.t("num2words.currencies.CZK.fractional.name", locale: :cs)
13
+ MAJOR_UNIT = I18n.t("num2words.currencies.CZK.name", locale: :cs)
14
+ MINOR_UNIT = I18n.t("num2words.currencies.CZK.fractional.name", locale: :cs)
15
15
  end
16
16
 
17
17
  register :cs, CS
@@ -10,8 +10,8 @@ module Num2words
10
10
  HUNDREDS = I18n.t("num2words.hundreds", locale: :da)
11
11
  SCALES = I18n.t("num2words.scales", locale: :da)
12
12
 
13
- RUB = I18n.t("num2words.currencies.DKK.name", locale: :da)
14
- KOP = I18n.t("num2words.currencies.DKK.fractional.name", locale: :da)
13
+ MAJOR_UNIT = I18n.t("num2words.currencies.DKK.name", locale: :da)
14
+ MINOR_UNIT = I18n.t("num2words.currencies.DKK.fractional.name", locale: :da)
15
15
  end
16
16
 
17
17
  register :da, DA
@@ -10,8 +10,8 @@ module Num2words
10
10
  HUNDREDS = I18n.t("num2words.hundreds", locale: :de)
11
11
  SCALES = I18n.t("num2words.scales", locale: :de)
12
12
 
13
- RUB = I18n.t("num2words.currencies.EUR.name", locale: :de)
14
- KOP = I18n.t("num2words.currencies.EUR.fractional.name", locale: :de)
13
+ MAJOR_UNIT = I18n.t("num2words.currencies.EUR.name", locale: :de)
14
+ MINOR_UNIT = I18n.t("num2words.currencies.EUR.fractional.name", locale: :de)
15
15
  end
16
16
 
17
17
  register :de, DE
@@ -10,8 +10,8 @@ module Num2words
10
10
  HUNDREDS = I18n.t("num2words.hundreds", locale: :el)
11
11
  SCALES = I18n.t("num2words.scales", locale: :el)
12
12
 
13
- RUB = I18n.t("num2words.currencies.EUR.name", locale: :el)
14
- KOP = I18n.t("num2words.currencies.EUR.fractional.name", locale: :el)
13
+ MAJOR_UNIT = I18n.t("num2words.currencies.EUR.name", locale: :el)
14
+ MINOR_UNIT = I18n.t("num2words.currencies.EUR.fractional.name", locale: :el)
15
15
  end
16
16
 
17
17
  register :el, EL
@@ -10,8 +10,16 @@ module Num2words
10
10
  HUNDREDS = I18n.t("num2words.hundreds", locale: :en)
11
11
  SCALES = I18n.t("num2words.scales", locale: :en)
12
12
 
13
- RUB = I18n.t("num2words.currencies.USD.name", locale: :en)
14
- KOP = I18n.t("num2words.currencies.USD.fractional.name", locale: :en)
13
+ MAJOR_UNIT = I18n.t("num2words.currencies.USD.name", locale: :en)
14
+ MINOR_UNIT = I18n.t("num2words.currencies.USD.fractional.name", locale: :en)
15
+
16
+ FRACTIONS = I18n.t("num2words.fractions", locale: :en)
17
+ GRAMMAR = I18n.t("num2words.grammar", locale: :en)
18
+
19
+ DATE = I18n.t("num2words.date", locale: :en)
20
+ TEMPLATE = I18n.t("num2words.date.template", locale: :en)
21
+
22
+ ORDINALS = I18n.t("num2words.numbers.ordinals", locale: :en)
15
23
  end
16
24
 
17
25
  register :en, EN
@@ -10,8 +10,8 @@ module Num2words
10
10
  HUNDREDS = I18n.t("num2words.hundreds", locale: :es)
11
11
  SCALES = I18n.t("num2words.scales", locale: :es)
12
12
 
13
- RUB = I18n.t("num2words.currencies.EUR.name", locale: :es)
14
- KOP = I18n.t("num2words.currencies.EUR.fractional.name", locale: :es)
13
+ MAJOR_UNIT = I18n.t("num2words.currencies.EUR.name", locale: :es)
14
+ MINOR_UNIT = I18n.t("num2words.currencies.EUR.fractional.name", locale: :es)
15
15
  end
16
16
 
17
17
  register :es, ES
@@ -10,8 +10,8 @@ module Num2words
10
10
  HUNDREDS = I18n.t("num2words.hundreds", locale: :et)
11
11
  SCALES = I18n.t("num2words.scales", locale: :et)
12
12
 
13
- RUB = I18n.t("num2words.currencies.EUR.name", locale: :et)
14
- KOP = I18n.t("num2words.currencies.EUR.fractional.name", locale: :et)
13
+ MAJOR_UNIT = I18n.t("num2words.currencies.EUR.name", locale: :et)
14
+ MINOR_UNIT = I18n.t("num2words.currencies.EUR.fractional.name", locale: :et)
15
15
  end
16
16
 
17
17
  register :et, ET
@@ -10,8 +10,8 @@ module Num2words
10
10
  HUNDREDS = I18n.t("num2words.hundreds", locale: :fa)
11
11
  SCALES = I18n.t("num2words.scales", locale: :fa)
12
12
 
13
- RUB = I18n.t("num2words.currencies.IRR.name", locale: :fa)
14
- KOP = I18n.t("num2words.currencies.IRR.fractional.name", locale: :fa)
13
+ MAJOR_UNIT = I18n.t("num2words.currencies.IRR.name", locale: :fa)
14
+ MINOR_UNIT = I18n.t("num2words.currencies.IRR.fractional.name", locale: :fa)
15
15
  end
16
16
 
17
17
  register :fa, FA
@@ -10,8 +10,8 @@ module Num2words
10
10
  HUNDREDS = I18n.t("num2words.hundreds", locale: :fi)
11
11
  SCALES = I18n.t("num2words.scales", locale: :fi)
12
12
 
13
- RUB = I18n.t("num2words.currencies.EUR.name", locale: :fi)
14
- KOP = I18n.t("num2words.currencies.EUR.fractional.name", locale: :fi)
13
+ MAJOR_UNIT = I18n.t("num2words.currencies.EUR.name", locale: :fi)
14
+ MINOR_UNIT = I18n.t("num2words.currencies.EUR.fractional.name", locale: :fi)
15
15
  end
16
16
 
17
17
  register :fi, FI
@@ -10,8 +10,8 @@ module Num2words
10
10
  HUNDREDS = I18n.t("num2words.hundreds", locale: :fr)
11
11
  SCALES = I18n.t("num2words.scales", locale: :fr)
12
12
 
13
- RUB = I18n.t("num2words.currencies.EUR.name", locale: :fr)
14
- KOP = I18n.t("num2words.currencies.EUR.fractional.name", locale: :fr)
13
+ MAJOR_UNIT = I18n.t("num2words.currencies.EUR.name", locale: :fr)
14
+ MINOR_UNIT = I18n.t("num2words.currencies.EUR.fractional.name", locale: :fr)
15
15
  end
16
16
 
17
17
  register :fr, FR
@@ -10,8 +10,8 @@ module Num2words
10
10
  HUNDREDS = I18n.t("num2words.hundreds", locale: :gu)
11
11
  SCALES = I18n.t("num2words.scales", locale: :gu)
12
12
 
13
- RUB = I18n.t("num2words.currencies.INR.name", locale: :gu)
14
- KOP = I18n.t("num2words.currencies.INR.fractional.name", locale: :gu)
13
+ MAJOR_UNIT = I18n.t("num2words.currencies.INR.name", locale: :gu)
14
+ MINOR_UNIT = I18n.t("num2words.currencies.INR.fractional.name", locale: :gu)
15
15
  end
16
16
 
17
17
  register :gu, GU
@@ -10,8 +10,8 @@ module Num2words
10
10
  HUNDREDS = I18n.t("num2words.hundreds", locale: :he)
11
11
  SCALES = I18n.t("num2words.scales", locale: :he)
12
12
 
13
- RUB = I18n.t("num2words.currencies.ILS.name", locale: :he)
14
- KOP = I18n.t("num2words.currencies.ILS.fractional.name", locale: :he)
13
+ MAJOR_UNIT = I18n.t("num2words.currencies.ILS.name", locale: :he)
14
+ MINOR_UNIT = I18n.t("num2words.currencies.ILS.fractional.name", locale: :he)
15
15
  end
16
16
 
17
17
  register :he, HE
@@ -10,8 +10,8 @@ module Num2words
10
10
  HUNDREDS = I18n.t("num2words.hundreds", locale: :hi)
11
11
  SCALES = I18n.t("num2words.scales", locale: :hi)
12
12
 
13
- RUB = I18n.t("num2words.currencies.INR.name", locale: :hi)
14
- KOP = I18n.t("num2words.currencies.INR.fractional.name", locale: :hi)
13
+ MAJOR_UNIT = I18n.t("num2words.currencies.INR.name", locale: :hi)
14
+ MINOR_UNIT = I18n.t("num2words.currencies.INR.fractional.name", locale: :hi)
15
15
  end
16
16
 
17
17
  register :hi, HI
@@ -10,8 +10,8 @@ module Num2words
10
10
  HUNDREDS = I18n.t("num2words.hundreds", locale: :hr)
11
11
  SCALES = I18n.t("num2words.scales", locale: :hr)
12
12
 
13
- RUB = I18n.t("num2words.currencies.EUR.name", locale: :hr)
14
- KOP = I18n.t("num2words.currencies.EUR.fractional.name", locale: :hr)
13
+ MAJOR_UNIT = I18n.t("num2words.currencies.EUR.name", locale: :hr)
14
+ MINOR_UNIT = I18n.t("num2words.currencies.EUR.fractional.name", locale: :hr)
15
15
  end
16
16
 
17
17
  register :hr, HR
@@ -10,8 +10,8 @@ module Num2words
10
10
  HUNDREDS = I18n.t("num2words.hundreds", locale: :hu)
11
11
  SCALES = I18n.t("num2words.scales", locale: :hu)
12
12
 
13
- RUB = I18n.t("num2words.currencies.HUF.name", locale: :hu)
14
- KOP = I18n.t("num2words.currencies.HUF.fractional.name", locale: :hu)
13
+ MAJOR_UNIT = I18n.t("num2words.currencies.HUF.name", locale: :hu)
14
+ MINOR_UNIT = I18n.t("num2words.currencies.HUF.fractional.name", locale: :hu)
15
15
  end
16
16
 
17
17
  register :hu, HU
@@ -10,8 +10,8 @@ module Num2words
10
10
  HUNDREDS = I18n.t("num2words.hundreds", locale: :id)
11
11
  SCALES = I18n.t("num2words.scales", locale: :id)
12
12
 
13
- RUB = I18n.t("num2words.currencies.IDR.name", locale: :id)
14
- KOP = I18n.t("num2words.currencies.IDR.fractional.name", locale: :id)
13
+ MAJOR_UNIT = I18n.t("num2words.currencies.IDR.name", locale: :id)
14
+ MINOR_UNIT = I18n.t("num2words.currencies.IDR.fractional.name", locale: :id)
15
15
  end
16
16
 
17
17
  register :id, ID
@@ -10,8 +10,8 @@ module Num2words
10
10
  HUNDREDS = I18n.t("num2words.hundreds", locale: :it)
11
11
  SCALES = I18n.t("num2words.scales", locale: :it)
12
12
 
13
- RUB = I18n.t("num2words.currencies.EUR.name", locale: :it)
14
- KOP = I18n.t("num2words.currencies.EUR.fractional.name", locale: :it)
13
+ MAJOR_UNIT = I18n.t("num2words.currencies.EUR.name", locale: :it)
14
+ MINOR_UNIT = I18n.t("num2words.currencies.EUR.fractional.name", locale: :it)
15
15
  end
16
16
 
17
17
  register :it, IT
@@ -10,8 +10,8 @@ module Num2words
10
10
  HUNDREDS = I18n.t("num2words.hundreds", locale: :ja)
11
11
  SCALES = I18n.t("num2words.scales", locale: :ja)
12
12
 
13
- RUB = I18n.t("num2words.currencies.JPY.name", locale: :ja)
14
- KOP = I18n.t("num2words.currencies.JPY.fractional.name", locale: :ja)
13
+ MAJOR_UNIT = I18n.t("num2words.currencies.JPY.name", locale: :ja)
14
+ MINOR_UNIT = I18n.t("num2words.currencies.JPY.fractional.name", locale: :ja)
15
15
  end
16
16
 
17
17
  register :ja, JA
@@ -10,8 +10,8 @@ module Num2words
10
10
  HUNDREDS = I18n.t("num2words.hundreds", locale: :kn)
11
11
  SCALES = I18n.t("num2words.scales", locale: :kn)
12
12
 
13
- RUB = I18n.t("num2words.currencies.INR.name", locale: :kn)
14
- KOP = I18n.t("num2words.currencies.INR.fractional.name", locale: :kn)
13
+ MAJOR_UNIT = I18n.t("num2words.currencies.INR.name", locale: :kn)
14
+ MINOR_UNIT = I18n.t("num2words.currencies.INR.fractional.name", locale: :kn)
15
15
  end
16
16
 
17
17
  register :kn, KN
@@ -10,8 +10,8 @@ module Num2words
10
10
  HUNDREDS = I18n.t("num2words.hundreds", locale: :ko)
11
11
  SCALES = I18n.t("num2words.scales", locale: :ko)
12
12
 
13
- RUB = I18n.t("num2words.currencies.KRW.name", locale: :ko)
14
- KOP = I18n.t("num2words.currencies.KRW.fractional.name", locale: :ko)
13
+ MAJOR_UNIT = I18n.t("num2words.currencies.KRW.name", locale: :ko)
14
+ MINOR_UNIT = I18n.t("num2words.currencies.KRW.fractional.name", locale: :ko)
15
15
  end
16
16
 
17
17
  register :ko, KO
@@ -10,8 +10,8 @@ module Num2words
10
10
  HUNDREDS = I18n.t("num2words.hundreds", locale: :kz)
11
11
  SCALES = I18n.t("num2words.scales", locale: :kz)
12
12
 
13
- RUB = I18n.t("num2words.currencies.KZT.name", locale: :kz)
14
- KOP = I18n.t("num2words.currencies.KZT.fractional.name", locale: :kz)
13
+ MAJOR_UNIT = I18n.t("num2words.currencies.KZT.name", locale: :kz)
14
+ MINOR_UNIT = I18n.t("num2words.currencies.KZT.fractional.name", locale: :kz)
15
15
  end
16
16
 
17
17
  register :kz, KZ
@@ -10,8 +10,8 @@ module Num2words
10
10
  HUNDREDS = I18n.t("num2words.hundreds", locale: :lt)
11
11
  SCALES = I18n.t("num2words.scales", locale: :lt)
12
12
 
13
- RUB = I18n.t("num2words.currencies.EUR.name", locale: :lt)
14
- KOP = I18n.t("num2words.currencies.EUR.fractional.name", locale: :lt)
13
+ MAJOR_UNIT = I18n.t("num2words.currencies.EUR.name", locale: :lt)
14
+ MINOR_UNIT = I18n.t("num2words.currencies.EUR.fractional.name", locale: :lt)
15
15
  end
16
16
 
17
17
  register :lt, LT
@@ -10,8 +10,8 @@ module Num2words
10
10
  HUNDREDS = I18n.t("num2words.hundreds", locale: :lv)
11
11
  SCALES = I18n.t("num2words.scales", locale: :lv)
12
12
 
13
- RUB = I18n.t("num2words.currencies.EUR.name", locale: :lv)
14
- KOP = I18n.t("num2words.currencies.EUR.fractional.name", locale: :lv)
13
+ MAJOR_UNIT = I18n.t("num2words.currencies.EUR.name", locale: :lv)
14
+ MINOR_UNIT = I18n.t("num2words.currencies.EUR.fractional.name", locale: :lv)
15
15
  end
16
16
 
17
17
  register :lv, LV
@@ -10,8 +10,8 @@ module Num2words
10
10
  HUNDREDS = I18n.t("num2words.hundreds", locale: :ml)
11
11
  SCALES = I18n.t("num2words.scales", locale: :ml)
12
12
 
13
- RUB = I18n.t("num2words.currencies.INR.name", locale: :ml)
14
- KOP = I18n.t("num2words.currencies.INR.fractional.name", locale: :ml)
13
+ MAJOR_UNIT = I18n.t("num2words.currencies.INR.name", locale: :ml)
14
+ MINOR_UNIT = I18n.t("num2words.currencies.INR.fractional.name", locale: :ml)
15
15
  end
16
16
 
17
17
  register :ml, ML
@@ -10,8 +10,8 @@ module Num2words
10
10
  HUNDREDS = I18n.t("num2words.hundreds", locale: :mr)
11
11
  SCALES = I18n.t("num2words.scales", locale: :mr)
12
12
 
13
- RUB = I18n.t("num2words.currencies.INR.name", locale: :mr)
14
- KOP = I18n.t("num2words.currencies.INR.fractional.name", locale: :mr)
13
+ MAJOR_UNIT = I18n.t("num2words.currencies.INR.name", locale: :mr)
14
+ MINOR_UNIT = I18n.t("num2words.currencies.INR.fractional.name", locale: :mr)
15
15
  end
16
16
 
17
17
  register :mr, MR
@@ -10,8 +10,8 @@ module Num2words
10
10
  HUNDREDS = I18n.t("num2words.hundreds", locale: :ms)
11
11
  SCALES = I18n.t("num2words.scales", locale: :ms)
12
12
 
13
- RUB = I18n.t("num2words.currencies.MYR.name", locale: :ms)
14
- KOP = I18n.t("num2words.currencies.MYR.fractional.name", locale: :ms)
13
+ MAJOR_UNIT = I18n.t("num2words.currencies.MYR.name", locale: :ms)
14
+ MINOR_UNIT = I18n.t("num2words.currencies.MYR.fractional.name", locale: :ms)
15
15
  end
16
16
 
17
17
  register :ms, MS
@@ -10,8 +10,8 @@ module Num2words
10
10
  HUNDREDS = I18n.t("num2words.hundreds", locale: :nl)
11
11
  SCALES = I18n.t("num2words.scales", locale: :nl)
12
12
 
13
- RUB = I18n.t("num2words.currencies.EUR.name", locale: :nl)
14
- KOP = I18n.t("num2words.currencies.EUR.fractional.name", locale: :nl)
13
+ MAJOR_UNIT = I18n.t("num2words.currencies.EUR.name", locale: :nl)
14
+ MINOR_UNIT = I18n.t("num2words.currencies.EUR.fractional.name", locale: :nl)
15
15
  end
16
16
 
17
17
  register :nl, NL
@@ -10,8 +10,8 @@ module Num2words
10
10
  HUNDREDS = I18n.t("num2words.hundreds", locale: :nb)
11
11
  SCALES = I18n.t("num2words.scales", locale: :nb)
12
12
 
13
- RUB = I18n.t("num2words.currencies.NOK.name", locale: :nb)
14
- KOP = I18n.t("num2words.currencies.NOK.fractional.name", locale: :nb)
13
+ MAJOR_UNIT = I18n.t("num2words.currencies.NOK.name", locale: :nb)
14
+ MINOR_UNIT = I18n.t("num2words.currencies.NOK.fractional.name", locale: :nb)
15
15
  end
16
16
 
17
17
  register :nb, NB
@@ -10,8 +10,8 @@ module Num2words
10
10
  HUNDREDS = I18n.t("num2words.hundreds", locale: :pa)
11
11
  SCALES = I18n.t("num2words.scales", locale: :pa)
12
12
 
13
- RUB = I18n.t("num2words.currencies.INR.name", locale: :pa)
14
- KOP = I18n.t("num2words.currencies.INR.fractional.name", locale: :pa)
13
+ MAJOR_UNIT = I18n.t("num2words.currencies.INR.name", locale: :pa)
14
+ MINOR_UNIT = I18n.t("num2words.currencies.INR.fractional.name", locale: :pa)
15
15
  end
16
16
 
17
17
  register :pa, PA
@@ -10,8 +10,8 @@ module Num2words
10
10
  HUNDREDS = I18n.t("num2words.hundreds", locale: :pl)
11
11
  SCALES = I18n.t("num2words.scales", locale: :pl)
12
12
 
13
- RUB = I18n.t("num2words.currencies.PLN.name", locale: :pl)
14
- KOP = I18n.t("num2words.currencies.PLN.fractional.name", locale: :pl)
13
+ MAJOR_UNIT = I18n.t("num2words.currencies.PLN.name", locale: :pl)
14
+ MINOR_UNIT = I18n.t("num2words.currencies.PLN.fractional.name", locale: :pl)
15
15
  end
16
16
 
17
17
  register :pl, PL
@@ -10,8 +10,8 @@ module Num2words
10
10
  HUNDREDS = I18n.t("num2words.hundreds", locale: :pt)
11
11
  SCALES = I18n.t("num2words.scales", locale: :pt)
12
12
 
13
- RUB = I18n.t("num2words.currencies.EUR.name", locale: :pt)
14
- KOP = I18n.t("num2words.currencies.EUR.fractional.name", locale: :pt)
13
+ MAJOR_UNIT = I18n.t("num2words.currencies.EUR.name", locale: :pt)
14
+ MINOR_UNIT = I18n.t("num2words.currencies.EUR.fractional.name", locale: :pt)
15
15
  end
16
16
 
17
17
  register :pt, PT
@@ -10,8 +10,8 @@ module Num2words
10
10
  HUNDREDS = I18n.t("num2words.hundreds", locale: :ro)
11
11
  SCALES = I18n.t("num2words.scales", locale: :ro)
12
12
 
13
- RUB = I18n.t("num2words.currencies.RON.name", locale: :ro)
14
- KOP = I18n.t("num2words.currencies.RON.fractional.name", locale: :ro)
13
+ MAJOR_UNIT = I18n.t("num2words.currencies.RON.name", locale: :ro)
14
+ MINOR_UNIT = I18n.t("num2words.currencies.RON.fractional.name", locale: :ro)
15
15
  end
16
16
 
17
17
  register :ro, RO
@@ -10,8 +10,16 @@ module Num2words
10
10
  HUNDREDS = I18n.t("num2words.hundreds", locale: :ru)
11
11
  SCALES = I18n.t("num2words.scales", locale: :ru)
12
12
 
13
- RUB = I18n.t("num2words.currencies.RUB.name", locale: :ru)
14
- KOP = I18n.t("num2words.currencies.RUB.fractional.name", locale: :ru)
13
+ MAJOR_UNIT = I18n.t("num2words.currencies.RUB.name", locale: :ru)
14
+ MINOR_UNIT = I18n.t("num2words.currencies.RUB.fractional.name", locale: :ru)
15
+
16
+ FRACTIONS = I18n.t("num2words.fractions", locale: :ru)
17
+ GRAMMAR = I18n.t("num2words.grammar", locale: :ru)
18
+
19
+ DATE = I18n.t("num2words.date", locale: :ru)
20
+ TEMPLATE = I18n.t("num2words.date.template", locale: :ru)
21
+
22
+ ORDINALS = I18n.t("num2words.numbers.ordinals", locale: :ru)
15
23
  end
16
24
 
17
25
  register :ru, RU
@@ -10,8 +10,8 @@ module Num2words
10
10
  HUNDREDS = I18n.t("num2words.hundreds", locale: :sk)
11
11
  SCALES = I18n.t("num2words.scales", locale: :sk)
12
12
 
13
- RUB = I18n.t("num2words.currencies.EUR.name", locale: :sk)
14
- KOP = I18n.t("num2words.currencies.EUR.fractional.name", locale: :sk)
13
+ MAJOR_UNIT = I18n.t("num2words.currencies.EUR.name", locale: :sk)
14
+ MINOR_UNIT = I18n.t("num2words.currencies.EUR.fractional.name", locale: :sk)
15
15
  end
16
16
 
17
17
  register :sk, SK
@@ -10,8 +10,8 @@ module Num2words
10
10
  HUNDREDS = I18n.t("num2words.hundreds", locale: :sl)
11
11
  SCALES = I18n.t("num2words.scales", locale: :sl)
12
12
 
13
- RUB = I18n.t("num2words.currencies.EUR.name", locale: :sl)
14
- KOP = I18n.t("num2words.currencies.EUR.fractional.name", locale: :sl)
13
+ MAJOR_UNIT = I18n.t("num2words.currencies.EUR.name", locale: :sl)
14
+ MINOR_UNIT = I18n.t("num2words.currencies.EUR.fractional.name", locale: :sl)
15
15
  end
16
16
 
17
17
  register :sl, SL
@@ -10,8 +10,8 @@ module Num2words
10
10
  HUNDREDS = I18n.t("num2words.hundreds", locale: :sr)
11
11
  SCALES = I18n.t("num2words.scales", locale: :sr)
12
12
 
13
- RUB = I18n.t("num2words.currencies.RSD.name", locale: :sr)
14
- KOP = I18n.t("num2words.currencies.RSD.fractional.name", locale: :sr)
13
+ MAJOR_UNIT = I18n.t("num2words.currencies.RSD.name", locale: :sr)
14
+ MINOR_UNIT = I18n.t("num2words.currencies.RSD.fractional.name", locale: :sr)
15
15
  end
16
16
 
17
17
  register :sr, Sr
@@ -10,8 +10,8 @@ module Num2words
10
10
  HUNDREDS = I18n.t("num2words.hundreds", locale: :sv)
11
11
  SCALES = I18n.t("num2words.scales", locale: :sv)
12
12
 
13
- RUB = I18n.t("num2words.currencies.SEK.name", locale: :sv)
14
- KOP = I18n.t("num2words.currencies.SEK.fractional.name", locale: :sv)
13
+ MAJOR_UNIT = I18n.t("num2words.currencies.SEK.name", locale: :sv)
14
+ MINOR_UNIT = I18n.t("num2words.currencies.SEK.fractional.name", locale: :sv)
15
15
  end
16
16
 
17
17
  register :sv, SV
@@ -10,8 +10,8 @@ module Num2words
10
10
  HUNDREDS = I18n.t("num2words.hundreds", locale: :sw)
11
11
  SCALES = I18n.t("num2words.scales", locale: :sw)
12
12
 
13
- RUB = I18n.t("num2words.currencies.KES.name", locale: :sw)
14
- KOP = I18n.t("num2words.currencies.KES.fractional.name", locale: :sw)
13
+ MAJOR_UNIT = I18n.t("num2words.currencies.KES.name", locale: :sw)
14
+ MINOR_UNIT = I18n.t("num2words.currencies.KES.fractional.name", locale: :sw)
15
15
  end
16
16
 
17
17
  register :sw, SW
@@ -10,8 +10,8 @@ module Num2words
10
10
  HUNDREDS = I18n.t("num2words.hundreds", locale: :ta)
11
11
  SCALES = I18n.t("num2words.scales", locale: :ta)
12
12
 
13
- RUB = I18n.t("num2words.currencies.INR.name", locale: :ta)
14
- KOP = I18n.t("num2words.currencies.INR.fractional.name", locale: :ta)
13
+ MAJOR_UNIT = I18n.t("num2words.currencies.INR.name", locale: :ta)
14
+ MINOR_UNIT = I18n.t("num2words.currencies.INR.fractional.name", locale: :ta)
15
15
  end
16
16
 
17
17
  register :ta, TA
@@ -10,8 +10,8 @@ module Num2words
10
10
  HUNDREDS = I18n.t("num2words.hundreds", locale: :te)
11
11
  SCALES = I18n.t("num2words.scales", locale: :te)
12
12
 
13
- RUB = I18n.t("num2words.currencies.INR.name", locale: :te)
14
- KOP = I18n.t("num2words.currencies.INR.fractional.name", locale: :te)
13
+ MAJOR_UNIT = I18n.t("num2words.currencies.INR.name", locale: :te)
14
+ MINOR_UNIT = I18n.t("num2words.currencies.INR.fractional.name", locale: :te)
15
15
  end
16
16
 
17
17
  register :te, TE
@@ -10,8 +10,8 @@ module Num2words
10
10
  HUNDREDS = I18n.t("num2words.hundreds", locale: :th)
11
11
  SCALES = I18n.t("num2words.scales", locale: :th)
12
12
 
13
- RUB = I18n.t("num2words.currencies.THB.name", locale: :th)
14
- KOP = I18n.t("num2words.currencies.THB.fractional.name", locale: :th)
13
+ MAJOR_UNIT = I18n.t("num2words.currencies.THB.name", locale: :th)
14
+ MINOR_UNIT = I18n.t("num2words.currencies.THB.fractional.name", locale: :th)
15
15
  end
16
16
 
17
17
  register :th, TH
@@ -10,8 +10,8 @@ module Num2words
10
10
  HUNDREDS = I18n.t("num2words.hundreds", locale: :tr)
11
11
  SCALES = I18n.t("num2words.scales", locale: :tr)
12
12
 
13
- RUB = I18n.t("num2words.currencies.TRY.name", locale: :tr)
14
- KOP = I18n.t("num2words.currencies.TRY.fractional.name", locale: :tr)
13
+ MAJOR_UNIT = I18n.t("num2words.currencies.TRY.name", locale: :tr)
14
+ MINOR_UNIT = I18n.t("num2words.currencies.TRY.fractional.name", locale: :tr)
15
15
  end
16
16
 
17
17
  register :tr, TR
@@ -10,8 +10,8 @@ module Num2words
10
10
  HUNDREDS = I18n.t("num2words.hundreds", locale: :uk)
11
11
  SCALES = I18n.t("num2words.scales", locale: :uk)
12
12
 
13
- RUB = I18n.t("num2words.currencies.UAH.name", locale: :uk)
14
- KOP = I18n.t("num2words.currencies.UAH.fractional.name", locale: :uk)
13
+ MAJOR_UNIT = I18n.t("num2words.currencies.UAH.name", locale: :uk)
14
+ MINOR_UNIT = I18n.t("num2words.currencies.UAH.fractional.name", locale: :uk)
15
15
  end
16
16
 
17
17
  register :uk, UK
@@ -10,8 +10,8 @@ module Num2words
10
10
  HUNDREDS = I18n.t("num2words.hundreds", locale: :ur)
11
11
  SCALES = I18n.t("num2words.scales", locale: :ur)
12
12
 
13
- RUB = I18n.t("num2words.currencies.PKR.name", locale: :ur)
14
- KOP = I18n.t("num2words.currencies.PKR.fractional.name", locale: :ur)
13
+ MAJOR_UNIT = I18n.t("num2words.currencies.PKR.name", locale: :ur)
14
+ MINOR_UNIT = I18n.t("num2words.currencies.PKR.fractional.name", locale: :ur)
15
15
  end
16
16
 
17
17
  register :ur, UR
@@ -10,8 +10,8 @@ module Num2words
10
10
  HUNDREDS = I18n.t("num2words.hundreds", locale: :vi)
11
11
  SCALES = I18n.t("num2words.scales", locale: :vi)
12
12
 
13
- RUB = I18n.t("num2words.currencies.VND.name", locale: :vi)
14
- KOP = I18n.t("num2words.currencies.VND.fractional.name", locale: :vi)
13
+ MAJOR_UNIT = I18n.t("num2words.currencies.VND.name", locale: :vi)
14
+ MINOR_UNIT = I18n.t("num2words.currencies.VND.fractional.name", locale: :vi)
15
15
  end
16
16
 
17
17
  register :vi, VI
@@ -10,8 +10,8 @@ module Num2words
10
10
  HUNDREDS = I18n.t("num2words.hundreds", locale: :zh)
11
11
  SCALES = I18n.t("num2words.scales", locale: :zh)
12
12
 
13
- RUB = I18n.t("num2words.currencies.CNY.name", locale: :zh)
14
- KOP = I18n.t("num2words.currencies.CNY.fractional.name", locale: :zh)
13
+ MAJOR_UNIT = I18n.t("num2words.currencies.CNY.name", locale: :zh)
14
+ MINOR_UNIT = I18n.t("num2words.currencies.CNY.fractional.name", locale: :zh)
15
15
  end
16
16
 
17
17
  register :zh, ZH
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Num2words
4
- VERSION = "0.1.2"
4
+ VERSION = "0.1.4"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: num2words
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ruslan Fedotov
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2025-08-19 00:00:00.000000000 Z
11
+ date: 2025-08-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: i18n
@@ -33,6 +33,7 @@ extensions: []
33
33
  extra_rdoc_files: []
34
34
  files:
35
35
  - ".gitignore"
36
+ - CHANGELOG.md
36
37
  - Gemfile
37
38
  - LICENSE.txt
38
39
  - README.md