standalone_typograf 2.0.2 → 3.0.0

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