uaenv 0.0.1
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.
- data/README +54 -0
- data/lib/datetime/datetime.rb +37 -0
- data/lib/pluralizer/pluralizer.rb +250 -0
- data/lib/uaenv.rb +26 -0
- metadata +49 -0
data/README
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
== UaEnv - Ukrainian Environment for Ruby
|
2
|
+
|
3
|
+
UaEnv - модуль для роботи з українським текстом в Ruby. Головна ціль UaEnv - полегшити
|
4
|
+
розробку україномовних програм на Ruby (і Rails).
|
5
|
+
|
6
|
+
UaEnv підтимує тільки UTF-8 (налаштування: $KCODE / KanjiCode 'u').
|
7
|
+
|
8
|
+
Переконайтесь, що ваш скрипт правильно працює з Unicode - тобто:
|
9
|
+
|
10
|
+
* Змінна $KCODE включена у режим 'u'
|
11
|
+
* Всі строки уже в кодуванні UTF-8
|
12
|
+
|
13
|
+
Величезне спасибі Julik і Mash - розробникам RuTils, на основі якого побудований UaEnv.
|
14
|
+
|
15
|
+
== Cума прописом
|
16
|
+
|
17
|
+
UaEnv реалізує суму прописом для цілих і дробових чисел із додатковим врахуванням роду. Наприклад:
|
18
|
+
15.propysom => "п'ятнадцять"
|
19
|
+
1357472.propysom => "один мільйон триста п'ятдесят сім тисяч чотириста сімдесят два"
|
20
|
+
901.propysom(2) => "дев'ятсот одна"
|
21
|
+
624.propysom_items(2,'книжка','книжки','книжок') => "шістсот двадцять чотири книжки"
|
22
|
+
|
23
|
+
|
24
|
+
|
25
|
+
Вибір варіанта числівника в залежності від числа
|
26
|
+
7.items('самурай','самураї','самураїв') => "самураїв"
|
27
|
+
|
28
|
+
і вивід "суми прописом" для сум у гривнях
|
29
|
+
(666.13).grn => "шістсот шістдесят шість гривень тринадцять копійок"
|
30
|
+
|
31
|
+
== Дати
|
32
|
+
|
33
|
+
В клас Date введені наступні константи:
|
34
|
+
* UA_ABBR_DAYNAMES (нд пн вт ...)
|
35
|
+
* UA_DAYNAMES_E (перше друге третє ...)
|
36
|
+
* UA_ABBR_MONTHNAMES (січ лют бер ...)
|
37
|
+
* UA_INFLECTED_MONTHNAMES (січня лютого березня)
|
38
|
+
* UA_DAYNAMES (неділя понеділок вівторок)
|
39
|
+
* UA_MONTHNAMES (січень лютий березень)
|
40
|
+
|
41
|
+
Приклад використання:
|
42
|
+
|
43
|
+
require 'date'
|
44
|
+
date = Date.new(2007, 01, 5)
|
45
|
+
puts "#{Date::UA_ABBR_MONTHNAMES[date.mon]}" => січ
|
46
|
+
puts "#{Date::UA_DAYNAMES[date.wday]}" => п'ятниця
|
47
|
+
|
48
|
+
Відбувається "перекриття" стандартної
|
49
|
+
функції Time#strftime ("рідну" #strftime можно продовжити використовуватичерез alias-метод #strftime_nouaenv):
|
50
|
+
|
51
|
+
Time.local(2007,"jan",5).strftime("%a, %A, %b, %B") => "пт, п'ятниця, січ, січень"
|
52
|
+
Time.local(2007,"jan",5).strftime_nouaenv("%a, %A, %b, %B") => "Fri, Friday, Jan, January"
|
53
|
+
|
54
|
+
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module UaEnv
|
2
|
+
|
3
|
+
module DateTime
|
4
|
+
|
5
|
+
@@ignored = "\xFF\xFF\xFF\xFF" # %% == Literal "%" character
|
6
|
+
|
7
|
+
def self.ua_strftime(date='%d.%m.%Y', time='')
|
8
|
+
date.gsub!(/%%/, @@ignored)
|
9
|
+
date.gsub!(/%a/, Date::UA_ABBR_DAYNAMES[time.wday])
|
10
|
+
date.gsub!(/%A/, Date::UA_DAYNAMES[time.wday])
|
11
|
+
date.gsub!(/%b/, Date::UA_ABBR_MONTHNAMES[time.mon])
|
12
|
+
date.gsub!(/%d(\s)*%B/, time.day.to_s + '\1' + Date::UA_INFLECTED_MONTHNAMES[time.mon])
|
13
|
+
date.gsub!(/%B/, Date::UA_MONTHNAMES[time.mon])
|
14
|
+
date.gsub!(@@ignored, '%%')
|
15
|
+
end
|
16
|
+
|
17
|
+
end # module DateTime
|
18
|
+
|
19
|
+
end # module UaEnv
|
20
|
+
|
21
|
+
class Date
|
22
|
+
UA_MONTHNAMES = [nil] + %w{ січень лютий березень квітень травень червень липень серпень вересень жовтень листопад грудень }
|
23
|
+
UA_DAYNAMES = %w(неділя понеділок вівторок середа черверг п'ятниця субота)
|
24
|
+
UA_ABBR_MONTHNAMES = [nil] + %w{ січ лют бер кві тра чер лип сер вер жов лис гру }
|
25
|
+
UA_ABBR_DAYNAMES = %w(нд пн вт ср чт пт сб)
|
26
|
+
UA_INFLECTED_MONTHNAMES = [nil] + %w{ січня лютого березня квітня травня червня липня серпня вересня жовтня листопада грудня }
|
27
|
+
UA_DAYNAMES_E = [nil] + %w{перше друге третє четверте п'яте шосте сьоме восьме дев'яте десяте одинадцяте дванадцяте тринадцяте чотирнадцяте п'ятнадцяте шістнадцяте сімнадцяте вісімнадцяте дев'ятнадцяте двадцяте двадцять тридцяте тридцять}
|
28
|
+
end
|
29
|
+
|
30
|
+
class Time
|
31
|
+
alias_method :strftime_nouaenv, :strftime
|
32
|
+
|
33
|
+
def strftime(date)
|
34
|
+
UaEnv::DateTime::ua_strftime(date, self)
|
35
|
+
strftime_nouaenv(date)
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,250 @@
|
|
1
|
+
module UaEnv
|
2
|
+
|
3
|
+
module Pluralization #:nodoc:
|
4
|
+
|
5
|
+
# Вибирає потрібний відмінок в зажежності від числа
|
6
|
+
def self.choose_plural( amount, *variants )
|
7
|
+
variant = ( amount % 10 == 1 && amount % 100 != 11 ? 1 : amount % 10 >= 2 && amount % 10 <= 4 && (amount % 100 < 10 || amount % 100 >= 20) ? 2 : 3 )
|
8
|
+
|
9
|
+
variants[ variant-1 ]
|
10
|
+
end # self.choose_plural
|
11
|
+
|
12
|
+
def self.grn( amount )
|
13
|
+
pts = []
|
14
|
+
pts << UaEnv::Pluralization::sum_string( amount.to_i, 2, "гривня", "гривні", "гривень" ) unless amount.to_i == 0
|
15
|
+
|
16
|
+
if amount.kind_of?( Float )
|
17
|
+
remainder = ( amount.divmod(1)[1] * 100 ).round
|
18
|
+
|
19
|
+
if ( remainder == 100 )
|
20
|
+
pts = [UaEnv::Pluralization::sum_string(amount.to_i+1, 2, 'гривня', 'гривні', 'гривень')]
|
21
|
+
else
|
22
|
+
pts << UaEnv::Pluralization::sum_string(remainder.to_i, 2, 'копійка', 'копійки', 'копійок')
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
pts.join(' ')
|
27
|
+
end # self.grn
|
28
|
+
|
29
|
+
# Виконує перетворення числа з цифрого виду в символьний
|
30
|
+
# (amount, gender, one_item='', two_items='', five_items='')
|
31
|
+
# amount - числівник
|
32
|
+
# gender = 1 - чоловічий, = 2 - жіночий, = 3 - середній
|
33
|
+
# one_item - називний відмінок однини (= 1)
|
34
|
+
# two_items - родовий відмінок однини (= 2-4)
|
35
|
+
# five_items - родовий відмінок множини ( = 5-10)
|
36
|
+
def self.sum_string(amount, gender, one_item='', two_items='', five_items='')
|
37
|
+
into = ''
|
38
|
+
tmp_val ||= 0
|
39
|
+
|
40
|
+
return "нуль " + five_items if amount == 0
|
41
|
+
|
42
|
+
tmp_val = amount
|
43
|
+
|
44
|
+
# одиниці
|
45
|
+
into, tmp_val = sum_string_fn(into, tmp_val, gender, one_item, two_items, five_items)
|
46
|
+
|
47
|
+
return into if tmp_val == 0
|
48
|
+
|
49
|
+
# тисячі
|
50
|
+
into, tmp_val = sum_string_fn(into, tmp_val, 2, "тисяча", "тисячі", "тисяч")
|
51
|
+
|
52
|
+
return into if tmp_val == 0
|
53
|
+
|
54
|
+
# мільйони
|
55
|
+
into, tmp_val = sum_string_fn(into, tmp_val, 1, "мільйон", "мільйона", "мільйонів")
|
56
|
+
|
57
|
+
return into if tmp_val == 0
|
58
|
+
|
59
|
+
# мільярдів
|
60
|
+
into, tmp_val = sum_string_fn(into, tmp_val, 1, "мільярд", "мільярда", "мільярдів")
|
61
|
+
|
62
|
+
return into
|
63
|
+
end # self.sum_string
|
64
|
+
|
65
|
+
private
|
66
|
+
def self.sum_string_fn(into, tmp_val, gender, one_item='', two_items='', five_items='')
|
67
|
+
rest, rest1, end_word, ones, tens, hundreds = [nil]*6
|
68
|
+
#
|
69
|
+
rest = tmp_val % 1000
|
70
|
+
tmp_val = tmp_val / 1000
|
71
|
+
if rest == 0
|
72
|
+
# останні три знаки нульові
|
73
|
+
into = five_items + " " if into == ""
|
74
|
+
return [into, tmp_val]
|
75
|
+
end
|
76
|
+
#
|
77
|
+
# починаємо підрахунок з Rest
|
78
|
+
end_word = five_items
|
79
|
+
# сотні
|
80
|
+
hundreds = case rest / 100
|
81
|
+
when 0 then ""
|
82
|
+
when 1 then "сто "
|
83
|
+
when 2 then "двісті "
|
84
|
+
when 3 then "триста "
|
85
|
+
when 4 then "чотириста "
|
86
|
+
when 5 then "п'ятсот "
|
87
|
+
when 6 then "шістсот "
|
88
|
+
when 7 then "сімсот "
|
89
|
+
when 8 then "вісімсот "
|
90
|
+
when 9 then "дев'ятсот "
|
91
|
+
end
|
92
|
+
|
93
|
+
# десятки
|
94
|
+
rest = rest % 100
|
95
|
+
rest1 = rest / 10
|
96
|
+
ones = ""
|
97
|
+
case rest1
|
98
|
+
when 0 then tens = ""
|
99
|
+
when 1 # особливий випадок
|
100
|
+
tens = case rest
|
101
|
+
when 10 then "десять "
|
102
|
+
when 11 then "одинадцять "
|
103
|
+
when 12 then "дванадцять "
|
104
|
+
when 13 then "тринадцять "
|
105
|
+
when 14 then "чотирнадцять "
|
106
|
+
when 15 then "п'ятнадцять "
|
107
|
+
when 16 then "шістнадцять "
|
108
|
+
when 17 then "сімнадцять "
|
109
|
+
when 18 then "вісімнадцять "
|
110
|
+
when 19 then "дев'ятнадцять "
|
111
|
+
end
|
112
|
+
when 2: tens = "двадцять "
|
113
|
+
when 3: tens = "тридцять "
|
114
|
+
when 4: tens = "сорок "
|
115
|
+
when 5: tens = "п'ятдесят "
|
116
|
+
when 6: tens = "шістдесят "
|
117
|
+
when 7: tens = "сімдесят "
|
118
|
+
when 8: tens = "вісімдесят "
|
119
|
+
when 9: tens = "дев'яносто "
|
120
|
+
end
|
121
|
+
#
|
122
|
+
|
123
|
+
if rest1 < 1 or rest1 > 1 # одиниці
|
124
|
+
case rest % 10
|
125
|
+
when 1
|
126
|
+
ones = case gender
|
127
|
+
when 1 then "один "
|
128
|
+
when 2 then "одна "
|
129
|
+
when 3 then "одне "
|
130
|
+
end
|
131
|
+
end_word = one_item
|
132
|
+
when 2
|
133
|
+
if gender == 2
|
134
|
+
ones = "дві "
|
135
|
+
else
|
136
|
+
ones = "два "
|
137
|
+
end
|
138
|
+
end_word = two_items
|
139
|
+
when 3
|
140
|
+
ones = "три " if end_word = two_items
|
141
|
+
when 4
|
142
|
+
ones = "чотири " if end_word = two_items
|
143
|
+
when 5
|
144
|
+
ones = "п'ять "
|
145
|
+
when 6
|
146
|
+
ones = "шість "
|
147
|
+
when 7
|
148
|
+
ones = "сім "
|
149
|
+
when 8
|
150
|
+
ones = "вісім "
|
151
|
+
when 9
|
152
|
+
ones = "дев'ять "
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
# складання строки
|
157
|
+
st = ''
|
158
|
+
return [(st << hundreds.to_s << tens.to_s << ones.to_s << end_word.to_s << " " << into.to_s).strip, tmp_val]
|
159
|
+
end # def self.sum_string_fn
|
160
|
+
|
161
|
+
|
162
|
+
|
163
|
+
# Реалізує вивід прописом будь-якого об'єкта, що реалізує Float
|
164
|
+
module FloatFormatting
|
165
|
+
# Повертає суму прописом із врахуванням дробової частини. Дробова частина заокруглюється до мільйонної, або (якщо
|
166
|
+
# дробова частина закінчується нулями) до найближчої долі (500 тисячних заокруглюється до 5 десятих).
|
167
|
+
# Додатковий аргумент - рід іменника (1 - чоловічий, 2 - жіночий, 3 - середній)
|
168
|
+
def propysom(gender = 2)
|
169
|
+
raise "Це не число!" if self.nan?
|
170
|
+
st = UaEnv::Pluralization::sum_string(self.to_i, gender, "ціла", "цілих", "цілих")
|
171
|
+
|
172
|
+
remainder = self.to_s.match(/\.(\d+)/)[1]
|
173
|
+
|
174
|
+
signs = remainder.to_s.size - 1
|
175
|
+
|
176
|
+
it = [["десята", "десятих"]]
|
177
|
+
it << ["сота", "сотих"]
|
178
|
+
it << ["тисячна", "тисячних"]
|
179
|
+
it << ["десятитисячна", "десятитисячних"]
|
180
|
+
it << ["стотисячна", "стотисячних"]
|
181
|
+
it << ["мільйонна", "мільйонних"]
|
182
|
+
it << ["десятиммільйонна", "десятимільйонних", "десятимільйонних"]
|
183
|
+
it << ["стомільнна", "стомільйонних", "стомільйонних"]
|
184
|
+
it << ["мільярдна", "мільярдних", "мільярдних"]
|
185
|
+
it << ["десятимільярдна", "десятимільярдних", "десятимільярдних"]
|
186
|
+
it << ["стомільярдна", "стомільярдних", "стомільярдних"]
|
187
|
+
it << ["трильйонна", "трильйонних", "трильйонних"]
|
188
|
+
|
189
|
+
while it[signs].nil?
|
190
|
+
remainder = (remainder/10).round
|
191
|
+
signs = remainder.to_s.size - 1
|
192
|
+
end
|
193
|
+
|
194
|
+
suf1, suf2, suf3 = it[signs][0], it[signs][1], it[signs][2]
|
195
|
+
st + " " + UaEnv::Pluralization::sum_string(remainder.to_i, 2, suf1, suf2, suf2)
|
196
|
+
end
|
197
|
+
|
198
|
+
|
199
|
+
def propysom_items(gender=1, *forms)
|
200
|
+
if self == self.to_i
|
201
|
+
return self.to_i.propysom_items(gender, *forms)
|
202
|
+
else
|
203
|
+
self.propysom(gender) + " " + forms[1]
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
|
208
|
+
|
209
|
+
end # module FloatFormatting
|
210
|
+
|
211
|
+
|
212
|
+
# Реалізує вивід прописом будь-якого об'єкта, що реалізує Numeric
|
213
|
+
module NumericFormatting
|
214
|
+
# Вибирає коректний варіант числівника в залежності від роду і числа і оформляє суму прописом
|
215
|
+
# 234.propysom => "двісті сорок три"
|
216
|
+
# 221.propysom(2) => "двісті двадцять одна"
|
217
|
+
def propysom(gender = 1)
|
218
|
+
UaEnv::Pluralization::sum_string(self, gender, "")
|
219
|
+
end
|
220
|
+
|
221
|
+
def propysom_items(gender=1, *forms)
|
222
|
+
self.propysom(gender) + " " + UaEnv::Pluralization::choose_plural(self.to_i, *forms)
|
223
|
+
end
|
224
|
+
|
225
|
+
# Вибирає коректний варіант числівника у залежності від роду і числа. Наприклад:
|
226
|
+
# * 4.items("монітор", "монітори", "моніторів") => "монітори"
|
227
|
+
def items(one_item, two_items, five_items)
|
228
|
+
UaEnv::Pluralization::choose_plural(self, one_item, two_items, five_items)
|
229
|
+
end
|
230
|
+
|
231
|
+
# Виводить суму у гривнях прописом. Наприклад:
|
232
|
+
# * (128.83).grn => "сто двадцять вісім гривень вісімдесят три копійки"
|
233
|
+
def grn
|
234
|
+
UaEnv::Pluralization::grn(self)
|
235
|
+
end
|
236
|
+
end # module NumericFormatting
|
237
|
+
|
238
|
+
end # module Pluralization
|
239
|
+
|
240
|
+
end # module UaEnv
|
241
|
+
|
242
|
+
|
243
|
+
class Object::Numeric
|
244
|
+
include UaEnv::Pluralization::NumericFormatting
|
245
|
+
end
|
246
|
+
|
247
|
+
|
248
|
+
class Object::Float
|
249
|
+
include UaEnv::Pluralization::FloatFormatting
|
250
|
+
end
|
data/lib/uaenv.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
$KCODE='u'
|
2
|
+
|
3
|
+
module UaEnv
|
4
|
+
# Каталог, куди встановлений модуль UaEnv. Потрібен для автоматичного копіювання у інші додатки.
|
5
|
+
INSTALLATION_DIRECTORY = File.expand_path(File.dirname(__FILE__) + '/../') #:nodoc:
|
6
|
+
MAJOR = 0
|
7
|
+
MINOR = 0
|
8
|
+
TINY = 1
|
9
|
+
|
10
|
+
# Версія UaEnv
|
11
|
+
VERSION = [MAJOR, MINOR ,TINY].join('.') #:nodoc:
|
12
|
+
|
13
|
+
# Стандартний маркер для підстановок - invalid UTF sequence
|
14
|
+
SUBSTITUTION_MARKER = "\xF0\xF0\xF0\xF0" #:nodoc:
|
15
|
+
|
16
|
+
def self.load_component(name) #:nodoc:
|
17
|
+
require File.join(UaEnv::INSTALLATION_DIRECTORY, "lib", name.to_s, name.to_s)
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.reload_component(name) #:nodoc:
|
21
|
+
load File.join(UaEnv::INSTALLATION_DIRECTORY, "lib", name.to_s, "#{name}.rb")
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
UaEnv::load_component :datetime # Дата і час без локалі
|
26
|
+
UaEnv::load_component :pluralizer #Вивід чисел прописом
|
metadata
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
rubygems_version: 0.9.0
|
3
|
+
specification_version: 1
|
4
|
+
name: uaenv
|
5
|
+
version: !ruby/object:Gem::Version
|
6
|
+
version: 0.0.1
|
7
|
+
date: 2007-01-06 00:00:00 +02:00
|
8
|
+
summary: Simply procesing Ukrainian text
|
9
|
+
require_paths:
|
10
|
+
- lib
|
11
|
+
email: anton.linux @nospam@ google.com
|
12
|
+
homepage:
|
13
|
+
rubyforge_project:
|
14
|
+
description:
|
15
|
+
autorequire: uaenv
|
16
|
+
default_executable:
|
17
|
+
bindir: bin
|
18
|
+
has_rdoc: true
|
19
|
+
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">"
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 0.0.0
|
24
|
+
version:
|
25
|
+
platform: ruby
|
26
|
+
signing_key:
|
27
|
+
cert_chain:
|
28
|
+
post_install_message:
|
29
|
+
authors:
|
30
|
+
- Anton Maminov
|
31
|
+
files:
|
32
|
+
- lib/uaenv.rb
|
33
|
+
- lib/datetime/datetime.rb
|
34
|
+
- lib/pluralizer/pluralizer.rb
|
35
|
+
- README
|
36
|
+
test_files: []
|
37
|
+
|
38
|
+
rdoc_options: []
|
39
|
+
|
40
|
+
extra_rdoc_files:
|
41
|
+
- README
|
42
|
+
executables: []
|
43
|
+
|
44
|
+
extensions: []
|
45
|
+
|
46
|
+
requirements: []
|
47
|
+
|
48
|
+
dependencies: []
|
49
|
+
|