rsyntaxtree 1.0.8 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +77 -0
- data/.solargraph.yml +22 -0
- data/.tags +211 -10
- data/Gemfile +10 -5
- data/README.md +3 -2
- data/Rakefile +3 -1
- data/bin/rsyntaxtree +42 -50
- data/docs/Gemfile +3 -1
- data/docs/_layouts/default.html +1 -1
- data/lib/rsyntaxtree/base_graph.rb +260 -264
- data/lib/rsyntaxtree/element.rb +167 -179
- data/lib/rsyntaxtree/elementlist.rb +105 -124
- data/lib/rsyntaxtree/markup_parser.rb +82 -93
- data/lib/rsyntaxtree/string_parser.rb +221 -237
- data/lib/rsyntaxtree/svg_graph.rb +158 -197
- data/lib/rsyntaxtree/utils.rb +59 -63
- data/lib/rsyntaxtree/version.rb +3 -2
- data/lib/rsyntaxtree.rb +174 -177
- data/rsyntaxtree.gemspec +10 -10
- data/test/markup_parser_test.rb +3 -2
- metadata +23 -21
@@ -1,7 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'parslet'
|
2
4
|
|
3
5
|
class MarkupParser < Parslet::Parser
|
4
|
-
rule(:cr) { str('\\n')}
|
6
|
+
rule(:cr) { str('\\n') }
|
5
7
|
rule(:eof) { any.absent? }
|
6
8
|
rule(:border) { match('[^\-]').absent? >> str('-').repeat(3).as(:border) >> (eof | cr) }
|
7
9
|
rule(:bborder) { match('[^=]').absent? >> str('=').repeat(3).as(:bborder) >> (eof | cr) }
|
@@ -12,7 +14,7 @@ class MarkupParser < Parslet::Parser
|
|
12
14
|
rule(:triangle) { str('^') }
|
13
15
|
|
14
16
|
rule(:path) { (str('+') >> str('>').maybe >> match('\d').repeat(1)).as(:path) }
|
15
|
-
rule(:escaped) { str('\\') >>
|
17
|
+
rule(:escaped) { str('\\') >> match('[#<>{}\\^+*_=~\|\n\-]').as(:chr) }
|
16
18
|
rule(:non_escaped) { ((match('[#<>{}\\^+*_=~\|\-]') | str('\\n')).absent? >> any).as(:chr) }
|
17
19
|
rule(:text) { (escaped | non_escaped).repeat(1).as(:text) }
|
18
20
|
|
@@ -24,37 +26,31 @@ class MarkupParser < Parslet::Parser
|
|
24
26
|
rule(:empty_box) { str('||').as(:empty_box) }
|
25
27
|
rule(:hatched_circle) { str('{/}').as(:hatched_circle) }
|
26
28
|
rule(:hatched_box) { str('|/|').as(:hatched_box) }
|
27
|
-
rule(:circle) { str('{') >> (text|decoration).as(:circle) >> str('}')}
|
28
|
-
rule(:box) { str('|') >> (text|decoration).as(:box) >> str('|')}
|
29
|
+
rule(:circle) { str('{') >> (text | decoration).as(:circle) >> str('}') }
|
30
|
+
rule(:box) { str('|') >> (text | decoration).as(:box) >> str('|') }
|
29
31
|
|
30
|
-
rule(:bolditalic) { str('***') >> (text|decoration).as(:bolditalic) >> str('***')}
|
31
|
-
rule(:bold) { str('**') >> (text|decoration).as(:bold) >> str('**')}
|
32
|
-
rule(:italic) { str('*') >> (text|decoration).as(:italic) >> str('*')}
|
32
|
+
rule(:bolditalic) { str('***') >> (text | decoration).as(:bolditalic) >> str('***') }
|
33
|
+
rule(:bold) { str('**') >> (text | decoration).as(:bold) >> str('**') }
|
34
|
+
rule(:italic) { str('*') >> (text | decoration).as(:italic) >> str('*') }
|
33
35
|
|
34
|
-
rule(:bstroke) { str('*') >> shape.as(:bstroke) >> str('*')}
|
36
|
+
rule(:bstroke) { str('*') >> shape.as(:bstroke) >> str('*') }
|
35
37
|
|
36
|
-
rule(:overline) { str('=') >> (text|decoration).as(:overline) >> str('=')}
|
37
|
-
rule(:underline) { str('-') >> (text|decoration).as(:underline) >> str('-')}
|
38
|
-
rule(:linethrough) { str('~') >> (text|decoration).as(:linethrough) >> str('~')}
|
38
|
+
rule(:overline) { str('=') >> (text | decoration).as(:overline) >> str('=') }
|
39
|
+
rule(:underline) { str('-') >> (text | decoration).as(:underline) >> str('-') }
|
40
|
+
rule(:linethrough) { str('~') >> (text | decoration).as(:linethrough) >> str('~') }
|
39
41
|
|
40
|
-
rule(:small) { str('___') >> (text|decoration|shape).as(:small) >> str('___')}
|
41
|
-
rule(:superscript) { str('__') >> (text|decoration|shape).as(:superscript) >> str('__')}
|
42
|
-
rule(:subscript) { str('_') >> (text|decoration|shape).as(:subscript) >> str('_')}
|
42
|
+
rule(:small) { str('___') >> (text | decoration | shape).as(:small) >> str('___') }
|
43
|
+
rule(:superscript) { str('__') >> (text | decoration | shape).as(:superscript) >> str('__') }
|
44
|
+
rule(:subscript) { str('_') >> (text | decoration | shape).as(:subscript) >> str('_') }
|
43
45
|
|
44
|
-
rule(:decoration) {(bolditalic | bold | italic | small | superscript | subscript |
|
45
|
-
overline | underline | linethrough) }
|
46
|
+
rule(:decoration) { (bolditalic | bold | italic | small | superscript | subscript | overline | underline | linethrough) }
|
46
47
|
|
47
|
-
rule(:shape) {(hatched_circle | hatched_box | empty_circle | empty_box |
|
48
|
-
horizontal_bar | arrow_both | arrow_to_l | arrow_to_r |
|
49
|
-
circle | box ) }
|
48
|
+
rule(:shape) { (hatched_circle | hatched_box | empty_circle | empty_box | horizontal_bar | arrow_both | arrow_to_l | arrow_to_r | circle | box) }
|
50
49
|
|
51
|
-
rule(:markup) {(text | decoration | shape | bstroke)}
|
50
|
+
rule(:markup) { (text | decoration | shape | bstroke) }
|
52
51
|
|
53
|
-
rule(:line) { (
|
54
|
-
rule(:lines) { triangle.maybe.as(:triangle) >>
|
55
|
-
(brectangle | rectangle | brackets).maybe.as(:enclosure) >>
|
56
|
-
line.repeat(1) >>
|
57
|
-
path.repeat(0).as(:paths) >> (cr | eof) }
|
52
|
+
rule(:line) { (cr.as(:extracr) | border | bborder | markup.repeat(1).as(:line) >> (cr | eof | str('+').present?)) }
|
53
|
+
rule(:lines) { triangle.maybe.as(:triangle) >> (brectangle | rectangle | brackets).maybe.as(:enclosure) >> line.repeat(1) >> path.repeat(0).as(:paths) >> (cr | eof) }
|
58
54
|
root :lines
|
59
55
|
end
|
60
56
|
|
@@ -62,107 +58,106 @@ module Markup
|
|
62
58
|
@parser = MarkupParser.new
|
63
59
|
|
64
60
|
@evaluator = Parslet::Transform.new do
|
65
|
-
rule(:
|
66
|
-
rule(:
|
61
|
+
rule(chr: simple(:chr)) { chr.to_s }
|
62
|
+
rule(text: sequence(:text)) { { text: text.join(""), decoration: [] } }
|
67
63
|
|
68
|
-
rule(:
|
69
|
-
{:
|
64
|
+
rule(horizontal_bar: subtree(:empty)) {
|
65
|
+
{ text: +" ", decoration: [:bar] }
|
70
66
|
}
|
71
|
-
rule(:
|
72
|
-
{:
|
67
|
+
rule(arrow_both: subtree(:empty)) {
|
68
|
+
{ text: +" ", decoration: [:bar, :arrow_to_l, :arrow_to_r] }
|
73
69
|
}
|
74
|
-
rule(:
|
75
|
-
{:
|
70
|
+
rule(arrow_to_l: subtree(:empty)) {
|
71
|
+
{ text: +" ", decoration: [:bar, :arrow_to_l] }
|
76
72
|
}
|
77
|
-
rule(:
|
78
|
-
{:
|
73
|
+
rule(arrow_to_r: subtree(:empty)) {
|
74
|
+
{ text: +" ", decoration: [:bar, :arrow_to_r] }
|
79
75
|
}
|
80
76
|
|
81
|
-
rule(:
|
82
|
-
{:
|
77
|
+
rule(empty_circle: subtree(:empty)) {
|
78
|
+
{ text: +" ", decoration: [:circle] }
|
83
79
|
}
|
84
|
-
rule(:
|
85
|
-
{:
|
80
|
+
rule(empty_box: subtree(:empty)) {
|
81
|
+
{ text: +" ", decoration: [:box] }
|
86
82
|
}
|
87
|
-
rule(:
|
88
|
-
{:
|
83
|
+
rule(hatched_circle: subtree(:empty)) {
|
84
|
+
{ text: +" ", decoration: [:hatched, :circle] }
|
89
85
|
}
|
90
|
-
rule(:
|
91
|
-
{:
|
86
|
+
rule(hatched_box: subtree(:empty)) {
|
87
|
+
{ text: +" ", decoration: [:hatched, :box] }
|
92
88
|
}
|
93
89
|
|
94
|
-
rule(:
|
90
|
+
rule(bolditalic: subtree(:text)) {
|
95
91
|
text[:decoration] << :bolditalic; text
|
96
92
|
}
|
97
|
-
rule(:
|
93
|
+
rule(bold: subtree(:text)) {
|
98
94
|
text[:decoration] << :bold; text
|
99
95
|
}
|
100
|
-
rule(:
|
96
|
+
rule(italic: subtree(:text)) {
|
101
97
|
text[:decoration] << :italic; text
|
102
98
|
}
|
103
99
|
|
104
|
-
rule(:
|
100
|
+
rule(bstroke: subtree(:box)) {
|
105
101
|
box[:decoration] << :bstroke; box
|
106
102
|
}
|
107
|
-
rule(:
|
103
|
+
rule(bstroke: subtree(:circle)) {
|
108
104
|
circle[:decoration] << :bstroke; circle
|
109
105
|
}
|
110
|
-
rule(:
|
106
|
+
rule(bstroke: subtree(:horizontal_bar)) {
|
111
107
|
horizontal_bar[:decoration] << :bstroke; horizontal_bar
|
112
108
|
}
|
113
|
-
rule(:
|
109
|
+
rule(bstroke: subtree(:empty_circle)) {
|
114
110
|
empty_circle[:decoration] << :bstroke; empty_circle
|
115
111
|
}
|
116
|
-
rule(:
|
112
|
+
rule(bstroke: subtree(:empty_box)) {
|
117
113
|
empty_box[:decoration] << :bstroke; empty_box
|
118
114
|
}
|
119
|
-
rule(:
|
115
|
+
rule(bstroke: subtree(:hatched_circle)) {
|
120
116
|
hatched_circle[:decoration] << :bstroke; hatched_circle
|
121
117
|
}
|
122
|
-
rule(:
|
118
|
+
rule(bstroke: subtree(:hatched_box)) {
|
123
119
|
hatched_box[:decoration] << :bstroke; hatched_box
|
124
120
|
}
|
125
121
|
|
126
|
-
rule(:
|
122
|
+
rule(overline: subtree(:text)) {
|
127
123
|
text[:decoration] << :overline; text
|
128
124
|
}
|
129
|
-
rule(:
|
125
|
+
rule(underline: subtree(:text)) {
|
130
126
|
text[:decoration] << :underline; text
|
131
127
|
}
|
132
|
-
rule(:
|
128
|
+
rule(linethrough: subtree(:text)) {
|
133
129
|
text[:decoration] << :linethrough; text
|
134
130
|
}
|
135
|
-
rule(:
|
131
|
+
rule(subscript: subtree(:text)) {
|
136
132
|
text[:decoration] << :subscript; text
|
137
133
|
}
|
138
|
-
rule(:
|
134
|
+
rule(superscript: subtree(:text)) {
|
139
135
|
text[:decoration] << :superscript; text
|
140
136
|
}
|
141
|
-
rule(:
|
137
|
+
rule(small: subtree(:text)) {
|
142
138
|
text[:decoration] << :small; text
|
143
139
|
}
|
144
|
-
rule(:
|
140
|
+
rule(box: subtree(:text)) {
|
145
141
|
text[:decoration] << :box; text
|
146
142
|
}
|
147
|
-
rule(:
|
143
|
+
rule(circle: subtree(:text)) {
|
148
144
|
text[:decoration] << :circle; text
|
149
145
|
}
|
150
|
-
rule(:
|
146
|
+
rule(math: subtree(:text)) {
|
151
147
|
text[:decoration] << :math; text
|
152
148
|
}
|
153
|
-
rule(:
|
154
|
-
{:
|
149
|
+
rule(border: simple(:border)) {
|
150
|
+
{ type: :border }
|
155
151
|
}
|
156
|
-
rule(:
|
157
|
-
{:
|
152
|
+
rule(bborder: simple(:bborder)) {
|
153
|
+
{ type: :bborder }
|
158
154
|
}
|
159
|
-
rule(:
|
160
|
-
{:
|
155
|
+
rule(line: subtree(:line)) {
|
156
|
+
{ type: :text, elements: line }
|
161
157
|
}
|
162
|
-
rule(:
|
163
|
-
{:
|
158
|
+
rule(extracr: subtree(:extracr)) {
|
159
|
+
{ type: :text, elements: [{ text: +" ", decoration: [] }] }
|
164
160
|
}
|
165
|
-
|
166
161
|
end
|
167
162
|
|
168
163
|
def parse(txt)
|
@@ -170,36 +165,30 @@ module Markup
|
|
170
165
|
parsed = @parser.parse(txt)
|
171
166
|
rescue Parslet::ParseFailed
|
172
167
|
# puts e.parse_failure_cause.ascii_tree
|
173
|
-
return {:
|
168
|
+
return { status: :error, text: txt }
|
174
169
|
end
|
175
170
|
|
176
171
|
applied = @evaluator.apply(parsed)
|
177
172
|
|
178
|
-
results = {:
|
173
|
+
results = { enclosure: :none, triangle: false, paths: [], contents: [] }
|
179
174
|
applied.each do |h|
|
180
175
|
if h[:enclosure]
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
if h[:triangle]
|
192
|
-
results[:triangle] = h[:triangle].to_s == '^' ? true : false
|
193
|
-
end
|
194
|
-
if h[:paths]
|
195
|
-
results[:paths] = h[:paths]
|
196
|
-
end
|
197
|
-
if h[:type] == :text || h[:type] == :border || h[:type] == :bborder
|
198
|
-
results[:contents] << h
|
176
|
+
results[:enclosure] = case h[:enclosure].to_s
|
177
|
+
when '###'
|
178
|
+
:brectangle
|
179
|
+
when '##'
|
180
|
+
:rectangle
|
181
|
+
when '#'
|
182
|
+
:brackets
|
183
|
+
else
|
184
|
+
:none
|
185
|
+
end
|
199
186
|
end
|
187
|
+
results[:triangle] = h[:triangle].to_s == '^'
|
188
|
+
results[:paths] = h[:paths] if h[:paths]
|
189
|
+
results[:contents] << h if h[:type] == :text || h[:type] == :border || h[:type] == :bborder
|
200
190
|
end
|
201
|
-
|
202
|
-
result
|
191
|
+
{ status: :success, results: results }
|
203
192
|
end
|
204
193
|
|
205
194
|
module_function :parse
|