rutils 0.1.9 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +4 -0
- data/lib/datetime/datetime.rb +3 -3
- data/lib/rutils.rb +2 -2
- data/lib/transliteration/simple.rb +1 -1
- data/test/t_integration.rb +1 -0
- data/test/t_transliteration.rb +6 -4
- metadata +4 -5
- data/lib/gilenson/gilenson.rb +0 -617
- data/test/t_gilenson.rb +0 -324
data/CHANGELOG
CHANGED
data/lib/datetime/datetime.rb
CHANGED
@@ -66,17 +66,17 @@ class Time
|
|
66
66
|
end
|
67
67
|
|
68
68
|
class Date
|
69
|
-
|
69
|
+
|
70
70
|
# Inside rails we have date formatting
|
71
71
|
if self.instance_methods.include?('strftime')
|
72
72
|
alias_method :strftime_norutils, :strftime
|
73
|
-
def strftime(fmt=
|
73
|
+
def strftime(fmt='%F')
|
74
74
|
RuTils::DateTime::ru_strftime(fmt, self) if RuTils::overrides_enabled?
|
75
75
|
strftime_norutils(fmt)
|
76
76
|
end
|
77
77
|
|
78
78
|
else
|
79
|
-
def strftime(fmt=
|
79
|
+
def strftime(fmt='%F')
|
80
80
|
RuTils::DateTime::ru_strftime(fmt, self) if RuTils::overrides_enabled?
|
81
81
|
self.to_time.strftime(fmt)
|
82
82
|
end
|
data/lib/rutils.rb
CHANGED
@@ -5,8 +5,8 @@ module RuTils
|
|
5
5
|
# Папка, куда установлен модуль RuTils. Нужно чтобы автоматически копировать RuTils в другие приложения.
|
6
6
|
INSTALLATION_DIRECTORY = File.expand_path(File.dirname(__FILE__) + '/../') #:nodoc:
|
7
7
|
MAJOR = 0
|
8
|
-
MINOR =
|
9
|
-
TINY =
|
8
|
+
MINOR = 2
|
9
|
+
TINY = 0
|
10
10
|
|
11
11
|
# Версия RuTils
|
12
12
|
VERSION = [MAJOR, MINOR ,TINY].join('.') #:nodoc:
|
@@ -69,6 +69,6 @@ module RuTils::Transliteration::Simple
|
|
69
69
|
st.gsub!(/\W/, ' ') #replace non-chars
|
70
70
|
st.gsub!(/(_)$/, '') #trailing underscores
|
71
71
|
st.gsub!(/^(_)/, '') #leading unders
|
72
|
-
st.strip.translify.gsub(/(\s)/,'-').downcase.squeeze
|
72
|
+
st.strip.translify.gsub(/(\s)/,'-').downcase.squeeze('-')
|
73
73
|
end
|
74
74
|
end
|
data/test/t_integration.rb
CHANGED
data/test/t_transliteration.rb
CHANGED
@@ -6,7 +6,7 @@ require File.dirname(__FILE__) + '/../lib/rutils'
|
|
6
6
|
class TranslitTest < Test::Unit::TestCase
|
7
7
|
|
8
8
|
def setup
|
9
|
-
@string = "Это кусок строки русских букв v
|
9
|
+
@string = "Это кусок строки русских букв v peremeshku s latinizey i амперсандом (pozor!) & something"
|
10
10
|
end
|
11
11
|
|
12
12
|
def test_translify
|
@@ -16,7 +16,7 @@ class TranslitTest < Test::Unit::TestCase
|
|
16
16
|
assert_equal "sh", 'ш'.translify
|
17
17
|
assert_equal "SH", 'Ш'.translify
|
18
18
|
assert_equal "ts", 'ц'.translify
|
19
|
-
assert_equal "Eto kusok stroki russkih bukv v
|
19
|
+
assert_equal "Eto kusok stroki russkih bukv v peremeshku s latinizey i ampersandom (pozor!) & something", @string.translify
|
20
20
|
assert_equal "Это просто некий текст".translify, "Eto prosto nekiy tekst"
|
21
21
|
|
22
22
|
assert_equal "NEVEROYATNOE UPUSCHENIE", 'НЕВЕРОЯТНОЕ УПУЩЕНИЕ'.translify
|
@@ -36,8 +36,10 @@ class TranslitTest < Test::Unit::TestCase
|
|
36
36
|
# end
|
37
37
|
|
38
38
|
def test_dirify
|
39
|
-
assert_equal "eto-kusok-stroki-
|
40
|
-
assert_equal "esche-
|
39
|
+
assert_equal "eto-kusok-stroki-russkih-bukv-v-peremeshku-s-latinizey-i-ampersandom-pozor-and-something", @string.dirify
|
40
|
+
assert_equal "esche-russkiy-tekst", "Еще РусСКий теКст".dirify
|
41
|
+
# dirify не должен съедать парные буквы
|
42
|
+
assert_equal "kooperator-poobedal-offlayn", "кооператор пообедал оффлайн".dirify
|
41
43
|
end
|
42
44
|
end
|
43
45
|
|
metadata
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
|
-
rubygems_version: 0.
|
2
|
+
rubygems_version: 0.9.2
|
3
3
|
specification_version: 1
|
4
4
|
name: rutils
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.
|
7
|
-
date: 2007-
|
6
|
+
version: 0.2.0
|
7
|
+
date: 2007-04-03 00:00:00 +02:00
|
8
8
|
summary: Simple processing of russian strings
|
9
9
|
require_paths:
|
10
10
|
- lib
|
@@ -25,6 +25,7 @@ required_ruby_version: !ruby/object:Gem::Version::Requirement
|
|
25
25
|
platform: ruby
|
26
26
|
signing_key:
|
27
27
|
cert_chain:
|
28
|
+
post_install_message:
|
28
29
|
authors:
|
29
30
|
- Julian "Julik" Tarkhanov
|
30
31
|
files:
|
@@ -32,7 +33,6 @@ files:
|
|
32
33
|
- bin/rutilize
|
33
34
|
- test/run_tests.rb
|
34
35
|
- test/t_datetime.rb
|
35
|
-
- test/t_gilenson.rb
|
36
36
|
- test/t_integration.rb
|
37
37
|
- test/t_pluralize.rb
|
38
38
|
- test/t_rutils_base.rb
|
@@ -47,7 +47,6 @@ files:
|
|
47
47
|
- lib/transliteration
|
48
48
|
- lib/countries/countries.rb
|
49
49
|
- lib/datetime/datetime.rb
|
50
|
-
- lib/gilenson/gilenson.rb
|
51
50
|
- lib/gilenson/gilenson_port.rb
|
52
51
|
- lib/integration/blue_cloth_override.rb
|
53
52
|
- lib/integration/integration.rb
|
data/lib/gilenson/gilenson.rb
DELETED
@@ -1,617 +0,0 @@
|
|
1
|
-
module RuTils
|
2
|
-
module Gilenson
|
3
|
-
# Позволяет возвращать класс форматтера при вызове
|
4
|
-
# RuTils::Gilenson.new
|
5
|
-
def self.new(*args) #:nodoc:
|
6
|
-
RuTils::Gilenson::Formatter.new(*args)
|
7
|
-
end
|
8
|
-
|
9
|
-
# Загружаем "старый" Гиленсон если он будет нужен
|
10
|
-
def self.const_missing(const) #:nodoc:
|
11
|
-
super(const) unless const == :Obsolete
|
12
|
-
require File.dirname(__FILE__) + '/gilenson_port'
|
13
|
-
return RuTils::Gilenson::Obsolete
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
# ==Что такое Gilenson
|
19
|
-
# Обработчик типографских символов в HTML согласно общепринятым правилам.
|
20
|
-
# Посвящается П.Г.Гиленсону[http://www.rudtp.ru/lib.php?book=172], благодаря которому русские правила тех.
|
21
|
-
# редактуры еще как минимум 20 лет останутся столь-же бессмысленно старомодными и строгими.
|
22
|
-
#
|
23
|
-
# Gilenson расставит в тексте "умные" правильные кавычки (русские - для кириллицы, английские - для латиницы),
|
24
|
-
# заменит "хитрые" пунктуационные символы на entities и отформатирует знаки типа (c), (tm), телефоны и адреса.
|
25
|
-
#
|
26
|
-
# Gilenson базируется на коде Typografica[http://pixel-apes.com/typografica] от PixelApes,
|
27
|
-
# который был приведен к положенному в Ruby стандарту. Основные отличия Gilenson от Typografica на PHP:
|
28
|
-
# * работа только и полностью в UTF-8 (включая entities, применимые в XML)
|
29
|
-
# * поддержка "raw"-вывода (символов вместо entities) - текст выводимый GIlenson можно верстать на бумаге
|
30
|
-
#
|
31
|
-
# Если вам нужно получать идентичный Typografica вывод, пользуйтесь RuTils::Gilenson::Obsolete
|
32
|
-
# вместо RuTils::Gilenson::Formatter.
|
33
|
-
#
|
34
|
-
# ==Использование
|
35
|
-
# Быстрее всего - через метод ++gilensize++ для любой строковой переменной
|
36
|
-
# %{ И вот они таки "приехали"}.gilensize => 'И вот они таки «приехали»'
|
37
|
-
# Все дополнительные настройки в таком случае передаются форматтеру
|
38
|
-
# %{ И вот они таки "приехали"}.gilensize(:laquo=>false) => 'И вот они таки "приехали"'
|
39
|
-
#
|
40
|
-
# Если форматтер надо настроить более тонко, можно использовать его и так:
|
41
|
-
# typ = RuTils::Gilenson.new('Эти "так называемые" великие деятели')
|
42
|
-
# typ.to_html => 'Эти «так называемые» великие деятели'
|
43
|
-
#
|
44
|
-
# или как фильтр
|
45
|
-
# formatter = RuTils::Gilenson.new
|
46
|
-
# formatter.configure(:dash=>true)
|
47
|
-
# for string in strings
|
48
|
-
# puts formatter.process(string)
|
49
|
-
# end
|
50
|
-
#
|
51
|
-
# ==Настройки
|
52
|
-
# Настройки регулируются через методы
|
53
|
-
# formatter.dashglue = true
|
54
|
-
# или ассоциированным хешем
|
55
|
-
# formatter.configure!(:dash=>true, :quotes=>false)
|
56
|
-
#
|
57
|
-
# Хеш также можно передавать как последний аргумент методам process и to_html,
|
58
|
-
# в таком случае настройки будут применены только при этом вызове
|
59
|
-
#
|
60
|
-
# beautified = formatter.process(my_text, :dash=>true)
|
61
|
-
#
|
62
|
-
# В параметры можно подставить также ключ :all чтобы временно включить или выключить все фильтры
|
63
|
-
#
|
64
|
-
# beautified = formatter.process(my_text, :all=>true)
|
65
|
-
#
|
66
|
-
# Помимо этого можно пользоваться каждым фильтром по отдельности используя метод +apply+
|
67
|
-
#
|
68
|
-
# Можно менять глифы, которые форматтер использует для подстановок. К примеру,
|
69
|
-
# formatter.glyph[:nbsp] = ' '
|
70
|
-
# заставит форматтер расставлять "традиционные" неразрывные пробелы. Именно это - большая глупость,
|
71
|
-
# но другие глифы заменить может быть нужно.
|
72
|
-
#
|
73
|
-
# ==Настройки форматтера
|
74
|
-
# "inches" - преобразовывать дюймы в знак дюйма;
|
75
|
-
# "laquo" - кавычки-ёлочки
|
76
|
-
# "quotes" - кавычки-английские лапки
|
77
|
-
# "dash" - проставлять короткое тире (150)
|
78
|
-
# "emdash" - длинное тире двумя минусами (151)
|
79
|
-
# "initials" - проставлять тонкие шпации в инициалах
|
80
|
-
# "copypaste" - замена непечатных и "специальных" юникодных символов на entities
|
81
|
-
# "(c)" - обрабатывать знак копирайта
|
82
|
-
# "(r)", "(tm)", "(p)", "+-" - спецсимволы, какие - понятно
|
83
|
-
# "degrees" - знак градуса
|
84
|
-
# "dashglue", "wordglue" - приклеивание предлогов и дефисов
|
85
|
-
# "spacing" - запятые и пробелы, перестановка
|
86
|
-
# "phones" - обработка телефонов
|
87
|
-
# "html" - при false - запрет использования тагов html
|
88
|
-
# "de_nobr" - при true все <nobr/> заменяются на <span class="nobr"/>
|
89
|
-
# "raw_output" - (по умолчанию false) - при true вместо entities выводятся UTF-символы
|
90
|
-
# "skip_attr" - (по умолчанию false) - при true не отрабатывать типографику в атрибутах тегов (title, alt)
|
91
|
-
# "skip_code" - (по умолчанию true) - при true не отрабатывать типографику внутри <code/>, <tt/>, CDATA
|
92
|
-
|
93
|
-
class RuTils::Gilenson::Formatter
|
94
|
-
attr_accessor :glyph
|
95
|
-
|
96
|
-
SETTINGS = {
|
97
|
-
"inches" => true, # преобразовывать дюймы в знак дюйма;
|
98
|
-
"laquo" => true, # кавычки-ёлочки
|
99
|
-
"quotes" => true, # кавычки-английские лапки
|
100
|
-
"dash" => true, # короткое тире (150)
|
101
|
-
"emdash" => true, # длинное тире двумя минусами (151)
|
102
|
-
"initials" => true, # тонкие шпации в инициалах
|
103
|
-
"copypaste" => false, # замена непечатных и "специальных" юникодных символов на entities
|
104
|
-
"(c)" => true, # обрабатывать знак копирайта
|
105
|
-
"(r)" => true,
|
106
|
-
"(tm)" => true,
|
107
|
-
"(p)" => true,
|
108
|
-
"+-" => true, # спецсимволы, какие - понятно
|
109
|
-
"degrees" => true, # знак градуса
|
110
|
-
"dashglue" => true, "wordglue" => true, # приклеивание предлогов и дефисов
|
111
|
-
"spacing" => true, # запятые и пробелы, перестановка
|
112
|
-
"phones" => true, # обработка телефонов
|
113
|
-
"html" => true, # разрешение использования тагов html
|
114
|
-
"de_nobr" => false, # при true все <nobr/> заменяются на <span class="nobr"/>
|
115
|
-
"raw_output" => false, # выводить UTF-8 вместо entities
|
116
|
-
"skip_attr" => false, # при true не отрабатывать типографику в атрибутах тегов
|
117
|
-
"skip_code" => true, # при true не отрабатывать типографику внутри <code/>, <tt/>, CDATA
|
118
|
-
} #:nodoc:
|
119
|
-
|
120
|
-
# Глифы, использующиеся в подстановках по-умолчанию
|
121
|
-
GLYPHS = {
|
122
|
-
:quot => """, # quotation mark
|
123
|
-
:amp => "&", # ampersand
|
124
|
-
:apos => "'", # apos
|
125
|
-
:gt => ">", # greater-than sign
|
126
|
-
:lt => "<", # less-than sign
|
127
|
-
:nbsp => " ", # non-breaking space
|
128
|
-
:sect => "§", # section sign
|
129
|
-
:copy => "©", # copyright sign
|
130
|
-
:laquo => "«", # left-pointing double angle quotation mark = left pointing guillemet
|
131
|
-
:reg => "®", # registered sign = registered trade mark sign
|
132
|
-
:deg => "°", # degree sign
|
133
|
-
:plusmn => "±", # plus-minus sign = plus-or-minus sign
|
134
|
-
:para => "¶", # pilcrow sign = paragraph sign
|
135
|
-
:middot => "·", # middle dot = Georgian comma = Greek middle dot
|
136
|
-
:raquo => "»", # right-pointing double angle quotation mark = right pointing guillemet
|
137
|
-
:ndash => "–", # en dash
|
138
|
-
:mdash => "—", # em dash
|
139
|
-
:lsquo => "‘", # left single quotation mark
|
140
|
-
:rsquo => "’", # right single quotation mark
|
141
|
-
:ldquo => "“", # left double quotation mark
|
142
|
-
:rdquo => "”", # right double quotation mark
|
143
|
-
:bdquo => "„", # double low-9 quotation mark
|
144
|
-
:bull => "•", # bullet = black small circle
|
145
|
-
:hellip => "…", # horizontal ellipsis = three dot leader
|
146
|
-
:numero => "№", # numero
|
147
|
-
:trade => "™", # trade mark sign
|
148
|
-
:minus => "−", # minus sign
|
149
|
-
:inch => "″", # inch/second sign (u0x2033) (не путать с кавычками!)
|
150
|
-
:thinsp => " ", # полукруглая шпация (тонкий пробел)
|
151
|
-
:nob_open => '<nobr>', # открывающий блок без переноса слов
|
152
|
-
:nob_close => '</nobr>', # открывающий блок без переноса слов
|
153
|
-
} #:nodoc:
|
154
|
-
|
155
|
-
# Нормальные "типографские" символы в UTF-виде. Браузерами обрабатываются плохонько, поэтому
|
156
|
-
# лучше заменять их на entities.
|
157
|
-
VERBATIM_GLYPHS = {
|
158
|
-
' ' => :nbsp,# alt+0160 (NBSP here)
|
159
|
-
'«' => :laquo,
|
160
|
-
'»' => :raquo,
|
161
|
-
'§' => :sect,
|
162
|
-
'©' => :copy,
|
163
|
-
'®' => :reg,
|
164
|
-
'°' => :deg,
|
165
|
-
'±' => :plusmn,
|
166
|
-
'¶' => :para,
|
167
|
-
'·' => :middot,
|
168
|
-
'–' => :ndash,
|
169
|
-
'—' => :mdash,
|
170
|
-
'‘' => :lsquo,
|
171
|
-
'’' => :rsquo,
|
172
|
-
'“' => :ldquo,
|
173
|
-
'”' => :rdquo,
|
174
|
-
'„' => :bdquo,
|
175
|
-
'•' => :bull,
|
176
|
-
'…' => :hellip,
|
177
|
-
'№' => :numero,
|
178
|
-
'™' => :trade,
|
179
|
-
'−' => :minus,
|
180
|
-
' ' => :thinsp,
|
181
|
-
'″' => :inch,
|
182
|
-
} #:nodoc:
|
183
|
-
|
184
|
-
# Для маркера мы применяем invalid UTF-sequence чтобы его НЕЛЬЗЯ было перепутать с частью
|
185
|
-
# любого другого мультибайтного глифа. Thanks to huNter.
|
186
|
-
REPLACEMENT_MARKER = RuTils::SUBSTITUTION_MARKER #:nodoc:
|
187
|
-
|
188
|
-
# Кто придумал “? Не учите людей плохому...
|
189
|
-
# Привет А.Лебедеву http://www.artlebedev.ru/kovodstvo/62/
|
190
|
-
# Используем символы, потом берем по символам из glyphs форматтера.
|
191
|
-
# Молодец mash!
|
192
|
-
FORBIDDEN_NUMERIC_ENTITIES = {
|
193
|
-
'132' => :bdquo,
|
194
|
-
'133' => :hellip,
|
195
|
-
'146' => :apos,
|
196
|
-
'147' => :ldquo,
|
197
|
-
'148' => :rdquo,
|
198
|
-
'149' => :bull,
|
199
|
-
'150' => :ndash,
|
200
|
-
'151' => :mdash,
|
201
|
-
'153' => :trade,
|
202
|
-
} #:nodoc:
|
203
|
-
|
204
|
-
PROTECTED_SETTINGS = [ :raw_output ] #:nodoc:
|
205
|
-
|
206
|
-
def initialize(*args)
|
207
|
-
@_text = args[0].is_a?(String) ? args[0] : ''
|
208
|
-
setup_default_settings!
|
209
|
-
accept_configuration_arguments!(args.last) if args.last.is_a?(Hash)
|
210
|
-
end
|
211
|
-
|
212
|
-
# Настраивает форматтер ассоциированным хешем
|
213
|
-
# formatter.configure!(:dash=>true, :wordglue=>false)
|
214
|
-
def configure!(*config)
|
215
|
-
accept_configuration_arguments!(config.last) if config.last.is_a?(Hash)
|
216
|
-
end
|
217
|
-
|
218
|
-
alias :configure :configure! #Дружественный API
|
219
|
-
|
220
|
-
# Неизвестные методы - настройки. С = - установка ключа, без - получение значения
|
221
|
-
def method_missing(meth, *args) #:nodoc:
|
222
|
-
setting = meth.to_s.gsub(/=$/, '')
|
223
|
-
super(meth, *args) unless @settings.has_key?(setting) #this will pop the exception if we have no such setting
|
224
|
-
|
225
|
-
return (@settings[setting] = args[0])
|
226
|
-
end
|
227
|
-
|
228
|
-
# Обрабатывает text_to_process с сохранением настроек, присвоенных обьекту-форматтеру
|
229
|
-
# Дополнительные аргументы передаются как параметры форматтера и не сохраняются после прогона.
|
230
|
-
def process(text_to_process, *args)
|
231
|
-
@_text = text_to_process
|
232
|
-
if args.last.is_a?(Hash)
|
233
|
-
with_configuration(args.last) { self.to_html }
|
234
|
-
else
|
235
|
-
self.to_html
|
236
|
-
end
|
237
|
-
end
|
238
|
-
|
239
|
-
# Обрабатывает текст, присвоенный форматтеру при создании и возвращает результат обработки.
|
240
|
-
def to_html()
|
241
|
-
return '' unless @_text
|
242
|
-
|
243
|
-
text = @_text.strip
|
244
|
-
|
245
|
-
# -4. запрет тагов html
|
246
|
-
process_escape_html(text) unless @settings["html"]
|
247
|
-
|
248
|
-
# -3. Никогда (вы слышите?!) не пущать лабуду &#not_correct_number;
|
249
|
-
FORBIDDEN_NUMERIC_ENTITIES.dup.each_pair do | key, rep |
|
250
|
-
text.gsub!(/&##{key};/, glyph[rep])
|
251
|
-
end
|
252
|
-
|
253
|
-
# -2. Чистим copy&paste
|
254
|
-
process_copy_paste_clearing(text) if @settings['copypaste']
|
255
|
-
|
256
|
-
# -1. Замена &entity_name; на входе (' ' => ' ' и т.д.)
|
257
|
-
process_html_entities(text)
|
258
|
-
|
259
|
-
# 0. Вырезаем таги
|
260
|
-
tags = lift_ignored_elements(text) if @skip_tags
|
261
|
-
|
262
|
-
# 1. Запятые и пробелы
|
263
|
-
process_spacing(text) if @settings["spacing"]
|
264
|
-
|
265
|
-
# 3. Спецсимволы
|
266
|
-
# 0. дюймы с цифрами
|
267
|
-
# заменено на инчи
|
268
|
-
process_inches(text) if @settings["inches"]
|
269
|
-
|
270
|
-
# 1. лапки
|
271
|
-
process_quotes(text) if @settings["quotes"]
|
272
|
-
|
273
|
-
# 2. ёлочки
|
274
|
-
process_laquo(text) if @settings["laquo"]
|
275
|
-
|
276
|
-
# 2b. одновременно ёлочки и лапки
|
277
|
-
process_compound_quotes(text) if (@settings["quotes"] && @settings["laquo"])
|
278
|
-
|
279
|
-
# 3. тире
|
280
|
-
process_dash(text) if @settings["dash"]
|
281
|
-
|
282
|
-
# 3a. тире длинное
|
283
|
-
process_emdash(text) if @settings["emdash"]
|
284
|
-
|
285
|
-
# 5. +/-
|
286
|
-
process_plusmin(text) if @settings["+-"]
|
287
|
-
|
288
|
-
# 5a. 12^C
|
289
|
-
process_degrees(text) if @settings["degrees"]
|
290
|
-
|
291
|
-
# 6. телефоны
|
292
|
-
process_phones(text) if @settings["phones"]
|
293
|
-
|
294
|
-
# 7. Короткие слова и
|
295
|
-
process_wordglue(text) if @settings["wordglue"]
|
296
|
-
|
297
|
-
# 8. Склейка ласт. Тьфу! дефисов.
|
298
|
-
process_dashglue(text) if @settings["dashglue"]
|
299
|
-
|
300
|
-
# 8a. Инициалы
|
301
|
-
process_initials(text) if @settings['initials']
|
302
|
-
|
303
|
-
# 8b. Троеточия
|
304
|
-
process_ellipsises(text) if @settings["wordglue"]
|
305
|
-
|
306
|
-
# БЕСКОНЕЧНОСТЬ. Вставляем таги обратно.
|
307
|
-
reinsert_fragments(text, tags) if @skip_tags
|
308
|
-
|
309
|
-
# фуф, закончили.
|
310
|
-
process_span_instead_of_nobr(text) if @settings["de_nobr"]
|
311
|
-
|
312
|
-
# заменяем entities на истинные символы
|
313
|
-
process_raw_output(text) if @settings["raw_output"]
|
314
|
-
|
315
|
-
text.strip
|
316
|
-
end
|
317
|
-
|
318
|
-
|
319
|
-
# Применяет отдельный фильтр к text и возвращает результат. Например:
|
320
|
-
# formatter.apply(:wordglue, "Вот так") => "Вот так"
|
321
|
-
# Удобно применять когда вам нужно задействовать отдельный фильтр Гиленсона, но не нужна остальная механика
|
322
|
-
# Последний аргумент определяет, нужно ли при применении фильтра сохранить в неприкосновенности таги и другие
|
323
|
-
# игнорируемые фрагменты текста (по умолчанию они сохраняются).
|
324
|
-
def apply(filter, text, lift_ignored_elements = true)
|
325
|
-
copy = text.dup
|
326
|
-
unless lift_ignored_elements
|
327
|
-
self.send("process_#{filter}".to_sym, copy)
|
328
|
-
else
|
329
|
-
lifting_fragments(copy) { self.send("process_#{filter}".to_sym, copy) }
|
330
|
-
end
|
331
|
-
copy
|
332
|
-
end
|
333
|
-
|
334
|
-
private
|
335
|
-
|
336
|
-
def setup_default_settings!
|
337
|
-
@skip_tags = true;
|
338
|
-
@ignore = /notypo/ # regex, который игнорируется. Этим надо воспользоваться для обработки pre и code
|
339
|
-
|
340
|
-
@glueleft = ['рис.', 'табл.', 'см.', 'им.', 'ул.', 'пер.', 'кв.', 'офис', 'оф.', 'г.']
|
341
|
-
@glueright = ['руб.', 'коп.', 'у.е.', 'мин.']
|
342
|
-
|
343
|
-
# Установки можно менять в каждом экземпляре
|
344
|
-
@settings = SETTINGS.dup
|
345
|
-
|
346
|
-
@mark_tag = REPLACEMENT_MARKER
|
347
|
-
# Глифы можено подменять в экземпляре форматтера поэтому копируем их из константы
|
348
|
-
@glyph = GLYPHS.dup
|
349
|
-
|
350
|
-
@phonemasks = [[ /([0-9]{4})\-([0-9]{2})\-([0-9]{2}) ([0-9]{2}):([0-9]{2}):([0-9]{2})/,
|
351
|
-
/([0-9]{4})\-([0-9]{2})\-([0-9]{2})/,
|
352
|
-
/(\([0-9\+\-]+\)) ?([0-9]{3})\-([0-9]{2})\-([0-9]{2})/,
|
353
|
-
/(\([0-9\+\-]+\)) ?([0-9]{2})\-([0-9]{2})\-([0-9]{2})/,
|
354
|
-
/(\([0-9\+\-]+\)) ?([0-9]{3})\-([0-9]{2})/,
|
355
|
-
/(\([0-9\+\-]+\)) ?([0-9]{2})\-([0-9]{3})/,
|
356
|
-
/([0-9]{3})\-([0-9]{2})\-([0-9]{2})/,
|
357
|
-
/([0-9]{2})\-([0-9]{2})\-([0-9]{2})/,
|
358
|
-
/([0-9]{1})\-([0-9]{2})\-([0-9]{2})/,
|
359
|
-
/([0-9]{2})\-([0-9]{3})/,
|
360
|
-
/([0-9]+)\-([0-9]+)/,
|
361
|
-
],[
|
362
|
-
':nob_open\1:ndash\2:ndash\3:nbsp\4:\5:\6:nob_close',
|
363
|
-
':nob_open\1:ndash\2:ndash\3:nob_close',
|
364
|
-
':nob_open\1:nbsp\2:ndash\3:ndash\4:nob_close',
|
365
|
-
':nob_open\1:nbsp\2:ndash\3:ndash\4:nob_close',
|
366
|
-
':nob_open\1:nbsp\2:ndash\3:nob_close',
|
367
|
-
':nob_open\1:nbsp\2:ndash\3:nob_close',
|
368
|
-
':nob_open\1:ndash\2:ndash\3:nob_close',
|
369
|
-
':nob_open\1:ndash\2:ndash\3:nob_close',
|
370
|
-
':nob_open\1:ndash\2:ndash\3:nob_close',
|
371
|
-
':nob_open\1:ndash\2:nob_close',
|
372
|
-
':nob_open\1:ndash\2:nob_close'
|
373
|
-
]]
|
374
|
-
end
|
375
|
-
|
376
|
-
# Позволяет получить процедуру, при вызове возвращающую значение глифа
|
377
|
-
def lookup(glyph_to_lookup)
|
378
|
-
return Proc.new { self.glyph[glyph_to_lookup] }
|
379
|
-
end
|
380
|
-
|
381
|
-
# Подставляет "символы" (двоеточие + имя глифа) на нужное значение глифа заданное в данном форматтере
|
382
|
-
def substitute_glyphs_in_string(str)
|
383
|
-
re = str.dup
|
384
|
-
@glyph.each_pair do | key, subst |
|
385
|
-
re.gsub!(":#{key.to_s}", subst)
|
386
|
-
end
|
387
|
-
re
|
388
|
-
end
|
389
|
-
|
390
|
-
# Выполняет блок, временно включая настройки переданные в +hash+
|
391
|
-
def with_configuration(hash, &block)
|
392
|
-
old_settings, old_glyphs = @settings.dup, @glyph.dup
|
393
|
-
accept_configuration_arguments!(hash)
|
394
|
-
txt = yield
|
395
|
-
@settings, @glyph = old_settings, old_glyphs
|
396
|
-
|
397
|
-
return txt
|
398
|
-
end
|
399
|
-
|
400
|
-
def accept_configuration_arguments!(args_hash)
|
401
|
-
|
402
|
-
# Специальный случай - :all=>true|false
|
403
|
-
if args_hash.has_key?(:all)
|
404
|
-
if args_hash[:all]
|
405
|
-
@settings.each_pair {|k, v| @settings[k] = true unless PROTECTED_SETTINGS.include?(k.to_sym)}
|
406
|
-
else
|
407
|
-
@settings.each_pair {|k, v| @settings[k] = false unless PROTECTED_SETTINGS.include?(k.to_sym)}
|
408
|
-
end
|
409
|
-
else
|
410
|
-
|
411
|
-
# Кинуть ошибку если настройка нам неизвестна
|
412
|
-
unknown_settings = args_hash.keys.collect{|k|k.to_s} - @settings.keys.collect { |k| k.to_s }
|
413
|
-
raise RuTils::Gilenson::UnknownSetting, unknown_settings if unknown_settings.any?
|
414
|
-
|
415
|
-
args_hash.each_pair do | key, value |
|
416
|
-
@settings[key.to_s] = (value ? true : false)
|
417
|
-
end
|
418
|
-
end
|
419
|
-
end
|
420
|
-
|
421
|
-
# Вынимает игнорируемые фрагменты и заменяет их маркером, выполняет переданный блок и вставляет вынутое на место
|
422
|
-
def lifting_fragments(text, &block)
|
423
|
-
lifted = lift_ignored_elements(text)
|
424
|
-
yield
|
425
|
-
reinsert_fragments(text, lifted)
|
426
|
-
end
|
427
|
-
|
428
|
-
#Вынимает фрагменты из текста и возвращает массив с фрагментами
|
429
|
-
def lift_ignored_elements(text)
|
430
|
-
# re = /<\/?[a-z0-9]+("+ # имя тага
|
431
|
-
# "\s+("+ # повторяющая конструкция: хотя бы один разделитель и тельце
|
432
|
-
# "[a-z]+("+ # атрибут из букв, за которым может стоять знак равенства и потом
|
433
|
-
# "=((\'[^\']*\')|(\"[^\"]*\")|([0-9@\-_a-z:\/?&=\.]+))"+ #
|
434
|
-
# ")?"+
|
435
|
-
# ")?"+
|
436
|
-
# ")*\/?>|\xA2\xA2[^\n]*?==/i;
|
437
|
-
|
438
|
-
re_skipcode = '((<(code|tt)[ >](.*?)<\/(code|tt)>)|(<!\[CDATA\[(.*?)\]\]>))|' if @settings['skip_code']
|
439
|
-
re = /(#{re_skipcode}<\/?[a-z0-9]+(\s+([a-z]+(=((\'[^\']*\')|(\"[^\"]*\")|([0-9@\-_a-z:\/?&=\.]+)))?)?)*\/?>)/uim
|
440
|
-
tags = text.scan(re).map{ |tag| tag[0] } # первая группа!
|
441
|
-
text.gsub!(re, @mark_tag) #маркер тега, мы используем Invalid UTF-sequence для него
|
442
|
-
return tags
|
443
|
-
end
|
444
|
-
|
445
|
-
def reinsert_fragments(text, fragments)
|
446
|
-
fragments.each do |fragment|
|
447
|
-
fragment.gsub!(/ (href|src|data)=((?:(\')([^\']*)(\'))|(?:(\")([^\"]*)(\")))/uim) do
|
448
|
-
" #{$1}=" + $2.gsub(/&(?!(#0*38)|(amp);)/, self.glyph[:amp])
|
449
|
-
end # unless @settings['raw_output'] -- делать это надо всегда (mash)
|
450
|
-
|
451
|
-
unless @settings['skip_attr']
|
452
|
-
fragment.gsub!(/ (title|alt)=((?:(\')([^\']*)(\'))|(?:(\")([^\"]*)(\")))/uim) do
|
453
|
-
" #{$1}=#{$3}" + self.process($4.to_s) + "#{$5}#{$6}" + self.process($7.to_s) + "#{$8}"
|
454
|
-
end
|
455
|
-
end
|
456
|
-
text.sub!(@mark_tag, fragment)
|
457
|
-
end
|
458
|
-
end
|
459
|
-
|
460
|
-
### Имплементации фильтров
|
461
|
-
def process_html_entities(text)
|
462
|
-
self.glyph.each { |key, value| text.gsub!(/&#{key};/, value)}
|
463
|
-
end
|
464
|
-
|
465
|
-
def process_initials(text)
|
466
|
-
initials = /([А-Я])[\.]{1,2}[\s]*?([А-Я])[\.]*[\s]*?([А-Я])([а-я])/u
|
467
|
-
replacement = substitute_glyphs_in_string('\1.\2.:thinsp\3\4')
|
468
|
-
text.gsub!(initials, replacement)
|
469
|
-
end
|
470
|
-
|
471
|
-
def process_copy_paste_clearing(text)
|
472
|
-
VERBATIM_GLYPHS.each {|key,value| text.gsub!(/#{key}/, glyph[value]) }
|
473
|
-
end
|
474
|
-
|
475
|
-
def process_spacing(text)
|
476
|
-
text.gsub!( /(\s*)([,]*)/sui, '\2\1');
|
477
|
-
text.gsub!( /(\s*)([\.?!]*)(\s*[ЁА-ЯA-Z])/su, '\2\1\3');
|
478
|
-
end
|
479
|
-
|
480
|
-
def process_dashglue(text)
|
481
|
-
text.gsub!( /([a-zа-яА-Я0-9]+(\-[a-zа-яА-Я0-9]+)+)/ui, glyph[:nob_open]+'\1'+glyph[:nob_close])
|
482
|
-
end
|
483
|
-
|
484
|
-
def process_escape_html(text)
|
485
|
-
text.gsub!(/&/, self.glyph[:amp])
|
486
|
-
text.gsub!(/</, self.glyph[:lt])
|
487
|
-
text.gsub!(/>/, self.glyph[:gt])
|
488
|
-
end
|
489
|
-
|
490
|
-
def process_span_instead_of_nobr(text)
|
491
|
-
text.gsub!(/<nobr>/, '<span class="nobr">')
|
492
|
-
text.gsub!(/<\/nobr>/, '</span>')
|
493
|
-
end
|
494
|
-
|
495
|
-
def process_dash(text)
|
496
|
-
text.gsub!( /(\s|;)\-(\s)/ui, '\1'+self.glyph[:ndash]+'\2')
|
497
|
-
end
|
498
|
-
|
499
|
-
def process_emdash(text)
|
500
|
-
text.gsub!( /(\s|;)\-\-(\s)/ui, '\1'+self.glyph[:mdash]+'\2')
|
501
|
-
# 4. (с)
|
502
|
-
text.gsub!(/\([сСcC]\)((?=\w)|(?=\s[0-9]+))/u, self.glyph[:copy]) if @settings["(c)"]
|
503
|
-
# 4a. (r)
|
504
|
-
text.gsub!( /\(r\)/ui, '<sup>'+self.glyph[:reg]+'</sup>') if @settings["(r)"]
|
505
|
-
|
506
|
-
# 4b. (tm)
|
507
|
-
text.gsub!( /\(tm\)|\(тм\)/ui, self.glyph[:trade]) if @settings["(tm)"]
|
508
|
-
# 4c. (p)
|
509
|
-
text.gsub!( /\(p\)/ui, self.glyph[:sect]) if @settings["(p)"]
|
510
|
-
end
|
511
|
-
|
512
|
-
def process_ellipsises(text)
|
513
|
-
text.gsub!( '...', self.glyph[:hellip])
|
514
|
-
end
|
515
|
-
|
516
|
-
def process_laquo(text)
|
517
|
-
text.gsub!( /\"\"/ui, self.glyph[:quot]*2);
|
518
|
-
text.gsub!( /(^|\s|#{@mark_tag}|>|\()\"((#{@mark_tag})*[~0-9ёЁA-Za-zА-Яа-я\-:\/\.])/ui, '\1'+self.glyph[:laquo]+'\2');
|
519
|
-
_text = '""';
|
520
|
-
until _text == text do
|
521
|
-
_text = text;
|
522
|
-
text.gsub!( /(#{self.glyph[:laquo]}([^\"]*)[ёЁA-Za-zА-Яа-я0-9\.\-:\/\?\!](#{@mark_tag})*)\"/sui,
|
523
|
-
'\1'+self.glyph[:raquo])
|
524
|
-
end
|
525
|
-
end
|
526
|
-
|
527
|
-
def process_quotes(text)
|
528
|
-
text.gsub!( /\"\"/ui, self.glyph[:quot]*2)
|
529
|
-
text.gsub!( /\"\.\"/ui, self.glyph[:quot]+"."+self.glyph[:quot])
|
530
|
-
_text = '""';
|
531
|
-
until _text == text do
|
532
|
-
_text = text.dup
|
533
|
-
text.gsub!( /(^|\s|#{@mark_tag}|>)\"([0-9A-Za-z\'\!\s\.\?\,\-\&\;\:\_\#{@mark_tag}]+(\"|#{self.glyph[:rdquo]}))/ui, '\1'+self.glyph[:ldquo]+'\2')
|
534
|
-
#this doesnt work in-place. somehow.
|
535
|
-
text.gsub!( /(#{self.glyph[:ldquo]}([A-Za-z0-9\'\!\s\.\?\,\-\&\;\:\#{@mark_tag}\_]*).*[A-Za-z0-9][\#{@mark_tag}\?\.\!\,]*)\"/ui, '\1'+self.glyph[:rdquo])
|
536
|
-
end
|
537
|
-
end
|
538
|
-
|
539
|
-
def process_compound_quotes(text)
|
540
|
-
text.gsub!(/(#{self.glyph[:ldquo]}(([A-Za-z0-9'!\.?,\-&;:]|\s|#{@mark_tag})*)#{self.glyph[:laquo]}(.*)#{self.glyph[:raquo]})#{self.glyph[:raquo]}/ui,'\1'+self.glyph[:rdquo]);
|
541
|
-
end
|
542
|
-
|
543
|
-
def process_degrees(text)
|
544
|
-
text.gsub!( /-([0-9])+\^([FCС])/, self.glyph[:ndash]+'\1'+self.glyph[:deg]+'\2') #deg
|
545
|
-
text.gsub!( /\+([0-9])+\^([FCС])/, '+\1'+self.glyph[:deg]+'\2')
|
546
|
-
text.gsub!( /\^([FCС])/, self.glyph[:deg]+'\1')
|
547
|
-
end
|
548
|
-
|
549
|
-
def process_wordglue(text)
|
550
|
-
text.replace(" " + text + " ")
|
551
|
-
_text = " " + text + " "
|
552
|
-
|
553
|
-
until _text == text
|
554
|
-
_text = text
|
555
|
-
text.gsub!( /(\s+)([a-zа-яА-Я]{1,2})(\s+)([^\\s$])/ui, '\1\2'+self.glyph[:nbsp]+'\4')
|
556
|
-
text.gsub!( /(\s+)([a-zа-яА-Я]{3})(\s+)([^\\s$])/ui, '\1\2'+self.glyph[:nbsp]+'\4')
|
557
|
-
end
|
558
|
-
|
559
|
-
text.gsub!(/(\s+)([a-zа-яА-Я]{1,2}[\)\]\!\?,\.;]{0,3}\s$)/ui, self.glyph[:nbsp]+'\2')
|
560
|
-
|
561
|
-
@glueleft.each { | i | text.gsub!( /(\s)(#{i})(\s+)/sui, '\1\2' + self.glyph[:nbsp]) }
|
562
|
-
|
563
|
-
@glueright.each { | i | text.gsub!( /(\s)(#{i})(\s+)/sui, self.glyph[:nbsp]+'\2\3') }
|
564
|
-
|
565
|
-
text.strip!
|
566
|
-
end
|
567
|
-
|
568
|
-
def process_phones(text)
|
569
|
-
@phonemasks[0].each_with_index do |pattern, i|
|
570
|
-
replacement = substitute_glyphs_in_string(@phonemasks[1][i])
|
571
|
-
text.gsub!(pattern, replacement)
|
572
|
-
end
|
573
|
-
end
|
574
|
-
|
575
|
-
def process_inches(text)
|
576
|
-
text.gsub!(/\s([0-9]{1,2}([\.,][0-9]{1,2})?)\"/ui, ' \1'+self.glyph[:inch])
|
577
|
-
end
|
578
|
-
|
579
|
-
def process_plusmin(text)
|
580
|
-
text.gsub!(/[^+]\+\-/ui, self.glyph[:plusmn])
|
581
|
-
end
|
582
|
-
|
583
|
-
# Подменяет все юникодные entities в тексте на истинные UTF-8-символы
|
584
|
-
def process_raw_output(text)
|
585
|
-
# Все глифы
|
586
|
-
@glyph.values.each do | entity |
|
587
|
-
next unless entity =~ /^&#(\d+);/
|
588
|
-
text.gsub!(/#{entity}/, entity_to_raw_utf8(entity))
|
589
|
-
end
|
590
|
-
end
|
591
|
-
|
592
|
-
# Конвертирует юникодные entities в UTF-8-codepoints
|
593
|
-
def entity_to_raw_utf8(entity)
|
594
|
-
entity =~ /^&#(\d+);/
|
595
|
-
$1 ? [$1.to_i].pack("U") : entity
|
596
|
-
end
|
597
|
-
end #end Gilenson
|
598
|
-
|
599
|
-
# Выбрасывается если форматтеру задается неизвестная настройка
|
600
|
-
class RuTils::Gilenson::UnknownSetting < RuntimeError
|
601
|
-
end
|
602
|
-
|
603
|
-
module RuTils::Gilenson::StringFormatting
|
604
|
-
# Форматирует строку с помощью Gilenson::Formatter. Все дополнительные опции передаются форматтеру.
|
605
|
-
def gilensize(*args)
|
606
|
-
opts = args.last.is_a?(Hash) ? args.last : {}
|
607
|
-
RuTils::Gilenson::Formatter.new(self, *opts).to_html
|
608
|
-
end
|
609
|
-
|
610
|
-
# Форматирует строку с помощью Gilenson::Obsolete. Всe дополнительные опции передаются форматтеру.
|
611
|
-
def o_gilensize(*args)
|
612
|
-
opts = args.last.is_a?(Hash) ? args.last : {}
|
613
|
-
RuTils::Gilenson::Obsolete.new(self, *opts).to_html
|
614
|
-
end
|
615
|
-
end
|
616
|
-
|
617
|
-
Object::String.send(:include, RuTils::Gilenson::StringFormatting)
|
data/test/t_gilenson.rb
DELETED
@@ -1,324 +0,0 @@
|
|
1
|
-
$KCODE = 'u'
|
2
|
-
require 'test/unit'
|
3
|
-
require File.dirname(__FILE__) + '/../lib/rutils'
|
4
|
-
|
5
|
-
|
6
|
-
# Cюда идут наши тесты типографа. Мы содержим их отдельно поскольку набор тестов Типографицы нами не контролируется.
|
7
|
-
# Когда у рутилей появятся собственные баги под каждый баг следует завести тест
|
8
|
-
class GilensonOwnTest < Test::Unit::TestCase
|
9
|
-
|
10
|
-
def setup
|
11
|
-
@gilenson = RuTils::Gilenson::Formatter.new
|
12
|
-
end
|
13
|
-
|
14
|
-
def test_tag_lift
|
15
|
-
assert_equal "Вот такие<tag some='foo>' /> <tagmore></tagmore> дела", "Вот такие<tag some='foo>' /> <tagmore></tagmore> дела".gilensize
|
16
|
-
end
|
17
|
-
|
18
|
-
def test_byte_pass
|
19
|
-
assert_equal '<p>Теперь добираться до офиса Студии автортранспортом стало удобнее. ' +
|
20
|
-
'Для этого мы разместили в разделе <a href="#">«Контакт»</a> окно вебкамеры, ' +
|
21
|
-
'которая непрерывно транслирует дорожную обстановку на Садовом кольце по адресу Земляной Вал, 23. <br>' +
|
22
|
-
'Удачной дороги! </p>',
|
23
|
-
'<p>Теперь добираться до офиса Студии автортранспортом стало удобнее. ' +
|
24
|
-
'Для этого мы разместили в разделе <a href="#">«Контакт»</a> окно вебкамеры, ' +
|
25
|
-
'которая непрерывно транслирует дорожную обстановку на Садовом кольце по адресу Земляной Вал, 23. <br>' +
|
26
|
-
'Удачной дороги! </p>'.gilensize
|
27
|
-
end
|
28
|
-
|
29
|
-
def test_phones
|
30
|
-
assert_equal '<nobr>3–12–30</nobr>', '3-12-30'.gilensize
|
31
|
-
assert_equal '<nobr>12–34–56</nobr>', '12-34-56'.gilensize
|
32
|
-
assert_equal '<nobr>88–25–04</nobr>', '88-25-04'.gilensize
|
33
|
-
assert_equal '+7 <nobr>(99284) 65–818</nobr>', '+7 (99284) 65-818'.gilensize
|
34
|
-
assert_equal '<nobr>725–01–10</nobr>', '725-01-10'.gilensize
|
35
|
-
end
|
36
|
-
|
37
|
-
def test_address
|
38
|
-
assert_equal 'табл. 2, рис. 2.10', 'табл. 2, рис. 2.10'.gilensize
|
39
|
-
assert_equal 'офис 415, оф.340, д.5, ул. Народной Воли, пл. Малышева', 'офис 415, оф.340, д.5, ул. Народной Воли, пл. Малышева'.gilensize
|
40
|
-
end
|
41
|
-
|
42
|
-
def test_html_entities_replace
|
43
|
-
assert_equal '" & ' > <   § © « ® ° ± · » – — ‘ ’ “ ” „ • … ™ −', '" & ' > < § © « ® ° ± · » – — ‘ ’ “ ” „ • … ™ −'.gilensize
|
44
|
-
end
|
45
|
-
|
46
|
-
def test_ugly_entities_replace1 # not_correct_number
|
47
|
-
assert_equal '„ … ' “ ” • – — ™', '„ … ’ “ ” • – — ™'.gilensize
|
48
|
-
end
|
49
|
-
|
50
|
-
def test_specials
|
51
|
-
assert_equal '© 2002, © 2003, © 2004, © 2005 — тоже без пробелов: ©2002, ©Кукуц. однако: варианты (а) и (с)', '(с) 2002, (С) 2003, (c) 2004, (C) 2005 -- тоже без пробелов: (с)2002, (c)Кукуц. однако: варианты (а) и (с)'.gilensize
|
52
|
-
assert_equal '+5°С, +7°C, –5°F', '+5^С, +17^C, -275^F'.gilensize
|
53
|
-
assert_equal 'об этом подробнее — читай §25', 'об этом подробнее -- читай (p)25'.gilensize
|
54
|
-
assert_equal 'один же минус – краткое тире', 'один же минус - краткое тире'.gilensize
|
55
|
-
assert_equal 'Sharpdesign™, Microsoft<sup>®</sup>', 'Sharpdesign(tm), Microsoft(r)'.gilensize
|
56
|
-
end
|
57
|
-
|
58
|
-
def test_breaking
|
59
|
-
assert_equal 'скажи, мне, ведь не даром! Москва, клеймённая пожаром. Французу отдана', 'скажи ,мне, ведь не даром !Москва, клеймённая пожаром .Французу отдана'.gilensize
|
60
|
-
assert_equal 'so be it, my liege. Tiny dwellers roam thru midnight! Hell raised, the Balrog is hiding in your backyard!', 'so be it ,my liege .Tiny dwellers roam thru midnight !Hell raised, the Balrog is hiding in your backyard!'.gilensize
|
61
|
-
assert_equal 'при установке командой строки в ?page=help <nobr>бла-бла-бла-бла</nobr>', 'при установке командой строки в ?page=help бла-бла-бла-бла'.gilensize
|
62
|
-
assert_equal 'как интересно будет переноситься со строки на строку <nobr>что-то</nobr> разделённое дефисом, ведь дефис тот тоже ведь из наших. <nobr>Какие-то</nobr> браузеры думают, что следует переносить и его…', 'как интересно будет переноситься со строки на строку что-то разделённое дефисом, ведь дефис тот тоже ведь из наших. Какие-то браузеры думают, что следует переносить и его...'.gilensize
|
63
|
-
end
|
64
|
-
|
65
|
-
def test_quotes
|
66
|
-
assert_equal 'english “quotes” should be quite like this', 'english "quotes" should be quite like this'.gilensize
|
67
|
-
assert_equal 'русские же «оформляются» подобным образом', 'русские же "оформляются" подобным образом'.gilensize
|
68
|
-
assert_equal 'кавычки «расставлены» “in a chaotic order”', 'кавычки "расставлены" "in a chaotic order"'.gilensize
|
69
|
-
assert_equal 'диагональ моего монитора — 17″, а размер пениса — 1,5″', 'диагональ моего монитора -- 17", а размер пениса -- 1,5"'.gilensize
|
70
|
-
assert_equal 'в толщину, «вложенные “quotes” вот так», “or it «будет вложено» elsewhere”', 'в толщину, "вложенные "quotes" вот так", "or it "будет вложено" elsewhere"'.gilensize
|
71
|
-
assert_equal '“complicated «кавычки», «странные “includements” кавычек»', '"complicated "кавычки", "странные "includements" кавычек"'.gilensize
|
72
|
-
assert_equal '“double “quotes”', '"double "quotes"'.gilensize
|
73
|
-
assert_equal '«дважды вложенные «кавычки»', '"дважды вложенные "кавычки"'.gilensize
|
74
|
-
assert_equal '«01/02/03», дискеты в 5.25″', '"01/02/03", дискеты в 5.25"'.gilensize
|
75
|
-
assert_equal 'после троеточия правая кавычка — «Вот…»', 'после троеточия правая кавычка -- "Вот..."'.gilensize
|
76
|
-
assert_equal 'setlocale(LC_ALL, “ru_RU.UTF8”);', 'setlocale(LC_ALL, "ru_RU.UTF8");'.gilensize
|
77
|
-
assert_equal '“read, write, delete” с флагом “only_mine”', '"read, write, delete" с флагом "only_mine"'.gilensize
|
78
|
-
assert_equal '«Двоеточие:», «такую умную тему должен писать чувак умеющий скрипты скриптить.»', '"Двоеточие:", "такую умную тему должен писать чувак умеющий скрипты скриптить."'.gilensize
|
79
|
-
assert_equal '(«Вики != HTML» — «Вики != HTML» — («всякая чушь»))', '("Вики != HTML" -- "Вики != HTML" -- ("всякая чушь"))'.gilensize
|
80
|
-
assert_equal '«фигня123», “fignya123”', '"фигня123", "fignya123"'.gilensize
|
81
|
-
# assert_equal '«сбалансированные «кавычки<!--notypo--><!--/notypo--> (четыре в конце) — связано с синтаксисом ваки', '"сбалансированные "кавычки"""" (четыре в конце) -- связано с синтаксисом ваки'.gilensize
|
82
|
-
assert_equal '«несбалансированные «кавычки""" (три в конце) — связано с синтаксисом ваки', '"несбалансированные "кавычки""" (три в конце) -- связано с синтаксисом ваки'.gilensize
|
83
|
-
assert_equal '«разноязыкие quotes»', '"разноязыкие quotes"'.gilensize
|
84
|
-
assert_equal '«multilanguage кавычки»', '"multilanguage кавычки"'.gilensize
|
85
|
-
end
|
86
|
-
|
87
|
-
def test_additional_quote_cases
|
88
|
-
assert_equal "«И это называется языком?», — таков был его вопрос",
|
89
|
-
%q{ "И это называется языком?", -- таков был его вопрос }.gilensize
|
90
|
-
|
91
|
-
assert_equal "«Он — сволочь!», сказал я",
|
92
|
-
%q{ "Он -- сволочь!", сказал я }.gilensize
|
93
|
-
end
|
94
|
-
|
95
|
-
def test_initials
|
96
|
-
assert_equal 'Это нам сказал П.И. Петров', 'Это нам сказал П. И. Петров'.gilensize
|
97
|
-
|
98
|
-
assert_equal "А Ефимов…",
|
99
|
-
@gilenson.process("А Ефимов...")
|
100
|
-
|
101
|
-
assert_equal "Обратился за ПО. К негодяям.",
|
102
|
-
@gilenson.process("Обратился за ПО. К негодяям.")
|
103
|
-
|
104
|
-
assert_equal "ГО Самарской обл.",
|
105
|
-
@gilenson.process("ГО Самарской обл.")
|
106
|
-
|
107
|
-
assert_equal "ГОР Самарской обл.",
|
108
|
-
@gilenson.process("ГОР Самарской обл.")
|
109
|
-
|
110
|
-
assert_equal "КОШМАР Самарской обл.",
|
111
|
-
@gilenson.process("КОШМАР Самарской обл.")
|
112
|
-
|
113
|
-
assert_equal "УФПС Самарской обл.",
|
114
|
-
@gilenson.process("УФПС Самарской обл.")
|
115
|
-
|
116
|
-
end
|
117
|
-
|
118
|
-
def test_nbsp_last_letters
|
119
|
-
assert_equal "сказал я", "сказал я".gilensize
|
120
|
-
assert_equal "сказал я!", "сказал я!".gilensize
|
121
|
-
assert_equal "сказал я?", "сказал я?".gilensize
|
122
|
-
assert_equal "сказал я…", "сказал я...".gilensize
|
123
|
-
assert_equal "сказал он…", "сказал он...".gilensize
|
124
|
-
assert_equal "сказали мы?..", "сказали мы?..".gilensize
|
125
|
-
assert_equal "сказали мы?!", "сказали мы?!".gilensize
|
126
|
-
assert_equal "сказали мы?!!!", "сказали мы?!!!".gilensize
|
127
|
-
assert_equal "сказали нам", "сказали нам".gilensize
|
128
|
-
assert_equal "(сказали им)", "(сказали им)".gilensize
|
129
|
-
end
|
130
|
-
|
131
|
-
def test_marker_bypass
|
132
|
-
assert_equal "<p><nobr>МИЭЛЬ-Недвижимость</nobr></p>", "<p>МИЭЛЬ-Недвижимость</p>".gilensize
|
133
|
-
end
|
134
|
-
|
135
|
-
def test_skip_code
|
136
|
-
@gilenson.configure!(:all => true, :skip_code => true)
|
137
|
-
|
138
|
-
assert_equal "<code>Скип -- скип!</code>",
|
139
|
-
@gilenson.process("<code>Скип -- скип!</code>")
|
140
|
-
|
141
|
-
assert_equal '<code attr="test -- attr">Скип -- скип!</code>',
|
142
|
-
@gilenson.process('<code attr="test -- attr">Скип -- скип!</code>')
|
143
|
-
|
144
|
-
assert_equal "<tt>Скип -- скип!</tt> test — test <tt attr='test -- attr'>Скип -- скип!</tt>",
|
145
|
-
@gilenson.process("<tt>Скип -- скип!</tt> test -- test <tt attr='test -- attr'>Скип -- скип!</tt>")
|
146
|
-
|
147
|
-
assert_equal "<tt>Скип -- скип!</tt><tt>Скип -- скип!</tt> — <code attr='test -- attr'>Скип -- скип!</code>",
|
148
|
-
@gilenson.process("<tt>Скип -- скип!</tt><tt>Скип -- скип!</tt> -- <code attr='test -- attr'>Скип -- скип!</code>")
|
149
|
-
|
150
|
-
assert_equal "<ttt>Скип — скип!</tt>",
|
151
|
-
@gilenson.process("<ttt>Скип -- скип!</tt>")
|
152
|
-
|
153
|
-
assert_equal "<tt>Скип — скип!</ttt>",
|
154
|
-
@gilenson.process("<tt>Скип -- скип!</ttt>")
|
155
|
-
|
156
|
-
assert_equal "Ах, — <code>var x = j // -- тест</code>",
|
157
|
-
@gilenson.process("Ах, -- <code>var x = j // -- тест</code>")
|
158
|
-
|
159
|
-
assert_equal "<![CDATA[ CDATA -- ]]> — CDATA",
|
160
|
-
@gilenson.process("<![CDATA[ CDATA -- ]]> -- CDATA")
|
161
|
-
|
162
|
-
assert_equal "<![CDATA[ CDATA -- >] -- CDATA ]]> — <![CDATA[ CDATA ]> -- CDATA ]]>",
|
163
|
-
@gilenson.process("<![CDATA[ CDATA -- >] -- CDATA ]]> -- <![CDATA[ CDATA ]> -- CDATA ]]>")
|
164
|
-
|
165
|
-
assert_equal "<![CDATA[ CDATA -- >] -- CDATA ]]> — <![CDATA[ CDATA ]> -- CDATA ]]> — CDATA ]]>",
|
166
|
-
@gilenson.process("<![CDATA[ CDATA -- >] -- CDATA ]]> -- <![CDATA[ CDATA ]> -- CDATA ]]> -- CDATA ]]>")
|
167
|
-
|
168
|
-
@gilenson.configure!(:skip_code => false)
|
169
|
-
|
170
|
-
assert_equal "Ах, — <code>var x = j // — тест</code>",
|
171
|
-
@gilenson.process("Ах, -- <code>var x = j // -- тест</code>")
|
172
|
-
end
|
173
|
-
|
174
|
-
def test_skip_attr
|
175
|
-
@gilenson.configure!(:skip_attr => true)
|
176
|
-
|
177
|
-
assert_equal "<a href='#' attr='смотри -- смотри' title='test -- me' alt=\"смотри -- смотри\">just — test</a>",
|
178
|
-
@gilenson.process("<a href='#' attr='смотри -- смотри' title='test -- me' alt=\"смотри -- смотри\">just -- test</a>")
|
179
|
-
|
180
|
-
assert_equal 'мы напишем title="test — me" и alt=\'test — me\', вот',
|
181
|
-
@gilenson.process('мы напишем title="test -- me" и alt=\'test -- me\', вот')
|
182
|
-
|
183
|
-
@gilenson.configure!(:skip_attr => false)
|
184
|
-
|
185
|
-
assert_equal "<a href='#' attr='смотри -- смотри' title='test — me' alt=\"смотри — смотри\">just — test</a>",
|
186
|
-
@gilenson.process("<a href='#' attr='смотри -- смотри' title='test -- me' alt=\"смотри -- смотри\">just -- test</a>")
|
187
|
-
|
188
|
-
assert_equal 'мы напишем title="test — me" и alt=\'test — me\', вот',
|
189
|
-
@gilenson.process('мы напишем title="test -- me" и alt=\'test -- me\', вот')
|
190
|
-
end
|
191
|
-
|
192
|
-
def test_escape_html
|
193
|
-
assert_equal "Используйте & вместо &amp;",
|
194
|
-
@gilenson.process("Используйте & вместо &amp;")
|
195
|
-
|
196
|
-
@gilenson.configure!(:html => false)
|
197
|
-
|
198
|
-
assert_equal "&#38; — &amp; <code/> <some_tag>таги не пройдут!</some_tag>. Ну и?..",
|
199
|
-
@gilenson.process("& -- & <code/> <some_tag>таги не пройдут!</some_tag>. Ну и?..")
|
200
|
-
|
201
|
-
assert_equal "Используйте &#38; вместо &amp;",
|
202
|
-
@gilenson.process("Используйте & вместо &")
|
203
|
-
|
204
|
-
end
|
205
|
-
|
206
|
-
def test_ampersand_in_urls
|
207
|
-
|
208
|
-
@gilenson.configure!(:html=>false)
|
209
|
-
|
210
|
-
assert_equal "<a href='test?test5=5&#38;test6=6'>test&#38;</a>",
|
211
|
-
@gilenson.process("<a href='test?test5=5&test6=6'>test&</a>")
|
212
|
-
|
213
|
-
@gilenson.configure!(:html=>true)
|
214
|
-
|
215
|
-
assert_equal "<a href='test?test7=7&test8=8'>test&</a>",
|
216
|
-
@gilenson.process("<a href='test?test7=7&test8=8'>test&</a>")
|
217
|
-
|
218
|
-
assert_equal "<a href='test?test9=9&test10=10'>test&</a>",
|
219
|
-
@gilenson.process("<a href='test?test9=9&test10=10'>test&</a>")
|
220
|
-
|
221
|
-
assert_equal "<a href='test?test11=11&test12=12'>test&</a>",
|
222
|
-
@gilenson.process("<a href='test?test11=11&test12=12'>test&</a>")
|
223
|
-
|
224
|
-
assert_equal "<a href='test?test12=12&'>test</a>",
|
225
|
-
@gilenson.process("<a href='test?test12=12&'>test</a>")
|
226
|
-
|
227
|
-
assert_equal "<a href='test?x=1&y=2' title='&-amp, …-hellip'>test</a>",
|
228
|
-
@gilenson.process("<a href='test?x=1&y=2' title='&-amp, …-hellip'>test</a>")
|
229
|
-
|
230
|
-
assert_equal "<a href='test?x=3&#039;y=4'>test</a>",
|
231
|
-
@gilenson.process("<a href='test?x=3'y=4'>test</a>")
|
232
|
-
|
233
|
-
|
234
|
-
@gilenson.glyph[:amp] = '&'
|
235
|
-
|
236
|
-
assert_equal "<a href='test?test11=11&test12=12'>test&</a>",
|
237
|
-
@gilenson.process("<a href='test?test11=11&test12=12'>test&</a>")
|
238
|
-
|
239
|
-
assert_equal "<a href='test?test13=13&test14=14'>test&</a>",
|
240
|
-
@gilenson.process("<a href='test?test13=13&test14=14'>test&</a>")
|
241
|
-
|
242
|
-
assert_equal "<a href='test?test15=15&amppp;test16=16'>test&</a>",
|
243
|
-
@gilenson.process("<a href='test?test15=15&pp;test16=16'>test&</a>")
|
244
|
-
|
245
|
-
end
|
246
|
-
end
|
247
|
-
|
248
|
-
|
249
|
-
class GilensonConfigurationTest < Test::Unit::TestCase
|
250
|
-
def setup
|
251
|
-
@gilenson = RuTils::Gilenson::Formatter.new
|
252
|
-
end
|
253
|
-
|
254
|
-
def test_settings_as_tail_arguments
|
255
|
-
|
256
|
-
assert_equal "Ну и куда вот — да туда!",
|
257
|
-
@gilenson.process("Ну и куда вот -- да туда!")
|
258
|
-
|
259
|
-
assert_equal "Ну и куда вот — да туда!",
|
260
|
-
@gilenson.process("Ну и куда вот -- да туда!", :dash => false, :dashglue => false, :wordglue => false)
|
261
|
-
|
262
|
-
assert_equal "Ну и куда вот — да туда!",
|
263
|
-
@gilenson.process("Ну и куда вот -- да туда!")
|
264
|
-
|
265
|
-
@gilenson.configure!(:dash => false, :dashglue => false, :wordglue => false)
|
266
|
-
|
267
|
-
assert_equal "Ну и куда вот — да туда!",
|
268
|
-
@gilenson.process("Ну и куда вот -- да туда!")
|
269
|
-
|
270
|
-
@gilenson.configure!(:all => true)
|
271
|
-
|
272
|
-
assert_equal "Ну и куда вот — да туда!",
|
273
|
-
@gilenson.process("Ну и куда вот -- да туда!")
|
274
|
-
|
275
|
-
@gilenson.configure!(:all => false)
|
276
|
-
|
277
|
-
assert_equal "Ну и куда вот -- да туда!",
|
278
|
-
@gilenson.process("Ну и куда вот -- да туда!")
|
279
|
-
end
|
280
|
-
|
281
|
-
def test_glyph_override
|
282
|
-
assert_equal 'скажи, мне, ведь не даром! Москва, клеймённая пожаром. Французу отдана',
|
283
|
-
@gilenson.process('скажи ,мне, ведь не даром !Москва, клеймённая пожаром .Французу отдана')
|
284
|
-
|
285
|
-
@gilenson.glyph[:nbsp] = ' '
|
286
|
-
assert_equal 'скажи, мне, ведь не даром! Москва, клеймённая пожаром. Французу отдана',
|
287
|
-
@gilenson.process('скажи ,мне, ведь не даром !Москва, клеймённая пожаром .Французу отдана')
|
288
|
-
end
|
289
|
-
|
290
|
-
def test_ugly_entities_replace2 # copy&paste
|
291
|
-
@gilenson.configure!(:copypaste => true)
|
292
|
-
assert_equal '  « » § © ® ° ± ¶ · – — ‘ ’ “ ” „ • … № ™ −   ″', @gilenson.process(' « » § © ® ° ± ¶ · – — ‘ ’ “ ” „ • … № ™ − ″')
|
293
|
-
end
|
294
|
-
|
295
|
-
def test_raise_on_unknown_setting
|
296
|
-
assert_raise(RuTils::Gilenson::UnknownSetting) { @gilenson.configure!(:bararara => true) }
|
297
|
-
end
|
298
|
-
|
299
|
-
def test_raw_utf8_output
|
300
|
-
@gilenson.configure!(:raw_output=>true)
|
301
|
-
assert_equal '阪 Это просто «кавычки»',
|
302
|
-
@gilenson.process('阪 Это просто "кавычки"')
|
303
|
-
end
|
304
|
-
|
305
|
-
def test_configure_alternate_names
|
306
|
-
assert @gilenson.configure(:raw_output=>true)
|
307
|
-
assert @gilenson.configure!(:raw_output=>true)
|
308
|
-
end
|
309
|
-
|
310
|
-
end
|
311
|
-
|
312
|
-
# class TypograficaTrakoEntries < Test::Unit::TestCase
|
313
|
-
# def test_cpp
|
314
|
-
# assert_equal "C++-API", "C++-API".gilensize
|
315
|
-
# end
|
316
|
-
#
|
317
|
-
# def test_symmetricity # http://pixel-apes.com/typografica/trako/12
|
318
|
-
# assert_equal "«Справка 09»", '"Справка 09"'.gilensize
|
319
|
-
# end
|
320
|
-
#
|
321
|
-
# def test_paths # http://pixel-apes.com/typografica/trako/13
|
322
|
-
# assert_equal '«c:\www\sites\»', '"c:\www\sites\"'.gilensize
|
323
|
-
# end
|
324
|
-
# end
|