zenml 1.1.1 → 1.1.2

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 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.