zenml 1.1.1 → 1.1.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bed76e79eaf3831d8c59b24e1a00533a03c3ee3213eb2f20dd94c8d8a709a84b
4
- data.tar.gz: 0aa6f8c5b618d09409dd0003dadf1cc73b1f486480202283b7120023ea5311fa
3
+ metadata.gz: fa2dc3c1c455a8d8c9fb0fbc5f11a55a93db4ae6de31c3e72bfdb9c2a6a9a556
4
+ data.tar.gz: 31a7616c68e3aa6d8f7fb453b34f29b51a0f0c748496c3e0eaf6a44e6445441a
5
5
  SHA512:
6
- metadata.gz: f4ddeef015698ad21610239840155a04266406adca2491f8f4d741f01275212fd60102c7356315defe57767112ccceae84d46b42ac40c258d8971d593c144af5
7
- data.tar.gz: 8ce58dd4255cb435d4da9c95621c6fa34349d79cb8581648ba0b428234955d0081f614d09ded5cf3942474c59b02d436f1c93d19dc76e9baa689d956173ee12e
6
+ metadata.gz: fe8433f7f33ef8806233ff50666c09afe83c626edc16b9368c63d660196c70bd532dca705c9feae8413bb2b52f4906649d00d633adc8fdb426f47b081f0a8603
7
+ data.tar.gz: 063727ce5cb752ec122e1884b40b8dd55619462d5d9cfa9a3682388294d07262685d544a21fcf521bfaac2168550b40052bdb71babeb7c7b72eacedad1d0691c
@@ -14,9 +14,9 @@ module ZenithalParserMethod
14
14
  ATTRIBUTE_START = "|"
15
15
  ATTRIBUTE_END = "|"
16
16
  ATTRIBUTE_EQUAL = "="
17
- ATTRIBUTE_VALUE_START = "\""
18
- ATTRIBUTE_VALUE_END = "\""
19
17
  ATTRIBUTE_SEPARATOR = ","
18
+ STRING_START = "\""
19
+ STRING_END = "\""
20
20
  CONTENT_START = "<"
21
21
  CONTENT_END = ">"
22
22
  SPECIAL_ELEMENT_STARTS = {:brace => "{", :bracket => "[", :slash => "/"}
@@ -49,7 +49,7 @@ module ZenithalParserMethod
49
49
  def parse_document
50
50
  parser = Parser.build(self) do
51
51
  document = Document.new
52
- children = +parse_nodes(false)
52
+ children = +parse_nodes({})
53
53
  +parse_eof
54
54
  children.each do |child|
55
55
  document.add(child)
@@ -59,72 +59,71 @@ module ZenithalParserMethod
59
59
  return parser
60
60
  end
61
61
 
62
- def parse_nodes(verbal)
62
+ def parse_nodes(options)
63
63
  parser = Parser.build(self) do
64
- parsers = [parse_text(verbal)]
65
- unless verbal
66
- parsers.push(parse_element, parse_line_comment, parse_block_comment)
64
+ parsers = [parse_text(options)]
65
+ unless options[:verbal]
66
+ parsers.push(parse_element(options), parse_line_comment(options), parse_block_comment(options))
67
67
  @special_element_names.each do |kind, name|
68
- parsers.push(parse_special_element(kind))
68
+ parsers.push(parse_special_element(kind, options))
69
69
  end
70
70
  end
71
- nodes = Nodes[]
72
71
  raw_nodes = +parsers.inject(:|).many
73
- raw_nodes.each do |raw_node|
74
- nodes << raw_node
75
- end
72
+ nodes = raw_nodes.inject(Nodes[], :<<)
76
73
  next nodes
77
74
  end
78
75
  return parser
79
76
  end
80
77
 
81
- def parse_element
78
+ def parse_element(options)
82
79
  parser = Parser.build(self) do
83
80
  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))
81
+ name = +parse_identifier(options)
82
+ marks = +parse_marks(options)
83
+ attributes = +parse_attributes(options).maybe || {}
84
+ next_options = determine_options(name, marks, attributes, start_char == MACRO_START, options)
85
+ children_list = +parse_children_list(next_options)
88
86
  if name == SYSTEM_INSTRUCTION_NAME
89
87
  +parse_space
90
88
  end
91
89
  if start_char == MACRO_START
92
- marks.push(:macro)
90
+ next process_macro(name, marks, attributes, children_list, options)
91
+ else
92
+ next create_element(name, marks, attributes, children_list, options)
93
93
  end
94
- next create_nodes(name, marks, attributes, children_list)
95
94
  end
96
95
  return parser
97
96
  end
98
97
 
99
- def parse_special_element(kind)
98
+ def parse_special_element(kind, options)
100
99
  parser = Parser.build(self) do
101
100
  unless @special_element_names[kind]
102
101
  +parse_none
103
102
  end
104
103
  +parse_char(SPECIAL_ELEMENT_STARTS[kind])
105
- children = +parse_nodes(false)
104
+ children = +parse_nodes(options)
106
105
  +parse_char(SPECIAL_ELEMENT_ENDS[kind])
107
- next create_nodes(@special_element_names[kind], [], {}, [children])
106
+ next create_special_element(kind, children, options)
108
107
  end
109
108
  return parser
110
109
  end
111
110
 
112
- def parse_marks
113
- return parse_mark.many
111
+ def parse_marks(options)
112
+ return parse_mark(options).many
114
113
  end
115
114
 
116
- def parse_mark
115
+ def parse_mark(options)
117
116
  parsers = MARKS.map do |mark, query|
118
117
  next parse_char(query).map{|_| mark}
119
118
  end
120
119
  return parsers.inject(:|)
121
120
  end
122
121
 
123
- def parse_attributes
122
+ def parse_attributes(options)
124
123
  parser = Parser.build(self) do
125
124
  +parse_char(ATTRIBUTE_START)
126
- first_attribute = +parse_attribute(false)
127
- rest_attribtues = +parse_attribute(true).many
125
+ first_attribute = +parse_attribute(true, options)
126
+ rest_attribtues = +parse_attribute(false, options).many
128
127
  attributes = first_attribute.merge(*rest_attribtues)
129
128
  +parse_char(ATTRIBUTE_END)
130
129
  next attributes
@@ -132,68 +131,68 @@ module ZenithalParserMethod
132
131
  return parser
133
132
  end
134
133
 
135
- def parse_attribute(comma)
134
+ def parse_attribute(first, options)
136
135
  parser = Parser.build(self) do
137
- +parse_char(ATTRIBUTE_SEPARATOR) if comma
136
+ +parse_char(ATTRIBUTE_SEPARATOR) unless first
138
137
  +parse_space
139
- name = +parse_identifier
138
+ name = +parse_identifier(options)
140
139
  +parse_space
141
- value = +parse_attribute_value.maybe || name
140
+ value = +parse_attribute_value(options).maybe || name
142
141
  +parse_space
143
142
  next {name => value}
144
143
  end
145
144
  return parser
146
145
  end
147
146
 
148
- def parse_attribute_value
147
+ def parse_attribute_value(options)
149
148
  parser = Parser.build(self) do
150
149
  +parse_char(ATTRIBUTE_EQUAL)
151
150
  +parse_space
152
- value = +parse_quoted_string
151
+ value = +parse_string(options)
153
152
  next value
154
153
  end
155
154
  return parser
156
155
  end
157
156
 
158
- def parse_quoted_string
157
+ def parse_string(options)
159
158
  parser = Parser.build(self) do
160
- +parse_char(ATTRIBUTE_VALUE_START)
161
- texts = +(parse_quoted_string_plain | parse_escape).many
162
- +parse_char(ATTRIBUTE_VALUE_END)
163
- next texts.join
159
+ +parse_char(STRING_START)
160
+ strings = +(parse_string_plain(options) | parse_escape(:string, options)).many
161
+ +parse_char(STRING_END)
162
+ next strings.join
164
163
  end
165
164
  return parser
166
165
  end
167
166
 
168
- def parse_quoted_string_plain
167
+ def parse_string_plain(options)
169
168
  parser = Parser.build(self) do
170
- chars = +parse_char_out([ATTRIBUTE_VALUE_END, ESCAPE_START]).many(1)
169
+ chars = +parse_char_out([STRING_END, ESCAPE_START]).many(1)
171
170
  next chars.join
172
171
  end
173
172
  return parser
174
173
  end
175
174
 
176
- def parse_children_list(verbal)
175
+ def parse_children_list(options)
177
176
  parser = Parser.build(self) do
178
- first_children = +(parse_empty_children | parse_children(verbal))
179
- rest_children_list = +parse_children(verbal).many
177
+ first_children = +(parse_empty_children(options) | parse_children(options))
178
+ rest_children_list = +parse_children(options).many
180
179
  children_list = [first_children] + rest_children_list
181
180
  next children_list
182
181
  end
183
182
  return parser
184
183
  end
185
184
 
186
- def parse_children(verbal)
185
+ def parse_children(options)
187
186
  parser = Parser.build(self) do
188
187
  +parse_char(CONTENT_START)
189
- children = +parse_nodes(verbal)
188
+ children = +parse_nodes(options)
190
189
  +parse_char(CONTENT_END)
191
190
  next children
192
191
  end
193
192
  return parser
194
193
  end
195
194
 
196
- def parse_empty_children
195
+ def parse_empty_children(options)
197
196
  parser = Parser.build(self) do
198
197
  +parse_char(CONTENT_END)
199
198
  next Nodes[]
@@ -201,18 +200,18 @@ module ZenithalParserMethod
201
200
  return parser
202
201
  end
203
202
 
204
- def parse_text(verbal)
203
+ def parse_text(options)
205
204
  parser = Parser.build(self) do
206
- texts = +(parse_text_plain(verbal) | parse_escape).many(1)
207
- next Text.new(texts.join, true, nil, false)
205
+ raw_texts = +(parse_text_plain(options) | parse_escape(:text, options)).many(1)
206
+ next create_text(raw_texts.join, options)
208
207
  end
209
208
  return parser
210
209
  end
211
210
 
212
- def parse_text_plain(verbal)
211
+ def parse_text_plain(options)
213
212
  parser = Parser.build(self) do
214
213
  out_chars = [ESCAPE_START, CONTENT_END]
215
- unless verbal
214
+ unless options[:verbal]
216
215
  out_chars.push(ELEMENT_START, MACRO_START, CONTENT_START, COMMENT_DELIMITER)
217
216
  @special_element_names.each do |kind, name|
218
217
  out_chars.push(SPECIAL_ELEMENT_STARTS[kind], SPECIAL_ELEMENT_ENDS[kind]) if name
@@ -224,38 +223,38 @@ module ZenithalParserMethod
224
223
  return parser
225
224
  end
226
225
 
227
- def parse_line_comment
226
+ def parse_line_comment(options)
228
227
  parser = Parser.build(self) do
229
228
  +parse_char(COMMENT_DELIMITER)
230
229
  +parse_char(COMMENT_DELIMITER)
231
- content = +parse_line_comment_content
232
- next Comment.new(" " + content.strip + " ")
230
+ content = +parse_line_comment_content(options)
231
+ +parse_char("\n")
232
+ next create_comment(:line, content, options)
233
233
  end
234
234
  return parser
235
235
  end
236
236
 
237
- def parse_line_comment_content
237
+ def parse_line_comment_content(options)
238
238
  parser = Parser.build(self) do
239
239
  chars = +parse_char_out(["\n"]).many
240
- +parse_char("\n")
241
240
  next chars.join
242
241
  end
243
242
  return parser
244
243
  end
245
244
 
246
- def parse_block_comment
245
+ def parse_block_comment(options)
247
246
  parser = Parser.build(self) do
248
247
  +parse_char(COMMENT_DELIMITER)
249
248
  +parse_char(CONTENT_START)
250
- content = +parse_block_comment_content
249
+ content = +parse_block_comment_content(options)
251
250
  +parse_char(CONTENT_END)
252
251
  +parse_char(COMMENT_DELIMITER)
253
- next Comment.new(" " + content.strip + " ")
252
+ next create_comment(:block, content, options)
254
253
  end
255
254
  return parser
256
255
  end
257
256
 
258
- def parse_block_comment_content
257
+ def parse_block_comment_content(options)
259
258
  parser = Parser.build(self) do
260
259
  chars = +parse_char_out([CONTENT_END]).many
261
260
  next chars.join
@@ -263,30 +262,30 @@ module ZenithalParserMethod
263
262
  return parser
264
263
  end
265
264
 
266
- def parse_escape
265
+ def parse_escape(place, options)
267
266
  parser = Parser.build(self) do
268
267
  +parse_char(ESCAPE_START)
269
- char = +parse_char_any(ESCAPE_CHARS)
270
- next char
268
+ char = +parse_char
269
+ next create_escape(place, char, options)
271
270
  end
272
271
  return parser
273
272
  end
274
273
 
275
- def parse_identifier
274
+ def parse_identifier(options)
276
275
  parser = Parser.build(self) do
277
- first_char = +parse_first_identifier_char
278
- rest_chars = +parse_middle_identifier_char.many
276
+ first_char = +parse_first_identifier_char(options)
277
+ rest_chars = +parse_middle_identifier_char(options).many
279
278
  identifier = first_char + rest_chars.join
280
279
  next identifier
281
280
  end
282
281
  return parser
283
282
  end
284
283
 
285
- def parse_first_identifier_char
284
+ def parse_first_identifier_char(options)
286
285
  return parse_char_any(VALID_FIRST_IDENTIFIER_CHARS)
287
286
  end
288
287
 
289
- def parse_middle_identifier_char
288
+ def parse_middle_identifier_char(options)
290
289
  return parse_char_any(VALID_MIDDLE_IDENTIFIER_CHARS)
291
290
  end
292
291
 
@@ -294,33 +293,39 @@ module ZenithalParserMethod
294
293
  return parse_char_any(SPACE_CHARS).many
295
294
  end
296
295
 
297
- def create_nodes(name, marks, attributes, children_list)
296
+ # Determines options which are used when parsing the children nodes.
297
+ # This method may be overrided in order to change the parsing behaviour for another format based on ZenML.
298
+ def determine_options(name, marks, attributes, macro, options)
299
+ if marks.include?(:verbal)
300
+ options = options.clone
301
+ options[:verbal] = true
302
+ end
303
+ return options
304
+ end
305
+
306
+ def create_element(name, marks, attributes, children_list, options)
298
307
  nodes = Nodes[]
299
- unless marks.include?(:macro)
300
- if marks.include?(:trim)
301
- children_list.each do |children|
302
- children.trim_indents
303
- end
308
+ if marks.include?(:trim)
309
+ children_list.each do |children|
310
+ children.trim_indents
304
311
  end
305
- if marks.include?(:instruction)
306
- unless children_list.size <= 1
307
- throw(:error, error_message("Processing instruction cannot have more than one argument"))
308
- end
309
- nodes = create_instructions(name, attributes, children_list.first)
310
- else
311
- unless marks.include?(:multiple) || children_list.size <= 1
312
- throw(:error, error_message("Normal node cannot have more than one argument"))
313
- end
314
- nodes = create_elements(name, attributes, children_list)
312
+ end
313
+ if marks.include?(:instruction)
314
+ unless children_list.size <= 1
315
+ throw(:error, error_message("Processing instruction cannot have more than one argument"))
315
316
  end
317
+ nodes = create_instruction(name, attributes, children_list.first, options)
316
318
  else
317
- nodes = process_macro(name, attributes, children_list)
319
+ unless marks.include?(:multiple) || children_list.size <= 1
320
+ throw(:error, error_message("Normal node cannot have more than one argument"))
321
+ end
322
+ nodes = create_normal_element(name, attributes, children_list, options)
318
323
  end
319
324
  return nodes
320
325
  end
321
326
 
322
- def create_instructions(target, attributes, children)
323
- instructions = Nodes[]
327
+ def create_instruction(target, attributes, children, options)
328
+ nodes = Nodes[]
324
329
  if target == SYSTEM_INSTRUCTION_NAME
325
330
  @version = attributes["version"] if attributes["version"]
326
331
  @special_element_names[:brace] = attributes["brace"] if attributes["brace"]
@@ -331,7 +336,7 @@ module ZenithalParserMethod
331
336
  instruction.version = attributes["version"] || XMLDecl::DEFAULT_VERSION
332
337
  instruction.encoding = attributes["encoding"]
333
338
  instruction.standalone = attributes["standalone"]
334
- instructions << instruction
339
+ nodes << instruction
335
340
  else
336
341
  instruction = Instruction.new(target)
337
342
  actual_contents = []
@@ -342,13 +347,13 @@ module ZenithalParserMethod
342
347
  actual_contents << children.first
343
348
  end
344
349
  instruction.content = actual_contents.join(" ")
345
- instructions << instruction
350
+ nodes << instruction
346
351
  end
347
- return instructions
352
+ return nodes
348
353
  end
349
354
 
350
- def create_elements(name, attributes, children_list)
351
- elements = Nodes[]
355
+ def create_normal_element(name, attributes, children_list, options)
356
+ nodes = Nodes[]
352
357
  children_list.each do |children|
353
358
  element = Element.new(name)
354
359
  attributes.each do |key, value|
@@ -357,12 +362,33 @@ module ZenithalParserMethod
357
362
  children.each do |child|
358
363
  element.add(child)
359
364
  end
360
- elements << element
365
+ nodes << element
361
366
  end
362
- return elements
367
+ return nodes
368
+ end
369
+
370
+ def create_special_element(kind, children, options)
371
+ name = @special_element_names[kind]
372
+ nodes = create_element(name, [], {}, [children], options)
373
+ return nodes
374
+ end
375
+
376
+ def create_text(raw_text, options)
377
+ return Text.new(raw_text, true, nil, false)
378
+ end
379
+
380
+ def create_comment(kind, content, options)
381
+ return Comment.new(" " + content.strip + " ")
382
+ end
383
+
384
+ def create_escape(place, char, options)
385
+ unless ESCAPE_CHARS.include?(char)
386
+ throw(:error, "Invalid escape")
387
+ end
388
+ return char
363
389
  end
364
390
 
365
- def process_macro(name, attributes, children_list)
391
+ def process_macro(name, marks, attributes, children_list, options)
366
392
  elements = Nodes[]
367
393
  if @macros.key?(name)
368
394
  raw_elements = @macros[name].call(attributes, children_list)
@@ -115,7 +115,7 @@ module CommonParserMethod
115
115
  # Parses a single character which matches the specified query.
116
116
  # If the next character does not match the query or the end of file is reached, an error result is returned.
117
117
  # Otherwise, a success result with a string containing the matched chracter is returned.
118
- def parse_char(query)
118
+ def parse_char(query = nil)
119
119
  parser = Parser.new(self) do
120
120
  char = source.read
121
121
  unless char == nil
@@ -133,6 +133,9 @@ module CommonParserMethod
133
133
  when Range
134
134
  predicate = query.cover?(char.ord)
135
135
  message = "Expected '#{query.begin}'..'#{query.end}'"
136
+ when NilClass
137
+ predicate = true
138
+ message = ""
136
139
  end
137
140
  if predicate
138
141
  next Result.success(char)
@@ -92,6 +92,7 @@ class Nodes < Array
92
92
  else
93
93
  old_push(object)
94
94
  end
95
+ return self
95
96
  end
96
97
 
97
98
  def +(other)
data/source/zenml.rb CHANGED
@@ -6,7 +6,7 @@ require 'zenml/utility'
6
6
 
7
7
  module Zenithal
8
8
 
9
- VERSION = "1.1.1"
9
+ VERSION = "1.1.2"
10
10
 
11
11
  require 'zenml/error'
12
12
  require 'zenml/reader'
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.1
4
+ version: 1.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ziphil
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-10-01 00:00:00.000000000 Z
11
+ date: 2019-10-02 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.