zenml 1.1.0 → 1.1.1
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 +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
|