psychgus 1.2.0 → 1.3.4

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.
@@ -1,22 +1,11 @@
1
- #!/usr/bin/env ruby
2
1
  # encoding: UTF-8
2
+ # frozen_string_literal: true
3
3
 
4
4
  #--
5
5
  # This file is part of Psychgus.
6
- # Copyright (c) 2019 Jonathan Bradley Whited (@esotericpig)
7
- #
8
- # Psychgus is free software: you can redistribute it and/or modify
9
- # it under the terms of the GNU Lesser General Public License as published by
10
- # the Free Software Foundation, either version 3 of the License, or
11
- # (at your option) any later version.
12
- #
13
- # Psychgus is distributed in the hope that it will be useful,
14
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
15
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
- # GNU Lesser General Public License for more details.
17
- #
18
- # You should have received a copy of the GNU Lesser General Public License
19
- # along with Psychgus. If not, see <http://www.gnu.org/licenses/>.
6
+ # Copyright (c) 2019-2021 Jonathan Bradley Whited
7
+ #
8
+ # SPDX-License-Identifier: LGPL-3.0-or-later
20
9
  #++
21
10
 
22
11
 
@@ -26,12 +15,11 @@ module Psychgus
26
15
  class SuperSniffer
27
16
  ###
28
17
  # An empty {SuperSniffer} used for speed when you don't need sniffing in {StyledTreeBuilder}.
29
- #
30
- # @author Jonathan Bradley Whited (@esotericpig)
18
+ #
19
+ # @author Jonathan Bradley Whited
31
20
  # @since 1.0.0
32
21
  ###
33
22
  class Empty < SuperSniffer
34
- def initialize(*) end
35
23
  def add_alias(*) end
36
24
  def add_scalar(*) end
37
25
  def end_document(*) end
@@ -44,29 +32,31 @@ module Psychgus
44
32
  def start_stream(*) end
45
33
  end
46
34
  end
47
-
35
+
48
36
  ###
49
37
  # This is used in {StyledTreeBuilder} to "sniff" information about the YAML.
50
- #
38
+ #
51
39
  # Then this information can be used in a {Styler} and/or a {Blueberry}.
52
- #
40
+ #
53
41
  # Most information is straightforward:
54
42
  # - {#aliases} # Array of Psych::Nodes::Alias processed so far
43
+ # - {#documents} # Array of Psych::Nodes::Document processed so far
55
44
  # - {#mappings} # Array of Psych::Nodes::Mapping processed so far
56
- # - {#nodes} # Array of all Psych::Nodes::Node processed so far
45
+ # - {#nodes} # Array of Psych::Nodes::Node processed so far
57
46
  # - {#scalars} # Array of Psych::Nodes::Scalar processed so far
58
47
  # - {#sequences} # Array of Psych::Nodes::Sequence processed so far
59
- #
48
+ # - {#streams} # Array of Psych::Nodes::Stream processed so far
49
+ #
60
50
  # {#parent} is the current {SuperSniffer::Parent} of the node being processed,
61
- # which is nil for the first node.
62
- #
51
+ # which is an empty Parent for the first node (not nil).
52
+ #
63
53
  # {#parents} are all of the (grand){SuperSniffer::Parent}(s) for the current node,
64
- # which is empty for the first node.
65
- #
54
+ # which is an Array that just contains an empty Parent for the first node.
55
+ #
66
56
  # A parent is a Mapping or Sequence, or a Key (Scalar) in a Mapping.
67
- #
57
+ #
68
58
  # {#level} and {#position} can be best understood by an example.
69
- #
59
+ #
70
60
  # If you have this YAML:
71
61
  # Burgers:
72
62
  # Classic:
@@ -85,10 +75,10 @@ module Psychgus
85
75
  # - Mushrooms
86
76
  # - [Lettuce, Onions, Pickles, Tomatoes]
87
77
  # - [[Ketchup,Mustard], [Salt,Pepper]]
88
- #
78
+ #
89
79
  # Then the levels and positions will be as follows:
90
80
  # # (level:position):current_node - <parent:(parent_level:parent_position)>
91
- #
81
+ #
92
82
  # (1:1):Psych::Nodes::Stream - <root:(0:0)>
93
83
  # (1:1):Psych::Nodes::Document - <stream:(1:1)>
94
84
  # (1:1):Psych::Nodes::Mapping - <doc:(1:1)>
@@ -135,37 +125,37 @@ module Psychgus
135
125
  # (5:2):Psych::Nodes::Sequence - <seq:(4:3)>
136
126
  # (6:1):Salt - <seq:(5:2)>
137
127
  # (6:2):Pepper - <seq:(5:2)>
138
- #
139
- # The "Super Sniffer" is the nickname for Gus's nose from the TV show Psych
128
+ #
129
+ # "The Super Sniffer" is the nickname for Gus's nose from the TV show Psych
140
130
  # because he has a very refined sense of smell.
141
- #
131
+ #
142
132
  # @note You should never call the methods that are not readers, like {#add_alias}, {#start_mapping}, etc.
143
133
  # unless you are extending this class (creating a subclass).
144
- #
145
- # @author Jonathan Bradley Whited (@esotericpig)
134
+ #
135
+ # @author Jonathan Bradley Whited
146
136
  # @since 1.0.0
147
- #
137
+ #
148
138
  # @see StyledTreeBuilder
149
139
  # @see Styler
150
140
  # @see Blueberry#psychgus_stylers
151
141
  ###
152
142
  class SuperSniffer
153
- EMPTY = Empty.new().freeze()
154
-
155
- attr_reader :aliases
156
- attr_reader :documents
157
- attr_reader :level
158
- attr_reader :mappings
159
- attr_reader :nodes
160
- attr_reader :parent
161
- attr_reader :parents
162
- attr_reader :position
163
- attr_reader :scalars
164
- attr_reader :sequences
165
- attr_reader :streams
166
-
143
+ EMPTY = Empty.new.freeze
144
+
145
+ attr_reader :aliases # @return [Array<Psych::Nodes::Alias>] the aliases processed so far
146
+ attr_reader :documents # @return [Array<Psych::Nodes::Document>] the documents processed so far
147
+ attr_reader :level # @return [Integer] the current level
148
+ attr_reader :mappings # @return [Array<Psych::Nodes::Mapping>] the mappings processed so far
149
+ attr_reader :nodes # @return [Array<Psych::Nodes::Node>] the nodes processed so far
150
+ attr_reader :parent # @return [Parent] the current parent
151
+ attr_reader :parents # @return [Array<Parent>] the current (grand)parents
152
+ attr_reader :position # @return [Integer] the current position
153
+ attr_reader :scalars # @return [Array<Psych::Nodes::Scalar>] the scalars processed so far
154
+ attr_reader :sequences # @return [Array<Psych::Nodes::Sequence>] the sequences processed so far
155
+ attr_reader :streams # @return [Array<Psych::Nodes::Stream>] the streams processed so far
156
+
167
157
  # Initialize this class for sniffing.
168
- def initialize()
158
+ def initialize
169
159
  @aliases = []
170
160
  @documents = []
171
161
  @level = 0
@@ -177,240 +167,240 @@ module Psychgus
177
167
  @scalars = []
178
168
  @sequences = []
179
169
  @streams = []
180
-
170
+
181
171
  # Do not pass in "top_level: true"
182
172
  start_parent(nil,debug_tag: :root)
183
173
  end
184
-
174
+
185
175
  # Add a Psych::Nodes::Alias to this class only (not to the YAML).
186
- #
176
+ #
187
177
  # A {Styler} should probably never call this.
188
- #
178
+ #
189
179
  # @param node [Psych::Nodes::Alias] the alias to add
190
- #
180
+ #
191
181
  # @see add_child
192
182
  def add_alias(node)
193
183
  add_child(node)
194
184
  @aliases.push(node)
195
185
  end
196
-
186
+
197
187
  # Add a Psych::Nodes::Scalar to this class only (not to the YAML).
198
- #
188
+ #
199
189
  # A {Styler} should probably never call this.
200
- #
190
+ #
201
191
  # @param node [Psych::Nodes::Scalar] the scalar to add
202
- #
192
+ #
203
193
  # @see add_child
204
194
  def add_scalar(node)
205
195
  add_child(node)
206
196
  @scalars.push(node)
207
197
  end
208
-
198
+
209
199
  # End a Psych::Nodes::Document started with {#start_document}.
210
- #
200
+ #
211
201
  # Pops off a parent from {#parents} and sets {#parent} to the last one.
212
202
  # {#level} and {#position} are reset according to the last parent.
213
- #
203
+ #
214
204
  # A {Styler} should probably never call this.
215
- def end_document()
205
+ def end_document
216
206
  end_parent(top_level: true)
217
207
  end
218
-
208
+
219
209
  # End a Psych::Nodes::Mapping started with {#start_mapping}.
220
- #
210
+ #
221
211
  # Pops off a parent from {#parents} and sets {#parent} to the last one.
222
212
  # {#level} and {#position} are reset according to the last parent.
223
- #
213
+ #
224
214
  # A {Styler} should probably never call this.
225
- #
215
+ #
226
216
  # @see end_parent
227
- def end_mapping()
217
+ def end_mapping
228
218
  end_parent(mapping_value: true)
229
219
  end
230
-
220
+
231
221
  # End a Psych::Nodes::Sequence started with {#start_sequence}.
232
- #
222
+ #
233
223
  # Pops off a parent from {#parents} and sets {#parent} to the last one.
234
224
  # {#level} and {#position} are reset according to the last parent.
235
- #
225
+ #
236
226
  # A {Styler} should probably never call this.
237
- #
227
+ #
238
228
  # @see end_parent
239
- def end_sequence()
229
+ def end_sequence
240
230
  end_parent(mapping_value: true)
241
231
  end
242
-
232
+
243
233
  # End a Psych::Nodes::Stream started with {#start_stream}.
244
- #
234
+ #
245
235
  # Pops off a parent from {#parents} and sets {#parent} to the last one.
246
236
  # {#level} and {#position} are reset according to the last parent.
247
- #
237
+ #
248
238
  # A {Styler} should probably never call this.
249
- def end_stream()
239
+ def end_stream
250
240
  end_parent(top_level: true)
251
241
  end
252
-
242
+
253
243
  # Start a Psych::Nodes::Document.
254
- #
244
+ #
255
245
  # Creates a {SuperSniffer::Parent}, sets {#parent} to it, and adds it to {#parents}.
256
246
  # {#level} and {#position} are incremented/set accordingly.
257
- #
247
+ #
258
248
  # A {Styler} should probably never call this.
259
- #
249
+ #
260
250
  # @param node [Psych::Nodes::Document] the Document to start
261
- #
251
+ #
262
252
  # @see start_parent
263
253
  def start_document(node)
264
254
  start_parent(node,debug_tag: :doc,top_level: true)
265
255
  @documents.push(node)
266
256
  end
267
-
257
+
268
258
  # Start a Psych::Nodes::Mapping.
269
- #
259
+ #
270
260
  # Creates a {SuperSniffer::Parent}, sets {#parent} to it, and adds it to {#parents}.
271
261
  # {#level} and {#position} are incremented/set accordingly.
272
- #
262
+ #
273
263
  # A {Styler} should probably never call this.
274
- #
264
+ #
275
265
  # @param node [Psych::Nodes::Mapping] the Mapping to start
276
- #
266
+ #
277
267
  # @see start_parent
278
268
  def start_mapping(node)
279
269
  start_parent(node,debug_tag: :map,child_type: :key)
280
270
  @mappings.push(node)
281
271
  end
282
-
272
+
283
273
  # Start a Psych::Nodes::Sequence.
284
- #
274
+ #
285
275
  # Creates a {SuperSniffer::Parent}, sets {#parent} to it, and adds it to {#parents}.
286
276
  # {#level} and {#position} are incremented/set accordingly.
287
- #
277
+ #
288
278
  # A {Styler} should probably never call this.
289
- #
279
+ #
290
280
  # @param node [Psych::Nodes::Sequence] the Sequence to start
291
- #
281
+ #
292
282
  # @see start_parent
293
283
  def start_sequence(node)
294
284
  start_parent(node,debug_tag: :seq)
295
285
  @sequences.push(node)
296
286
  end
297
-
287
+
298
288
  # Start a Psych::Nodes::Stream.
299
- #
289
+ #
300
290
  # Creates a {SuperSniffer::Parent}, sets {#parent} to it, and adds it to {#parents}.
301
291
  # {#level} and {#position} are incremented/set accordingly.
302
- #
292
+ #
303
293
  # A {Styler} should probably never call this.
304
- #
294
+ #
305
295
  # @param node [Psych::Nodes::Stream] the Stream to start
306
- #
296
+ #
307
297
  # @see start_parent
308
298
  def start_stream(node)
309
299
  start_parent(node,debug_tag: :stream,top_level: true)
310
300
  @streams.push(node)
311
301
  end
312
-
302
+
313
303
  protected
314
-
304
+
315
305
  # Add a non-parent node.
316
- #
306
+ #
317
307
  # This will increment {#position} accordingly, and if the child is a Key to a Mapping,
318
308
  # create a fake "{SuperSniffer::Parent}".
319
- #
309
+ #
320
310
  # @param node [Psych::Nodes::Node] the non-parent Node to add
321
- #
311
+ #
322
312
  # @see end_mapping_value
323
313
  def add_child(node)
324
- if !@parent.nil?()
314
+ if !@parent.nil?
325
315
  # Fake a "parent" if necessary
326
316
  case @parent.child_type
327
317
  when :key
328
318
  start_mapping_key(node)
329
319
  return
330
320
  when :value
331
- end_mapping_value()
321
+ end_mapping_value
332
322
  return
333
323
  else
334
324
  @parent.child_position += 1
335
325
  end
336
326
  end
337
-
327
+
338
328
  @position += 1
339
-
329
+
340
330
  @nodes.push(node)
341
331
  end
342
-
332
+
343
333
  # End a fake "{SuperSniffer::Parent}" that is a Key/Value to a Mapping.
344
- #
334
+ #
345
335
  # @see add_child
346
- def end_mapping_value()
347
- end_parent() # Do not pass in "mapping_value: true" and/or "top_level: true"
348
-
349
- @parent.child_type = :key unless @parent.nil?()
336
+ def end_mapping_value
337
+ end_parent # Do not pass in "mapping_value: true" and/or "top_level: true"
338
+
339
+ @parent.child_type = :key unless @parent.nil?
350
340
  end
351
-
341
+
352
342
  # End a {SuperSniffer::Parent}.
353
- #
343
+ #
354
344
  # Pops off a parent from {#parents} and sets {#parent} to the last one.
355
345
  # {#level} and {#position} are reset according to the last parent.
356
- #
346
+ #
357
347
  # @param mapping_value [true,false] true if parent can be the value of a Mapping's key
358
348
  # @param top_level [true,false] true if a top-level parent (i.e., encapsulating the main data)
359
349
  def end_parent(mapping_value: false,top_level: false)
360
- @parents.pop()
350
+ @parents.pop
361
351
  @parent = @parents.last
362
-
352
+
363
353
  @level = top_level ? 1 : (@level - 1)
364
-
365
- if !@parent.nil?()
354
+
355
+ if !@parent.nil?
366
356
  @parent.child_position += 1
367
357
  @position = @parent.child_position
368
-
358
+
369
359
  # add_child() will not be called again, so end a fake "parent" manually with a fake "value"
370
360
  # - This is necessary for any parents that can be the value of a map's key (e.g., Sequence)
371
- end_mapping_value() if mapping_value && !@parent.child_type.nil?()
361
+ end_mapping_value if mapping_value && !@parent.child_type.nil?
372
362
  end
373
363
  end
374
-
364
+
375
365
  # Start a fake "{SuperSniffer::Parent}" that is a Key/Value to a Mapping.
376
- #
366
+ #
377
367
  # Creates a {SuperSniffer::Parent}, sets {#parent} to it, and adds it to {#parents}.
378
368
  # {#level} and {#position} are incremented/set accordingly.
379
- #
369
+ #
380
370
  # @param node [Psych::Nodes::Node] the Node to start
381
- #
371
+ #
382
372
  # @see start_parent
383
373
  def start_mapping_key(node)
384
374
  debug_tag = nil
385
-
375
+
386
376
  # Value must be first because Scalar also has an anchor
387
377
  if node.respond_to?(:value)
388
378
  debug_tag = node.value
389
379
  elsif node.respond_to?(:anchor)
390
380
  debug_tag = node.anchor
391
381
  end
392
-
393
- debug_tag = :noface if debug_tag.nil?()
394
-
382
+
383
+ debug_tag = :noface if debug_tag.nil?
384
+
395
385
  start_parent(node,debug_tag: debug_tag,child_type: :value)
396
386
  end
397
-
387
+
398
388
  # Start a {SuperSniffer::Parent}.
399
- #
389
+ #
400
390
  # Creates a {SuperSniffer::Parent}, sets {#parent} to it, and adds it to {#parents}.
401
391
  # {#level} and {#position} are incremented/set accordingly.
402
- #
392
+ #
403
393
  # @param node [Psych::Nodes::Node] the parent Node to start
404
394
  # @param top_level [true,false] true if a top-level parent (i.e., encapsulating the main data)
405
395
  # @param extra [Hash] the extra keyword args to pass to {SuperSniffer::Parent#initialize}
406
- #
396
+ #
407
397
  # @see SuperSniffer::Parent#initialize
408
398
  def start_parent(node,top_level: false,**extra)
409
399
  @parent = Parent.new(self,node,**extra)
410
-
400
+
411
401
  @parents.push(@parent)
412
- @nodes.push(node) unless node.nil?()
413
-
402
+ @nodes.push(node) unless node.nil?
403
+
414
404
  if top_level
415
405
  @level = 1
416
406
  @position = @parent.position