standalone_typograf 2.0.2 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. checksums.yaml +7 -0
  2. data/.rspec +2 -0
  3. data/.travis.yml +8 -0
  4. data/README.md +108 -72
  5. data/Rakefile +1 -9
  6. data/doc/fonts.md +1 -4
  7. data/doc/logo.png +0 -0
  8. data/doc/logo.psd +0 -0
  9. data/lib/standalone_typograf/dashes.rb +23 -0
  10. data/lib/standalone_typograf/ellipsis.rb +23 -0
  11. data/lib/standalone_typograf/fractions.rb +12 -28
  12. data/lib/standalone_typograf/mnemonics.rb +33 -0
  13. data/lib/standalone_typograf/nbspaces.rb +36 -0
  14. data/lib/standalone_typograf/quotes.rb +109 -77
  15. data/lib/standalone_typograf/version.rb +1 -1
  16. data/lib/standalone_typograf.rb +86 -42
  17. data/spec/processors/dashes_spec.rb +31 -0
  18. data/spec/processors/ellipsis_spec.rb +28 -0
  19. data/spec/processors/fractions_spec.rb +18 -0
  20. data/spec/processors/mnemonics_spec.rb +34 -0
  21. data/spec/processors/nbspaces_spec.rb +31 -0
  22. data/spec/processors/quotes_spec.rb +32 -0
  23. data/spec/spec_helper.rb +21 -0
  24. data/spec/standalone_typograf_spec.rb +12 -0
  25. data/spec/typograf_spec.rb +57 -0
  26. data/standalone_typograf.gemspec +6 -3
  27. metadata +76 -45
  28. data/.DS_Store +0 -0
  29. data/.rvmrc +0 -1
  30. data/lib/standalone_typograf/dasherize.rb +0 -12
  31. data/lib/standalone_typograf/dots.rb +0 -9
  32. data/lib/standalone_typograf/endash.rb +0 -9
  33. data/lib/standalone_typograf/nbspace.rb +0 -42
  34. data/lib/standalone_typograf/signs.rb +0 -26
  35. data/test/test_dash.rb +0 -24
  36. data/test/test_dots.rb +0 -24
  37. data/test/test_endash.rb +0 -12
  38. data/test/test_fractions.rb +0 -25
  39. data/test/test_nbspace.rb +0 -33
  40. data/test/test_prepare.rb +0 -34
  41. data/test/test_quotes.rb +0 -32
  42. data/test/test_signs.rb +0 -36
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: b43853037131f6e6f5688014e63d55263bc1a0f2
4
+ data.tar.gz: 76b0f8cbc97462ed5added4a66c100ac3297db08
5
+ SHA512:
6
+ metadata.gz: 90f4013887443a5732e44fce7ee5b967833997f8598064ccfbb058b27b595c2d448dcd645b4a6de4b7e29ed7446dc0b8b8e92c4429807287d146d814731945bb
7
+ data.tar.gz: 2cd5fd4359a50620cf154a6dc1fbf2465993c62569e866e95093c83dddb0ea5bd89c51b5bfa953b4011e1126f3e2105711ff762d6be370c6ae2df105cefeffe9
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format Fuubar
2
+ --color
data/.travis.yml ADDED
@@ -0,0 +1,8 @@
1
+ language: ruby
2
+ script: bundle exec rspec
3
+ rvm:
4
+ - 1.9.3
5
+ - 2.0.0
6
+ env:
7
+ - RAILS=3.2.14
8
+ - RAILS=4.0.0
data/README.md CHANGED
@@ -1,97 +1,135 @@
1
- ![StandaloneTypograf](https://raw.github.com/shlima/StandaloneTypograf/master/doc/logo.png)
1
+ # StandaloneTypograf
2
2
 
3
- **StandaloneTypograf** — gem для подготовки текста к публикации или типографирования текста на лету (вывод комментариев, например)
3
+ [![Travis CI ](https://api.travis-ci.org/shlima/standalone_typograf.png) ](https://travis-ci.org/shlima/standalone_typograf)
4
+ [![Code Climate](https://codeclimate.com/github/shlima/standalone_typograf.png) ](https://codeclimate.com/github/shlima/standalone_typograf)
5
+ [![Gemnasium ](https://gemnasium.com/shlima/standalone_typograf.png) ](https://gemnasium.com/shlima/standalone_typograf)
4
6
 
5
- Пушкин писал Дельвигу: "Жду "Цыганов" и тотчас тисну...", (c) 1827 - А. С. Пушкин
7
+
8
+ ![StandaloneTypograf](https://raw.github.com/shlima/standalone_typograf/master/doc/logo.png)
9
+
10
+ StandaloneTypograf — gem для подготовки текста к публикации или типографирования текста на лету (вывод комментариев, например)
11
+
12
+ > Пушкин писал Дельвигу: "Жду "Цыганов" и тотчас тисну...", (c) 1827 - А. С. Пушкин
6
13
 
7
14
  Превратится в:
8
-
9
- Пушкин писал Дельвигу: «Жду „Цыганов“ и тотчас тисну…», © 1827 — А. С. Пушкин
10
-
15
+
16
+ > Пушкин писал Дельвигу: «Жду „Цыганов“ и тотчас тисну…», © 1827 — А. С. Пушкин
17
+
11
18
  Пример работы (онлайн типограф): http://typograf.herokuapp.com
12
-
13
- ## Возможности
14
-
15
- - замена кавычек (поддерживаются внутренние и внешние кавычки);
16
- - замена знаков (с), (тм), (р) на аналогичные ©, ™, ®. Буква в скобке может быть как латинской, так и кириллической;
17
- - замена знака ±
18
- - короткое тире (между числами без отбивки);
19
- - замена многоточия;
20
- - подстановка длинного тире (с использованием неразрывного пробела);
21
- - привязка одно- и двухбуквенных слов к следующему за ними слову с помощью неразрывного пробела;
22
- - привязка частиц (>=3) к предыдущему слову с помощью неразрывного пробела;
23
- - замена всех 19 цельных символов дробей европейского вида, поддерживаемых стандартом Юникод.
24
-
25
- ## Отличия **StandaloneTypograf**
26
-
27
- - автономность (самостоятельная обработка текста не зависящая от сторонних сайтов и сервисов);
28
- - выполняет прямую функцию (не преобразует в html, работает с plain текстом, UTF-8 символы (© вместо &copy);
29
- - корректная обработка двойных кавычек (в отличие от gilenson);
30
- - высокая скорость;
31
-
19
+
20
+ ### Отличия StandaloneTypograf
21
+ Отличия от типографа Лебедева и ruby библиотеки Gilenson
22
+
23
+ * автономность (самостоятельная/standalone обработка текста не зависящая от сторонних сервисов);
24
+ * выполняет прямую функцию (не преобразует в html, работает с plain текстом);
25
+ * корректная обработка вложенных кавычек (в отличие от gilenson);
26
+
32
27
  ## Использование
33
28
 
34
- Пример использования:
29
+ Создайте экземпляр типографа и передайте ему текст как единственный обязательный аргумент:
30
+
31
+ ```ruby
32
+ @text = %Q( "Я "читал" стихи Быкова,- сказал он." (c) )
33
+ typograph = StandaloneTypograph::Typograph.new(@text)
34
+ typograph.prepare #=> «Я „читал“ стихи Быкова,— сказал он.» ©
35
+ ```
36
+
37
+ По умолчанию типограф работает в режиме `utf`, если вам необходма подстановка html-кодов, передайте переметр `mode` со значением `html`
38
+
39
+ ```ruby
40
+ typograph = StandaloneTypograph::Typograph.new(@text, mode: :html)
41
+ typograph.prepare #=> «Я „читал“ стихи Быкова,— сказал он.» ©
42
+ ```
43
+
44
+ Метод `prepare` вызывает все возможные обработчики текста. Вы можете вызвать только некоторые, передав массив с названием необходимых _процессоров_, в метод `processor`
45
+
46
+ ```ruby
47
+ typograph = StandaloneTypograph::Typograph.new(@text)
48
+ typograph.processor(:dashes, :mnemonics)
49
+ ```
50
+
51
+ Вы так же можете использовать метод `prepare` исключив ненужные обработчики. Для этого необходимо передать массив с названием ненужных _процессоров_ с параметром `exclude` при инициализации типографа:
35
52
 
36
- require 'standalone_typograf'
37
-
38
- text = StandaloneTypograf::Typograf.new('"StandaloneTypograf" - простой и быстрый, его можно использовать "на лету"')
39
- text.dasherize # Преобразует все тире
40
- text.signs # Заменит знаки (с) => ©
41
- text.quotes # Преобразует кавычки
42
-
43
- # Эти три метода можно заменить одной командой: prepare
44
- text.prepare # => «StandaloneTypograf» — простой и быстрый, его можно использовать «на лету»
45
-
46
- ## Параметры
47
- ### Вызов определенных обработчиков
53
+ ```ruby
54
+ typograph = StandaloneTypograph::Typograph.new(@text, exclude: :fractions)
55
+ typograph.prepare # бедут выполнены все преобразования кроме замены дробей
56
+ ```
48
57
 
49
- Вы можете вызвать только нужные вам типографы или использовать все одной командой *prepare*. Список поддерживаемых типографов:
50
58
 
51
- - dasherize (тире)
52
- - signs (символы)
53
- - quotes (кавычки)
54
- - dots (многоточие)
55
- - endash (короткое тире)
56
- - nbspace (неразрывные пробелы)
57
- - fractions (дроби)
59
+ ## Обработчики
60
+ ### Кавычки
61
+ Значение | Тип | Замена Utf | Замена Html
62
+ --- | --- | --- | ---
63
+ " | Внешняя, открывающая | « | \«
64
+ " | Внешняя, закрывающая | » | \»
65
+ " | Внутренняя, открывающая | „ | \„
66
+ " | Внутренняя, закрывающая | “ | \“
58
67
 
59
- Или наоборот, вы можете исключить ненужный вам типограф, передав символьный массив в параметре *except* с ненужными обработчиками:
68
+ ```ruby
69
+ StandaloneTypograf::Typograf.new(text).processor(:quotes)
70
+ ```
60
71
 
61
- require 'standalone_typograf'
62
- text = StandaloneTypograf::Typograf.new('(c) А. А. Шилов', except: [:fractions])
63
- # Выполнит все преобразования кроме замены дробей
64
- text.prepare
65
-
66
- ### Переопределение или добавление знаков
72
+ ### Длинное тире
73
+ Значение | Замена Utf | Замена Html
74
+ --- | --- | ---
75
+ - | — | \—
67
76
 
68
- Чтобы переопределить знаки по-умолчанию или добавить собственные, передайте хеш *signs* или *signs_ru* (для русских заменяемых обозначений) 'заменяемый текст (в формате *regexp*)' => 'знак'.
77
+ ```ruby
78
+ StandaloneTypograf::Typograf.new(text).processor(:dashes)
79
+ ```
69
80
 
70
- text = StandaloneTypograf::Typograf.new('(copy) 2013', signs: {'[(]copy[)]' => '©'})
71
- text.signs # => 2013"
81
+ ### Неразрывные пробелы
82
+ Значение | Замена Utf | Замена Html
83
+ --- | --- | ---
84
+ - |   | \ 
72
85
 
73
- ### Переопределение кавычек
86
+ Неразрывные пробелы используются при отбивке длинного тире, одно-двухбуквенных слов и некоторых частиц.
74
87
 
75
- Чтобы переопределить кавычки (outer: внешние, inner: внутренние) передайте хеш quotes с ключем outer/inner и массивом из двух символов (левая и правая кавычки):
76
-
77
- text = StandaloneTypograf::Typograf.new('"Мерседес"', quotes: { outer: ['«', '»'] } )
78
- text.quotes # => "«Мерседес»'
88
+ ```ruby
89
+ StandaloneTypograf::Typograf.new(text).processor(:nbspaces)
90
+ ```
79
91
 
80
- ## Installation
92
+ ### Мнемоники
93
+ Значение | Замена Utf | Замена Html
94
+ --- | --- | ---
95
+ (c) | © | \©
96
+ (tm) | ™ | \™
97
+ (r) | ® | \®
98
+ +- | ± | \±
99
+ -> | → | \→
100
+ <- | ← | \&larr;
101
+ ~= | ≈ | \&asymp;
81
102
 
82
- Ruby 1.9.3 - 2.0.0; Rails 3-4
103
+ ```ruby
104
+ StandaloneTypograf::Typograf.new(text).processor(:mnemonics)
105
+ ```
83
106
 
84
- Add this line to your application's Gemfile:
107
+ ### Дроби
108
+ Значение | Замена Utf | Замена Html | Html код
109
+ --- | --- | --- | ---
110
+ 1/1 | none | <sup>1</sup>&frasl;<sub>1</sub> | `<sup>1</sup>&frasl;<sub>1</sub>`
111
+ 1234124/454325 | none | <sup>1234124</sup>&frasl;<sub>454325</sub> | `<sup>1234124</sup>&frasl;<sub>454325</sub>`
85
112
 
86
- gem 'standalone_typograf'
113
+ Типограф производит замену дробей только в режиме **html**, при этом он генерирует html код используя теги верхнего и нижнего индексов, вследствие чего, количество заменяемых дробей бесконечно.
87
114
 
88
- And then execute:
115
+ ```ruby
116
+ StandaloneTypograf::Typograf.new(text).processor(:fractions)
117
+ ```
89
118
 
90
- $ bundle
119
+ Чтобы отключить замену дробей используйте параметр `exclude` при инициализации
91
120
 
92
- Or install it yourself as:
121
+ ```ruby
122
+ StandaloneTypograf::Typograf.new(text, :exclude => :fractions)
123
+ ```
93
124
 
94
- $ gem install standalone_typograf
125
+ ### Многоточие
126
+ Значение | Замена Utf | Замена Html
127
+ --- | --- | ---
128
+ ... | &hellip; | \&hellip;
129
+
130
+ ```ruby
131
+ StandaloneTypograf::Typograf.new(text).processor(:ellipsis)
132
+ ```
95
133
 
96
134
  ## Contributing
97
135
 
@@ -100,5 +138,3 @@ Or install it yourself as:
100
138
  3. Commit your changes (`git commit -am 'Add some feature'`)
101
139
  4. Push to the branch (`git push origin my-new-feature`)
102
140
  5. Create new Pull Request
103
-
104
-
data/Rakefile CHANGED
@@ -1,9 +1 @@
1
- require 'rake/testtask'
2
- Bundler::GemHelper.install_tasks
3
-
4
- Rake::TestTask.new do |t|
5
- t.libs << 'test'
6
- end
7
-
8
- desc 'Run tests'
9
- task default: :test
1
+ require "bundler/gem_tasks"
data/doc/fonts.md CHANGED
@@ -1,4 +1 @@
1
- Fonts:
2
- Standalone = Voluptate_demo
3
- Typograf = Telugu MN
4
- 2 = PT Sans Caption
1
+ Fonts: Standalone = Voluptate_demo Typograf = Telugu MN 2 = PT Sans Caption
data/doc/logo.png CHANGED
Binary file
data/doc/logo.psd CHANGED
Binary file
@@ -0,0 +1,23 @@
1
+ # encoding: UTF-8
2
+
3
+ module StandaloneTypograf #:nodoc:
4
+ module Dashes
5
+ extend ActiveSupport::Concern
6
+
7
+ CHAR = {
8
+ :html => '&mdash;',
9
+ :utf => '—',
10
+ }.freeze
11
+
12
+ included do
13
+ register_processor(Processor)
14
+ end
15
+
16
+ module Processor
17
+ def self.compile(text, mode)
18
+ text.gsub!(/-(\s)/, CHAR[mode]+'\1')
19
+ return text
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,23 @@
1
+ # encoding: UTF-8
2
+
3
+ module StandaloneTypograf #:nodoc:
4
+ module Ellipsis
5
+ extend ActiveSupport::Concern
6
+
7
+ CHAR = {
8
+ :html => '&hellip;',
9
+ :utf => '…',
10
+ }.freeze
11
+
12
+ included do
13
+ register_processor(Processor)
14
+ end
15
+
16
+ module Processor
17
+ def self.compile(text, mode)
18
+ text.gsub!(/([[:alpha:]])([.][.][.])(\s|$)/, '\1'+CHAR[mode]+'\3')
19
+ return text
20
+ end
21
+ end
22
+ end
23
+ end
@@ -1,35 +1,19 @@
1
1
  # encoding: UTF-8
2
2
 
3
- module StandaloneTypograf
3
+ module StandaloneTypograf #:nodoc:
4
4
  module Fractions
5
- FRACTIONS = {
6
- '1/4' => '¼',
7
- '1/2' => '½',
8
- '3/4' => '¾',
9
- '1/7' => '⅐',
10
- '1/9' => '⅑',
11
- '1/10' => '⅒',
12
- '1/3' => '⅓',
13
- '2/3' => '⅔',
14
- '1/5' => '⅕',
15
- '2/5' => '⅖',
16
- '3/5' => '⅗',
17
- '4/5' => '⅘',
18
- '1/6' => '⅙',
19
- '5/6' => '⅚',
20
- '1/8' => '⅛',
21
- '3/8' => '⅜',
22
- '5/8' => '⅝',
23
- '7/8' => '⅞',
24
- '0/3' => '↉'
25
- }
5
+ extend ActiveSupport::Concern
26
6
 
27
- def fractions
28
- FRACTIONS.each_pair do |text, sign|
29
- #@text = @text.gsub(/#{text}/i, sign)
30
- @text = @text.gsub(/(\D|\A)([#{text[0]}][\/][#{text[2]}])(\D|\z)/i, '\1' + sign + '\3')
31
- end
32
- @text
7
+ included do
8
+ register_processor(Processor)
33
9
  end
10
+
11
+ module Processor
12
+ def self.compile(text, mode)
13
+ return text unless mode == :html
14
+ text.gsub!(/(\s|^)(\d+)(\/)(\d+)(?:\s|$)/, '\1<sup>\2</sup>&frasl;<sub>\4</sub>')
15
+ return text
16
+ end
34
17
  end
18
+ end
35
19
  end
@@ -0,0 +1,33 @@
1
+ # encoding: UTF-8
2
+
3
+ module StandaloneTypograf #:nodoc:
4
+ module Mnemonics
5
+ extend ActiveSupport::Concern
6
+
7
+ # Contains regexps.
8
+ # May contain signs in several languages separated by regexp's OR
9
+ # e.g. eng|рус
10
+ TEMPLATES = {
11
+ '\([c|с]\)' => { html: '&copy;', utf: '©' },
12
+ '\((tm|тм)\)' => { html: '&trade;', utf: '™' },
13
+ '\([r|р]\)' => { html: '&reg;', utf: '®' },
14
+ '(\+\-)' => { html: '&plusmn;', utf: '±' },
15
+ '(\-\>)' => { html: '&rarr;', utf: '→' },
16
+ '(\<\-)' => { html: '&larr;', utf: '←' },
17
+ '(\~\=)' => { html: '&asymp;', utf: '≈' },
18
+ }.freeze
19
+
20
+ included do
21
+ register_processor(Processor)
22
+ end
23
+
24
+ module Processor
25
+ def self.compile(text, mode)
26
+ TEMPLATES.each_pair do |regexp, data|
27
+ text.gsub!(/#{regexp}/i, data[mode])
28
+ end
29
+ return text
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,36 @@
1
+ # encoding: UTF-8
2
+
3
+ module StandaloneTypograf #:nodoc:
4
+ module Nbspaces
5
+ extend ActiveSupport::Concern
6
+
7
+ CHAR = {
8
+ :html => '&nbsp;',
9
+ :utf => ' ',
10
+ }.freeze
11
+
12
+ PARTICLES = %w(
13
+ разве неужели едва вряд вроде якобы мол дескать даже ведь таки лишь
14
+ почти только исключительно вон вот именно точь-в-точь приблизительно прямо
15
+ )
16
+
17
+ included do
18
+ register_processor(Processor)
19
+ end
20
+
21
+ module Processor
22
+ def self.compile(text, mode)
23
+ # One or three letter word - nbspace to the right
24
+ text.gsub!(/(\s|^)([[:alpha:]]{1,2})(\s)/i, '\1\2'+CHAR[mode])
25
+
26
+ # nbspace to the right
27
+ text.gsub!(/(#{PARTICLES.join('|')})(\s)/i, '\1'+CHAR[mode])
28
+
29
+ # dash - nbspace to the left
30
+ text.gsub!(/(\s)(-|#{Dashes::CHAR[:html]}|#{Dashes::CHAR[:utf]})/i, CHAR[mode]+'\2')
31
+
32
+ return text
33
+ end
34
+ end
35
+ end
36
+ end
@@ -1,94 +1,126 @@
1
1
  # encoding: UTF-8
2
2
 
3
- module StandaloneTypograf
3
+ module StandaloneTypograf #:nodoc:
4
4
  module Quotes
5
- QUOTES = {
6
- outer: %w( « » ),
7
- inner: %w( ),
8
- }
5
+ extend ActiveSupport::Concern
6
+
7
+ Q = '"' # source quote
8
+
9
+ CHARS = {
10
+ :outer_left => {html: '&laquo;', utf: '«'},
11
+ :outer_right => {html: '&raquo;', utf: '»'},
12
+ :inner_left => {html: '&bdquo;', utf: '„'},
13
+ :inner_right => {html: '&ldquo;', utf: '“'},
14
+ }.freeze
15
+
16
+ included do
17
+ register_processor(Processor)
18
+ end
9
19
 
10
- SOURCE = {
11
- double: '"'
20
+ # global locks
21
+ LOCK = {
22
+ inside: false, # inside outer quotes
23
+ outer_open: false, # outer quote opens but not still closed
24
+ inner_open: false, # inner quote opens but not still closed
12
25
  }
13
26
 
14
- def quotes
15
- arr_text = @text.split('')
16
- # [[0, :open], [10, :close]]
17
- quotes_tree = build_quotes_tree(arr_text)
18
- type_tree = build_type_tree(quotes_tree)
19
- # [[5, :open, :inner], [10, :close, :inner]]
20
-
21
- type_tree.each do |e|
22
- # ОТКРЫВАЮЩИЕ
23
- if e[1] == :open
24
- arr_text[e[0]] = (e[2] == :inner) ? @quotes[:inner][0] : @quotes[:outer][0]
25
- else
26
- # ЗАКРЫВАЮЩИЕ
27
- arr_text[e[0]] = (e[2] == :inner) ? @quotes[:inner][1] : @quotes[:outer][1]
28
- end
27
+ class Processor
28
+ attr_reader :text, :mode, :tarr
29
+
30
+ def self.compile(text, mode)
31
+ compiler = self.new(text, mode)
32
+ compiler.compile
33
+ text = compiler.tarr.join()
29
34
  end
30
- @text = arr_text.join
31
- end
32
35
 
33
- # PRIVATE
34
- #
35
- private
36
-
37
- # Вернет массив [[0, :open], [10, :close]]
38
- # Где цифра - индекс кавычки в тексте,
39
- # символ :open или :close - тип кавычки (открывающая или закрывающая)
40
- #
41
- def build_quotes_tree(arr_text)
42
- quotes_tree = []
43
- total = arr_text.size
44
- arr_text.each_with_index do |char, index|
45
- _next_, _prev_ = index + 1, index - 1
46
- # Если кавычка - первый символ в строке или за кавычкой примыкает буква,
47
- # то эта кавычка - открывающая.
48
- if char == SOURCE[:double]
49
- if index == 0 || (arr_text[_next_] != ' ' and arr_text[_prev_] == ' ')
50
- quotes_tree << [index, :open]
51
- # Ситуация с двойными кавычками идущими сразу за одинарными, например:
52
- # "Привет, "Медвед"".
53
- elsif arr_text[_prev_] == SOURCE[:double] and (arr_text[_next_] != ' ' and index + 1 != total)
54
- quotes_tree << [index, :open]
55
- else
56
- quotes_tree << [index, :close]
57
- end
58
- end
36
+ def initialize(text, mode)
37
+ @text = text
38
+ @mode = mode
39
+ # `tarr` means <b>text array</b>
40
+ # this is because replaced item may contain more than 1 char (like `&laquo;`)
41
+ # so replaced value will be placed into the one array cell.
42
+ @tarr = text.split(//)
43
+ end
44
+
45
+ def lock
46
+ @lock ||= LOCK.deep_dup
59
47
  end
60
- quotes_tree
61
- end
62
48
 
63
- # Вернет массив [[0, :open, :outer], [10, :close, :outer]]
64
- #
65
- def build_type_tree(quotes_tree)
66
- type_tree = quotes_tree.clone
67
- # [[0, :open], [10, :close]]
68
- quotes_tree.each_with_index do |e, i|
69
- even = (i%2 == 0)? true : false
70
- # ОТКРЫВАЮЩИЕ КАВЫЧКИ
71
- if e[1] == :open
72
- # Каждая кавычка с четным индексом (или индексом == 0)
73
- # внешняя.
74
- if even || i == 0
75
- type_tree[i] << :outer
76
- else
77
- type_tree[i] << :inner
49
+ def compile
50
+ tarr.each_with_index do |symbol, index|
51
+ next unless symbol == Q
52
+
53
+ # == Outer
54
+ if outside? && open_quote?(index)
55
+ tarr[index] = CHARS[:outer_left][mode]
56
+ outer_open_lock!
57
+ next
58
+ end
59
+ if inside? && !lock[:inner_open] && close_quote?(index)
60
+ tarr[index] = CHARS[:outer_right][mode]
61
+ outer_open_unlock!
62
+ next
78
63
  end
79
- end
80
64
 
81
- # ЗАКРЫВАЮЩИЕ КАВЫЧКИ
82
- if e[1] == :close
83
- # Каждая нечётная кавычка (или кавычка с индексом = 1) - внешняя
84
- if !even || i == 1
85
- type_tree[i] << :outer
86
- else
87
- type_tree[i] << :inner
65
+ # == Inner
66
+ if inside? && !lock[:inner_open] && open_quote?(index)
67
+ tarr[index] = CHARS[:inner_left][mode]
68
+ inner_open_lock!
69
+ next
70
+ end
71
+ if inside? && lock[:inner_open] && close_quote?(index)
72
+ tarr[index] = CHARS[:inner_right][mode]
73
+ inner_open_unlock!
74
+ next
88
75
  end
89
76
  end
90
- type_tree
77
+ end
78
+
79
+ private
80
+
81
+ # @return [Boolean]
82
+ # If this quote is open
83
+ def open_quote?(index)
84
+ return true if index == 0
85
+ (text[index-1] =~ /\s|^/) && (text[index+1] =~ /[[:alpha:]]/)
86
+ end
87
+
88
+ # @return [Boolean]
89
+ # If this quote is close
90
+ def close_quote?(index)
91
+ return true if index == (@tarr.length-1)
92
+ (text[index-1] =~ /[[:alpha:]]|[?!."]/) && (text[index+1] =~ /\s|[,.;!?#{Q}]/)
93
+ end
94
+
95
+ # @return [Boolean]
96
+ # If we outside of outer quotes
97
+ def outside?
98
+ !lock[:outer_open] && !lock[:inside]
99
+ end
100
+
101
+ # @return [Boolean]
102
+ # If we inside of outer quotes
103
+ def inside?
104
+ !outside?
105
+ end
106
+
107
+ def outer_open_lock!
108
+ lock[:inside] = true
109
+ lock[:outer_open] = true
110
+ end
111
+
112
+ def outer_open_unlock!
113
+ lock[:inside] = false
114
+ lock[:outer_open] = false
115
+ end
116
+
117
+ def inner_open_lock!
118
+ lock[:inner_open] = true
119
+ end
120
+
121
+ def inner_open_unlock!
122
+ lock[:inner_open] = false
91
123
  end
92
124
  end
93
125
  end
94
- end
126
+ end
@@ -1,5 +1,5 @@
1
1
  # encoding: UTF-8
2
2
 
3
3
  module StandaloneTypograf
4
- VERSION = '2.0.2'
4
+ VERSION = '3.0.0'
5
5
  end