psychgus 1.3.3 → 1.3.5

Sign up to get free protection for your applications and to get access to all the features.
data/lib/psychgus.rb CHANGED
@@ -1,29 +1,16 @@
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) 2017-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) 2017 Bradley Whited
7
+ #
8
+ # SPDX-License-Identifier: LGPL-3.0-or-later
20
9
  #++
21
10
 
22
-
23
11
  require 'psych'
24
12
 
25
13
  require 'psychgus/blueberry'
26
- require 'psychgus/ext'
27
14
  require 'psychgus/stylables'
28
15
  require 'psychgus/styled_document_stream'
29
16
  require 'psychgus/styled_tree_builder'
@@ -42,22 +29,22 @@ require 'psychgus/super_sniffer/parent'
42
29
  # Psychgus uses the core standard library {https://github.com/ruby/psych Psych} for working with YAML
43
30
  # and extends it so that developers can easily style the YAML according to their needs.
44
31
  # Thank you to the people that worked and continue to work hard on that project.
45
- #
32
+ #
46
33
  # The name comes from the well-styled character Gus from the TV show Psych.
47
- #
34
+ #
48
35
  # == Create a Styler
49
- #
36
+ #
50
37
  # First, we will create a {Styler}.
51
- #
38
+ #
52
39
  # All you need to do is add +include Psychgus::Styler+ to a class.
53
- #
40
+ #
54
41
  # Here is a complex {Styler} for the examples below:
55
42
  # require 'psychgus'
56
- #
43
+ #
57
44
  # class BurgerStyler
58
45
  # # Mix in methods needed for styling
59
46
  # include Psychgus::Styler
60
- #
47
+ #
61
48
  # def initialize(sniffer=nil)
62
49
  # if sniffer.nil?()
63
50
  # @class_level = 0
@@ -68,48 +55,48 @@ require 'psychgus/super_sniffer/parent'
68
55
  # @class_position = sniffer.position
69
56
  # end
70
57
  # end
71
- #
58
+ #
72
59
  # # Style all nodes (Psych::Nodes::Node)
73
60
  # def style(sniffer,node)
74
61
  # # Remove "!ruby/object:..." for classes
75
62
  # node.tag = nil if node.node_of?(:mapping,:scalar,:sequence)
76
- #
63
+ #
77
64
  # # This is another way to do the above
78
65
  # #node.tag = nil if node.respond_to?(:tag=)
79
66
  # end
80
- #
67
+ #
81
68
  # # Style aliases (Psych::Nodes::Alias)
82
69
  # def style_alias(sniffer,node)
83
70
  # end
84
- #
71
+ #
85
72
  # # Style maps (Psych::Nodes::Mapping)
86
73
  # # - Hashes (key/value pairs)
87
74
  # # - Example: "Burgers: Classic {}"
88
75
  # def style_mapping(sniffer,node)
89
76
  # parent = sniffer.parent
90
- #
77
+ #
91
78
  # if !parent.nil?()
92
79
  # # BBQ
93
80
  # node.style = Psychgus::MAPPING_FLOW if parent.node_of?(:scalar) &&
94
81
  # parent.value.casecmp('BBQ') == 0
95
82
  # end
96
83
  # end
97
- #
84
+ #
98
85
  # # Style scalars (Psych::Nodes::Scalar)
99
86
  # # - Any text (non-alias)
100
87
  # def style_scalar(sniffer,node)
101
88
  # parent = sniffer.parent
102
- #
89
+ #
103
90
  # # Single quote scalars that are not keys to a map
104
91
  # # - "child_key?" is the same as "child_type == :key"
105
92
  # node.style = Psychgus::SCALAR_SINGLE_QUOTED unless parent.child_key?()
106
- #
93
+ #
107
94
  # # Remove colon (change symbols into strings)
108
95
  # node.value = node.value.sub(':','')
109
- #
96
+ #
110
97
  # # Change lettuce to spinach
111
98
  # node.value = 'Spinach' if node.value.casecmp('Lettuce') == 0
112
- #
99
+ #
113
100
  # # Capitalize each word
114
101
  # node.value = node.value.split(' ').map do |v|
115
102
  # if v.casecmp('BBQ') == 0
@@ -119,23 +106,23 @@ require 'psychgus/super_sniffer/parent'
119
106
  # end
120
107
  # end.join(' ')
121
108
  # end
122
- #
109
+ #
123
110
  # # Style sequences (Psych::Nodes::Sequence)
124
111
  # # - Arrays
125
112
  # # - Example: "[Lettuce, Onions, Pickles, Tomatoes]"
126
113
  # def style_sequence(sniffer,node)
127
114
  # relative_level = (sniffer.level - @class_level) + 1
128
- #
115
+ #
129
116
  # node.style = Psychgus::SEQUENCE_FLOW if sniffer.level >= 4
130
- #
117
+ #
131
118
  # # Make "[Ketchup, Mustard]" a block for the Class Example
132
119
  # node.style = Psychgus::SEQUENCE_BLOCK if relative_level == 7
133
120
  # end
134
121
  # end
135
- #
122
+ #
136
123
  # @example Hash example
137
124
  # require 'psychgus'
138
- #
125
+ #
139
126
  # burgers = {
140
127
  # :Burgers => {
141
128
  # :Classic => {
@@ -161,9 +148,9 @@ require 'psychgus/super_sniffer/parent'
161
148
  # ]
162
149
  # }
163
150
  # burgers[:Favorite] = burgers[:Burgers][:BBQ] # Alias
164
- #
151
+ #
165
152
  # puts burgers.to_yaml(indent: 3,stylers: BurgerStyler.new,deref_aliases: true)
166
- #
153
+ #
167
154
  # # Output:
168
155
  # # ---
169
156
  # # Burgers:
@@ -184,21 +171,21 @@ require 'psychgus/super_sniffer/parent'
184
171
  # # Sauce: 'Honey BBQ'
185
172
  # # Cheese: 'Cheddar'
186
173
  # # Bun: 'Kaiser'
187
- #
174
+ #
188
175
  # @example Class example
189
176
  # require 'psychgus'
190
- #
177
+ #
191
178
  # class Burger
192
179
  # attr_accessor :bun
193
180
  # attr_accessor :cheese
194
181
  # attr_accessor :sauce
195
- #
182
+ #
196
183
  # def initialize(sauce,cheese,bun)
197
184
  # @bun = bun
198
185
  # @cheese = cheese
199
186
  # @sauce = sauce
200
187
  # end
201
- #
188
+ #
202
189
  # # You can still use Psych's encode_with(), no problem
203
190
  # #def encode_with(coder)
204
191
  # # coder['Bun'] = @bun
@@ -206,34 +193,34 @@ require 'psychgus/super_sniffer/parent'
206
193
  # # coder['Sauce'] = @sauce
207
194
  # #end
208
195
  # end
209
- #
196
+ #
210
197
  # class Burgers
211
198
  # include Psychgus::Blueberry
212
- #
199
+ #
213
200
  # attr_accessor :burgers
214
201
  # attr_accessor :toppings
215
202
  # attr_accessor :favorite
216
- #
203
+ #
217
204
  # def initialize()
218
205
  # @burgers = {
219
206
  # 'Classic' => Burger.new(['Ketchup','Mustard'],'American','Sesame Seed'),
220
207
  # 'BBQ' => Burger.new('Honey BBQ','Cheddar','Kaiser'),
221
208
  # 'Fancy' => Burger.new('Spicy Wasabi','Smoked Gouda','Hawaiian')
222
209
  # }
223
- #
210
+ #
224
211
  # @toppings = [
225
212
  # 'Mushrooms',
226
213
  # %w(Lettuce Onions Pickles Tomatoes),
227
214
  # [%w(Ketchup Mustard),%w(Salt Pepper)]
228
215
  # ]
229
- #
216
+ #
230
217
  # @favorite = @burgers['BBQ'] # Alias
231
218
  # end
232
- #
219
+ #
233
220
  # def psychgus_stylers(sniffer)
234
221
  # return BurgerStyler.new(sniffer)
235
222
  # end
236
- #
223
+ #
237
224
  # # You can still use Psych's encode_with(), no problem
238
225
  # #def encode_with(coder)
239
226
  # # coder['Burgers'] = @burgers
@@ -241,10 +228,10 @@ require 'psychgus/super_sniffer/parent'
241
228
  # # coder['Favorite'] = @favorite
242
229
  # #end
243
230
  # end
244
- #
231
+ #
245
232
  # burgers = Burgers.new
246
233
  # puts burgers.to_yaml(indent: 3,deref_aliases: true)
247
- #
234
+ #
248
235
  # # Output:
249
236
  # # ---
250
237
  # # Burgers:
@@ -267,144 +254,141 @@ require 'psychgus/super_sniffer/parent'
267
254
  # # Bun: 'Kaiser'
268
255
  # # Cheese: 'Cheddar'
269
256
  # # Sauce: 'Honey BBQ'
270
- #
257
+ #
271
258
  # @example Emitting / Parsing examples
272
259
  # styler = BurgerStyler.new()
273
260
  # options = {:indentation=>3,:stylers=>styler,:deref_aliases=>true}
274
261
  # yaml = burgers.to_yaml(options)
275
- #
262
+ #
276
263
  # # High-level emitting
277
264
  # Psychgus.dump(burgers,options)
278
265
  # Psychgus.dump_file('burgers.yaml',burgers,options)
279
266
  # burgers.to_yaml(options)
280
- #
267
+ #
281
268
  # # High-level parsing
282
269
  # # - Because to_ruby() will be called, just use Psych:
283
270
  # # - load(), load_file(), load_stream(), safe_load()
284
- #
271
+ #
285
272
  # # Mid-level emitting
286
273
  # stream = Psychgus.parse_stream(yaml,stylers: styler,deref_aliases: true)
287
- #
274
+ #
288
275
  # stream.to_yaml()
289
- #
276
+ #
290
277
  # # Mid-level parsing
291
278
  # Psychgus.parse(yaml,stylers: styler,deref_aliases: true)
292
279
  # Psychgus.parse_file('burgers.yaml',stylers: styler,deref_aliases: true)
293
280
  # Psychgus.parse_stream(yaml,stylers: styler,deref_aliases: true)
294
- #
281
+ #
295
282
  # # Low-level emitting
296
283
  # tree_builder = Psychgus::StyledTreeBuilder.new(styler,deref_aliases: true)
297
284
  # visitor = Psych::Visitors::YAMLTree.create(options,tree_builder)
298
- #
285
+ #
299
286
  # visitor << burgers
300
287
  # visitor.tree.to_yaml
301
- #
288
+ #
302
289
  # # Low-level parsing
303
290
  # parser = Psychgus.parser(stylers: styler,deref_aliases: true)
304
- #
291
+ #
305
292
  # parser.parse(yaml)
306
293
  # parser.handler
307
294
  # parser.handler.root
308
- #
309
- # @author Jonathan Bradley Whited (@esotericpig)
310
- # @since 1.0.0
311
295
  ###
312
296
  module Psychgus
313
297
  # Include these in the top namespace for convenience (i.e., less typing).
314
- include Stylables # @since 1.2.0
315
- include Stylers # @since 1.2.0
316
-
317
- NODE_CLASS_ALIASES = {:Doc => :Document,:Map => :Mapping,:Seq => :Sequence}
318
- OPTIONS_ALIASES = {:canon => :canonical,:indent => :indentation}
319
-
298
+ include Stylables
299
+ include Stylers
300
+
301
+ NODE_CLASS_ALIASES = {Doc: :Document,Map: :Mapping,Seq: :Sequence}.freeze
302
+ OPTIONS_ALIASES = {canon: :canonical,indent: :indentation}.freeze
303
+
320
304
  # Get a Class (constant) from Psych::Nodes.
321
- #
305
+ #
322
306
  # Some +name+s have aliases:
323
307
  # :doc => :document
324
308
  # :map => :mapping
325
309
  # :seq => :sequence
326
- #
310
+ #
327
311
  # @param name [Symbol,String] the name of the class from Psych::Nodes
328
- #
312
+ #
329
313
  # @return [Class] a class from Psych::Nodes
330
- #
314
+ #
331
315
  # @see Psych::Nodes
332
316
  # @see NODE_CLASS_ALIASES
333
317
  def self.node_class(name)
334
- name = name.to_sym().capitalize()
335
-
318
+ name = name.to_sym.capitalize
319
+
336
320
  actual_name = NODE_CLASS_ALIASES[name]
337
- name = actual_name unless actual_name.nil?()
338
-
321
+ name = actual_name unless actual_name.nil?
322
+
339
323
  return Psych::Nodes.const_get(name)
340
324
  end
341
-
325
+
342
326
  # Get a constant from a Psych::Nodes class (using {.node_class}).
343
- #
327
+ #
344
328
  # @param class_name [Symbol,String] the name of the class to get using {.node_class}
345
329
  # @param const_name [Symbol,String] the constant to get from the class
346
330
  # @param lenient [true,false] if true, will return 0 if not const_defined?(), else raise an error
347
- #
331
+ #
348
332
  # @return [Integer,Object] the constant value from the class (usually an int)
349
- #
333
+ #
350
334
  # @see .node_class
351
335
  def self.node_const(class_name,const_name,lenient=true)
352
336
  node_class = node_class(class_name)
353
- const_name = const_name.to_sym().upcase()
354
-
337
+ const_name = const_name.to_sym.upcase
338
+
355
339
  return 0 if lenient && !node_class.const_defined?(const_name,true)
356
340
  return node_class.const_get(const_name,true)
357
341
  end
358
-
342
+
359
343
  MAPPING_ANY = node_const(:mapping,:any)
360
344
  MAPPING_BLOCK = node_const(:mapping,:block)
361
345
  MAPPING_FLOW = node_const(:mapping,:flow)
362
346
  MAP_ANY = MAPPING_ANY
363
347
  MAP_BLOCK = MAPPING_BLOCK
364
348
  MAP_FLOW = MAPPING_FLOW
365
-
349
+
366
350
  SCALAR_ANY = node_const(:scalar,:any)
367
351
  SCALAR_PLAIN = node_const(:scalar,:plain)
368
352
  SCALAR_SINGLE_QUOTED = node_const(:scalar,:single_quoted)
369
353
  SCALAR_DOUBLE_QUOTED = node_const(:scalar,:double_quoted)
370
354
  SCALAR_LITERAL = node_const(:scalar,:literal)
371
355
  SCALAR_FOLDED = node_const(:scalar,:folded)
372
-
356
+
373
357
  SEQUENCE_ANY = node_const(:sequence,:any)
374
358
  SEQUENCE_BLOCK = node_const(:sequence,:block)
375
359
  SEQUENCE_FLOW = node_const(:sequence,:flow)
376
360
  SEQ_ANY = SEQUENCE_ANY
377
361
  SEQ_BLOCK = SEQUENCE_BLOCK
378
362
  SEQ_FLOW = SEQUENCE_FLOW
379
-
363
+
380
364
  STREAM_ANY = node_const(:stream,:any)
381
365
  STREAM_UTF8 = node_const(:stream,:utf8)
382
366
  STREAM_UTF16LE = node_const(:stream,:utf16le)
383
367
  STREAM_UTF16BE = node_const(:stream,:utf16be)
384
-
368
+
385
369
  # Convert +object+ to YAML and dump to +io+.
386
- #
370
+ #
387
371
  # +object+, +io+, and +options+ are used like in Psych.dump so can be a drop-in replacement for Psych.
388
- #
372
+ #
389
373
  # @param object [Object] the Object to convert to YAML and dump
390
374
  # @param io [nil,IO,Hash] the IO to dump the YAML to or the +options+ Hash; if nil, will use StringIO
391
375
  # @param options [Hash] the options (or keyword args) to use; see {.dump_stream}
392
- #
376
+ #
393
377
  # @return [String,Object] the result of converting +object+ to YAML using the params
394
- #
378
+ #
395
379
  # @see .dump_stream
396
380
  # @see Psych.dump_stream
397
381
  def self.dump(object,io=nil,**options)
398
382
  return dump_stream(object,io: io,**options)
399
383
  end
400
-
384
+
401
385
  # Convert +objects+ to YAML and dump to a file.
402
- #
386
+ #
403
387
  # @example
404
388
  # Psychgus.dump_file('my_dir/my_file.yaml',my_object1,my_object2,mode: 'w:UTF-16',
405
389
  # stylers: MyStyler.new())
406
390
  # Psychgus.dump_file('my_file.yaml',my_object,stylers: [MyStyler1.new(),MyStyler2.new()])
407
- #
391
+ #
408
392
  # @param filename [String] the name of the file (and path) to dump to
409
393
  # @param objects [Object,Array<Object>] the Object(s) to convert to YAML and dump
410
394
  # @param mode [String,Integer] the IO open mode to use; examples:
@@ -415,23 +399,23 @@ module Psychgus
415
399
  # @param perm [Integer] the permission bits to use (platform dependent)
416
400
  # @param opt [Hash] Hash of keyword args to pass to +File.open()+
417
401
  # @param options [Hash] the options (or keyword args) to use; see {.dump_stream}
418
- #
402
+ #
419
403
  # @see .dump_stream
420
404
  # @see File.open
421
405
  # @see IO.new
422
406
  # @see https://ruby-doc.org/core/IO.html#method-c-new
423
407
  def self.dump_file(filename,*objects,mode: 'w',perm: nil,opt: nil,**options)
424
408
  opt = Hash(opt)
425
-
409
+
426
410
  File.open(filename,mode,perm,**opt) do |file|
427
411
  file.write(dump_stream(*objects,**options))
428
412
  end
429
413
  end
430
-
414
+
431
415
  # Convert +objects+ to YAML and dump to +io+.
432
- #
416
+ #
433
417
  # +io+ and +options+ are used like in Psych.dump so can be a drop-in replacement for Psych.
434
- #
418
+ #
435
419
  # @param objects [Object,Array<Object>] the Object(s) to convert to YAML and dump
436
420
  # @param io [nil,IO,Hash] the IO to dump the YAML to or the +options+ Hash; if nil, will use StringIO
437
421
  # @param stylers [nil,Styler,Array<Styler>] the Styler(s) to use when converting to YAML
@@ -449,47 +433,48 @@ module Psychgus
449
433
  # Write "canonical" YAML form (very verbose, yet strictly formal).
450
434
  # [+:header+] Default: +false+.
451
435
  # Write +%YAML [version]+ at the beginning of document.
452
- #
436
+ #
453
437
  # @return [String,Object] the result of converting +object+ to YAML using the params
454
- #
438
+ #
455
439
  # @see Psych.dump_stream
456
440
  # @see OPTIONS_ALIASES
457
441
  def self.dump_stream(*objects,io: nil,stylers: nil,deref_aliases: false,**options)
458
442
  # If you call this method with only a Hash that uses symbols as keys,
459
443
  # then options will be set to the Hash, instead of objects.
460
- #
444
+ #
461
445
  # For example, the below will be stored in options, not objects:
462
446
  # - dump_stream({:coffee => {:roast => [],:style => []}})
463
- #
447
+ #
464
448
  # This if-statement is guaranteed because dump_stream([]) and dump_stream(nil)
465
449
  # will produce [[]] and [nil], which are not empty.
466
- #
450
+ #
467
451
  # dump_stream() w/o any args is the only problem, but resolved w/ [nil].
468
- if objects.empty?()
469
- objects = options.empty?() ? [nil] : [options]
452
+ if objects.empty?
453
+ objects = options.empty? ? [nil] : [options]
470
454
  options = {}
471
455
  end
472
-
473
- if Hash === io
456
+
457
+ if io.is_a?(Hash)
474
458
  options = io
475
459
  io = nil
476
460
  end
477
-
478
- if !options.empty?()
461
+
462
+ if !options.empty?
479
463
  OPTIONS_ALIASES.each do |option_alias,actual_option|
480
464
  if options.key?(option_alias) && !options.key?(actual_option)
481
465
  options[actual_option] = options[option_alias]
482
466
  end
483
467
  end
484
468
  end
485
-
469
+
486
470
  visitor = Psych::Visitors::YAMLTree.create(options,StyledTreeBuilder.new(*stylers,
487
471
  deref_aliases: deref_aliases))
488
-
489
- if objects.empty?()
472
+
473
+ if objects.empty?
490
474
  # Else, will throw a cryptic NoMethodError:
491
- # - "psych/tree_builder.rb:in `set_end_location': undefined method `end_line=' for nil:NilClass (NoMethodError)"
492
- #
475
+ # - "psych/tree_builder.rb:in `set_end_location':
476
+ # undefined method `end_line=' for nil:NilClass (NoMethodError)"
477
+ #
493
478
  # This should never occur because of the if-statement at the top of this method.
494
479
  visitor << nil
495
480
  else
@@ -497,17 +482,17 @@ module Psychgus
497
482
  visitor << object
498
483
  end
499
484
  end
500
-
485
+
501
486
  return visitor.tree.yaml(io,options)
502
487
  end
503
-
488
+
504
489
  # Get a visual hierarchy of the levels as a String.
505
- #
490
+ #
506
491
  # This is useful for determining the correct level/position when writing a {Styler}.
507
- #
492
+ #
508
493
  # @example
509
494
  # require 'psychgus'
510
- #
495
+ #
511
496
  # burgers = {
512
497
  # :burgers => {
513
498
  # :classic => {:sauce => %w(Ketchup Mustard),
@@ -526,9 +511,9 @@ module Psychgus
526
511
  # [%w(Ketchup Mustard), %w(Salt Pepper)]
527
512
  # ]
528
513
  # }
529
- #
514
+ #
530
515
  # puts Psychgus.hierarchy(burgers)
531
- #
516
+ #
532
517
  # # Output:
533
518
  # # ---
534
519
  # # (level:position):current_node - <parent:(parent_level:parent_position)>
@@ -579,34 +564,32 @@ module Psychgus
579
564
  # # (5:2):Psych::Nodes::Sequence - <seq:(4:3)>
580
565
  # # (6:1):Salt - <seq:(5:2)>
581
566
  # # (6:2):Pepper - <seq:(5:2)>
582
- #
567
+ #
583
568
  # @param objects [Object,Array<Object>] the Object(s) to get a visual hierarchy of
584
569
  # @param kargs [Hash] the keyword args to pass to {Stylers::HierarchyStyler} and to {dump_stream}
585
- #
570
+ #
586
571
  # @return [String] the visual hierarchy of levels
587
- #
572
+ #
588
573
  # @see Stylers::HierarchyStyler
589
574
  # @see dump_stream
590
- #
591
- # @since 1.2.0
592
575
  def self.hierarchy(*objects,**kargs)
593
576
  styler = Stylers::HierarchyStyler.new(**kargs)
594
-
577
+
595
578
  dump_stream(*objects,stylers: styler,**kargs)
596
-
597
- return styler.to_s()
579
+
580
+ return styler.to_s
598
581
  end
599
-
582
+
600
583
  # Parse +yaml+ into a Psych::Nodes::Document.
601
- #
584
+ #
602
585
  # If you're just going to call to_ruby(), then using this method is unnecessary,
603
586
  # and the styler(s) will do nothing for you.
604
- #
587
+ #
605
588
  # @param yaml [String] the YAML to parse
606
589
  # @param kargs [Hash] the keyword args to use; see {.parse_stream}
607
- #
590
+ #
608
591
  # @return [Psych::Nodes::Document] the parsed Document node
609
- #
592
+ #
610
593
  # @see .parse_stream
611
594
  # @see Psych.parse
612
595
  # @see Psych::Nodes::Document
@@ -614,23 +597,23 @@ module Psychgus
614
597
  parse_stream(yaml,**kargs) do |node|
615
598
  return node
616
599
  end
617
-
600
+
618
601
  return false
619
602
  end
620
-
603
+
621
604
  # Parse a YAML file into a Psych::Nodes::Document.
622
- #
605
+ #
623
606
  # If you're just going to call to_ruby(), then using this method is unnecessary,
624
607
  # and the styler(s) will do nothing for you.
625
- #
608
+ #
626
609
  # @param filename [String] the name of the YAML file (and path) to parse
627
610
  # @param fallback [Object] the return value when nothing is parsed
628
611
  # @param mode [String,Integer] the IO open mode to use; example: +'r:BOM|UTF-8'+
629
612
  # @param opt [Hash] Hash of keyword args to pass to +File.open()+
630
613
  # @param kargs [Hash] the keyword args to use; see {.parse_stream}
631
- #
614
+ #
632
615
  # @return [Psych::Nodes::Document] the parsed Document node
633
- #
616
+ #
634
617
  # @see .parse_stream
635
618
  # @see Psych.parse_file
636
619
  # @see Psych::Nodes::Document
@@ -638,19 +621,19 @@ module Psychgus
638
621
  # @see IO.new
639
622
  def self.parse_file(filename,fallback: false,mode: 'r:BOM|UTF-8',opt: nil,**kargs)
640
623
  opt = Hash(opt)
641
-
624
+
642
625
  result = File.open(filename,mode,**opt) do |file|
643
626
  parse(file,filename: filename,**kargs)
644
627
  end
645
-
628
+
646
629
  return result || fallback
647
630
  end
648
-
631
+
649
632
  # Parse +yaml+ into a Psych::Nodes::Stream for one document or for multiple documents in one YAML.
650
- #
633
+ #
651
634
  # If you're just going to call to_ruby(), then using this method is unnecessary,
652
635
  # and the styler(s) will do nothing for you.
653
- #
636
+ #
654
637
  # @example
655
638
  # burgers = <<EOY
656
639
  # ---
@@ -664,9 +647,9 @@ module Psychgus
664
647
  # ---
665
648
  # `Invalid`
666
649
  # EOY
667
- #
650
+ #
668
651
  # i = 0
669
- #
652
+ #
670
653
  # begin
671
654
  # Psychgus.parse_stream(burgers,filename: 'burgers.yaml') do |document|
672
655
  # puts "Document ##{i += 1}"
@@ -675,52 +658,52 @@ module Psychgus
675
658
  # rescue Psych::SyntaxError => err
676
659
  # puts "File: #{err.file}"
677
660
  # end
678
- #
661
+ #
679
662
  # # Output:
680
663
  # # Document #1
681
664
  # # {"Burgers"=>{"Classic"=>{"BBQ"=>{"Sauce"=>"Honey BBQ", "Cheese"=>"Cheddar", "Bun"=>"Kaiser"}}}}
682
665
  # # Document #2
683
666
  # # {"Toppings"=>[["Mushrooms", "Mustard"], ["Salt", "Pepper", "Pickles"]]}
684
667
  # # File: burgers.yaml
685
- #
668
+ #
686
669
  # @param yaml [String] the YAML to parse
687
670
  # @param filename [String] the filename to pass as +file+ to the Error potentially raised
688
671
  # @param stylers [nil,Styler,Array<Styler>] the Styler(s) to use when parsing the YAML
689
672
  # @param deref_aliases [true,false] whether to dereference aliases; output the actual value
690
673
  # instead of the alias
691
674
  # @param block [Proc] an optional block for parsing multiple documents
692
- #
675
+ #
693
676
  # @return [Psych::Nodes::Stream] the parsed Stream node
694
- #
677
+ #
695
678
  # @see StyledDocumentStream
696
679
  # @see Psych.parse_stream
697
680
  # @see Psych::Nodes::Stream
698
681
  # @see Psych::SyntaxError
699
682
  def self.parse_stream(yaml,filename: nil,stylers: nil,deref_aliases: false,**options,&block)
700
- if block_given?()
683
+ if block_given?
701
684
  parser = Psych::Parser.new(StyledDocumentStream.new(*stylers,deref_aliases: deref_aliases,**options,
702
685
  &block))
703
-
686
+
704
687
  return parser.parse(yaml,filename)
705
688
  else
706
689
  parser = self.parser(stylers: stylers,deref_aliases: deref_aliases,**options)
707
690
  parser.parse(yaml,filename)
708
-
691
+
709
692
  return parser.handler.root
710
693
  end
711
694
  end
712
-
695
+
713
696
  # Create a new styled Psych::Parser for parsing YAML.
714
- #
697
+ #
715
698
  # @example
716
699
  # class CoffeeStyler
717
700
  # include Psychgus::Styler
718
- #
701
+ #
719
702
  # def style_sequence(sniffer,node)
720
703
  # node.style = Psychgus::SEQUENCE_FLOW
721
704
  # end
722
705
  # end
723
- #
706
+ #
724
707
  # coffee = <<EOY
725
708
  # Coffee:
726
709
  # Roast:
@@ -732,91 +715,88 @@ module Psychgus
732
715
  # - Latte
733
716
  # - Mocha
734
717
  # EOY
735
- #
718
+ #
736
719
  # parser = Psychgus.parser(stylers: CoffeeStyler.new)
737
720
  # parser.parse(coffee)
738
721
  # puts parser.handler.root.to_yaml
739
- #
722
+ #
740
723
  # # Output:
741
724
  # # Coffee:
742
725
  # # Roast: [Light, Medium, Dark]
743
726
  # # Style: [Cappuccino, Latte, Mocha]
744
- #
727
+ #
745
728
  # @param stylers [nil,Styler,Array<Styler>] the Styler(s) to use when parsing the YAML
746
729
  # @param deref_aliases [true,false] whether to dereference aliases; output the actual value
747
730
  # instead of the alias
748
- #
731
+ #
749
732
  # @return [Psych::Parser] the new styled Parser
750
- #
733
+ #
751
734
  # @see StyledTreeBuilder
752
735
  # @see Psych.parser
753
736
  def self.parser(stylers: nil,deref_aliases: false,**options)
754
737
  return Psych::Parser.new(StyledTreeBuilder.new(*stylers,deref_aliases: deref_aliases,**options))
755
738
  end
756
-
739
+
757
740
  ###
758
741
  # Unnecessary Methods
759
- #
742
+ #
760
743
  # All of the below methods are not needed, but are defined
761
744
  # so that Psychgus can be a drop-in replacement for Psych.
762
- #
745
+ #
763
746
  # Instead, you should probably use Psych.
764
747
  # This is also the recommended practice in case your version
765
748
  # of Psych defines the method differently.
766
- #
749
+ #
767
750
  # Private methods of Psych are not defined.
768
- #
751
+ #
769
752
  # @note For devs/hacking: because extend is used, do not prefix methods with "self."
770
- #
771
- # @author Jonathan Bradley Whited (@esotericpig)
772
- # @since 1.0.0
773
753
  ###
774
754
  module PsychDropIn
775
755
  # @see Psych.add_builtin_type
776
756
  def add_builtin_type(*args,&block)
777
757
  Psych.add_builtin_type(*args,&block)
778
758
  end
779
-
759
+
780
760
  # @see Psych.add_domain_type
781
761
  def add_domain_type(*args,&block)
782
762
  Psych.add_domain_type(*args,&block)
783
763
  end
784
-
764
+
785
765
  # @see Psych.add_tag
786
766
  def add_tag(*args)
787
767
  Psych.add_tag(*args)
788
768
  end
789
-
769
+
790
770
  # @see Psych.load
791
771
  def load(*args,**kargs)
792
772
  Psych.load(*args,**kargs)
793
773
  end
794
-
774
+
795
775
  # @see Psych.load_file
796
776
  def load_file(*args,**kargs)
797
777
  Psych.load_file(*args,**kargs)
798
778
  end
799
-
779
+
800
780
  # @see Psych.load_stream
801
781
  def load_stream(*args,**kargs)
802
782
  Psych.load_stream(*args,**kargs)
803
783
  end
804
-
784
+
805
785
  # @see Psych.remove_type
806
786
  def remove_type(*args)
807
787
  Psych.remove_type(*args)
808
788
  end
809
-
789
+
810
790
  # @see Psych.safe_load
811
791
  def safe_load(*args,**kargs)
812
792
  Psych.safe_load(*args,**kargs)
813
793
  end
814
-
794
+
815
795
  # @see Psych.to_json
816
796
  def to_json(*args)
817
797
  Psych.to_json(*args)
818
798
  end
819
799
  end
820
-
800
+
821
801
  extend PsychDropIn
822
802
  end