typograph 0.0.1.pre.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in typograph.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 sterebooster
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,46 @@
1
+ # Typograph
2
+
3
+ Gem for typographing russian texts. Ruby port of [SamDark's Typograph](https://github.com/samdark/Typograph).
4
+
5
+ ## TODO
6
+ - implement best opensource russian typograph as ruby gem
7
+ - Port [Typograph](https://github.com/samdark/Typograph) (one of the best opensource russain typographs)
8
+ - add to [multi_typograf](https://github.com/stereobooster/multi_typograf)
9
+ - implement english typograph
10
+ - implement typograph for other languages. Implement settings throught YAML
11
+ - [web typography 6](http://habrahabr.ru/post/25958/)
12
+ - [foreign typography](http://habrahabr.ru/post/117142/)
13
+ - [deutch](http://habrahabr.ru/post/12742/)
14
+ - http://de.wikipedia.org/wiki/Geviertstrich
15
+ - http://de.wikipedia.org/wiki/Typografie_für_HTML
16
+
17
+ ## Alternatives
18
+
19
+ ### ruby gems, wrappers for online services - russian
20
+ - [art_typograf](https://github.com/stereobooster/art_typograf) wrapper for http://www.artlebedev.ru/tools/typograf/
21
+ - [typograf](https://github.com/stereobooster/typograf) wrapper for http://www.typograf.ru/
22
+
23
+ ### ruby gems - russian
24
+ - [typographer](https://github.com/brain-geek/typographer)
25
+ - [typography](https://github.com/antonversal/typography)
26
+ - [typographica](https://github.com/akolosov/typographica)
27
+
28
+ ### ruby - english
29
+ - [SmartyPants](http://rubydoc.info/gems/redcarpet/2.1.1/Redcarpet/Render/SmartyPants)
30
+ - [rubypants](https://github.com/jmcnevin/rubypants)
31
+
32
+ ### other
33
+ - [habari-typography](https://github.com/ahutchings/habari-typography)
34
+ - [typography-helper](https://github.com/hunter/typography-helper) english
35
+
36
+ ## Usage
37
+
38
+ TODO: Write usage instructions here
39
+
40
+ ## Contributing
41
+
42
+ 1. Fork it
43
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
44
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
45
+ 4. Push to the branch (`git push origin my-new-feature`)
46
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,21 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ require 'rspec/core/rake_task'
4
+ desc "Run all specs"
5
+ RSpec::Core::RakeTask.new(:spec)
6
+
7
+ task :default => :spec
8
+
9
+ LANG = "ru_RU.UTF-8"
10
+
11
+ SET_CMD = case RUBY_PLATFORM
12
+ when /mingw32/ then
13
+ "set"
14
+ else
15
+ "export"
16
+ end
17
+
18
+ desc "run tests"
19
+ task :test do
20
+ sh "#{SET_CMD} LANG=#{LANG} && chcp 65001 && bundle exec rake"
21
+ end
@@ -0,0 +1,26 @@
1
+ # encoding: utf-8
2
+
3
+ require 'htmlentities'
4
+
5
+ module Typograph
6
+ class Adapter
7
+ def initialize(options={})
8
+ @options = options
9
+ end
10
+
11
+ def process(text)
12
+
13
+ end
14
+
15
+ # Приводим символы в строке к единой форме для последующей обработки
16
+ def normalize(str)
17
+ # Убираем неразрывные пробелы
18
+ str.gsub!(/ | /, ' ')
19
+ # Приводим кавычки к «"»
20
+ str.gsub!(/(„|“|")/, '"')
21
+ #
22
+ str.gsub!(/^\s+|\s+$/, '')
23
+ HTMLEntities.new.decode(str)
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,267 @@
1
+ # encoding: utf-8
2
+
3
+ module Typograph
4
+ module Adapters
5
+ class Russian < Adapter
6
+ def initialize(options={})
7
+ @options = options
8
+
9
+ abbr = 'ООО|ОАО|ЗАО|ЧП|ИП|НПФ|НИИ|ООО\p{Zs}ТПК'
10
+ prepos = 'а|в|во|вне|и|или|к|о|с|у|со|об|обо|от|ото|то|на|не|ни|но|из|изо|за|уж|на|по|под|подо|пред|предо|про|над|надо|как|без|безо|что|да|для|до|там|ещё|их|ко|меж|между|перед|передо|около|через|сквозь|для|при|я'
11
+ metrics = 'мм|см|м|км|г|кг|б|кб|мб|гб|dpi|px'
12
+ shortages = 'г|гр|тов|пос|c|ул|д|пер|м|зам|см'
13
+ money = 'руб\.|долл\.|евро|у\.е\.'
14
+ countables = 'млн|тыс'
15
+
16
+ @rules_strict = {
17
+ # Много пробелов или табуляций -> один пробел
18
+ /( |\t)+/ => ' ',
19
+ # Запятые после «а» и «но». Если уже есть — не ставим.
20
+ /([^,])\s(а|но)\s/ => '\1, \2 ',
21
+ }
22
+
23
+ @rules_symbols = {
24
+ # Лишние знаки.
25
+ # TODO: сделать красиво
26
+ /([^!])!!([^!])/ => '\1!\2',
27
+ /([^?])\?\?([^?])/ => '\1?\2',
28
+ /(\p{L})\s*\.\.(\p{Zs})/ => '\1.\2', # new
29
+ /(\p{L});[;\s]*(;)/ => '\1;', # new
30
+ /(\p{L}),[,\s]*(,)/ => '\1,', # new
31
+ /(\p{L}):[:\s]*(:)/ => '\1:', # new
32
+
33
+ /([!\?])\s*(!\s*)[!\s]*(!)/ => '\1!!', # new
34
+ /(\?\s*)(\?\s*)[\?\s]*(\?)/ => '???', # new
35
+ /(\.\s*)(\.\s*)[\.\s]*(\.)/ => '...', # new
36
+ /(,\s*)[,\s]*(,)/ => ',', # new
37
+ /;{2,}/ => ';', # new
38
+ /,{2,}/ => ',', # new
39
+ /:{2,}/ => ':', # new
40
+
41
+ # /([;,:])(\S)/ => '\1 \2', # new
42
+
43
+ # Занятная комбинация
44
+ /!\?/ => '?!',
45
+
46
+ # Знаки (c), (r), (tm)
47
+ /\((c|с)\)/i => '©',
48
+ /\(r\)/i => '<sup><small>®</small></sup>',
49
+ /\(tm\)/i => '<sup>™</sup>',
50
+
51
+ # От 2 до 5 знака точки подряд - на знак многоточия (больше - мб авторской задумкой).
52
+ /\s*\.{2,5}/ => '…',
53
+
54
+ # Дроби
55
+ # TODO: найти замену \b
56
+ /\b1\/2\b/ => '½',
57
+ /\b1\/3\b/ => '⅓',
58
+ /\b1\/4\b/ => '¼',
59
+ /\b3\/4\b/ => '¾',
60
+
61
+ # LО'Лайт, O'Reilly
62
+ /([a-zA-Z])'([а-яА-Яa-zA-Z])/i => '\1’\2',
63
+
64
+ /'/ => '&#39;', # str_replace?
65
+
66
+ # Размеры 10x10, правильный знак + убираем лишние пробелы
67
+ /(\p{Nd}+)\p{Zs}{0,}?[x|X|х|Х|*]\p{Zs}{0,}(\p{Nd}+)/ => '\1×\2',
68
+
69
+ # +-
70
+ /([^\+]|^)\+-/ => '\1±',
71
+
72
+ # Стрелки
73
+ /([^-]|^)->/ => '\1→',
74
+ /<-([^-]|$)/ => '←\1'
75
+ }
76
+
77
+ @rules_quotes = {
78
+ # Разносим неправильные кавычки
79
+ /([^"]\p{L}+)"(\p{L}+)"/ => '\1 "\2"',
80
+ /"(\p{L}+)"(\p{L}+)/ => '"\1" \2',
81
+
82
+ # Превращаем кавычки в ёлочки.
83
+ /(\P{L})?"([^"]*)"(\P{L})?/ => '\1«\2»\3'
84
+ }
85
+
86
+ @rules_braces = {
87
+ # Оторвать скобку от слова
88
+ /(\p{L})\(/ => '\1 (',
89
+ # Слепляем скобки со словами
90
+ /\( /m => '(',
91
+ / \)/m => ')'
92
+ }
93
+
94
+ @rules_main = {
95
+ # Конфликт с «газо- и электросварка»
96
+ # Оторвать тире от слова
97
+ # /(\p{L})- / => '\1 - ',
98
+
99
+ # Знаки с предшествующим пробелом… нехорошо!
100
+ /(\p{L}|>|\p{Nd}) +([?!:,;]|…)/ => '\1\2',
101
+ /([?!:,;])(\p{L}|<)/ => '\1 \2',
102
+ # Для точки отдельно
103
+ /(\p{L})\p{Zs}(?:\.)(\p{Zs}|$)/ => '\1.\2',
104
+ # Но перед кавычками пробелов не ставим
105
+ /([?!:,;\.])\p{Zs}(»)/ => '\1\2',
106
+
107
+ # Неразрывные названия организаций и абревиатуры форм собственности
108
+ # ~ почему не один &nbsp;?
109
+ # ! названия организаций тоже могут содержать пробел !
110
+ /(#{abbr})\p{Zs}+(«[^»]*»)/ => '<nobr>\1 \2</nobr>',
111
+
112
+ # Нельзя отрывать сокращение от относящегося к нему слова.
113
+ # Например: тов. Сталин, г. Воронеж
114
+ # Ставит пробел, если его нет.
115
+ /(^|[^a-zA-Zа-яА-Я])(#{shortages})\.\s?([А-Я0-9]+)/m => '\1\2.&nbsp;\3',
116
+
117
+ # Не отделять стр., с. и т.д. от номера.
118
+ /(стр|с|табл|рис|илл)\.\p{Zs}*(\p{Nd}+)~/mi => '\1.&nbsp;\2',
119
+
120
+ # Не разделять 2007 г., ставить пробел, если его нет. Ставит точку, если её нет.
121
+ /({Nd}+)\p{Zs}*([гГ])\.\s/m => '\1&nbsp;\2. ',
122
+
123
+ # Неразрывный пробел между цифрой и единицей измерения
124
+ /(\p{Nd}+)\s*(#{metrics})/m => '\1&nbsp;\2',
125
+
126
+ # Сантиметр и другие ед. измерения в квадрате, кубе и т.д.
127
+ /(\p{Zs}#{metrics})(\p{Nd}+)/ => '\1<sup>\2</sup>',
128
+
129
+ # Знак дефиса или два знака дефиса подряд — на знак длинного тире.
130
+ # + Нельзя разрывать строку перед тире, например: Знание&nbsp;— сила, Курить&nbsp;— здоровью вредить.
131
+ /\p{Zs}+(?:--?|—)(?=\p{Zs})/ => '&nbsp;—',
132
+ /^(?:--?|—)(?=\p{Zs})/ => '—',
133
+
134
+ # Прямая речь
135
+ /(?:^|\s+)(?:--?|—)(?=\p{Zs})/ => "—",
136
+
137
+ # Знак дефиса, ограниченный с обоих сторон цифрами — на знак короткого тире.
138
+ /(?<=\p{Nd})-(?=\p{Nd})/ => '–',
139
+
140
+ # Знак дефиса, ограниченный с обоих сторон пробелами — на знак длинного тире.
141
+ /(\s)(&ndash|–)(\s)/ => '&nbsp;&mdash; ',
142
+
143
+ # Знак дефиса, идущий после тэга и справа пробел — на знак длинного тире.
144
+ /(?<=>)(&ndash|–|-)(\s)/ => '&mdash; ',
145
+
146
+ # Расстановка дефисов перед -ка, -де, -кась
147
+ /\b(\S+)\s(ка|де|кась)\b/i => '<nobr>\1-\2</nobr>',
148
+
149
+ # Расстановка дефиса после кое-, кой-
150
+ /\b(кое|кой)[\s-](как|кого|какой)\b/i => '<nobr>\1-\2</nobr>',
151
+
152
+ # Расстановка дефисов перед «-либо», «-нибудь».
153
+ /(кто|что|где|когда|почему|зачем|кем|чем)[\s-]?(либо|нибудь|то)/i => '<nobr>\1–\2</nobr>',
154
+
155
+ # Расстановка дефисов в предлогах «из-за», «из-под», «по-над», «по-под».
156
+ /\b(из)[\s-]?(за|под)\b/i => '<nobr>\1–\2</nobr>',
157
+ /\b(по)[\s-]?(над|под)\b/i => '<nobr>\1–\2</nobr>',
158
+
159
+ # Нельзя оставлять в конце строки предлоги и союзы
160
+ /(?<=\p{Zs}|^|\P{L})(#{prepos})(\s+)/i => '\1&nbsp;',
161
+
162
+ # Нельзя отрывать частицы бы, ли, же от предшествующего слова, например: как бы, вряд ли, так же.
163
+ # /(?<=[^\p{Zs}])(\p{Zs}+)(ж|бы|б|же|ли|ль|либо|или)(?=<.*?>*[\p{Zs})!?.])/i => '&nbsp;\2',
164
+ /(?<=\S)(\s+)(ж|бы|б|же|ли|ль|либо|или)(?=(<.*?>)*[\p{Zs})!?.…])/i => '&nbsp;\2',
165
+
166
+ # Неразрывный пробел после инициалов.
167
+ /([А-ЯA-Z]\.)\s?([А-ЯA-Z]\.)\p{Zs}?([А-Яа-яA-Za-z]+)/m => '\1\2&nbsp;\3',
168
+
169
+ # Сокращения сумм не отделяются от чисел.
170
+ /(\p{Nd}+)\p{Zs}?(#{countables})/m => '\1&nbsp;\2',
171
+
172
+ # «уе» в денежных суммах
173
+ /(\p{Nd}+|#{countables})\p{Zs}?уе/m => '\1&nbsp;у.е.',
174
+
175
+ # Денежные суммы, расставляя пробелы в нужных местах.
176
+ /(\p{Nd}+|#{countables})\p{Zs}?(#{money})/m => '\1&nbsp;\2',
177
+
178
+ # Неразрывные пробелы в кавычках
179
+ # "/($sym[lquote]\S*)(\s+)(\S*$sym[rquote])/U" => '\1'.\sym["nbsp"].'\3',
180
+
181
+ # Телефоны
182
+ /(?:тел\.?\/?факс:?\s?\((\d+)\))/i => 'тел./факс:&nbsp(\1)',
183
+
184
+ /тел[:\.] ?(\p{Nd}+)/m => '<nobr>тел: \1</nobr>',
185
+
186
+ # Номер версии программы пишем неразрывно с буковкой v.
187
+ /([vв]\.) ?(\p{Nd})/i => '\1&nbsp;\2',
188
+ /(\p{L}) ([vв]\.)/i => '\1&nbsp;\2',
189
+
190
+ # % не отделяется от числа
191
+ /(\p{Nd}+)\p{Zs}+%/ => '\1%',
192
+
193
+ # IP-адреса рвать нехорошо
194
+ /(1\p{Nd}{0,2}|2(\p{Nd}|[0-5]\p{Nd}+)?)\.(0|1\p{Nd}{0,2}|2(\p{Nd}|[0-5]\p{Nd})?)\.(0|1\p{Nd}{0,2}|2(\p{Nd}|[0-5]\p{Nd})?)\.(0|1\p{Nd}{0,2}|2(\p{Nd}|[0-5]\p{Nd})?)/ =>
195
+ '<nobr>\0</nobr>'
196
+ }
197
+ end
198
+
199
+ def apply_rules(rules, str)
200
+ res = str.dup
201
+ rules.each do |rul, rep|
202
+ str.gsub!(rul, rep)
203
+ end
204
+ str
205
+ end
206
+
207
+ def process(str)
208
+ # str = apply_rules(rules_quotes, str) <------- DON'T WORK PROP!!!
209
+ str = apply_rules(@rules_strict, str) # Сначала применим строгие правила: пробелы, запятые
210
+ str = quotes(str) # правильно расставим кавычки
211
+ str = apply_rules(@rules_main, str)
212
+ str = apply_rules(@rules_symbols, str)
213
+ str = apply_rules(@rules_braces, str)
214
+ end
215
+
216
+ def quotes(text)
217
+ quot11='«'
218
+ quot12='»'
219
+ quot21='«'
220
+ quot22='»'
221
+ # „“
222
+
223
+ quotes = ['&quot;','&laquo;','&raquo;','«','»','&#171;','&#187;','&#147;','&#132;','&#8222;','&#8220;','„','“','”','‘','’']
224
+ quotes = Regexp.new quotes.join('|')
225
+ text.gsub!(quotes, '"') # Единый тип кавычек
226
+ text.gsub!('""', '"')
227
+
228
+ text.gsub!(/"(\P{L})/, '»\1') # Взято из старой реализации
229
+ text.gsub!(/(\P{L})"/, '\1«') # Взято из старой реализации
230
+
231
+ # text.gsub!(/([^=]|\A)""(\.{2,4}[а-яА-Я\w\-]+|[а-яА-Я\w\-]+)/, '\1<typo:quot1>"\2') # Двойных кавычек уже нет
232
+ text.gsub!(/([^=]|\A)"(\.{2,4}[\p{L}\p{M}]+|[\p{L}\p{M}\-]+)/, '\1<typo:quot1>\2')
233
+ # text.gsub!(/([а-яА-Я\w\.\-]+)""([\n\.\?\!, \)][^>]{0,1})/, '\1"</typo:quot1>\2') # Двойных кавычек уже нет
234
+ text.gsub!(/([\p{L}\p{M}\.\-]+)"([\n\.\?\!, \)][^>]{0,1})/, '\1</typo:quot1>\2')
235
+ text.gsub!(/(<\/typo:quot1>[\.\?\!]{1,3})"([\n\.\?\!, \)][^>]{0,1})/, '\1</typo:quot1>\2')
236
+ text.gsub!(/(<typo:quot1>[\p{L}\p{M}\.\- \n]*?)<typo:quot1>(.+?)<\/typo:quot1>/, '\1<typo:quot2>\2</typo:quot2>')
237
+ text.gsub!(/(<\/typo:quot2>.+?)<typo:quot1>(.+?)<\/typo:quot1>/, '\1<typo:quot2>\2</typo:quot2>')
238
+ text.gsub!(/(<typo:quot2>.+?<\/typo:quot2>)\.(.+?<typo:quot1>)/, '\1</typo:quot1>.\2')
239
+ text.gsub!(/(<typo:quot2>.+?<\/typo:quot2>)\.(?!<\/typo:quot1>)/, '\1</typo:quot1>.\2\3\4')
240
+ # text.gsub!(/""/, '</typo:quot2></typo:quot1>') # Двойных кавычек уже нет
241
+ text.gsub!(/(?<=<typo:quot1>)(.+?)<typo:quot2>(.+?)(?!<\/typo:quot2>)/, '\1<typo:quot2>\2')
242
+ # text.gsub!(/"/, '<typo:quot1>') # Непонятный хак
243
+ # text.gsub!(/(<[^>]+)<\/typo:quot\d>/, '\1"') # Еще более непонятный хак
244
+
245
+ text.gsub!(/"$/, '</typo:quot2>') # new
246
+
247
+ text.gsub!('<typo:quot1>', quot11)
248
+ text.gsub!('</typo:quot1>', quot12)
249
+ text.gsub!('<typo:quot2>', quot21)
250
+ text.gsub!('</typo:quot2>', quot22)
251
+
252
+ text.gsub!(/(^|\s)»(<)/, '\1«\2') # new
253
+ text.gsub!(/([а-я\w\d,])«(.)/i, '\1 «\2') # new
254
+ text.gsub!(/» ([:,])/i, '»\1') # new
255
+ text.gsub!(/«$/, '»') # new
256
+ text.gsub!(/^»/, '«') # new
257
+ text.gsub!('.».', '».') # new
258
+ text.gsub!(/ »(.)/, ' «\1') # new
259
+ text.gsub!(/^«\s+/, '«') # new
260
+ text.gsub!(/\s+»$/, '»') # new
261
+
262
+ text
263
+ end
264
+ end
265
+ end
266
+ end
267
+
@@ -0,0 +1,55 @@
1
+ # encoding: utf-8
2
+
3
+ module Typograph
4
+ class Processor
5
+
6
+ DEFAULTS = {}
7
+
8
+ SAFE_BLOCKS = [
9
+ ['<pre[^>]*>','</pre>'],
10
+ ['<style[^>]*>','</style>'],
11
+ ['<script[^>]*>','</script>'],
12
+ ['<!--','-->'],
13
+ ['<code[^>]*>','</code>']
14
+ ]
15
+
16
+ def safe_blocks
17
+ @pattern ||= begin
18
+ pattern = SAFE_BLOCKS.map do |val|
19
+ val.join('.*?')
20
+ end.join('|')
21
+ Regexp.new("(#{pattern}|<[^>]*[\\s][^>]*>)", Regexp::IGNORECASE | Regexp::MULTILINE)
22
+ end
23
+ end
24
+
25
+ # Вызывает типограф, обходя html-блоки и безопасные блоки
26
+ def process(str)
27
+ str = @profile.normalize(str)
28
+
29
+ @safe_blocks = {}
30
+ str.gsub!(safe_blocks) do |match|
31
+ key = "<#{@safe_blocks.length}>"
32
+ @safe_blocks[key] = match
33
+ key
34
+ end
35
+
36
+ str = @profile.process(str)
37
+
38
+ if @safe_blocks
39
+ str.gsub! /(<\d>)/ do |match|
40
+ @safe_blocks[match]
41
+ end
42
+ end
43
+ @safe_blocks = {}
44
+
45
+ # выдераем дублирующиеся nowrap
46
+ str.gsub!(/(\<(\/?nobr)\>)+/i, '\1')
47
+
48
+ str
49
+ end
50
+
51
+ def initialize(options = {})
52
+ @profile = Adapters::Russian.new options
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,3 @@
1
+ module Typograph
2
+ VERSION = "0.0.1.pre.1"
3
+ end
data/lib/typograph.rb ADDED
@@ -0,0 +1,10 @@
1
+ require "typograph/version"
2
+ require "typograph/processor"
3
+ require "typograph/adapter"
4
+ require "typograph/adapters/russian"
5
+
6
+ module Typograph
7
+ def self.process(text, options={})
8
+ Processor.new(options).process(text)
9
+ end
10
+ end
@@ -0,0 +1,2 @@
1
+ ����� ������ �1"������-�����" �����
2
+ ����� ������ �1 �������-����� �����
@@ -0,0 +1,2 @@
1
+ 2008 , �����
2
+ 2008, �����
@@ -0,0 +1,50 @@
1
+ "����� ���������� �� ����", - ������ ��, -"��!"
2
+ ������ ���������� ��&nbsp;����,&nbsp;� ������ ��, -���!�
3
+
4
+ " �� ���� � ������ "
5
+ ���&nbsp;����&nbsp;� ������
6
+
7
+ ������ ���������� ���� ��� �������� �����. ��� ���������,"���������" ��, ��������� �������.
8
+ ������ ���������� ���� ���&nbsp;�������� �����. ���&nbsp;���������, ����������� ��, ��������� �������.
9
+
10
+ ""��-��""
11
+ ���-���
12
+
13
+ ���!,!
14
+ ���!
15
+
16
+ ��, , ��!
17
+ ��, ��!
18
+
19
+ "�����.".
20
+ ������.
21
+
22
+ ���� ������::
23
+ ���� ������:
24
+
25
+ ���� ������: :
26
+ ���� ������:
27
+
28
+ ���� ������: : :
29
+ ���� ������:
30
+
31
+ ���� ������, , ,
32
+ ���� ������,
33
+
34
+ ���� ������; ; ; ; ;
35
+ ���� ������;
36
+
37
+ "����������!!" - ���� ��!"
38
+ �����������!�&nbsp;� ���� ��!�
39
+
40
+ �������, �� ����� ���-������ O''Really?
41
+ �������, �� ����� ���-������ O&rsquo;Really?
42
+
43
+ ������: "������: "�������" � "�����, ����� "��������"", ����� ���� ����".
44
+ ������: �������: ��������� � ������, ����� ����������, ����� ���� �����.
45
+
46
+ ��� �����
47
+ ���-�����
48
+
49
+ ����� ��
50
+ �����-��