rotuka-rutils 0.2.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.
- data/CHANGELOG +110 -0
- data/README +202 -0
- data/Rakefile.rb +128 -0
- data/TODO +11 -0
- data/bin/gilensize +18 -0
- data/bin/rutilize +38 -0
- data/init.rb +6 -0
- data/lib/countries/countries.rb +1772 -0
- data/lib/datetime/datetime.rb +87 -0
- data/lib/gilenson/gilenson.rb +642 -0
- data/lib/gilenson/gilenson_port.rb +321 -0
- data/lib/integration/blue_cloth_override.rb +12 -0
- data/lib/integration/integration.rb +32 -0
- data/lib/integration/rails_date_helper_override.rb +113 -0
- data/lib/integration/red_cloth_override.rb +27 -0
- data/lib/pluralizer/pluralizer.rb +236 -0
- data/lib/rutils.rb +32 -0
- data/lib/transliteration/bidi.rb +71 -0
- data/lib/transliteration/simple.rb +74 -0
- data/lib/transliteration/transliteration.rb +51 -0
- data/test/run_tests.rb +4 -0
- data/test/t_datetime.rb +42 -0
- data/test/t_gilenson.rb +371 -0
- data/test/t_integration.rb +125 -0
- data/test/t_pluralize.rb +69 -0
- data/test/t_rutils_base.rb +10 -0
- data/test/t_transliteration.rb +109 -0
- data/test/t_typografica.rb +57 -0
- metadata +92 -0
@@ -0,0 +1,321 @@
|
|
1
|
+
module RuTils
|
2
|
+
module Gilenson
|
3
|
+
end
|
4
|
+
end
|
5
|
+
|
6
|
+
# Это - прямой порт Тыпографицы от pixelapes.
|
7
|
+
# Настройки можно регулировать через методы, т.е.
|
8
|
+
#
|
9
|
+
# typ = RuTils::Gilenson::Obsolete.new('Эти "так называемые" великие деятели')
|
10
|
+
# typ.html = false => "false"
|
11
|
+
# typ.dash = true => "true"
|
12
|
+
# typ.to_html => 'Эти «так называемые» великие деятели'
|
13
|
+
# Ни обновляться ни поддерживаться этот модуль более не будет.
|
14
|
+
class RuTils::Gilenson::Obsolete
|
15
|
+
def initialize(text, *args)
|
16
|
+
@_text = text
|
17
|
+
@skip_tags = true;
|
18
|
+
@p_prefix = "<p class=typo>";
|
19
|
+
@p_postfix = "</p>";
|
20
|
+
@a_soft = true;
|
21
|
+
@indent_a = "images/z.gif width=25 height=1 border=0 alt=\'\' align=top />" # <->
|
22
|
+
@indent_b = "images/z.gif width=50 height=1 border=0 alt=\'\' align=top />" # <-->
|
23
|
+
@fixed_size = 80 # максимальная ширина
|
24
|
+
@ignore = /notypo/ # regex, который игнорируется. Этим надо воспользоваться для обработки pre и code
|
25
|
+
|
26
|
+
@de_nobr = true;
|
27
|
+
|
28
|
+
@phonemasks = [[ /([0-9]{4})\-([0-9]{2})\-([0-9]{2}) ([0-9]{2}):([0-9]{2}):([0-9]{2})/,
|
29
|
+
/([0-9]{4})\-([0-9]{2})\-([0-9]{2})/,
|
30
|
+
/(\([0-9\+\-]+\)) ?([0-9]{3})\-([0-9]{2})\-([0-9]{2})/,
|
31
|
+
/(\([0-9\+\-]+\)) ?([0-9]{2})\-([0-9]{2})\-([0-9]{2})/,
|
32
|
+
/(\([0-9\+\-]+\)) ?([0-9]{3})\-([0-9]{2})/,
|
33
|
+
/(\([0-9\+\-]+\)) ?([0-9]{2})\-([0-9]{3})/,
|
34
|
+
/([0-9]{3})\-([0-9]{2})\-([0-9]{2})/,
|
35
|
+
/([0-9]{2})\-([0-9]{2})\-([0-9]{2})/,
|
36
|
+
/([0-9]{1})\-([0-9]{2})\-([0-9]{2})/,
|
37
|
+
/([0-9]{2})\-([0-9]{3})/,
|
38
|
+
/([0-9]+)\-([0-9]+)/,
|
39
|
+
],[
|
40
|
+
'<nobr>\1–\2–\3 \4:\5:\6</nobr>',
|
41
|
+
'<nobr>\1–\2–\3</nobr>',
|
42
|
+
'<nobr>\1 \2–\3–\4</nobr>',
|
43
|
+
'<nobr>\1 \2–\3–\4</nobr>',
|
44
|
+
'<nobr>\1 \2–\3</nobr>',
|
45
|
+
'<nobr>\1 \2–\3</nobr>',
|
46
|
+
'<nobr>\1–\2–\3</nobr>',
|
47
|
+
'<nobr>\1–\2–\3</nobr>',
|
48
|
+
'<nobr>\1–\2–\3</nobr>',
|
49
|
+
'<nobr>\1–\2</nobr>',
|
50
|
+
'<nobr>\1–\2</nobr>'
|
51
|
+
]]
|
52
|
+
|
53
|
+
@glueleft = ['рис.', 'табл.', 'см.', 'им.', 'ул.', 'пер.', 'кв.', 'офис', 'оф.', 'г.']
|
54
|
+
@glueright = ['руб.', 'коп.', 'у.е.', 'мин.']
|
55
|
+
|
56
|
+
@settings = {
|
57
|
+
"inches" => true, # преобразовывать дюймы в "
|
58
|
+
"laquo" => true, # кавычки-ёлочки
|
59
|
+
"farlaquo" => false, # кавычки-ёлочки для фара (знаки "больше-меньше")
|
60
|
+
"quotes" => true, # кавычки-английские лапки
|
61
|
+
"dash" => true, # короткое тире (150)
|
62
|
+
"emdash" => true, # длинное тире двумя минусами (151)
|
63
|
+
"(c)" => true,
|
64
|
+
"(r)" => true,
|
65
|
+
"(tm)" => true,
|
66
|
+
"(p)" => true,
|
67
|
+
"+-" => true, # спецсимволы, какие - понятно
|
68
|
+
"degrees" => true, # знак градуса
|
69
|
+
"<-->" => true, # отступы $Indent*
|
70
|
+
"dashglue" => true, "wordglue" => true, # приклеивание предлогов и дефисов
|
71
|
+
"spacing" => true, # запятые и пробелы, перестановка
|
72
|
+
"phones" => true, # обработка телефонов
|
73
|
+
"fixed" => false, # подгон под фиксированную ширину
|
74
|
+
"html" => false # запрет тагов html
|
75
|
+
}
|
76
|
+
# irrelevant - indentation with images
|
77
|
+
@indent_a = "<!--indent-->"
|
78
|
+
@indent_b = "<!--indent-->"
|
79
|
+
|
80
|
+
@mark_tag = "\xF0\xF0\xF0\xF0" # Подстановочные маркеры тегов
|
81
|
+
@mark_ignored = "\201" # Подстановочные маркеры неизменяемых групп
|
82
|
+
end
|
83
|
+
|
84
|
+
|
85
|
+
# Proxy unknown method calls as setting switches. Methods with = will set settings, methods without - fetch them
|
86
|
+
def method_missing(meth, *args) #:nodoc:
|
87
|
+
setting = meth.to_s.gsub(/=$/, '')
|
88
|
+
super(meth, *args) unless @settings.has_key?(setting) #this will pop the exception if we have no such setting
|
89
|
+
|
90
|
+
return @settings[meth.to_s] if setting == meth.to_s
|
91
|
+
return (@settings[meth.to_s] = args[0])
|
92
|
+
end
|
93
|
+
|
94
|
+
|
95
|
+
def to_html(no_paragraph = false)
|
96
|
+
|
97
|
+
text = @_text
|
98
|
+
|
99
|
+
# -2. игнорируем ещё регексп
|
100
|
+
ignored = []
|
101
|
+
|
102
|
+
|
103
|
+
text.scan(@ignore) do |result|
|
104
|
+
ignored << result
|
105
|
+
end
|
106
|
+
|
107
|
+
text.gsub!(@ignore, @mark_ignored) # маркер игнора
|
108
|
+
|
109
|
+
# -1. запрет тагов html
|
110
|
+
text.gsub!(/&/, '&') if @settings["html"]
|
111
|
+
|
112
|
+
|
113
|
+
# 0. Вырезаем таги
|
114
|
+
# проблема на самом деле в том, на что похожи таги.
|
115
|
+
# вариант 1, простой (закрывающий таг) </abcz>
|
116
|
+
# вариант 2, простой (просто таг) <abcz>
|
117
|
+
# вариант 3, посложней <abcz href="abcz">
|
118
|
+
# вариант 4, простой (просто таг) <abcz />
|
119
|
+
# вариант 5, вакка \xA2\xA2...== нафиг нафиг
|
120
|
+
# самый сложный вариант - это когда в параметре тага встречается вдруг символ ">"
|
121
|
+
# вот он: <abcz href="abcz>">
|
122
|
+
# как работает вырезание? введём спецсимвол. Да, да, спецсимвол.
|
123
|
+
# нам он ещё вопьётся =)
|
124
|
+
# заменим все таги на спец.символ, запоминая одновременно их в массив.
|
125
|
+
# и будем верить, что спец.символы в дикой природе не встречаются.
|
126
|
+
|
127
|
+
tags = []
|
128
|
+
if (@skip_tags)
|
129
|
+
# re = /<\/?[a-z0-9]+("+ # имя тага
|
130
|
+
# "\s+("+ # повторяющая конструкция: хотя бы один разделитель и тельце
|
131
|
+
# "[a-z]+("+ # атрибут из букв, за которым может стоять знак равенства и потом
|
132
|
+
# "=((\'[^\']*\')|(\"[^\"]*\")|([0-9@\-_a-z:\/?&=\.]+))"+ #
|
133
|
+
# ")?"+
|
134
|
+
# ")?"+
|
135
|
+
# ")*\/?>|\xA2\xA2[^\n]*?==/i;
|
136
|
+
|
137
|
+
# re = /<\/?[a-z0-9]+(\s+([a-z]+(=((\'[^\']*\')|(\"[^\"]*\")|([0-9@\-_a-z:\/?&=\.]+)))?)?)*\/?>|\xA2\xA2[^\n]*?==/ui
|
138
|
+
|
139
|
+
re = /(<\/?[a-z0-9]+(\s+([a-z]+(=((\'[^\']*\')|(\"[^\"]*\")|([0-9@\-_a-z:\/?&=\.]+)))?)?)*\/?>)/ui
|
140
|
+
|
141
|
+
# по-хорошему атрибуты тоже нужно типографить. Или не нужно? бугага...
|
142
|
+
|
143
|
+
tags = text.scan(re).map{|tag| tag[0] }
|
144
|
+
# match = "<" + match if @settings["html"]
|
145
|
+
text.gsub!(re, @mark_tag) #маркер тега, мы используем Invalid UTF-sequence для него
|
146
|
+
|
147
|
+
# puts "matched #{tags.size} tags"
|
148
|
+
end
|
149
|
+
|
150
|
+
# 1. Запятые и пробелы
|
151
|
+
if @settings["spacing"]
|
152
|
+
text.gsub!( /(\s*)([,]*)/sui, '\2\1');
|
153
|
+
text.gsub!( /(\s*)([\.?!]*)(\s*[ЁА-ЯA-Z])/su, '\2\1\3');
|
154
|
+
end
|
155
|
+
|
156
|
+
# 2. Разбиение на строки длиной не более ХХ символов
|
157
|
+
# --- для ваки не портировано ---
|
158
|
+
# --- для ваки не портировано ---
|
159
|
+
|
160
|
+
# 3. Спецсимволы
|
161
|
+
# 0. дюймы с цифрами
|
162
|
+
text.gsub!(/\s([0-9]{1,2}([\.,][0-9]{1,2})?)\"/ui, ' \1"') if @settings["inches"]
|
163
|
+
|
164
|
+
# 1. лапки
|
165
|
+
if (@settings["quotes"])
|
166
|
+
text.gsub!( /\"\"/ui, """")
|
167
|
+
text.gsub!( /\"\.\"/ui, ""."")
|
168
|
+
_text = '""';
|
169
|
+
while _text != text do
|
170
|
+
_text = text
|
171
|
+
text.gsub!( /(^|\s|\201|\xF0\xF0\xF0\xF0|>)\"([0-9A-Za-z\'\!\s\.\?\,\-\&\;\:\_\xF0\xF0\xF0\xF0\201]+(\"|”))/ui, '\1“\2')
|
172
|
+
#this doesnt work in-place. somehow.
|
173
|
+
text = text.gsub( /(\&\#147\;([A-Za-z0-9\'\!\s\.\?\,\-\&\;\:\xF0\xF0\xF0\xF0\201\_]*).*[A-Za-z0-9][\xF0\xF0\xF0\xF0\201\?\.\!\,]*)\"/ui, '\1”')
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
# 2. ёлочки
|
178
|
+
if @settings["laquo"]
|
179
|
+
text.gsub!( /\"\"/ui, """");
|
180
|
+
text.gsub!( /(^|\s|\201|\xF0\xF0\xF0\xF0|>|\()\"((\201|\xF0\xF0\xF0\xF0)*[~0-9ёЁA-Za-zА-Яа-я\-:\/\.])/ui, "\\1«\\2");
|
181
|
+
# nb: wacko only regexp follows:
|
182
|
+
text.gsub!( /(^|\s|\201|\xF0\xF0\xF0\xF0|>|\()\"((\201|\xF0\xF0\xF0\xF0|\/ |\/|\!)*[~0-9ёЁA-Za-zА-Яа-я\-:\/\.])/ui, "\\1«\\2")
|
183
|
+
_text = "\"\"";
|
184
|
+
while (_text != text) do
|
185
|
+
_text = text;
|
186
|
+
text.gsub!( /(\«\;([^\"]*)[ёЁA-Za-zА-Яа-я0-9\.\-:\/](\201|\xF0\xF0\xF0\xF0)*)\"/sui, "\\1»")
|
187
|
+
# nb: wacko only regexps follows:
|
188
|
+
text.gsub!( /(\«\;([^\"]*)[ёЁA-Za-zА-Яа-я0-9\.\-:\/](\201|\xF0\xF0\xF0\xF0)*\?(\201|\xF0\xF0\xF0\xF0)*)\"/sui, "\\1»")
|
189
|
+
text.gsub!( /(\«\;([^\"]*)[ёЁA-Za-zА-Яа-я0-9\.\-:\/](\201|\xF0\xF0\xF0\xF0|\/|\!)*)\"/sui, "\\1»")
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
|
194
|
+
# 2b. одновременно ёлочки и лапки
|
195
|
+
if (@settings["quotes"] && (@settings["laquo"] or @settings["farlaquo"]))
|
196
|
+
text.gsub!(/(\&\#147;\;(([A-Za-z0-9'!\.?,\-&;:]|\s|\xF0\xF0\xF0\xF0|\201)*)«(.*)»)»/ui,"\\1”");
|
197
|
+
end
|
198
|
+
|
199
|
+
|
200
|
+
# 3. тире
|
201
|
+
if (@settings["dash"])
|
202
|
+
text.gsub!( /(\s|;)\-(\s)/ui, "\\1–\\2")
|
203
|
+
end
|
204
|
+
|
205
|
+
|
206
|
+
# 3a. тире длинное
|
207
|
+
if (@settings["emdash"])
|
208
|
+
text.gsub!( /(\s|;)\-\-(\s)/ui, "\\1—\\2")
|
209
|
+
# 4. (с)
|
210
|
+
text.gsub!(/\([сСcC]\)((?=\w)|(?=\s[0-9]+))/u, "©") if @settings["(c)"]
|
211
|
+
# 4a. (r)
|
212
|
+
text.gsub!( /\(r\)/ui, "<sup>®</sup>") if @settings["(r)"]
|
213
|
+
|
214
|
+
# 4b. (tm)
|
215
|
+
text.gsub!( /\(tm\)|\(тм\)/ui, "™") if @settings["(tm)"]
|
216
|
+
# 4c. (p)
|
217
|
+
text.gsub!( /\(p\)/ui, "§") if @settings["(p)"]
|
218
|
+
end
|
219
|
+
|
220
|
+
|
221
|
+
# 5. +/-
|
222
|
+
text.gsub!(/[^+]\+\-/ui, "±") if @settings["+-"]
|
223
|
+
|
224
|
+
|
225
|
+
# 5a. 12^C
|
226
|
+
if @settings["degrees"]
|
227
|
+
text.gsub!( /-([0-9])+\^([FCС])/, "–\\1°\\2")
|
228
|
+
text.gsub!( /\+([0-9])+\^([FCС])/, "+\\1°\\2")
|
229
|
+
text.gsub!( /\^([FCС])/, "°\\1")
|
230
|
+
end
|
231
|
+
|
232
|
+
|
233
|
+
# 6. телефоны
|
234
|
+
if @settings["phones"]
|
235
|
+
@phonemasks[0].each_with_index do |v, i|
|
236
|
+
text.gsub!(v, @phonemasks[1][i])
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
240
|
+
|
241
|
+
# 7. Короткие слова и
|
242
|
+
if (@settings["wordglue"])
|
243
|
+
|
244
|
+
text = " " + text + " ";
|
245
|
+
_text = " " + text + " ";
|
246
|
+
until _text == text
|
247
|
+
_text = text
|
248
|
+
text.gsub!( /(\s+)([a-zа-яА-Я]{1,2})(\s+)([^\\s$])/ui, '\1\2 \4')
|
249
|
+
text.gsub!( /(\s+)([a-zа-яА-Я]{3})(\s+)([^\\s$])/ui, '\1\2 \4')
|
250
|
+
end
|
251
|
+
|
252
|
+
for i in @glueleft
|
253
|
+
text.gsub!( /(\s)(#{i})(\s+)/sui, '\1\2 ')
|
254
|
+
end
|
255
|
+
|
256
|
+
for i in @glueright
|
257
|
+
text.gsub!( /(\s)(#{i})(\s+)/sui, ' \2\3')
|
258
|
+
end
|
259
|
+
end
|
260
|
+
|
261
|
+
|
262
|
+
|
263
|
+
# 8. Склейка ласт. Тьфу! дефисов.
|
264
|
+
text.gsub!( /([a-zа-яА-Я0-9]+(\-[a-zа-яА-Я0-9]+)+)/ui, '<nobr>\1</nobr>') if @settings["dashglue"]
|
265
|
+
|
266
|
+
|
267
|
+
# 9. Макросы
|
268
|
+
|
269
|
+
|
270
|
+
|
271
|
+
# 10. Переводы строк
|
272
|
+
# --- для ваки не портировано ---
|
273
|
+
# --- для ваки не портировано ---
|
274
|
+
|
275
|
+
|
276
|
+
# БЕСКОНЕЧНОСТЬ. Вставляем таги обратно.
|
277
|
+
# if (@skip_tags)
|
278
|
+
# text = text.split("\xF0\xF0\xF0\xF0").join
|
279
|
+
#
|
280
|
+
|
281
|
+
tags.each do |tag|
|
282
|
+
text.sub!(@mark_tag, tag)
|
283
|
+
end
|
284
|
+
|
285
|
+
# i = 0
|
286
|
+
# text.gsub!(@mark_tag) {
|
287
|
+
# i + 1
|
288
|
+
# tags[i-1]
|
289
|
+
# }
|
290
|
+
|
291
|
+
# text = text.split("\xF0\xF0\xF0\xF0")
|
292
|
+
#puts "reinserted #{i} tags"
|
293
|
+
#
|
294
|
+
# end
|
295
|
+
|
296
|
+
|
297
|
+
#ext.gsub!("a", '')
|
298
|
+
# raise "Text still has tag markers!" if text.include?("a")
|
299
|
+
|
300
|
+
# БЕСКОНЕЧНОСТЬ-2. вставляем ещё сигнорированный регексп
|
301
|
+
#
|
302
|
+
# if @ignore
|
303
|
+
# ignored.each { | tag | text.sub!(@mark_ignored, tag) }
|
304
|
+
# end
|
305
|
+
|
306
|
+
# raise "Text still has ignored markers!" if text.include?("\201")
|
307
|
+
|
308
|
+
# БОНУС: прокручивание ссылок через A(...)
|
309
|
+
# --- для ваки не портировано ---
|
310
|
+
# --- для ваки не портировано ---
|
311
|
+
|
312
|
+
# фуф, закончили.
|
313
|
+
# text.gsub!(/<nobr>/, "<span class=\"nobr\">").gsub(/<\/nobr>/, "</span>") if (@de_nobr)
|
314
|
+
|
315
|
+
# text.gsub!(/<nobr>/, "<span class=\"nobr\">").gsub(/<\/nobr>/, "</span>") if (@de_nobr)
|
316
|
+
|
317
|
+
text.gsub(/(\s)+$/, "").gsub(/^(\s)+/, "")
|
318
|
+
|
319
|
+
end
|
320
|
+
|
321
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
if defined?(BlueCloth) && !BlueCloth.instance_methods.include?("to_html_without_rutils")
|
2
|
+
class Object::BlueCloth < String #:nodoc:
|
3
|
+
alias_method :to_html_without_rutils, :to_html
|
4
|
+
def to_html(*opts)
|
5
|
+
if RuTils::overrides_enabled?
|
6
|
+
RuTils::Gilenson::Formatter.new(to_html_without_rutils(*opts)).to_html
|
7
|
+
else
|
8
|
+
to_html_without_rutils(*opts)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module RuTils
|
2
|
+
@@overrides = true
|
3
|
+
|
4
|
+
# Метод позволяет проверить, включена ли перегрузка функций других модулей.
|
5
|
+
# Попутно он спрашивает модуль Locale (если таковой имеется) является ли русский
|
6
|
+
# текущим языком, и если является, включает перегрузку функций имплицитно.
|
7
|
+
# Это позволяет подчинить настройку перегруженных функций настроенной локали.
|
8
|
+
# Модуль Locale можно получить как часть Ruby-Gettext или как отдельный
|
9
|
+
# модуль ruby-locale. Мы поддерживаем оба.
|
10
|
+
def self.overrides_enabled?
|
11
|
+
if defined?(Locale) and Locale.respond_to?(:current)
|
12
|
+
return true if Locale.current.to_s.split('_').first == 'ru'
|
13
|
+
end
|
14
|
+
@@overrides ? true : false
|
15
|
+
end
|
16
|
+
|
17
|
+
# Включает или выключает перегрузки других модулей. Полезно, например, в случае когда нужно рендерить страницу
|
18
|
+
# сайта на нескольких языках и нужно отключить русское оформление текста для других языков.
|
19
|
+
def self.overrides= (new_override_flag)
|
20
|
+
@@overrides = (new_override_flag ? true : false)
|
21
|
+
end
|
22
|
+
|
23
|
+
# Вновь выполняет перегрузку. Делать это надо после того, как в программу импортированы
|
24
|
+
# другие модули.
|
25
|
+
def self.reload_integrations!
|
26
|
+
load File.dirname(__FILE__) + '/blue_cloth_override.rb'
|
27
|
+
load File.dirname(__FILE__) + '/red_cloth_override.rb'
|
28
|
+
load File.dirname(__FILE__) + '/rails_date_helper_override.rb'
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
RuTils::reload_integrations!
|
@@ -0,0 +1,113 @@
|
|
1
|
+
if defined?(Object::ActionView)
|
2
|
+
module Object::ActionView::Helpers::DateHelper
|
3
|
+
|
4
|
+
# Заменяет ActionView::Helpers::DateHelper::distance_of_time_in_words на русское сообщение.
|
5
|
+
#
|
6
|
+
# Целые числа интерпретируются как секунды
|
7
|
+
# <tt>distance_of_time_in_words(50)</tt> возвращает "меньше минуты".
|
8
|
+
|
9
|
+
alias :stock_distance_of_time_in_words :distance_of_time_in_words
|
10
|
+
def distance_of_time_in_words(*args)
|
11
|
+
RuTils::overrides_enabled? ? RuTils::DateTime::distance_of_time_in_words(*args) : stock_distance_of_time_in_words
|
12
|
+
end
|
13
|
+
|
14
|
+
|
15
|
+
# В Rails >= 2.1 3 аргумента у select_month
|
16
|
+
args_num = 2
|
17
|
+
begin
|
18
|
+
class TestClass
|
19
|
+
include Object::ActionView::Helpers::DateHelper
|
20
|
+
end
|
21
|
+
TestClass.new.select_month(Time.now, {}, {}, {}, {}, {}, {})
|
22
|
+
rescue ArgumentError => e
|
23
|
+
if e.message =~ /wrong number of arguments \(7 for (\d+)\)/
|
24
|
+
args_num = $1.to_i
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
case args_num
|
29
|
+
when 2
|
30
|
+
# Заменяет ActionView::Helpers::DateHelper::select_month меню выбора русских месяцев.
|
31
|
+
#
|
32
|
+
# select_month(Date.today) # Использует ключи "Январь", "Март"
|
33
|
+
# select_month(Date.today, :use_month_numbers => true) # Использует ключи "1", "3"
|
34
|
+
# select_month(Date.today, :add_month_numbers => true) # Использует ключи "1 - Январь", "3 - Март"
|
35
|
+
def select_month(date, options = {})
|
36
|
+
month_options = []
|
37
|
+
if RuTils::overrides_enabled?
|
38
|
+
month_names = case true
|
39
|
+
when options[:use_short_month]
|
40
|
+
Date::RU_ABBR_MONTHNAMES
|
41
|
+
# использование в контексте date_select с днями требует родительный падеж
|
42
|
+
when options[:order] && options[:order].include?(:day)
|
43
|
+
Date::RU_INFLECTED_MONTHNAMES
|
44
|
+
else
|
45
|
+
Date::RU_MONTHNAMES
|
46
|
+
end
|
47
|
+
else
|
48
|
+
month_names = options[:use_short_month] ? Date::ABBR_MONTHNAMES : Date::MONTHNAMES
|
49
|
+
end
|
50
|
+
1.upto(12) do |month_number|
|
51
|
+
month_name = if options[:use_month_numbers]
|
52
|
+
month_number
|
53
|
+
elsif options[:add_month_numbers]
|
54
|
+
month_number.to_s + ' - ' + month_names[month_number]
|
55
|
+
else
|
56
|
+
month_names[month_number]
|
57
|
+
end
|
58
|
+
|
59
|
+
month_options << ((date && (date.kind_of?(Fixnum) ? date : date.month) == month_number) ?
|
60
|
+
%(<option value="#{month_number}" selected="selected">#{month_name}</option>\n) :
|
61
|
+
%(<option value="#{month_number}">#{month_name}</option>\n)
|
62
|
+
)
|
63
|
+
end
|
64
|
+
|
65
|
+
select_html(options[:field_name] || 'month', month_options, options)
|
66
|
+
end
|
67
|
+
|
68
|
+
# Заменяет ActionView::Helpers::DateHelper::select_date меню выбора русской даты.
|
69
|
+
def select_date(date = Date.today, options = {})
|
70
|
+
options[:order] ||= []
|
71
|
+
[:day, :month, :year].each { |o| options[:order].push(o) unless options[:order].include?(o) }
|
72
|
+
|
73
|
+
options[:order].map{ |o| self.send("select_#{o}", date, options) }.join
|
74
|
+
end
|
75
|
+
|
76
|
+
# Заменяет ActionView::Helpers::DateHelper::select_datetime меню выбора русской даты.
|
77
|
+
def select_datetime(datetime = Time.now, options = {})
|
78
|
+
select_day(datetime, options) + select_month(datetime, options) + select_year(datetime, options) +
|
79
|
+
select_hour(datetime, options) + select_minute(datetime, options)
|
80
|
+
end
|
81
|
+
when 3
|
82
|
+
# Rails 2.1
|
83
|
+
|
84
|
+
# Заменяет ActionView::Helpers::DateHelper::select_month меню выбора русских месяцев.
|
85
|
+
#
|
86
|
+
# select_month(Date.today) # Использует ключи "Январь", "Март"
|
87
|
+
# select_month(Date.today, :use_month_numbers => true) # Использует ключи "1", "3"
|
88
|
+
# select_month(Date.today, :add_month_numbers => true) # Использует ключи "1 - Январь", "3 - Март"
|
89
|
+
def select_month_with_rutils(date, options = {}, html_options = {})
|
90
|
+
if RuTils::overrides_enabled?
|
91
|
+
month_names = case true
|
92
|
+
when options[:use_short_month]
|
93
|
+
Date::RU_ABBR_MONTHNAMES
|
94
|
+
# использование в контексте date_select с днями требует родительный падеж
|
95
|
+
when options[:order] && options[:order].include?(:day)
|
96
|
+
Date::RU_INFLECTED_MONTHNAMES
|
97
|
+
else
|
98
|
+
Date::RU_MONTHNAMES
|
99
|
+
end
|
100
|
+
options = options.reverse_merge(:use_month_names => month_names)
|
101
|
+
end
|
102
|
+
select_month_without_rutils(date, options, html_options)
|
103
|
+
end
|
104
|
+
alias_method_chain :select_month, :rutils
|
105
|
+
|
106
|
+
def select_date_with_rutils(date = Date.today, options = {}, html_options = {})
|
107
|
+
options = options.reverse_merge(:order => [:day, :month, :year])
|
108
|
+
select_date_without_rutils(date, options, html_options)
|
109
|
+
end
|
110
|
+
alias_method_chain :select_date, :rutils
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end #endif
|