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 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
+