zenml 1.1.0 → 1.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/source/zenml.rb +1 -1
- data/source/zenml/parser.rb +53 -53
- data/source/zenml/parser_utility.rb +4 -1
- metadata +2 -3
- data/source/zenml/old_parser.rb +0 -550
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bed76e79eaf3831d8c59b24e1a00533a03c3ee3213eb2f20dd94c8d8a709a84b
|
4
|
+
data.tar.gz: 0aa6f8c5b618d09409dd0003dadf1cc73b1f486480202283b7120023ea5311fa
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f4ddeef015698ad21610239840155a04266406adca2491f8f4d741f01275212fd60102c7356315defe57767112ccceae84d46b42ac40c258d8971d593c144af5
|
7
|
+
data.tar.gz: 8ce58dd4255cb435d4da9c95621c6fa34349d79cb8581648ba0b428234955d0081f614d09ded5cf3942474c59b02d436f1c93d19dc76e9baa689d956173ee12e
|
data/source/zenml.rb
CHANGED
data/source/zenml/parser.rb
CHANGED
@@ -49,8 +49,8 @@ module ZenithalParserMethod
|
|
49
49
|
def parse_document
|
50
50
|
parser = Parser.build(self) do
|
51
51
|
document = Document.new
|
52
|
-
children =
|
53
|
-
|
52
|
+
children = +parse_nodes(false)
|
53
|
+
+parse_eof
|
54
54
|
children.each do |child|
|
55
55
|
document.add(child)
|
56
56
|
end
|
@@ -69,7 +69,7 @@ module ZenithalParserMethod
|
|
69
69
|
end
|
70
70
|
end
|
71
71
|
nodes = Nodes[]
|
72
|
-
raw_nodes =
|
72
|
+
raw_nodes = +parsers.inject(:|).many
|
73
73
|
raw_nodes.each do |raw_node|
|
74
74
|
nodes << raw_node
|
75
75
|
end
|
@@ -80,13 +80,13 @@ module ZenithalParserMethod
|
|
80
80
|
|
81
81
|
def parse_element
|
82
82
|
parser = Parser.build(self) do
|
83
|
-
start_char =
|
84
|
-
name =
|
85
|
-
marks =
|
86
|
-
attributes =
|
87
|
-
children_list =
|
83
|
+
start_char = +parse_char_any([ELEMENT_START, MACRO_START])
|
84
|
+
name = +parse_identifier
|
85
|
+
marks = +parse_marks
|
86
|
+
attributes = +parse_attributes.maybe || {}
|
87
|
+
children_list = +parse_children_list(marks.include?(:verbal))
|
88
88
|
if name == SYSTEM_INSTRUCTION_NAME
|
89
|
-
|
89
|
+
+parse_space
|
90
90
|
end
|
91
91
|
if start_char == MACRO_START
|
92
92
|
marks.push(:macro)
|
@@ -99,11 +99,11 @@ module ZenithalParserMethod
|
|
99
99
|
def parse_special_element(kind)
|
100
100
|
parser = Parser.build(self) do
|
101
101
|
unless @special_element_names[kind]
|
102
|
-
|
102
|
+
+parse_none
|
103
103
|
end
|
104
|
-
|
105
|
-
children =
|
106
|
-
|
104
|
+
+parse_char(SPECIAL_ELEMENT_STARTS[kind])
|
105
|
+
children = +parse_nodes(false)
|
106
|
+
+parse_char(SPECIAL_ELEMENT_ENDS[kind])
|
107
107
|
next create_nodes(@special_element_names[kind], [], {}, [children])
|
108
108
|
end
|
109
109
|
return parser
|
@@ -122,11 +122,11 @@ module ZenithalParserMethod
|
|
122
122
|
|
123
123
|
def parse_attributes
|
124
124
|
parser = Parser.build(self) do
|
125
|
-
|
126
|
-
first_attribute =
|
127
|
-
rest_attribtues =
|
125
|
+
+parse_char(ATTRIBUTE_START)
|
126
|
+
first_attribute = +parse_attribute(false)
|
127
|
+
rest_attribtues = +parse_attribute(true).many
|
128
128
|
attributes = first_attribute.merge(*rest_attribtues)
|
129
|
-
|
129
|
+
+parse_char(ATTRIBUTE_END)
|
130
130
|
next attributes
|
131
131
|
end
|
132
132
|
return parser
|
@@ -134,12 +134,12 @@ module ZenithalParserMethod
|
|
134
134
|
|
135
135
|
def parse_attribute(comma)
|
136
136
|
parser = Parser.build(self) do
|
137
|
-
|
138
|
-
|
139
|
-
name =
|
140
|
-
|
141
|
-
value =
|
142
|
-
|
137
|
+
+parse_char(ATTRIBUTE_SEPARATOR) if comma
|
138
|
+
+parse_space
|
139
|
+
name = +parse_identifier
|
140
|
+
+parse_space
|
141
|
+
value = +parse_attribute_value.maybe || name
|
142
|
+
+parse_space
|
143
143
|
next {name => value}
|
144
144
|
end
|
145
145
|
return parser
|
@@ -147,9 +147,9 @@ module ZenithalParserMethod
|
|
147
147
|
|
148
148
|
def parse_attribute_value
|
149
149
|
parser = Parser.build(self) do
|
150
|
-
|
151
|
-
|
152
|
-
value =
|
150
|
+
+parse_char(ATTRIBUTE_EQUAL)
|
151
|
+
+parse_space
|
152
|
+
value = +parse_quoted_string
|
153
153
|
next value
|
154
154
|
end
|
155
155
|
return parser
|
@@ -157,9 +157,9 @@ module ZenithalParserMethod
|
|
157
157
|
|
158
158
|
def parse_quoted_string
|
159
159
|
parser = Parser.build(self) do
|
160
|
-
|
161
|
-
texts =
|
162
|
-
|
160
|
+
+parse_char(ATTRIBUTE_VALUE_START)
|
161
|
+
texts = +(parse_quoted_string_plain | parse_escape).many
|
162
|
+
+parse_char(ATTRIBUTE_VALUE_END)
|
163
163
|
next texts.join
|
164
164
|
end
|
165
165
|
return parser
|
@@ -167,7 +167,7 @@ module ZenithalParserMethod
|
|
167
167
|
|
168
168
|
def parse_quoted_string_plain
|
169
169
|
parser = Parser.build(self) do
|
170
|
-
chars =
|
170
|
+
chars = +parse_char_out([ATTRIBUTE_VALUE_END, ESCAPE_START]).many(1)
|
171
171
|
next chars.join
|
172
172
|
end
|
173
173
|
return parser
|
@@ -175,8 +175,8 @@ module ZenithalParserMethod
|
|
175
175
|
|
176
176
|
def parse_children_list(verbal)
|
177
177
|
parser = Parser.build(self) do
|
178
|
-
first_children =
|
179
|
-
rest_children_list =
|
178
|
+
first_children = +(parse_empty_children | parse_children(verbal))
|
179
|
+
rest_children_list = +parse_children(verbal).many
|
180
180
|
children_list = [first_children] + rest_children_list
|
181
181
|
next children_list
|
182
182
|
end
|
@@ -185,9 +185,9 @@ module ZenithalParserMethod
|
|
185
185
|
|
186
186
|
def parse_children(verbal)
|
187
187
|
parser = Parser.build(self) do
|
188
|
-
|
189
|
-
children =
|
190
|
-
|
188
|
+
+parse_char(CONTENT_START)
|
189
|
+
children = +parse_nodes(verbal)
|
190
|
+
+parse_char(CONTENT_END)
|
191
191
|
next children
|
192
192
|
end
|
193
193
|
return parser
|
@@ -195,7 +195,7 @@ module ZenithalParserMethod
|
|
195
195
|
|
196
196
|
def parse_empty_children
|
197
197
|
parser = Parser.build(self) do
|
198
|
-
|
198
|
+
+parse_char(CONTENT_END)
|
199
199
|
next Nodes[]
|
200
200
|
end
|
201
201
|
return parser
|
@@ -203,7 +203,7 @@ module ZenithalParserMethod
|
|
203
203
|
|
204
204
|
def parse_text(verbal)
|
205
205
|
parser = Parser.build(self) do
|
206
|
-
texts =
|
206
|
+
texts = +(parse_text_plain(verbal) | parse_escape).many(1)
|
207
207
|
next Text.new(texts.join, true, nil, false)
|
208
208
|
end
|
209
209
|
return parser
|
@@ -218,7 +218,7 @@ module ZenithalParserMethod
|
|
218
218
|
out_chars.push(SPECIAL_ELEMENT_STARTS[kind], SPECIAL_ELEMENT_ENDS[kind]) if name
|
219
219
|
end
|
220
220
|
end
|
221
|
-
chars =
|
221
|
+
chars = +parse_char_out(out_chars).many(1)
|
222
222
|
next chars.join
|
223
223
|
end
|
224
224
|
return parser
|
@@ -226,9 +226,9 @@ module ZenithalParserMethod
|
|
226
226
|
|
227
227
|
def parse_line_comment
|
228
228
|
parser = Parser.build(self) do
|
229
|
-
|
230
|
-
|
231
|
-
content =
|
229
|
+
+parse_char(COMMENT_DELIMITER)
|
230
|
+
+parse_char(COMMENT_DELIMITER)
|
231
|
+
content = +parse_line_comment_content
|
232
232
|
next Comment.new(" " + content.strip + " ")
|
233
233
|
end
|
234
234
|
return parser
|
@@ -236,8 +236,8 @@ module ZenithalParserMethod
|
|
236
236
|
|
237
237
|
def parse_line_comment_content
|
238
238
|
parser = Parser.build(self) do
|
239
|
-
chars =
|
240
|
-
|
239
|
+
chars = +parse_char_out(["\n"]).many
|
240
|
+
+parse_char("\n")
|
241
241
|
next chars.join
|
242
242
|
end
|
243
243
|
return parser
|
@@ -245,11 +245,11 @@ module ZenithalParserMethod
|
|
245
245
|
|
246
246
|
def parse_block_comment
|
247
247
|
parser = Parser.build(self) do
|
248
|
-
|
249
|
-
|
250
|
-
content =
|
251
|
-
|
252
|
-
|
248
|
+
+parse_char(COMMENT_DELIMITER)
|
249
|
+
+parse_char(CONTENT_START)
|
250
|
+
content = +parse_block_comment_content
|
251
|
+
+parse_char(CONTENT_END)
|
252
|
+
+parse_char(COMMENT_DELIMITER)
|
253
253
|
next Comment.new(" " + content.strip + " ")
|
254
254
|
end
|
255
255
|
return parser
|
@@ -257,7 +257,7 @@ module ZenithalParserMethod
|
|
257
257
|
|
258
258
|
def parse_block_comment_content
|
259
259
|
parser = Parser.build(self) do
|
260
|
-
chars =
|
260
|
+
chars = +parse_char_out([CONTENT_END]).many
|
261
261
|
next chars.join
|
262
262
|
end
|
263
263
|
return parser
|
@@ -265,8 +265,8 @@ module ZenithalParserMethod
|
|
265
265
|
|
266
266
|
def parse_escape
|
267
267
|
parser = Parser.build(self) do
|
268
|
-
|
269
|
-
char =
|
268
|
+
+parse_char(ESCAPE_START)
|
269
|
+
char = +parse_char_any(ESCAPE_CHARS)
|
270
270
|
next char
|
271
271
|
end
|
272
272
|
return parser
|
@@ -274,8 +274,8 @@ module ZenithalParserMethod
|
|
274
274
|
|
275
275
|
def parse_identifier
|
276
276
|
parser = Parser.build(self) do
|
277
|
-
first_char =
|
278
|
-
rest_chars =
|
277
|
+
first_char = +parse_first_identifier_char
|
278
|
+
rest_chars = +parse_middle_identifier_char.many
|
279
279
|
identifier = first_char + rest_chars.join
|
280
280
|
next identifier
|
281
281
|
end
|
@@ -29,7 +29,7 @@ class Parser
|
|
29
29
|
return @builder.instance_eval(&@method)
|
30
30
|
end
|
31
31
|
|
32
|
-
def
|
32
|
+
def exec_get
|
33
33
|
result = self.exec
|
34
34
|
if result.success?
|
35
35
|
return result.value
|
@@ -38,6 +38,9 @@ class Parser
|
|
38
38
|
end
|
39
39
|
end
|
40
40
|
|
41
|
+
alias -@ exec
|
42
|
+
alias +@ exec_get
|
43
|
+
|
41
44
|
def |(other)
|
42
45
|
this = self
|
43
46
|
if this.builder.equal?(other.builder)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: zenml
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.1.
|
4
|
+
version: 1.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ziphil
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-10-01 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: |
|
14
14
|
This gem serves a tool for parsing a document written in ZenML, an alternative new syntax for XML, to an XML node tree.
|
@@ -22,7 +22,6 @@ files:
|
|
22
22
|
- source/zenml.rb
|
23
23
|
- source/zenml/converter.rb
|
24
24
|
- source/zenml/error.rb
|
25
|
-
- source/zenml/old_parser.rb
|
26
25
|
- source/zenml/parser.rb
|
27
26
|
- source/zenml/parser_utility.rb
|
28
27
|
- source/zenml/reader.rb
|
data/source/zenml/old_parser.rb
DELETED
@@ -1,550 +0,0 @@
|
|
1
|
-
# coding: utf-8
|
2
|
-
|
3
|
-
|
4
|
-
require 'pp'
|
5
|
-
require 'rexml/document'
|
6
|
-
include REXML
|
7
|
-
|
8
|
-
|
9
|
-
class ZenithalOldParser
|
10
|
-
|
11
|
-
TAG_START = "\\"
|
12
|
-
MACRO_START = "&"
|
13
|
-
ESCAPE_START = "`"
|
14
|
-
ATTRIBUTE_START = "|"
|
15
|
-
ATTRIBUTE_END = "|"
|
16
|
-
ATTRIBUTE_EQUAL = "="
|
17
|
-
ATTRIBUTE_VALUE_START = "\""
|
18
|
-
ATTRIBUTE_VALUE_END = "\""
|
19
|
-
ATTRIBUTE_SEPARATOR = ","
|
20
|
-
CONTENT_START = "<"
|
21
|
-
CONTENT_END = ">"
|
22
|
-
BRACE_START = "{"
|
23
|
-
BRACE_END = "}"
|
24
|
-
BRACKET_START = "["
|
25
|
-
BRACKET_END = "]"
|
26
|
-
SLASH_START = "/"
|
27
|
-
SLASH_END = "/"
|
28
|
-
COMMENT_DELIMITER = "#"
|
29
|
-
INSTRUCTION_MARK = "?"
|
30
|
-
TRIM_MARK = "*"
|
31
|
-
VERBAL_MARK = "~"
|
32
|
-
MULTIPLE_MARK = "+"
|
33
|
-
SYSTEM_INSTRUCTION_NAME = "zml"
|
34
|
-
ENTITIES = {"amp" => "&", "lt" => "<", "gt" => ">", "apos" => "'", "quot" => "\"",
|
35
|
-
"lcub" => "{", "rcub" => "}", "lbrace" => "{", "rbrace" => "}", "lsqb" => "[", "rsqb" => "]", "lbrack" => "[", "rbrack" => "]",
|
36
|
-
"sol" => "/", "bsol" => "\\", "verbar" => "|", "vert" => "|", "grave" => "`", "num" => "#"}
|
37
|
-
ESCAPES = ["&", "<", ">", "'", "\"", "{", "}", "[", "]", "/", "\\", "|", "`", "#"]
|
38
|
-
VALID_START_CHARS = [0x3A, 0x41..0x5A, 0x5F, 0x61..0x7A, 0xC0..0xD6, 0xD8..0xF6, 0xF8..0x2FF, 0x370..0x37D, 0x37F..0x1FFF, 0x200C..0x200D,
|
39
|
-
0x2070..0x218F, 0x2C00..0x2FEF, 0x3001..0xD7FF, 0xF900..0xFDCF, 0xFDF0..0xFFFD, 0x10000..0xEFFFF]
|
40
|
-
VALID_MIDDLE_CHARS = [0x2D, 0x2E, 0x30..0x39, 0xB7, 0x0300..0x036F, 0x203F..0x2040]
|
41
|
-
|
42
|
-
attr_writer :brace_name
|
43
|
-
attr_writer :bracket_name
|
44
|
-
attr_writer :slash_name
|
45
|
-
|
46
|
-
def initialize(source)
|
47
|
-
@source = StringReader.new(source)
|
48
|
-
@version = nil
|
49
|
-
@brace_name = nil
|
50
|
-
@bracket_name = nil
|
51
|
-
@slash_name = nil
|
52
|
-
@macros = {}
|
53
|
-
end
|
54
|
-
|
55
|
-
def parse
|
56
|
-
document = Document.new
|
57
|
-
children = parse_nodes
|
58
|
-
children.each do |child|
|
59
|
-
document.add(child)
|
60
|
-
end
|
61
|
-
return document
|
62
|
-
end
|
63
|
-
|
64
|
-
def parse_nodes(option = {}, in_slash = false)
|
65
|
-
children = []
|
66
|
-
while char = @source.read
|
67
|
-
if char == TAG_START || char == MACRO_START
|
68
|
-
@source.unread
|
69
|
-
children.concat(parse_element)
|
70
|
-
elsif @brace_name && char == BRACE_START
|
71
|
-
@source.unread
|
72
|
-
children << parse_brace
|
73
|
-
elsif @bracket_name && char == BRACKET_START
|
74
|
-
@source.unread
|
75
|
-
children << parse_bracket
|
76
|
-
elsif @slash_name && !in_slash && char == SLASH_START
|
77
|
-
@source.unread
|
78
|
-
children << parse_slash
|
79
|
-
elsif char == COMMENT_DELIMITER
|
80
|
-
@source.unread
|
81
|
-
children << parse_comment
|
82
|
-
elsif char == CONTENT_END || (@brace_name && char == BRACE_END) || (@bracket_name && char == BRACKET_END) || (@slash_name && char == SLASH_END)
|
83
|
-
@source.unread
|
84
|
-
break
|
85
|
-
else
|
86
|
-
@source.unread
|
87
|
-
children << parse_text(option)
|
88
|
-
end
|
89
|
-
end
|
90
|
-
return children
|
91
|
-
end
|
92
|
-
|
93
|
-
def parse_verbal_nodes(option = {})
|
94
|
-
children = []
|
95
|
-
while char = @source.read
|
96
|
-
next_char = @source.peek
|
97
|
-
if char == CONTENT_END
|
98
|
-
@source.unread
|
99
|
-
break
|
100
|
-
else
|
101
|
-
@source.unread
|
102
|
-
children << parse_verbal_text(option)
|
103
|
-
end
|
104
|
-
end
|
105
|
-
return children
|
106
|
-
end
|
107
|
-
|
108
|
-
def parse_element
|
109
|
-
first_char = @source.read
|
110
|
-
unless first_char == TAG_START || first_char == MACRO_START
|
111
|
-
raise ZenithalParseError.new(@source)
|
112
|
-
end
|
113
|
-
name, option = parse_element_name
|
114
|
-
if first_char == MACRO_START
|
115
|
-
option[:macro] = true
|
116
|
-
end
|
117
|
-
attributes = parse_attributes
|
118
|
-
children_list = parse_children_list(option)
|
119
|
-
nodes = create_nodes(name, attributes, children_list, option)
|
120
|
-
return nodes
|
121
|
-
end
|
122
|
-
|
123
|
-
def parse_element_name
|
124
|
-
name, marks, option = "", [], {}
|
125
|
-
while char = @source.read
|
126
|
-
if char == ATTRIBUTE_START || char == CONTENT_START || char == CONTENT_END || char =~ /\s/
|
127
|
-
@source.unread
|
128
|
-
break
|
129
|
-
elsif char == INSTRUCTION_MARK || char == TRIM_MARK || char == VERBAL_MARK || char == MULTIPLE_MARK
|
130
|
-
marks << char
|
131
|
-
elsif name.empty? && marks.empty? && ZenithalOldParser.valid_start_char?(char)
|
132
|
-
name << char
|
133
|
-
elsif !name.empty? && marks.empty? && ZenithalOldParser.valid_char?(char)
|
134
|
-
name << char
|
135
|
-
else
|
136
|
-
raise ZenithalParseError.new(@source)
|
137
|
-
end
|
138
|
-
end
|
139
|
-
skip_spaces
|
140
|
-
if marks.include?(INSTRUCTION_MARK)
|
141
|
-
option[:instruction] = true
|
142
|
-
end
|
143
|
-
if marks.include?(TRIM_MARK)
|
144
|
-
option[:trim_indents] = true
|
145
|
-
end
|
146
|
-
if marks.include?(VERBAL_MARK)
|
147
|
-
option[:verbal] = true
|
148
|
-
end
|
149
|
-
if marks.include?(MULTIPLE_MARK)
|
150
|
-
option[:multiple] = true
|
151
|
-
end
|
152
|
-
return name, option
|
153
|
-
end
|
154
|
-
|
155
|
-
def parse_attributes
|
156
|
-
attributes = {}
|
157
|
-
if @source.read == ATTRIBUTE_START
|
158
|
-
current_key = nil
|
159
|
-
skip_spaces
|
160
|
-
loop do
|
161
|
-
key, value = parse_attribute
|
162
|
-
attributes[key] = value
|
163
|
-
char = @source.read
|
164
|
-
if char == ATTRIBUTE_SEPARATOR
|
165
|
-
skip_spaces
|
166
|
-
elsif char == ATTRIBUTE_END
|
167
|
-
@source.unread
|
168
|
-
break
|
169
|
-
else
|
170
|
-
raise ZenithalParseError.new(@source)
|
171
|
-
end
|
172
|
-
end
|
173
|
-
unless @source.read == ATTRIBUTE_END
|
174
|
-
raise ZenithalParseError.new(@source)
|
175
|
-
end
|
176
|
-
else
|
177
|
-
@source.unread
|
178
|
-
end
|
179
|
-
return attributes
|
180
|
-
end
|
181
|
-
|
182
|
-
def parse_attribute
|
183
|
-
key = parse_attribute_key
|
184
|
-
skip_spaces
|
185
|
-
if @source.read == ATTRIBUTE_EQUAL
|
186
|
-
skip_spaces
|
187
|
-
value = parse_attribute_value
|
188
|
-
else
|
189
|
-
@source.unread
|
190
|
-
value = key
|
191
|
-
end
|
192
|
-
skip_spaces
|
193
|
-
return key, value
|
194
|
-
end
|
195
|
-
|
196
|
-
def parse_attribute_key
|
197
|
-
key = ""
|
198
|
-
while char = @source.read
|
199
|
-
if char == ATTRIBUTE_EQUAL || char == ATTRIBUTE_END || char =~ /\s/
|
200
|
-
@source.unread
|
201
|
-
break
|
202
|
-
elsif key.empty? && ZenithalOldParser.valid_start_char?(char)
|
203
|
-
key << char
|
204
|
-
elsif !key.empty? && ZenithalOldParser.valid_char?(char)
|
205
|
-
key << char
|
206
|
-
else
|
207
|
-
raise ZenithalParseError.new(@source)
|
208
|
-
end
|
209
|
-
end
|
210
|
-
return key
|
211
|
-
end
|
212
|
-
|
213
|
-
def parse_attribute_value
|
214
|
-
unless @source.read == ATTRIBUTE_VALUE_START
|
215
|
-
raise ZenithalParseError.new(@source)
|
216
|
-
end
|
217
|
-
value = ""
|
218
|
-
while char = @source.read
|
219
|
-
next_char = @source.peek
|
220
|
-
if char == ATTRIBUTE_VALUE_END
|
221
|
-
break
|
222
|
-
elsif char == ESCAPE_START && ESCAPES.include?(next_char)
|
223
|
-
@source.unread
|
224
|
-
value << parse_escape_string
|
225
|
-
else
|
226
|
-
value << char
|
227
|
-
end
|
228
|
-
end
|
229
|
-
return value
|
230
|
-
end
|
231
|
-
|
232
|
-
def parse_children_list(option = {})
|
233
|
-
children_list = []
|
234
|
-
first_char = @source.read
|
235
|
-
if first_char == CONTENT_START
|
236
|
-
loop do
|
237
|
-
children = []
|
238
|
-
if option[:verbal] || option[:instruction]
|
239
|
-
children = parse_verbal_nodes(option)
|
240
|
-
else
|
241
|
-
children = parse_nodes(option)
|
242
|
-
end
|
243
|
-
if option[:trim_indents]
|
244
|
-
trim_indents(children)
|
245
|
-
end
|
246
|
-
children_list << children
|
247
|
-
unless @source.read == CONTENT_END
|
248
|
-
raise ZenithalParseError.new(@source)
|
249
|
-
end
|
250
|
-
space_count = skip_spaces
|
251
|
-
unless @source.read == CONTENT_START
|
252
|
-
@source.unread(space_count + 1)
|
253
|
-
break
|
254
|
-
end
|
255
|
-
end
|
256
|
-
elsif first_char == CONTENT_END
|
257
|
-
children_list << []
|
258
|
-
else
|
259
|
-
raise ZenithalParseError.new(@source)
|
260
|
-
end
|
261
|
-
return children_list
|
262
|
-
end
|
263
|
-
|
264
|
-
def create_nodes(name, attributes, children_list, option = {})
|
265
|
-
nodes = []
|
266
|
-
unless option[:macro]
|
267
|
-
if option[:instruction]
|
268
|
-
unless children_list.size <= 1
|
269
|
-
raise ZenithalParseError.new(@source)
|
270
|
-
end
|
271
|
-
nodes = create_instructions(name, attributes, children_list.first)
|
272
|
-
if name == SYSTEM_INSTRUCTION_NAME
|
273
|
-
skip_spaces
|
274
|
-
end
|
275
|
-
else
|
276
|
-
unless option[:multiple] || children_list.size <= 1
|
277
|
-
raise ZenithalParseError.new(@source)
|
278
|
-
end
|
279
|
-
nodes = create_elements(name, attributes, children_list)
|
280
|
-
end
|
281
|
-
else
|
282
|
-
nodes = process_macro(name, attributes, children_list)
|
283
|
-
end
|
284
|
-
return nodes
|
285
|
-
end
|
286
|
-
|
287
|
-
def create_elements(name, attributes, children_list)
|
288
|
-
elements = []
|
289
|
-
children_list.each do |children|
|
290
|
-
element = Element.new(name)
|
291
|
-
attributes.each do |key, value|
|
292
|
-
element.add_attribute(key, value)
|
293
|
-
end
|
294
|
-
children.each do |child|
|
295
|
-
element.add(child)
|
296
|
-
end
|
297
|
-
elements << element
|
298
|
-
end
|
299
|
-
return elements
|
300
|
-
end
|
301
|
-
|
302
|
-
def create_instructions(target, attributes, children)
|
303
|
-
instructions = []
|
304
|
-
if target == SYSTEM_INSTRUCTION_NAME
|
305
|
-
@version = attributes["version"] if attributes["version"]
|
306
|
-
@brace_name = attributes["brace"] if attributes["brace"]
|
307
|
-
@bracket_name = attributes["bracket"] if attributes["bracket"]
|
308
|
-
@slash_name = attributes["slash"] if attributes["slash"]
|
309
|
-
elsif target == "xml"
|
310
|
-
instruction = XMLDecl.new
|
311
|
-
instruction.version = attributes["version"] || XMLDecl::DEFAULT_VERSION
|
312
|
-
instruction.encoding = attributes["encoding"]
|
313
|
-
instruction.standalone = attributes["standalone"]
|
314
|
-
instructions << instruction
|
315
|
-
else
|
316
|
-
instruction = Instruction.new(target)
|
317
|
-
actual_contents = []
|
318
|
-
attributes.each do |key, value|
|
319
|
-
actual_contents << "#{key}=\"#{value}\""
|
320
|
-
end
|
321
|
-
if children.first && !children.first.empty?
|
322
|
-
actual_contents << children.first
|
323
|
-
end
|
324
|
-
instruction.content = actual_contents.join(" ")
|
325
|
-
instructions << instruction
|
326
|
-
end
|
327
|
-
return instructions
|
328
|
-
end
|
329
|
-
|
330
|
-
def process_macro(name, attributes, children_list)
|
331
|
-
elements = []
|
332
|
-
if @macros.key?(name)
|
333
|
-
elements = @macros[name].call(attributes, children_list)
|
334
|
-
elsif ENTITIES.key?(name)
|
335
|
-
text = Text.new(ENTITIES[name], true, nil, false)
|
336
|
-
elements << text
|
337
|
-
else
|
338
|
-
raise ZenithalParseError.new(@source)
|
339
|
-
end
|
340
|
-
return elements
|
341
|
-
end
|
342
|
-
|
343
|
-
def register_macro(name, &block)
|
344
|
-
@macros.store(name, block)
|
345
|
-
end
|
346
|
-
|
347
|
-
def parse_brace
|
348
|
-
unless @source.read == BRACE_START
|
349
|
-
raise ZenithalParseError.new(@source)
|
350
|
-
end
|
351
|
-
children = parse_nodes
|
352
|
-
unless @source.read == BRACE_END
|
353
|
-
raise ZenithalParseError.new(@source)
|
354
|
-
end
|
355
|
-
element = Element.new(@brace_name)
|
356
|
-
children.each do |child|
|
357
|
-
element.add(child)
|
358
|
-
end
|
359
|
-
return element
|
360
|
-
end
|
361
|
-
|
362
|
-
def parse_bracket
|
363
|
-
unless @source.read == BRACKET_START
|
364
|
-
raise ZenithalParseError.new(@source)
|
365
|
-
end
|
366
|
-
children = parse_nodes
|
367
|
-
unless @source.read == BRACKET_END
|
368
|
-
raise ZenithalParseError.new(@source)
|
369
|
-
end
|
370
|
-
element = Element.new(@bracket_name)
|
371
|
-
children.each do |child|
|
372
|
-
element.add(child)
|
373
|
-
end
|
374
|
-
return element
|
375
|
-
end
|
376
|
-
|
377
|
-
def parse_slash
|
378
|
-
unless @source.read == SLASH_START
|
379
|
-
raise ZenithalParseError.new(@source)
|
380
|
-
end
|
381
|
-
children = parse_nodes({}, true)
|
382
|
-
unless @source.read == SLASH_END
|
383
|
-
raise ZenithalParseError.new(@source)
|
384
|
-
end
|
385
|
-
element = Element.new(@slash_name)
|
386
|
-
children.each do |child|
|
387
|
-
element.add(child)
|
388
|
-
end
|
389
|
-
return element
|
390
|
-
end
|
391
|
-
|
392
|
-
def parse_comment
|
393
|
-
unless @source.read == COMMENT_DELIMITER
|
394
|
-
raise ZenithalParseError.new(@source)
|
395
|
-
end
|
396
|
-
char = @source.read
|
397
|
-
string = ""
|
398
|
-
if char == COMMENT_DELIMITER
|
399
|
-
while char = @source.read
|
400
|
-
if char == "\n"
|
401
|
-
@source.unread
|
402
|
-
break
|
403
|
-
else
|
404
|
-
string << char
|
405
|
-
end
|
406
|
-
end
|
407
|
-
elsif char == CONTENT_START
|
408
|
-
while char = @source.read
|
409
|
-
if char == CONTENT_END
|
410
|
-
next_char = @source.read
|
411
|
-
if next_char == COMMENT_DELIMITER
|
412
|
-
break
|
413
|
-
else
|
414
|
-
string << char
|
415
|
-
@source.unread
|
416
|
-
end
|
417
|
-
else
|
418
|
-
string << char
|
419
|
-
end
|
420
|
-
end
|
421
|
-
else
|
422
|
-
raise ZenithalParseError.new(@source)
|
423
|
-
end
|
424
|
-
comment = Comment.new(" #{string.strip} ")
|
425
|
-
return comment
|
426
|
-
end
|
427
|
-
|
428
|
-
def parse_text(option = {})
|
429
|
-
string = ""
|
430
|
-
while char = @source.read
|
431
|
-
next_char = @source.peek
|
432
|
-
if char == TAG_START || char == MACRO_START
|
433
|
-
@source.unread
|
434
|
-
break
|
435
|
-
elsif (@brace_name && char == BRACE_START) || (@bracket_name && char == BRACKET_START) || (@slash_name && char == SLASH_START)
|
436
|
-
@source.unread
|
437
|
-
break
|
438
|
-
elsif char == CONTENT_END
|
439
|
-
@source.unread
|
440
|
-
break
|
441
|
-
elsif (@brace_name && char == BRACE_END) || (@bracket_name && char == BRACKET_END) || (@slash_name && char == SLASH_END)
|
442
|
-
@source.unread
|
443
|
-
break
|
444
|
-
elsif char == COMMENT_DELIMITER
|
445
|
-
@source.unread
|
446
|
-
break
|
447
|
-
elsif char == ESCAPE_START && ESCAPES.include?(next_char)
|
448
|
-
@source.unread
|
449
|
-
string << parse_escape_string
|
450
|
-
else
|
451
|
-
string << char
|
452
|
-
end
|
453
|
-
end
|
454
|
-
text = Text.new(string, true, nil, false)
|
455
|
-
return text
|
456
|
-
end
|
457
|
-
|
458
|
-
def parse_verbal_text(option = {})
|
459
|
-
string = ""
|
460
|
-
while char = @source.read
|
461
|
-
next_char = @source.peek
|
462
|
-
if char == CONTENT_END
|
463
|
-
@source.unread
|
464
|
-
break
|
465
|
-
elsif char == ESCAPE_START && ESCAPES.include?(next_char)
|
466
|
-
@source.unread
|
467
|
-
string << parse_escape_string
|
468
|
-
else
|
469
|
-
string << char
|
470
|
-
end
|
471
|
-
end
|
472
|
-
text = Text.new(string, true, nil, false)
|
473
|
-
return text
|
474
|
-
end
|
475
|
-
|
476
|
-
def parse_escape_string
|
477
|
-
unless @source.read == ESCAPE_START
|
478
|
-
raise ZenithalParseError.new(@source)
|
479
|
-
end
|
480
|
-
char = @source.read
|
481
|
-
return char
|
482
|
-
end
|
483
|
-
|
484
|
-
def skip_spaces
|
485
|
-
count = 0
|
486
|
-
while @source.read =~ /\s/
|
487
|
-
count += 1
|
488
|
-
end
|
489
|
-
@source.unread
|
490
|
-
return count
|
491
|
-
end
|
492
|
-
|
493
|
-
def trim_spaces(children)
|
494
|
-
if children.first.is_a?(Text)
|
495
|
-
children.first.value = children.first.value.lstrip
|
496
|
-
end
|
497
|
-
if children.last.is_a?(Text)
|
498
|
-
children.last.value = children.last.value.rstrip
|
499
|
-
end
|
500
|
-
end
|
501
|
-
|
502
|
-
def trim_indents(children)
|
503
|
-
texts = []
|
504
|
-
if children.last.is_a?(Text)
|
505
|
-
children.last.value = children.last.value.rstrip
|
506
|
-
end
|
507
|
-
children.each do |child|
|
508
|
-
case child
|
509
|
-
when Text
|
510
|
-
texts << child
|
511
|
-
when Parent
|
512
|
-
texts.concat(ZenithalOldParser.get_all_texts(child))
|
513
|
-
end
|
514
|
-
end
|
515
|
-
indent_length = 10000
|
516
|
-
texts.each do |text|
|
517
|
-
text.value.scan(/\n(\x20+)/) do |match|
|
518
|
-
indent_length = [match[0].length, indent_length].min
|
519
|
-
end
|
520
|
-
end
|
521
|
-
texts.each do |text|
|
522
|
-
text.value = text.value.gsub(/\n(\x20+)/){"\n" + " " * ($1.length - indent_length)}
|
523
|
-
end
|
524
|
-
if children.first.is_a?(Text)
|
525
|
-
children.first.value = children.first.value.lstrip
|
526
|
-
end
|
527
|
-
end
|
528
|
-
|
529
|
-
def self.valid_start_char?(char)
|
530
|
-
return VALID_START_CHARS.any?{|s| s === char.ord}
|
531
|
-
end
|
532
|
-
|
533
|
-
def self.valid_char?(char)
|
534
|
-
return VALID_START_CHARS.any?{|s| s === char.ord} || VALID_MIDDLE_CHARS.any?{|s| s === char.ord}
|
535
|
-
end
|
536
|
-
|
537
|
-
def self.get_all_texts
|
538
|
-
texts = []
|
539
|
-
self.children.each do |child|
|
540
|
-
case child
|
541
|
-
when Text
|
542
|
-
texts << child
|
543
|
-
when Parent
|
544
|
-
texts.concat(get_all_texts(child))
|
545
|
-
end
|
546
|
-
end
|
547
|
-
return texts
|
548
|
-
end
|
549
|
-
|
550
|
-
end
|