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.
- checksums.yaml +7 -0
- data/.rspec +2 -0
- data/.travis.yml +8 -0
- data/README.md +108 -72
- data/Rakefile +1 -9
- data/doc/fonts.md +1 -4
- data/doc/logo.png +0 -0
- data/doc/logo.psd +0 -0
- data/lib/standalone_typograf/dashes.rb +23 -0
- data/lib/standalone_typograf/ellipsis.rb +23 -0
- data/lib/standalone_typograf/fractions.rb +12 -28
- data/lib/standalone_typograf/mnemonics.rb +33 -0
- data/lib/standalone_typograf/nbspaces.rb +36 -0
- data/lib/standalone_typograf/quotes.rb +109 -77
- data/lib/standalone_typograf/version.rb +1 -1
- data/lib/standalone_typograf.rb +86 -42
- data/spec/processors/dashes_spec.rb +31 -0
- data/spec/processors/ellipsis_spec.rb +28 -0
- data/spec/processors/fractions_spec.rb +18 -0
- data/spec/processors/mnemonics_spec.rb +34 -0
- data/spec/processors/nbspaces_spec.rb +31 -0
- data/spec/processors/quotes_spec.rb +32 -0
- data/spec/spec_helper.rb +21 -0
- data/spec/standalone_typograf_spec.rb +12 -0
- data/spec/typograf_spec.rb +57 -0
- data/standalone_typograf.gemspec +6 -3
- metadata +76 -45
- data/.DS_Store +0 -0
- data/.rvmrc +0 -1
- data/lib/standalone_typograf/dasherize.rb +0 -12
- data/lib/standalone_typograf/dots.rb +0 -9
- data/lib/standalone_typograf/endash.rb +0 -9
- data/lib/standalone_typograf/nbspace.rb +0 -42
- data/lib/standalone_typograf/signs.rb +0 -26
- data/test/test_dash.rb +0 -24
- data/test/test_dots.rb +0 -24
- data/test/test_endash.rb +0 -12
- data/test/test_fractions.rb +0 -25
- data/test/test_nbspace.rb +0 -33
- data/test/test_prepare.rb +0 -34
- data/test/test_quotes.rb +0 -32
- 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
data/.travis.yml
ADDED
data/README.md
CHANGED
@@ -1,97 +1,135 @@
|
|
1
|
-
|
1
|
+
# StandaloneTypograf
|
2
2
|
|
3
|
-
|
3
|
+
[ ](https://travis-ci.org/shlima/standalone_typograf)
|
4
|
+
[ ](https://codeclimate.com/github/shlima/standalone_typograf)
|
5
|
+
[ ](https://gemnasium.com/shlima/standalone_typograf)
|
4
6
|
|
5
|
-
|
7
|
+
|
8
|
+

|
9
|
+
|
10
|
+
StandaloneTypograf — gem для подготовки текста к публикации или типографирования текста на лету (вывод комментариев, например)
|
11
|
+
|
12
|
+
> Пушкин писал Дельвигу: "Жду "Цыганов" и тотчас тисну...", (c) 1827 - А. С. Пушкин
|
6
13
|
|
7
14
|
Превратится в:
|
8
|
-
|
9
|
-
|
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 символы (© вместо ©);
|
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
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
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
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
59
|
+
## Обработчики
|
60
|
+
### Кавычки
|
61
|
+
Значение | Тип | Замена Utf | Замена Html
|
62
|
+
--- | --- | --- | ---
|
63
|
+
" | Внешняя, открывающая | « | \«
|
64
|
+
" | Внешняя, закрывающая | » | \»
|
65
|
+
" | Внутренняя, открывающая | „ | \„
|
66
|
+
" | Внутренняя, закрывающая | “ | \“
|
58
67
|
|
59
|
-
|
68
|
+
```ruby
|
69
|
+
StandaloneTypograf::Typograf.new(text).processor(:quotes)
|
70
|
+
```
|
60
71
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
### Переопределение или добавление знаков
|
72
|
+
### Длинное тире
|
73
|
+
Значение | Замена Utf | Замена Html
|
74
|
+
--- | --- | ---
|
75
|
+
- | — | \—
|
67
76
|
|
68
|
-
|
77
|
+
```ruby
|
78
|
+
StandaloneTypograf::Typograf.new(text).processor(:dashes)
|
79
|
+
```
|
69
80
|
|
70
|
-
|
71
|
-
|
81
|
+
### Неразрывные пробелы
|
82
|
+
Значение | Замена Utf | Замена Html
|
83
|
+
--- | --- | ---
|
84
|
+
- | | \
|
72
85
|
|
73
|
-
|
86
|
+
Неразрывные пробелы используются при отбивке длинного тире, одно-двухбуквенных слов и некоторых частиц.
|
74
87
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
text.quotes # => "«Мерседес»'
|
88
|
+
```ruby
|
89
|
+
StandaloneTypograf::Typograf.new(text).processor(:nbspaces)
|
90
|
+
```
|
79
91
|
|
80
|
-
|
92
|
+
### Мнемоники
|
93
|
+
Значение | Замена Utf | Замена Html
|
94
|
+
--- | --- | ---
|
95
|
+
(c) | © | \©
|
96
|
+
(tm) | ™ | \™
|
97
|
+
(r) | ® | \®
|
98
|
+
+- | ± | \±
|
99
|
+
-> | → | \→
|
100
|
+
<- | ← | \←
|
101
|
+
~= | ≈ | \≈
|
81
102
|
|
82
|
-
|
103
|
+
```ruby
|
104
|
+
StandaloneTypograf::Typograf.new(text).processor(:mnemonics)
|
105
|
+
```
|
83
106
|
|
84
|
-
|
107
|
+
### Дроби
|
108
|
+
Значение | Замена Utf | Замена Html | Html код
|
109
|
+
--- | --- | --- | ---
|
110
|
+
1/1 | none | <sup>1</sup>⁄<sub>1</sub> | `<sup>1</sup>⁄<sub>1</sub>`
|
111
|
+
1234124/454325 | none | <sup>1234124</sup>⁄<sub>454325</sub> | `<sup>1234124</sup>⁄<sub>454325</sub>`
|
85
112
|
|
86
|
-
|
113
|
+
Типограф производит замену дробей только в режиме **html**, при этом он генерирует html код используя теги верхнего и нижнего индексов, вследствие чего, количество заменяемых дробей бесконечно.
|
87
114
|
|
88
|
-
|
115
|
+
```ruby
|
116
|
+
StandaloneTypograf::Typograf.new(text).processor(:fractions)
|
117
|
+
```
|
89
118
|
|
90
|
-
|
119
|
+
Чтобы отключить замену дробей используйте параметр `exclude` при инициализации
|
91
120
|
|
92
|
-
|
121
|
+
```ruby
|
122
|
+
StandaloneTypograf::Typograf.new(text, :exclude => :fractions)
|
123
|
+
```
|
93
124
|
|
94
|
-
|
125
|
+
### Многоточие
|
126
|
+
Значение | Замена Utf | Замена Html
|
127
|
+
--- | --- | ---
|
128
|
+
... | … | \…
|
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
data/doc/fonts.md
CHANGED
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 => '—',
|
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 => '…',
|
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
|
-
|
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
|
-
|
28
|
-
|
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>⁄<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: '©', utf: '©' },
|
12
|
+
'\((tm|тм)\)' => { html: '™', utf: '™' },
|
13
|
+
'\([r|р]\)' => { html: '®', utf: '®' },
|
14
|
+
'(\+\-)' => { html: '±', utf: '±' },
|
15
|
+
'(\-\>)' => { html: '→', utf: '→' },
|
16
|
+
'(\<\-)' => { html: '←', utf: '←' },
|
17
|
+
'(\~\=)' => { html: '≈', 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 => ' ',
|
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
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
Q = '"' # source quote
|
8
|
+
|
9
|
+
CHARS = {
|
10
|
+
:outer_left => {html: '«', utf: '«'},
|
11
|
+
:outer_right => {html: '»', utf: '»'},
|
12
|
+
:inner_left => {html: '„', utf: '„'},
|
13
|
+
:inner_right => {html: '“', utf: '“'},
|
14
|
+
}.freeze
|
15
|
+
|
16
|
+
included do
|
17
|
+
register_processor(Processor)
|
18
|
+
end
|
9
19
|
|
10
|
-
|
11
|
-
|
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
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
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
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
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 `«`)
|
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
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
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
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
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
|
-
|
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
|