enolib 0.5.0 → 0.5.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: 8aeeb10368acccea0f1381c34c6101a552493aea19ef50d8bdc7616f9a898cc7
4
- data.tar.gz: 576efc4e4191c945a4d262789e2d353d3521d712b63d1ce4236937d7a556e387
3
+ metadata.gz: 6b0463dcfa44839c7fecdb048f3678504d0616264bb71e3fe8ada2f97b9b8130
4
+ data.tar.gz: f4c541da00922054b230d6ff35860bfa49832fc24b064b52948ebb09d90da5e5
5
5
  SHA512:
6
- metadata.gz: a37196b8d2b69595e22f68b2b9025f64ec01028442ceddf4d6181cea71903f570561d0c2487d515bbad98ecde76c912284be282f8b3c54590cd026c716c8da33
7
- data.tar.gz: e9c8143539d6eb1fbf7a6e594208a70d5d6cad25f77d471556b1091d7bd4b3cfd268dbb28a0b764cbc0701b01184bd428cedfd6aecea24bac9d9c222ec8873f6
6
+ metadata.gz: 237cf74c59338475dfc4f0b8f4d8e5e5c7ced6aa57a41c9afb2a88d442d0c478e3459eadb956407d2f05109c6177cf9458d8e3c38e7fd489741d7774945f6b88
7
+ data.tar.gz: cd1266e224fbf84ef250dbbd71c65196a2d0d31eb9ef8ed1b6c0a903fc1b00f222966317b8e5c18e3d197b2c0dc9132253f4102634a0708a0d08ee034f136f53
@@ -12,5 +12,5 @@ module Enolib
12
12
  list_item: 'list_item',
13
13
  multiline_field_begin: 'field',
14
14
  section: 'section'
15
- }
15
+ }.freeze
16
16
  end
@@ -33,27 +33,27 @@ module Enolib
33
33
  shared_indent = Float::INFINITY
34
34
 
35
35
  element[:comments].each_with_index do |comment, index|
36
- if comment.has_key?(:comment)
37
- first_non_empty_line_index = index unless first_non_empty_line_index
38
- last_non_empty_line_index = index
36
+ next unless comment.has_key?(:comment)
39
37
 
40
- indent = comment[:ranges][:comment][RANGE_BEGIN] - comment[:ranges][:line][RANGE_BEGIN]
41
- shared_indent = indent if indent < shared_indent
42
- end
38
+ first_non_empty_line_index ||= index
39
+ last_non_empty_line_index = index
40
+
41
+ indent = comment[:ranges][:comment][RANGE_BEGIN] - comment[:ranges][:line][RANGE_BEGIN]
42
+ shared_indent = indent if indent < shared_indent
43
43
  end
44
44
 
45
45
  if first_non_empty_line_index
46
- non_empty_lines = element[:comments][first_non_empty_line_index..last_non_empty_line_index]
47
-
48
- non_empty_lines.map do |comment|
49
- if !comment.has_key?(:comment)
50
- ''
51
- elsif (comment[:ranges][:comment][RANGE_BEGIN] - comment[:ranges][:line][RANGE_BEGIN]) == shared_indent
52
- comment[:comment]
53
- else
54
- (' ' * (comment[:ranges][:comment][RANGE_BEGIN] - comment[:ranges][:line][RANGE_BEGIN] - shared_indent)) + comment[:comment]
55
- end
56
- end.join("\n")
46
+ non_empty_lines = element[:comments][first_non_empty_line_index..last_non_empty_line_index]
47
+
48
+ non_empty_lines.map do |comment|
49
+ if !comment.has_key?(:comment)
50
+ ''
51
+ elsif (comment[:ranges][:comment][RANGE_BEGIN] - comment[:ranges][:line][RANGE_BEGIN]) == shared_indent
52
+ comment[:comment]
53
+ else
54
+ (' ' * (comment[:ranges][:comment][RANGE_BEGIN] - comment[:ranges][:line][RANGE_BEGIN] - shared_indent)) + comment[:comment]
55
+ end
56
+ end.join("\n")
57
57
  else
58
58
  nil
59
59
  end
@@ -214,7 +214,7 @@ module Enolib
214
214
  end
215
215
  end
216
216
 
217
- return element[:computed_value]
217
+ element[:computed_value]
218
218
  end
219
219
  end
220
220
  end
@@ -16,7 +16,7 @@ module Enolib
16
16
  end
17
17
 
18
18
  unless message
19
- raise ArgumentError.new('A message or message function must be provided')
19
+ raise ArgumentError, 'A message or message function must be provided'
20
20
  end
21
21
 
22
22
  Errors::Validation.comment_error(@context, message, @instruction)
@@ -30,7 +30,7 @@ module Enolib
30
30
  end
31
31
 
32
32
  unless message
33
- raise ArgumentError.new('A message or message function must be provided')
33
+ raise ArgumentError, 'A message or message function must be provided'
34
34
  end
35
35
 
36
36
  Errors::Validation.element_error(@context, message, @instruction)
@@ -42,7 +42,7 @@ module Enolib
42
42
  @touched = true
43
43
 
44
44
  unless loader
45
- raise ArgumentError.new('A loader function must be provided')
45
+ raise ArgumentError, 'A loader function must be provided'
46
46
  end
47
47
 
48
48
  begin
@@ -60,7 +60,7 @@ module Enolib
60
60
  end
61
61
 
62
62
  unless message
63
- raise ArgumentError.new('A message or message function must be provided')
63
+ raise ArgumentError, 'A message or message function must be provided'
64
64
  end
65
65
 
66
66
  Errors::Validation.key_error(@context, message, @instruction)
@@ -70,13 +70,13 @@ module Enolib
70
70
  loader = Proc.new if block_given?
71
71
 
72
72
  unless loader
73
- raise ArgumentError.new('A loader function must be provided')
73
+ raise ArgumentError, 'A loader function must be provided'
74
74
  end
75
75
 
76
76
  _comment(loader, required: false)
77
77
  end
78
78
 
79
- def optional_string_comment()
79
+ def optional_string_comment
80
80
  _comment(required: false)
81
81
  end
82
82
 
@@ -88,13 +88,13 @@ module Enolib
88
88
  loader = Proc.new if block_given?
89
89
 
90
90
  unless loader
91
- raise ArgumentError.new('A loader function must be provided')
91
+ raise ArgumentError, 'A loader function must be provided'
92
92
  end
93
93
 
94
94
  _comment(loader, required: true)
95
95
  end
96
96
 
97
- def required_string_comment()
97
+ def required_string_comment
98
98
  _comment(required: true)
99
99
  end
100
100
 
@@ -10,14 +10,14 @@ module Enolib
10
10
  loader = Proc.new if block_given?
11
11
 
12
12
  unless loader
13
- raise ArgumentError.new('A loader function must be provided')
13
+ raise ArgumentError, 'A loader function must be provided'
14
14
  end
15
15
 
16
16
  _value(loader, required: false)
17
17
  end
18
18
 
19
19
  def parent
20
- return @parent || Section.new(@context, @instruction[:parent])
20
+ @parent || Section.new(@context, @instruction[:parent])
21
21
  end
22
22
 
23
23
  def required_string_value
@@ -28,7 +28,7 @@ module Enolib
28
28
  loader = Proc.new if block_given?
29
29
 
30
30
  unless loader
31
- raise ArgumentError.new('A loader function must be provided')
31
+ raise ArgumentError, 'A loader function must be provided'
32
32
  end
33
33
 
34
34
  _value(loader, required: true)
@@ -37,27 +37,5 @@ module Enolib
37
37
  def to_s
38
38
  "#<Enolib::Field key=#{@instruction[:key]} value=#{print_value}>"
39
39
  end
40
-
41
- private
42
-
43
- def _value(loader = nil, required:)
44
- @touched = true
45
-
46
- value = @context.value(@instruction)
47
-
48
- if value
49
- return value unless loader
50
-
51
- begin
52
- loader.call(value)
53
- rescue => message
54
- raise Errors::Validation.value_error(@context, message, @instruction)
55
- end
56
- else
57
- return nil unless required
58
-
59
- raise Errors::Validation.missing_value(@context, @instruction)
60
- end
61
- end
62
40
  end
63
41
  end
@@ -33,13 +33,13 @@ module Enolib
33
33
  next if except && except.include?(key) || only && !only.include?(key)
34
34
 
35
35
  entries.each do |entry|
36
- unless entry.touched # TODO: Revisit instance var existance question in ruby
37
- if message.is_a?(Proc)
38
- message = message.call(entry)
39
- end
40
-
41
- raise Errors::Validation.unexpected_element(@context, message, entry[:instruction])
36
+ next if entry.touched # TODO: Revisit instance var existance question in ruby
37
+
38
+ if message.is_a?(Proc)
39
+ message = message.call(entry)
42
40
  end
41
+
42
+ raise Errors::Validation.unexpected_element(@context, message, entry[:instruction])
43
43
  end
44
44
  end
45
45
  end
@@ -50,7 +50,7 @@ module Enolib
50
50
  if loader
51
51
  _comment(loader, required: false)
52
52
  else
53
- raise ArgumentError.new('A loader block or Proc must be provided')
53
+ raise ArgumentError, 'A loader block or Proc must be provided'
54
54
  end
55
55
  end
56
56
 
@@ -66,7 +66,7 @@ module Enolib
66
66
  @touched = true
67
67
 
68
68
  unless loader
69
- raise ArgumentError.new('A loader function must be provided')
69
+ raise ArgumentError, 'A loader function must be provided'
70
70
  end
71
71
 
72
72
  _items.map { |item| item.optional_value(loader) }
@@ -88,7 +88,7 @@ module Enolib
88
88
  @touched = true
89
89
 
90
90
  unless loader
91
- raise ArgumentError.new('A loader function must be provided')
91
+ raise ArgumentError, 'A loader function must be provided'
92
92
  end
93
93
 
94
94
  _items.map { |item| item.required_value(loader) }
@@ -61,13 +61,13 @@ module Enolib
61
61
  elements.each do |element|
62
62
  untouched = element._untouched
63
63
 
64
- if untouched
65
- if message.is_a?(Proc)
66
- message = message.call(Element.new(@context, untouched, self))
67
- end
64
+ next unless untouched
68
65
 
69
- raise Errors::Validation.unexpected_element(@context, message, untouched)
66
+ if message.is_a?(Proc)
67
+ message = message.call(Element.new(@context, untouched, self))
70
68
  end
69
+
70
+ raise Errors::Validation.unexpected_element(@context, message, untouched)
71
71
  end
72
72
  end
73
73
  end
@@ -270,9 +270,7 @@ module Enolib
270
270
  def touch
271
271
  @touched = true
272
272
 
273
- _elements.each do |element|
274
- element.touch
275
- end
273
+ _elements.each(&:touch)
276
274
  end
277
275
 
278
276
  private
@@ -291,7 +289,7 @@ module Enolib
291
289
  if required || @all_elements_required
292
290
  raise Errors::Validation.missing_element(@context, key, @instruction, 'missing_element')
293
291
  elsif required == nil
294
- return MissingElement.new(key, self)
292
+ return MissingSectionElement.new(key, self)
295
293
  else
296
294
  return nil
297
295
  end
@@ -17,7 +17,7 @@ module Enolib
17
17
  def to_empty
18
18
  unless instance_variable_defined?(:@empty)
19
19
  if instance_variable_defined?(:@yielded)
20
- raise TypeError.new("This element was already yielded as #{PRETTY_TYPES[@yielded]} and can't be yielded again as an empty.")
20
+ raise TypeError, "This element was already yielded as #{PRETTY_TYPES[@yielded]} and can't be yielded again as an empty."
21
21
  end
22
22
 
23
23
  unless @instruction[:type] == :empty_element
@@ -35,7 +35,7 @@ module Enolib
35
35
  def to_field
36
36
  unless instance_variable_defined?(:@field)
37
37
  if instance_variable_defined?(:@yielded)
38
- raise TypeError.new("This element was already yielded as #{PRETTY_TYPES[@yielded]} and can't be yielded again as a field.")
38
+ raise TypeError, "This element was already yielded as #{PRETTY_TYPES[@yielded]} and can't be yielded again as a field."
39
39
  end
40
40
 
41
41
  unless @instruction[:type] == :field ||
@@ -54,7 +54,7 @@ module Enolib
54
54
  def to_fieldset
55
55
  unless instance_variable_defined?(:@fieldset)
56
56
  if instance_variable_defined?(:@yielded)
57
- raise TypeError.new("This element was already yielded as #{PRETTY_TYPES[@yielded]} and can't be yielded again as a fieldset.")
57
+ raise TypeError, "This element was already yielded as #{PRETTY_TYPES[@yielded]} and can't be yielded again as a fieldset."
58
58
  end
59
59
 
60
60
  unless @instruction[:type] == :fieldset || @instruction[:type] == :empty_element
@@ -71,7 +71,7 @@ module Enolib
71
71
  def to_list
72
72
  unless instance_variable_defined?(:@list)
73
73
  if instance_variable_defined?(:@yielded)
74
- raise TypeError.new("This element was already yielded as #{PRETTY_TYPES[@yielded]} and can't be yielded again as a list.")
74
+ raise TypeError, "This element was already yielded as #{PRETTY_TYPES[@yielded]} and can't be yielded again as a list."
75
75
  end
76
76
 
77
77
  unless @instruction[:type] == :list || @instruction[:type] == :empty_element
@@ -10,7 +10,7 @@ module Enolib
10
10
  loader = Proc.new if block_given?
11
11
 
12
12
  unless loader
13
- raise ArgumentError.new('A loader function must be provided')
13
+ raise ArgumentError, 'A loader function must be provided'
14
14
  end
15
15
 
16
16
  _value(loader, required: false)
@@ -24,7 +24,7 @@ module Enolib
24
24
  loader = Proc.new if block_given?
25
25
 
26
26
  unless loader
27
- raise ArgumentError.new('A loader function must be provided')
27
+ raise ArgumentError, 'A loader function must be provided'
28
28
  end
29
29
 
30
30
  _value(loader, required: true)
@@ -38,7 +38,7 @@ module Enolib
38
38
  end
39
39
 
40
40
  unless message
41
- raise ArgumentError.new('A message or message function must be provided')
41
+ raise ArgumentError, 'A message or message function must be provided'
42
42
  end
43
43
 
44
44
  Errors::Validation.value_error(@context, message, @instruction)
@@ -3,7 +3,7 @@
3
3
  module Enolib
4
4
  module Errors
5
5
  module Parsing
6
- UNTERMINATED_ESCAPED_KEY = /^\s*#*\s*(`+)(?!`)((?:(?!\1).)+)$/
6
+ UNTERMINATED_ESCAPED_KEY = /^\s*#*\s*(`+)(?!`)((?:(?!\1).)+)$/.freeze
7
7
 
8
8
  def self.cyclic_dependency(context, instruction, instruction_chain)
9
9
  first_occurrence = instruction_chain.find_index(instruction)
@@ -24,9 +24,9 @@ module Enolib
24
24
  end
25
25
 
26
26
  ParseError.new(
27
- context.messages::cyclic_dependency(copy_instruction[:line] + Enolib::HUMAN_INDEXING, copy_instruction[:template]),
27
+ context.messages.cyclic_dependency(copy_instruction[:line] + Enolib::HUMAN_INDEXING, copy_instruction[:template]),
28
28
  reporter.snippet,
29
- Selections::select_template(copy_instruction)
29
+ Selections.select_template(copy_instruction)
30
30
  )
31
31
  end
32
32
 
@@ -37,41 +37,41 @@ module Enolib
37
37
  return unterminated_escaped_key(context, instruction, match.end(1)) if match
38
38
 
39
39
  ParseError.new(
40
- context.messages::invalid_line(instruction[:line] + Enolib::HUMAN_INDEXING),
40
+ context.messages.invalid_line(instruction[:line] + Enolib::HUMAN_INDEXING),
41
41
  context.reporter.new(context).report_line(instruction).snippet,
42
- Selections::select_line(instruction)
42
+ Selections.select_line(instruction)
43
43
  )
44
44
  end
45
45
 
46
46
  def self.missing_element_for_continuation(context, continuation)
47
47
  ParseError.new(
48
- context.messages::missing_element_for_continuation(continuation[:line] + Enolib::HUMAN_INDEXING),
48
+ context.messages.missing_element_for_continuation(continuation[:line] + Enolib::HUMAN_INDEXING),
49
49
  context.reporter.new(context).report_line(continuation).snippet,
50
- Selections::select_line(continuation)
50
+ Selections.select_line(continuation)
51
51
  )
52
52
  end
53
53
 
54
54
  def self.missing_fieldset_for_fieldset_entry(context, entry)
55
55
  ParseError.new(
56
- context.messages::missing_fieldset_for_fieldset_entry(entry[:line] + Enolib::HUMAN_INDEXING),
56
+ context.messages.missing_fieldset_for_fieldset_entry(entry[:line] + Enolib::HUMAN_INDEXING),
57
57
  context.reporter.new(context).report_line(entry).snippet,
58
- Selections::select_line(entry)
58
+ Selections.select_line(entry)
59
59
  )
60
60
  end
61
61
 
62
62
  def self.missing_list_for_list_item(context, item)
63
63
  ParseError.new(
64
- context.messages::missing_list_for_list_item(item[:line] + Enolib::HUMAN_INDEXING),
64
+ context.messages.missing_list_for_list_item(item[:line] + Enolib::HUMAN_INDEXING),
65
65
  context.reporter.new(context).report_line(item).snippet,
66
- Selections::select_line(item)
66
+ Selections.select_line(item)
67
67
  )
68
68
  end
69
69
 
70
70
  def self.non_section_element_not_found(context, copy)
71
71
  ParseError.new(
72
- context.messages::non_section_element_not_found(copy[:line] + Enolib::HUMAN_INDEXING, copy[:template]),
72
+ context.messages.non_section_element_not_found(copy[:line] + Enolib::HUMAN_INDEXING, copy[:template]),
73
73
  context.reporter.new(context).report_line(copy).snippet,
74
- Selections::select_line(copy)
74
+ Selections.select_line(copy)
75
75
  )
76
76
  end
77
77
 
@@ -81,23 +81,23 @@ module Enolib
81
81
  reporter.indicate_line(super_section) if super_section[:type] != :document
82
82
 
83
83
  ParseError.new(
84
- context.messages::section_hierarchy_layer_skip(section[:line] + Enolib::HUMAN_INDEXING),
84
+ context.messages.section_hierarchy_layer_skip(section[:line] + Enolib::HUMAN_INDEXING),
85
85
  reporter.snippet,
86
- Selections::select_line(section)
86
+ Selections.select_line(section)
87
87
  )
88
88
  end
89
89
 
90
90
  def self.section_not_found(context, copy)
91
91
  ParseError.new(
92
- context.messages::section_not_found(copy[:line] + Enolib::HUMAN_INDEXING, copy[:template]),
92
+ context.messages.section_not_found(copy[:line] + Enolib::HUMAN_INDEXING, copy[:template]),
93
93
  context.reporter.new(context).report_line(copy).snippet,
94
- Selections::select_line(copy)
94
+ Selections.select_line(copy)
95
95
  )
96
96
  end
97
97
 
98
98
  def self.unterminated_escaped_key(context, instruction, selection_column)
99
99
  ParseError.new(
100
- context.messages::unterminated_escaped_key(instruction[:line] + Enolib::HUMAN_INDEXING),
100
+ context.messages.unterminated_escaped_key(instruction[:line] + Enolib::HUMAN_INDEXING),
101
101
  context.reporter.new(context).report_line(instruction).snippet,
102
102
  {
103
103
  from: {
@@ -105,16 +105,16 @@ module Enolib
105
105
  index: instruction[:ranges][:line][RANGE_BEGIN] + selection_column,
106
106
  line: instruction[:line]
107
107
  },
108
- to: Selections::cursor(instruction, :line, RANGE_END)
108
+ to: Selections.cursor(instruction, :line, RANGE_END)
109
109
  }
110
110
  )
111
111
  end
112
112
 
113
113
  def self.two_or_more_templates_found(context, copy, first_template, second_template)
114
114
  ParseError.new(
115
- context.messages::two_or_more_templates_found(copy[:template]),
115
+ context.messages.two_or_more_templates_found(copy[:template]),
116
116
  context.reporter.new(context).report_line(copy).question_line(first_template).question_line(second_template).snippet,
117
- Selections::select_line(copy)
117
+ Selections.select_line(copy)
118
118
  )
119
119
  end
120
120
 
@@ -126,9 +126,9 @@ module Enolib
126
126
  end
127
127
 
128
128
  ParseError.new(
129
- context.messages::unterminated_multiline_field(field[:key], field[:line] + Enolib::HUMAN_INDEXING),
129
+ context.messages.unterminated_multiline_field(field[:key], field[:line] + Enolib::HUMAN_INDEXING),
130
130
  reporter.snippet,
131
- Selections::select_line(field)
131
+ Selections.select_line(field)
132
132
  )
133
133
  end
134
134
  end
@@ -7,7 +7,7 @@ module Enolib
7
7
  DOCUMENT_BEGIN = {
8
8
  from: { column: 0, index: 0, line: 0 },
9
9
  to: { column: 0, index: 0, line: 0 }
10
- }
10
+ }.freeze
11
11
 
12
12
  def self.last_in(element)
13
13
  if (element[:type] == :field ||
@@ -6,40 +6,40 @@ module Enolib
6
6
  def self.comment_error(context, message, element)
7
7
  ValidationError.new(
8
8
  context.messages.comment_error(message),
9
- context.reporter.new(context).report_comments(element).snippet(),
10
- Selections::select_comments(element)
9
+ context.reporter.new(context).report_comments(element).snippet,
10
+ Selections.select_comments(element)
11
11
  )
12
12
  end
13
13
 
14
14
  def self.element_error(context, message, element)
15
15
  ValidationError.new(
16
16
  message,
17
- context.reporter.new(context).report_element(element).snippet(),
18
- Selections::select_element(element)
17
+ context.reporter.new(context).report_element(element).snippet,
18
+ Selections.select_element(element)
19
19
  )
20
20
  end
21
21
 
22
22
  def self.key_error(context, message, element)
23
23
  ValidationError.new(
24
24
  context.messages.key_error(message),
25
- context.reporter.new(context).report_line(element).snippet(),
26
- Selections::select_key(element)
25
+ context.reporter.new(context).report_line(element).snippet,
26
+ Selections.select_key(element)
27
27
  )
28
28
  end
29
29
 
30
30
  def self.missing_comment(context, element)
31
31
  ValidationError.new(
32
32
  context.messages::MISSING_COMMENT,
33
- context.reporter.new(context).report_line(element).snippet(), # TODO: Question-tag an empty line before an element with missing comment
34
- Selections::selection(element, :line, RANGE_BEGIN)
33
+ context.reporter.new(context).report_line(element).snippet, # TODO: Question-tag an empty line before an element with missing comment
34
+ Selections.selection(element, :line, RANGE_BEGIN)
35
35
  )
36
36
  end
37
37
 
38
38
  def self.missing_element(context, key, parent, message)
39
39
  ValidationError.new(
40
40
  key ? context.messages.send(message + '_with_key', key) : context.messages.const_get(message.upcase), # TODO: Solve the upcase rather through a different generated message type, e.g. method instead of constant
41
- context.reporter.new(context).report_missing_element(parent).snippet(),
42
- parent[:type] == :document ? Selections::DOCUMENT_BEGIN : Selections::selection(parent, :line, RANGE_END)
41
+ context.reporter.new(context).report_missing_element(parent).snippet,
42
+ parent[:type] == :document ? Selections::DOCUMENT_BEGIN : Selections.selection(parent, :line, RANGE_END)
43
43
  )
44
44
  end
45
45
 
@@ -51,28 +51,30 @@ module Enolib
51
51
  element[:type] == :multiline_field_begin
52
52
  message = context.messages.missing_field_value(element[:key])
53
53
 
54
- if element[:ranges].has_key?(:template)
55
- selection[:from] = Selections::cursor(element, :template, RANGE_END)
56
- elsif element[:ranges].has_key?(:element_operator)
57
- selection[:from] = Selections::cursor(element, :element_operator, RANGE_END)
58
- else
59
- selection[:from] = Selections::cursor(element, :line, RANGE_END)
60
- end
54
+ selection[:from] =
55
+ if element[:ranges].has_key?(:template)
56
+ Selections.cursor(element, :template, RANGE_END)
57
+ elsif element[:ranges].has_key?(:element_operator)
58
+ Selections.cursor(element, :element_operator, RANGE_END)
59
+ else
60
+ Selections.cursor(element, :line, RANGE_END)
61
+ end
61
62
  elsif element[:type] == :fieldset_entry
62
63
  message = context.messages.missing_fieldset_entry_value(element[:key])
63
- selection[:from] = Selections::cursor(element, :entry_operator, RANGE_END)
64
+ selection[:from] = Selections.cursor(element, :entry_operator, RANGE_END)
64
65
  elsif element[:type] == :list_item
65
66
  message = context.messages.missing_list_item_value(element[:parent][:key])
66
- selection[:from] = Selections::cursor(element, :item_operator, RANGE_END)
67
+ selection[:from] = Selections.cursor(element, :item_operator, RANGE_END)
67
68
  end
68
69
 
69
- snippet = context.reporter.new(context).report_element(element).snippet()
70
+ snippet = context.reporter.new(context).report_element(element).snippet
70
71
 
71
- if element[:type] == :field and element.has_key?(:continuations)
72
- selection[:to] = Selections::cursor(element[:continuations].last, :line, RANGE_END)
73
- else
74
- selection[:to] = Selections::cursor(element, :line, RANGE_END)
75
- end
72
+ selection[:to] =
73
+ if element[:type] == :field && element.has_key?(:continuations)
74
+ Selections.cursor(element[:continuations].last, :line, RANGE_END)
75
+ else
76
+ Selections.cursor(element, :line, RANGE_END)
77
+ end
76
78
 
77
79
  ValidationError.new(message, snippet, selection)
78
80
  end
@@ -80,63 +82,64 @@ module Enolib
80
82
  def self.unexpected_element(context, message, element)
81
83
  ValidationError.new(
82
84
  message || context.messages::UNEXPECTED_ELEMENT,
83
- context.reporter.new(context).report_element(element).snippet(),
84
- Selections::select_element(element)
85
+ context.reporter.new(context).report_element(element).snippet,
86
+ Selections.select_element(element)
85
87
  )
86
88
  end
87
89
 
88
90
  def self.unexpected_multiple_elements(context, key, elements, message)
89
91
  ValidationError.new(
90
92
  key ? context.messages.send(message + '_with_key', key) : context.messages.const_get(message.upcase), # TODO: Solve the upcase rather through a different generated message type, e.g. method instead of constant
91
- context.reporter.new(context).report_elements(elements).snippet(),
92
- Selections::select_element(elements[0])
93
+ context.reporter.new(context).report_elements(elements).snippet,
94
+ Selections.select_element(elements[0])
93
95
  )
94
96
  end
95
97
 
96
98
  def self.unexpected_element_type(context, key, section, message)
97
99
  ValidationError.new(
98
100
  key ? context.messages.send(message + '_with_key', key) : context.messages.const_get(message.upcase), # TODO: Solve the upcase rather through a different generated message type, e.g. method instead of constant
99
- context.reporter.new(context).report_element(section).snippet(),
100
- Selections::select_element(section)
101
+ context.reporter.new(context).report_element(section).snippet,
102
+ Selections.select_element(section)
101
103
  )
102
104
  end
103
105
 
104
106
  def self.value_error(context, message, element)
105
107
  if element.has_key?(:mirror)
106
- snippet = context.reporter.new(context).report_line(element).snippet()
108
+ snippet = context.reporter.new(context).report_line(element).snippet
107
109
  select = select_key(element)
108
110
  elsif element[:type] == :multiline_field_begin
109
111
  if element.has_key?(:lines)
110
- snippet = context.reporter.new(context).report_multiline_value(element).snippet()
111
- select = Selections::selection(element[:lines][0], :line, RANGE_BEGIN, element[:lines][-1], :line, RANGE_END)
112
+ snippet = context.reporter.new(context).report_multiline_value(element).snippet
113
+ select = Selections.selection(element[:lines][0], :line, RANGE_BEGIN, element[:lines][-1], :line, RANGE_END)
112
114
  else
113
- snippet = context.reporter.new(context).report_element(element).snippet()
114
- select = Selections::selection(element, :line, RANGE_END)
115
+ snippet = context.reporter.new(context).report_element(element).snippet
116
+ select = Selections.selection(element, :line, RANGE_END)
115
117
  end
116
118
  else
117
- snippet = context.reporter.new(context).report_element(element).snippet()
118
- select = {}
119
-
120
- if element[:ranges].has_key?(:value)
121
- select[:from] = Selections::cursor(element, :value, RANGE_BEGIN)
122
- elsif element[:ranges].has_key?(:element_operator)
123
- select[:from] = Selections::cursor(element, :element_operator, RANGE_END)
124
- elsif element[:ranges].has_key?(:entry_operator)
125
- select[:from] = Selections::cursor(element, :entry_operator, RANGE_END)
126
- elsif element[:type] == :list_item
127
- select[:from] = Selections::cursor(element, :item_operator, RANGE_END)
128
- else
129
- # TODO: Possibly never reached - think through state permutations
130
- select[:from] = Selections::cursor(element, :line, RANGE_END)
131
- end
132
-
133
- if element.has_key?(:continuations)
134
- select[:to] = Selections::cursor(element[:continuations][-1], :line, RANGE_END)
135
- elsif element[:ranges].has_key?(:value)
136
- select[:to] = Selections::cursor(element, :value, RANGE_END)
137
- else
138
- select[:to] = Selections::cursor(element, :line, RANGE_END)
139
- end
119
+ snippet = context.reporter.new(context).report_element(element).snippet
120
+ select = {
121
+ from:
122
+ if element[:ranges].has_key?(:value)
123
+ Selections.cursor(element, :value, RANGE_BEGIN)
124
+ elsif element[:ranges].has_key?(:element_operator)
125
+ Selections.cursor(element, :element_operator, RANGE_END)
126
+ elsif element[:ranges].has_key?(:entry_operator)
127
+ Selections.cursor(element, :entry_operator, RANGE_END)
128
+ elsif element[:type] == :list_item
129
+ Selections.cursor(element, :item_operator, RANGE_END)
130
+ else
131
+ # TODO: Possibly never reached - think through state permutations
132
+ Selections.cursor(element, :line, RANGE_END)
133
+ end,
134
+ to:
135
+ if element.has_key?(:continuations)
136
+ Selections.cursor(element[:continuations][-1], :line, RANGE_END)
137
+ elsif element[:ranges].has_key?(:value)
138
+ Selections.cursor(element, :value, RANGE_END)
139
+ else
140
+ Selections.cursor(element, :line, RANGE_END)
141
+ end
142
+ }
140
143
  end
141
144
 
142
145
  ValidationError.new(context.messages.value_error(message), snippet, select)
@@ -98,6 +98,6 @@ module Enolib
98
98
 
99
99
  NOT_EMPTY = /(?:#{EARLY_DETERMINED}|#{LATE_DETERMINED})/.source
100
100
 
101
- REGEX = /[^\S\n]*(?:#{EMPTY}|#{NOT_EMPTY})[^\S\n]*(?=\n|$)/
101
+ REGEX = /[^\S\n]*(?:#{EMPTY}|#{NOT_EMPTY})[^\S\n]*(?=\n|$)/.freeze
102
102
  end
103
103
  end
data/lib/enolib/lookup.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  RANGE_BEGIN = 0
2
4
  RANGE_END = 1
3
5
 
@@ -63,7 +65,6 @@ def check_fieldset_by_line(fieldset, line)
63
65
  return false unless fieldset.has_key?(:entries) &&
64
66
  line <= fieldset[:entries].last[:line]
65
67
 
66
-
67
68
  fieldset[:entries].each do |entry|
68
69
  return { element: entry, instruction: entry } if line == entry[:line]
69
70
  return { element: fieldset, instruction: nil } if line < entry[:line]
@@ -190,13 +191,13 @@ module Enolib
190
191
  match = nil
191
192
  if index
192
193
  if index < 0 || index > context.input.length
193
- raise IndexError.new("You are trying to look up an index (#{index}) outside of the document's index range (0-#{context.input.length})")
194
+ raise IndexError, "You are trying to look up an index (#{index}) outside of the document's index range (0-#{context.input.length})"
194
195
  end
195
196
 
196
197
  match = check_in_section_by_index(context.document, index)
197
198
  else
198
199
  if line < 0 || line >= context.line_count
199
- raise IndexError.new("You are trying to look up a line (#{line}) outside of the document's line range (0-#{context.line_count - 1})")
200
+ raise IndexError, "You are trying to look up a line (#{line}) outside of the document's line range (0-#{context.line_count - 1})"
200
201
  end
201
202
 
202
203
  match = check_in_section_by_line(context.document, line)
data/lib/enolib/parser.rb CHANGED
@@ -7,8 +7,8 @@ module Enolib
7
7
  @depth = 0
8
8
  @index = 0
9
9
  @line = 0
10
- @unresolved_non_section_elements = nil
11
- @unresolved_sections = nil
10
+ @unresolved_non_section_elements = {}
11
+ @unresolved_sections = {}
12
12
  end
13
13
 
14
14
  def run
@@ -164,7 +164,7 @@ module Enolib
164
164
 
165
165
  elsif match[Grammar::SPACED_LINE_CONTINUATION_OPERATOR_INDEX]
166
166
 
167
- if !last_continuable_element
167
+ unless last_continuable_element
168
168
  instruction = tokenize_error_context
169
169
  raise Errors::Parsing.missing_element_for_continuation(@context, instruction)
170
170
  end
@@ -197,7 +197,7 @@ module Enolib
197
197
 
198
198
  elsif match[Grammar::DIRECT_LINE_CONTINUATION_OPERATOR_INDEX]
199
199
 
200
- if !last_continuable_element
200
+ unless last_continuable_element
201
201
  instruction = tokenize_error_context
202
202
  raise Errors::Parsing.missing_element_for_continuation(@context, instruction)
203
203
  end
@@ -292,8 +292,6 @@ module Enolib
292
292
  instruction[:ranges][:copy_operator] = copy_operator_offset
293
293
  end
294
294
 
295
- @unresolved_sections = {} unless @unresolved_sections
296
-
297
295
  if @unresolved_sections.has_key?(template)
298
296
  @unresolved_sections[template][:targets].push(instruction)
299
297
  else
@@ -381,9 +379,9 @@ module Enolib
381
379
  length: terminator_match.end(0),
382
380
  line: @line,
383
381
  ranges: {
384
- key: terminator_match.offset(2),
382
+ key: terminator_match.offset(2),
385
383
  line: [@index, terminator_match.end(0)],
386
- multiline_field_operator: terminator_match.offset(1),
384
+ multiline_field_operator: terminator_match.offset(1)
387
385
  },
388
386
  type: :multiline_field_end
389
387
  }
@@ -444,8 +442,6 @@ module Enolib
444
442
  last_continuable_element = nil
445
443
  last_non_section_element = instruction
446
444
 
447
- @unresolved_non_section_elements = {} unless @unresolved_non_section_elements
448
-
449
445
  if @unresolved_non_section_elements.has_key?(template)
450
446
  @unresolved_non_section_elements[template][:targets].push(instruction)
451
447
  else
@@ -461,15 +457,10 @@ module Enolib
461
457
  end
462
458
  end
463
459
 
464
- if @context.input[-1] == "\n"
465
- @context.line_count = @line + 1
466
- else
467
- @context.line_count = @line
468
- end
469
-
460
+ @context.line_count = @context.input[-1] == "\n" ? @line + 1 : @line
470
461
  @context.meta.concat(comments) if comments
471
462
 
472
- resolve if @unresolved_non_section_elements || @unresolved_sections
463
+ resolve unless @unresolved_non_section_elements.empty? && @unresolved_sections.empty?
473
464
  end
474
465
 
475
466
  private
@@ -529,24 +520,25 @@ module Enolib
529
520
  merge_map = {}
530
521
 
531
522
  section[:elements].each do |section_element|
532
- if section_element[:type] != :section || merge_map.has_key?(section_element[:key])
533
- merge_map[section_element[:key]] = false # non-mergable (no section or multiple instructions with same key)
534
- else
535
- merge_map[section_element[:key]] = { section: section_element }
536
- end
523
+ merge_map[section_element[:key]] =
524
+ if section_element[:type] != :section || merge_map.has_key?(section_element[:key])
525
+ false # non-mergable (no section or multiple instructions with same key)
526
+ else
527
+ { section: section_element }
528
+ end
537
529
  end
538
530
 
539
531
  template[:elements].each do |section_element|
540
- if merge_map.has_key?(section_element[:key])
541
- merger = merge_map[section_element[:key]]
532
+ next unless merge_map.has_key?(section_element[:key])
542
533
 
543
- next unless merger
534
+ merger = merge_map[section_element[:key]]
544
535
 
545
- if section_element[:type] != :section || merger.has_key?(:template)
546
- merge_map[section_element[:key]] = false # non-mergable (no section or multiple template instructions with same key)
547
- else
548
- merger[:template] = section_element
549
- end
536
+ next unless merger
537
+
538
+ if section_element[:type] != :section || merger.has_key?(:template)
539
+ merge_map[section_element[:key]] = false # non-mergable (no section or multiple template instructions with same key)
540
+ else
541
+ merger[:template] = section_element
550
542
  end
551
543
  end
552
544
 
@@ -692,7 +684,7 @@ module Enolib
692
684
  else
693
685
  instruction = {
694
686
  line: @line,
695
- ranges: { line: [@index, @context.input.length]}
687
+ ranges: { line: [@index, @context.input.length] }
696
688
  }
697
689
 
698
690
  instruction[:type] = :unparsed if first_instruction
@@ -86,10 +86,10 @@ module Enolib
86
86
  end
87
87
 
88
88
  def markup(gutter, content, tag_class = '')
89
- "<div class=\"eno-report-line #{tag_class}\">" +
90
- "<div class=\"eno-report-gutter\">#{gutter.rjust(10)}</div>" +
91
- "<div class=\"eno-report-content\">#{escape(content)}</div>" +
92
- '</div>'
89
+ "<div class=\"eno-report-line #{tag_class}\">" \
90
+ "<div class=\"eno-report-gutter\">#{gutter.rjust(10)}</div>" \
91
+ "<div class=\"eno-report-content\">#{escape(content)}</div>" \
92
+ '</div>'
93
93
  end
94
94
 
95
95
  def print
@@ -31,7 +31,7 @@ module Enolib
31
31
 
32
32
  def report_element(element)
33
33
  @snippet[element[:line]] = :emphasize
34
- tag_element(element, :indicate)
34
+ tag_children(element, :indicate)
35
35
 
36
36
  self
37
37
  end
@@ -39,7 +39,7 @@ module Enolib
39
39
  def report_elements(elements)
40
40
  elements.each do |element|
41
41
  @snippet[element[:line]] = :emphasize
42
- tag_element(element, :indicate)
42
+ tag_children(element, :indicate)
43
43
  end
44
44
 
45
45
  self
@@ -65,7 +65,7 @@ module Enolib
65
65
  if parent[:type] == :section
66
66
  tag_section(parent, :question, false)
67
67
  else
68
- tag_element(parent, :question)
68
+ tag_children(parent, :question)
69
69
  end
70
70
 
71
71
  self
@@ -139,10 +139,10 @@ module Enolib
139
139
 
140
140
  @index[item[:line]] = item
141
141
 
142
- if item.has_key?(:continuations)
143
- item[:continuations].each do |continuation|
144
- @index[continuation[:line]] = continuation
145
- end
142
+ next unless item.has_key?(:continuations)
143
+
144
+ item[:continuations].each do |continuation|
145
+ @index[continuation[:line]] = continuation
146
146
  end
147
147
  end
148
148
  end
@@ -153,10 +153,10 @@ module Enolib
153
153
 
154
154
  @index[entry[:line]] = entry
155
155
 
156
- if entry.has_key?(:continuations)
157
- entry[:continuations].each do |continuation|
158
- @index[continuation[:line]] = continuation
159
- end
156
+ next unless entry.has_key?(:continuations)
157
+
158
+ entry[:continuations].each do |continuation|
159
+ @index[continuation[:line]] = continuation
160
160
  end
161
161
  end
162
162
  end
@@ -209,14 +209,15 @@ module Enolib
209
209
  scan_line
210
210
  end
211
211
 
212
- def tag_element(element, tag)
213
- if element[:type] == :field || element[:type] == :list_item || element[:type] == :fieldset_entry
212
+ def tag_children(element, tag)
213
+ case element[:type]
214
+ when :field, :list_item, :fieldset_entry
214
215
  return tag_continuations(element, tag)
215
- elsif element[:type] == :list
216
+ when :list
216
217
  return tag_continuables(element, :items, tag)
217
- elsif element[:type] == :fieldset && element.has_key?(:entries)
218
+ when :fieldset
218
219
  return tag_continuables(element, :entries, tag)
219
- elsif element[:type] == :multiline_field_begin
220
+ when :multiline_field_begin
220
221
  if element.has_key?(:lines)
221
222
  element[:lines].each do |line|
222
223
  @snippet[line[:line]] = tag
@@ -226,30 +227,29 @@ module Enolib
226
227
  if element.has_key?(:end)
227
228
  @snippet[element[:end][:line]] = tag
228
229
  return element[:end][:line] + 1
229
- elsif element.has_key?(:lines)
230
- return element[:lines][-1][:line] + 1
231
- else
232
- return element[:line] + 1
233
230
  end
234
- elsif element[:type] == :section
231
+
232
+ return element[:lines][-1][:line] + 1 if element.has_key?(:lines)
233
+ return element[:line] + 1
234
+ when :section
235
235
  return tag_section(element, tag)
236
236
  end
237
237
  end
238
238
 
239
- def tag_section(section, tag, recursive=true)
239
+ def tag_section(section, tag, recursive = true)
240
240
  scan_line = section[:line] + 1
241
241
 
242
242
  section[:elements].each do |element|
243
243
  while scan_line < element[:line]
244
- @snippet[scan_line] = :indicate
244
+ @snippet[scan_line] = tag
245
245
  scan_line += 1
246
246
  end
247
247
 
248
248
  break if element[:type] == :section && !recursive
249
249
 
250
- @snippet[element[:line]] = :indicate
250
+ @snippet[element[:line]] = tag
251
251
 
252
- scan_line = tag_element(element, tag)
252
+ scan_line = tag_children(element, tag)
253
253
  end
254
254
 
255
255
  scan_line
@@ -18,14 +18,14 @@ INDICATORS = {
18
18
  emphasize: '>',
19
19
  indicate: '*',
20
20
  question: '?'
21
- }
21
+ }.freeze
22
22
 
23
23
  GUTTER_STYLE = {
24
24
  display: BRIGHT_BLACK_BACKGROUND,
25
25
  emphasize: BLACK + BRIGHT_RED_BACKGROUND,
26
26
  indicate: BLACK + WHITE_BACKGROUND,
27
27
  question: BLACK + WHITE_BACKGROUND
28
- }
28
+ }.freeze
29
29
 
30
30
  RANGE_STYLE = {
31
31
  'element_operator': WHITE,
@@ -42,7 +42,7 @@ RANGE_STYLE = {
42
42
  'key': BOLD + BRIGHT_WHITE,
43
43
  'template': BOLD + BRIGHT_WHITE,
44
44
  'value': DIM + WHITE
45
- }
45
+ }.freeze
46
46
 
47
47
  module Enolib
48
48
  class TerminalReporter < Reporter
@@ -76,12 +76,12 @@ module Enolib
76
76
 
77
77
  content = ''
78
78
  if instruction
79
- if instruction[:type] == :comment or instruction[:type] == :unparsed
79
+ if instruction[:type] == :comment || instruction[:type] == :unparsed
80
80
  content = BRIGHT_BLACK + @context.input[instruction[:ranges][:line][RANGE_BEGIN]...instruction[:ranges][:line][RANGE_END]] + RESET
81
81
  else
82
82
  content = @context.input[instruction[:ranges][:line][RANGE_BEGIN]...instruction[:ranges][:line][RANGE_END]]
83
83
 
84
- instruction[:ranges].sort_by { |type, range| range[0] }.reverse_each do |type, range|
84
+ instruction[:ranges].sort_by { |_type, range| range[0] }.reverse_each do |type, range|
85
85
  next if type == :line
86
86
 
87
87
  before = content[0...range[RANGE_BEGIN] - instruction[:ranges][:line][RANGE_BEGIN]]
@@ -7,7 +7,7 @@ module Enolib
7
7
  emphasize: '>',
8
8
  indicate: '*',
9
9
  question: '?'
10
- }
10
+ }.freeze
11
11
 
12
12
  def initialize(context)
13
13
  super(context)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: enolib
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.5.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Simon Repp
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-04-21 00:00:00.000000000 Z
11
+ date: 2019-05-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: deep-cover
@@ -52,6 +52,34 @@ dependencies:
52
52
  - - '='
53
53
  - !ruby/object:Gem::Version
54
54
  version: 0.1.0
55
+ - !ruby/object:Gem::Dependency
56
+ name: rubocop
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rubocop-performance
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
55
83
  description: The cross-language eno standard library
56
84
  email: simon@fdpl.io
57
85
  executables: []