psychgus 1.0.1 → 1.2.0

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: 3cfde7f03f882111004ff6803bccf54482e0fe87096339e9c2978dafbe75e886
4
- data.tar.gz: 5d2e3b11f94fe6272032cd94657f1918106b29446a72c90762a9c8ea04058405
3
+ metadata.gz: 8b9e7e5d21e498f39d61b2b83765879dd6c564cc2742b121dfdeb9f5b8051578
4
+ data.tar.gz: 13ef8c78dc13bcce6596534e2b94557033438289a86e459834b4d7acf0afb9c1
5
5
  SHA512:
6
- metadata.gz: cc8920579914bda512cfa5b347ecb5af3221843634e7b019e368be93ff2160a353e833aa631c388f5a3118ba5247fcb469cc7b23f4802c46837d839ab7331ce4
7
- data.tar.gz: f6cb6210f97e2178c8ce95c16ec7eb276115376c11ad200aec6540a2e98fe2a03721f7674407fa056aabec8f62a83643ca13358dbf6989ef0969ba8dcaf018c4
6
+ metadata.gz: abfc0427ed29d4e3d811476a2c957f7961a85fbb0445b558d3b1356f018b12b52026a6b268b9f23384aa0a9fd20e3c720a30091448ea1659c8ddb8298e5c3b74
7
+ data.tar.gz: ef2db56b9b41bc3aa3f81f3a033e5aaf9508578d9aa63e5de10e978950fa9c860f77ca39ffa8c0077409149f87059faa515b51080290bf59f8e9a53dc74d366a
@@ -0,0 +1,29 @@
1
+ # Changelog | Psychgus
2
+
3
+ Format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
4
+
5
+ ## [[Unreleased]](https://github.com/esotericpig/psychgus/compare/v1.2.0...master)
6
+
7
+ ## [v1.2.0] - 2019-07-11
8
+
9
+ ### Added
10
+ - Commonly-used Stylers and Stylables
11
+ - Changelog
12
+ - Psychgus.hierarchy()
13
+ - SuperSniffer::Parent#child_key?() & #child_value?()
14
+
15
+ ### Changed
16
+ - SuperSniffer's parent will never be nil, so don't have to check for nil in Stylers
17
+ - Some doc comments & README
18
+ - Gemspec's included files to be more specific (to prevent accidentally adding non-gem-related files)
19
+
20
+ ### Fixed
21
+ - Psychgus.dump_stream() if you only pass in a Hash w/ symbols as keys (options would be set to it, instead of objects)
22
+
23
+ ## [v1.0.0] - 2019-07-03
24
+ ### Added
25
+ ### Changed
26
+ ### Deprecated
27
+ ### Removed
28
+ ### Fixed
29
+ ### Security
data/README.md CHANGED
@@ -2,8 +2,41 @@
2
2
 
3
3
  [![Gem Version](https://badge.fury.io/rb/psychgus.svg)](https://badge.fury.io/rb/psychgus)
4
4
 
5
+ [![Documentation](https://img.shields.io/badge/doc-yard-%23A0522D.svg?style=for-the-badge)](https://esotericpig.github.io/docs/psychgus/yardoc/index.html)
6
+ [![Changelog](https://img.shields.io/badge/changelog-md-%23A0522D.svg?style=for-the-badge)](CHANGELOG.md)
7
+ [![License](https://img.shields.io/github/license/esotericpig/psychgus.svg?color=%23A0522D&style=for-the-badge)](LICENSE.txt)
8
+
5
9
  Psychgus uses the core standard library [Psych](https://github.com/ruby/psych) for working with [YAML](https://yaml.org) and extends it so that developers can easily style the YAML according to their needs.
6
10
 
11
+ Turn this YAML...
12
+
13
+ ```YAML
14
+ ---
15
+ Psych Gus:
16
+ Aliases:
17
+ - Longbranch Pennywhistle
18
+ - Squirts Macintosh
19
+ - Clementine Woolysocks
20
+ - Lavender Gooms
21
+ - Big Baby Burton
22
+ - Chocolate Einstein
23
+ - MC Clap Yo Handz
24
+ Skills:
25
+ - The Blueberry
26
+ - The Super Sniffer
27
+ - Positive Work Attitude
28
+ ```
29
+
30
+ Into this:
31
+
32
+ ```YAML
33
+ ---
34
+ Psych Gus:
35
+ Aliases: [Longbranch Pennywhistle, Squirts Macintosh, Clementine Woolysocks, Lavender
36
+ Gooms, Big Baby Burton, Chocolate Einstein, MC Clap Yo Handz]
37
+ Skills: [The Blueberry, The Super Sniffer, Positive Work Attitude]
38
+ ```
39
+
7
40
  Thank you to the people that worked and continue to work hard on the Psych project.
8
41
 
9
42
  The Psychgus name comes from the well-styled character Gus from the TV show Psych.
@@ -16,6 +49,8 @@ The Psychgus name comes from the well-styled character Gus from the TV show Psyc
16
49
  - [Hash Example](#hash-example)
17
50
  - [Class Example](#class-example)
18
51
  - [Advanced Usage](#advanced-usage)
52
+ - [Common Stylers](#common-stylers)
53
+ - [Stylers Example](#stylers-example)
19
54
  - [Hacking](#hacking)
20
55
  - [Testing](#testing)
21
56
  - [Generating Doc](#generating-doc)
@@ -25,21 +60,35 @@ The Psychgus name comes from the well-styled character Gus from the TV show Psyc
25
60
 
26
61
  Pick your poison...
27
62
 
28
- - With the RubyGems CLI package manager:
29
- - `$ gem install psychgus`
30
- - In your *Gemspec* (*<project>.gemspec*):
31
- - `spec.add_runtime_dependency 'psychgus','~> x.x.x'`
32
- - Or, if you only need Psychgus in development (e.g., tests, rake, documentation):
33
- - `spec.add_development_dependency 'psychgus','~> x.x.x'`
34
- - In your *Gemfile*:
35
- - `gem 'psychgus','~> x.x.x'`
36
- - Or, with GitHub:
37
- - `gem 'psychgus',:git=>'https://github.com/esotericpig/psychgus.git'`
38
- - Manually:
39
- - `$ git clone 'https://github.com/esotericpig/psychgus.git'`
40
- - `$ cd psychgus`
41
- - `$ bundle install`
42
- - `$ bundle exec rake install:local`
63
+ With the RubyGems CLI package manager:
64
+
65
+ `$ gem install psychgus`
66
+
67
+ In your *Gemspec* (*<project>.gemspec*):
68
+
69
+ ```Ruby
70
+ # Pick one...
71
+ spec.add_runtime_dependency 'psychgus', '~> X.X.X'
72
+ spec.add_development_dependency 'psychgus', '~> X.X.X'
73
+ ```
74
+
75
+ In your *Gemfile*:
76
+
77
+ ```Ruby
78
+ # Pick one...
79
+ gem 'psychgus', '~> X.X.X'
80
+ gem 'psychgus', '~> X.X.X', :group => :development
81
+ gem 'psychgus', :git => 'https://github.com/esotericpig/psychgus.git', :tag => 'vX.X.X'
82
+ ```
83
+
84
+ Manually:
85
+
86
+ ```
87
+ $ git clone 'https://github.com/esotericpig/psychgus.git'
88
+ $ cd psychgus
89
+ $ bundle install
90
+ $ bundle exec rake install:local
91
+ ```
43
92
 
44
93
  ## [Using](#contents)
45
94
 
@@ -49,7 +98,17 @@ To begin styling, create a class and mix in (include) `Psychgus::Styler`. Then p
49
98
 
50
99
  For classes, you can optionally include `Psychgus::Blueberry` and return the styler(s) for the class by defining the `psychgus_stylers(sniffer)` method.
51
100
 
52
- ### [Simple Example](#contents)
101
+ Instead of making your own styler, you can also use one of the [pre-defined stylers](#common-stylers).
102
+
103
+ ### Contents | Using
104
+
105
+ [Simple Example](#simple-example)
106
+ | [Hash Example](#hash-example)
107
+ | [Class Example](#class-example)
108
+ | [Advanced Usage](#advanced-usage)
109
+ | [Common Stylers](#common-stylers)
110
+
111
+ ### [Simple Example](#using)
53
112
 
54
113
  ```Ruby
55
114
  require 'psychgus'
@@ -95,7 +154,7 @@ puts Coffee.new.to_yaml
95
154
  # style: [Cappuccino, Espresso, Latte, Mocha]
96
155
  ```
97
156
 
98
- ### [Hash Example](#contents)
157
+ ### [Hash Example](#using)
99
158
 
100
159
  ```Ruby
101
160
  require 'psychgus'
@@ -190,7 +249,7 @@ puts burgers.to_yaml({:indent => 3,:stylers => BurgerStyler.new,:deref_aliases =
190
249
  # Bun: Kaiser
191
250
  ```
192
251
 
193
- ### [Class Example](#contents)
252
+ ### [Class Example](#using)
194
253
 
195
254
  ```Ruby
196
255
  require 'psychgus'
@@ -231,8 +290,8 @@ class BurgerStyler
231
290
  parent = sniffer.parent
232
291
 
233
292
  # Single quote scalars that are not keys to a map
234
- node.style = Psychgus::SCALAR_SINGLE_QUOTED if !parent.nil?() &&
235
- parent.child_type != :key
293
+ # - "child_key?" is the same as "child_type == :key"
294
+ node.style = Psychgus::SCALAR_SINGLE_QUOTED unless parent.child_key?()
236
295
  end
237
296
 
238
297
  # Style sequences (Psych::Nodes::Sequence)
@@ -361,7 +420,7 @@ puts burgers.to_yaml({:indent => 3,:deref_aliases => true})
361
420
  # Sauce: 'Honey BBQ'
362
421
  ```
363
422
 
364
- ### [Advanced Usage](#contents)
423
+ ### [Advanced Usage](#using)
365
424
 
366
425
  ```Ruby
367
426
  require 'psychgus'
@@ -452,6 +511,63 @@ puts parser.handler.root.to_ruby
452
511
  puts
453
512
  ```
454
513
 
514
+ ### [Common Stylers](#using)
515
+
516
+ A collection of commonly-used [Stylers](https://esotericpig.github.io/docs/psychgus/yardoc/Psychgus/Stylers.html) and [Stylables](https://esotericpig.github.io/docs/psychgus/yardoc/Psychgus/Stylables.html) are included with Psychgus.
517
+
518
+ | Styler | Description |
519
+ | --- | --- |
520
+ | [CapStyler](https://esotericpig.github.io/docs/psychgus/yardoc/Psychgus/Stylers/CapStyler.html) | Capitalizer for Scalars |
521
+ | [FlowStyler](https://esotericpig.github.io/docs/psychgus/yardoc/Psychgus/Stylers/FlowStyler.html) | FLOW style changer for Mappings & Sequences |
522
+ | [MapFlowStyler](https://esotericpig.github.io/docs/psychgus/yardoc/Psychgus/Stylers/MapFlowStyler.html) | FLOW style changer for Mappings only |
523
+ | [NoSymStyler](https://esotericpig.github.io/docs/psychgus/yardoc/Psychgus/Stylers/NoSymStyler.html) | Symbol remover for Scalars |
524
+ | [NoTagStyler](https://esotericpig.github.io/docs/psychgus/yardoc/Psychgus/Stylers/NoTagStyler.html) | Tag remover for classes |
525
+ | [SeqFlowStyler](https://esotericpig.github.io/docs/psychgus/yardoc/Psychgus/Stylers/SeqFlowStyler.html) | FLOW style changer for Sequences only |
526
+
527
+ #### [Stylers Example](#common-stylers)
528
+
529
+ ```Ruby
530
+ require 'psychgus'
531
+
532
+ class EggCarton
533
+ def initialize
534
+ @eggs = {
535
+ :styles => ['fried', 'scrambled', ['BBQ', 'ketchup & mustard']],
536
+ :colors => ['brown', 'white', ['blue', 'green']]
537
+ }
538
+ end
539
+ end
540
+
541
+ puts EggCarton.new.to_yaml(stylers: [
542
+ Psychgus::NoSymStyler.new,
543
+ Psychgus::NoTagStyler.new,
544
+ Psychgus::CapStyler.new,
545
+ Psychgus::FlowStyler.new(4)
546
+ ])
547
+
548
+ # Output:
549
+ # ---
550
+ # Eggs:
551
+ # Styles: [Fried, Scrambled, [BBQ, Ketchup & Mustard]]
552
+ # Colors: [Brown, White, [Blue, Green]]
553
+
554
+ puts EggCarton.new.to_yaml
555
+
556
+ # Output (without Stylers):
557
+ # --- !ruby/object:EggCarton
558
+ # eggs:
559
+ # :styles:
560
+ # - fried
561
+ # - scrambled
562
+ # - - BBQ
563
+ # - ketchup & mustard
564
+ # :colors:
565
+ # - brown
566
+ # - white
567
+ # - - blue
568
+ # - green
569
+ ```
570
+
455
571
  ## [Hacking](#contents)
456
572
 
457
573
  ```
@@ -460,7 +576,7 @@ $ bundle install
460
576
  $ bundle exec rake -T
461
577
  ```
462
578
 
463
- ### [Testing](#contents)
579
+ ### [Testing](#hacking)
464
580
 
465
581
  Run tests, excluding tests that create temp files:
466
582
 
@@ -470,7 +586,7 @@ Run all tests:
470
586
 
471
587
  `$ bundle exec rake test_all`
472
588
 
473
- ### [Generating Doc](#contents)
589
+ ### [Generating Doc](#hacking)
474
590
 
475
591
  Generate basic doc:
476
592
 
data/Rakefile CHANGED
@@ -52,7 +52,7 @@ task :ghp_doc,[:deploy] do |task,args|
52
52
 
53
53
  sh rsync_cmd
54
54
 
55
- if dry_run
55
+ if !args.deploy
56
56
  puts
57
57
  puts 'Execute "rake ghp_doc[true]" for actually deploying (non-dry-run)'
58
58
  end
@@ -80,7 +80,7 @@ end
80
80
  YARD::Rake::YardocTask.new() do |task|
81
81
  task.files = ['lib/**/*.rb']
82
82
 
83
- task.options += ['--files','LICENSE.txt']
83
+ task.options += ['--files','CHANGELOG.md,LICENSE.txt']
84
84
  task.options += ['--readme','README.md']
85
85
 
86
86
  task.options << '--protected' # Show protected methods
@@ -121,20 +121,25 @@ task :yard_fix,[:dev] do |task,args|
121
121
  out = true
122
122
  end
123
123
 
124
- # Contents relative links
124
+ # Anchor links
125
125
  tag = 'href="#'
126
- if !(i = line.index(Regexp.new(Regexp.quote(tag) + '[a-z]'))).nil?()
127
- i += tag.length
128
- j = line.index('"',i)
129
-
130
- href = line[i...j].split('-').map(&:capitalize).join('_')
131
- line = "#{line[0...i]}#{href}#{line[j..-1]}"
126
+ quoted_tag = Regexp.quote(tag)
127
+
128
+ if !(i = line.index(Regexp.new(quoted_tag + '[a-z]'))).nil?()
129
+ line = line.gsub(Regexp.new(quoted_tag + '[a-z][^"]*"')) do |href|
130
+ link = href[tag.length..-2]
131
+ link = link.split('-').map(&:capitalize).join('_')
132
+
133
+ %Q(#{tag}#{link}")
134
+ end
132
135
 
133
136
  out = true
134
137
  end
135
138
 
136
- out ||= !line.gsub!('href="LICENSE.txt"','href="file.LICENSE.html"').nil?()
137
- out ||= !line.gsub!('code class="Ruby"','code class="language-ruby"').nil?()
139
+ out = !line.gsub!('href="CHANGELOG.md"','href="file.CHANGELOG.html"').nil?() || out
140
+ out = !line.gsub!('href="LICENSE.txt"','href="file.LICENSE.html"').nil?() || out
141
+ out = !line.gsub!('code class="Ruby"','code class="language-ruby"').nil?() || out
142
+ out = !line.gsub!('code class="YAML"','code class="language-yaml"').nil?() || out
138
143
 
139
144
  if out
140
145
  puts " #{line}"
@@ -24,9 +24,11 @@ require 'psych'
24
24
 
25
25
  require 'psychgus/blueberry'
26
26
  require 'psychgus/ext'
27
+ require 'psychgus/stylables'
27
28
  require 'psychgus/styled_document_stream'
28
29
  require 'psychgus/styled_tree_builder'
29
30
  require 'psychgus/styler'
31
+ require 'psychgus/stylers'
30
32
  require 'psychgus/super_sniffer'
31
33
  require 'psychgus/version'
32
34
 
@@ -99,8 +101,8 @@ require 'psychgus/super_sniffer/parent'
99
101
  # parent = sniffer.parent
100
102
  #
101
103
  # # Single quote scalars that are not keys to a map
102
- # node.style = Psychgus::SCALAR_SINGLE_QUOTED if !parent.nil?() &&
103
- # parent.child_type != :key
104
+ # # - "child_key?" is the same as "child_type == :key"
105
+ # node.style = Psychgus::SCALAR_SINGLE_QUOTED unless parent.child_key?()
104
106
  #
105
107
  # # Remove colon (change symbols into strings)
106
108
  # node.value = node.value.sub(':','')
@@ -308,6 +310,12 @@ require 'psychgus/super_sniffer/parent'
308
310
  # @since 1.0.0
309
311
  ###
310
312
  module Psychgus
313
+ # Include these in the top namespace for convenience (i.e., less typing).
314
+ #
315
+ # @since 1.2.0
316
+ include Stylables
317
+ include Stylers
318
+
311
319
  NODE_CLASS_ALIASES = {:Doc => :Document,:Map => :Mapping,:Seq => :Sequence}
312
320
  OPTIONS_ALIASES = {:canon => :canonical,:indent => :indentation}
313
321
 
@@ -327,8 +335,8 @@ module Psychgus
327
335
  def self.node_class(name)
328
336
  name = name.to_sym().capitalize()
329
337
 
330
- name_alias = NODE_CLASS_ALIASES[name]
331
- name = name_alias unless name_alias.nil?()
338
+ actual_name = NODE_CLASS_ALIASES[name]
339
+ name = actual_name unless actual_name.nil?()
332
340
 
333
341
  return Psych::Nodes.const_get(name)
334
342
  end
@@ -448,15 +456,30 @@ module Psychgus
448
456
  # @see Psych.dump_stream
449
457
  # @see OPTIONS_ALIASES
450
458
  def self.dump_stream(*objects,io: nil,stylers: nil,deref_aliases: false,**options)
459
+ # If you call this method with only a Hash that uses symbols as keys,
460
+ # then options will be set to the Hash, instead of objects.
461
+ #
462
+ # For example, the below will be stored in options, not objects:
463
+ # - dump_stream({:coffee => {:roast => [],:style => []}})
464
+ #
465
+ # This if-statement is guaranteed because dump_stream([]) and dump_stream(nil)
466
+ # will produce [[]] and [nil], which are not empty.
467
+ #
468
+ # dump_stream() w/o any args is the only problem, but resolved w/ [nil].
469
+ if objects.empty?()
470
+ objects = options.empty?() ? [nil] : [options]
471
+ options = {}
472
+ end
473
+
451
474
  if Hash === io
452
475
  options = io
453
476
  io = nil
454
477
  end
455
478
 
456
- if !options.nil?()
457
- OPTIONS_ALIASES.each do |option_alias,option|
458
- if options.key?(option_alias) && !options.key?(option)
459
- options[option] = options[option_alias]
479
+ if !options.empty?()
480
+ OPTIONS_ALIASES.each do |option_alias,actual_option|
481
+ if options.key?(option_alias) && !options.key?(actual_option)
482
+ options[actual_option] = options[option_alias]
460
483
  end
461
484
  end
462
485
  end
@@ -464,13 +487,117 @@ module Psychgus
464
487
  visitor = Psych::Visitors::YAMLTree.create(options,StyledTreeBuilder.new(*stylers,
465
488
  deref_aliases: deref_aliases))
466
489
 
467
- objects.each do |object|
468
- visitor << object
490
+ if objects.empty?()
491
+ # Else, will throw a cryptic NoMethodError:
492
+ # - "psych/tree_builder.rb:in `set_end_location': undefined method `end_line=' for nil:NilClass (NoMethodError)"
493
+ #
494
+ # This should never occur because of the if-statement at the top of this method.
495
+ visitor << nil
496
+ else
497
+ objects.each do |object|
498
+ visitor << object
499
+ end
469
500
  end
470
501
 
471
502
  return visitor.tree.yaml(io,options)
472
503
  end
473
504
 
505
+ # Get a visual hierarchy of the levels as a String.
506
+ #
507
+ # This is useful for determining the correct level/position when writing a {Styler}.
508
+ #
509
+ # @example
510
+ # require 'psychgus'
511
+ #
512
+ # burgers = {
513
+ # :burgers => {
514
+ # :classic => {:sauce => %w(Ketchup Mustard),
515
+ # :cheese => 'American',
516
+ # :bun => 'Sesame Seed'},
517
+ # :bbq => {:sauce => 'Honey BBQ',
518
+ # :cheese => 'Cheddar',
519
+ # :bun => 'Kaiser'},
520
+ # :fancy => {:sauce => 'Spicy Wasabi',
521
+ # :cheese => 'Smoked Gouda',
522
+ # :bun => 'Hawaiian'}
523
+ # },
524
+ # :toppings => [
525
+ # 'Mushrooms',
526
+ # %w(Lettuce Onions Pickles Tomatoes),
527
+ # [%w(Ketchup Mustard), %w(Salt Pepper)]
528
+ # ]
529
+ # }
530
+ #
531
+ # puts Psychgus.hierarchy(burgers)
532
+ #
533
+ # # Output:
534
+ # # ---
535
+ # # (level:position):current_node - <parent:(parent_level:parent_position)>
536
+ # # ---
537
+ # # (1:1):Psych::Nodes::Stream - <root:(0:0)>
538
+ # # (1:1):Psych::Nodes::Document - <stream:(1:1)>
539
+ # # (1:1):Psych::Nodes::Mapping - <doc:(1:1)>
540
+ # # (2:1)::burgers - <map:(1:1)>
541
+ # # (3:1):Psych::Nodes::Mapping - <:burgers:(2:1)>
542
+ # # (4:1)::classic - <map:(3:1)>
543
+ # # (5:1):Psych::Nodes::Mapping - <:classic:(4:1)>
544
+ # # (6:1)::sauce - <map:(5:1)>
545
+ # # (7:1):Psych::Nodes::Sequence - <:sauce:(6:1)>
546
+ # # (8:1):Ketchup - <seq:(7:1)>
547
+ # # (8:2):Mustard - <seq:(7:1)>
548
+ # # (6:2)::cheese - <map:(5:1)>
549
+ # # (7:1):American - <:cheese:(6:2)>
550
+ # # (6:3)::bun - <map:(5:1)>
551
+ # # (7:1):Sesame Seed - <:bun:(6:3)>
552
+ # # (4:2)::bbq - <map:(3:1)>
553
+ # # (5:1):Psych::Nodes::Mapping - <:bbq:(4:2)>
554
+ # # (6:1)::sauce - <map:(5:1)>
555
+ # # (7:1):Honey BBQ - <:sauce:(6:1)>
556
+ # # (6:2)::cheese - <map:(5:1)>
557
+ # # (7:1):Cheddar - <:cheese:(6:2)>
558
+ # # (6:3)::bun - <map:(5:1)>
559
+ # # (7:1):Kaiser - <:bun:(6:3)>
560
+ # # (4:3)::fancy - <map:(3:1)>
561
+ # # (5:1):Psych::Nodes::Mapping - <:fancy:(4:3)>
562
+ # # (6:1)::sauce - <map:(5:1)>
563
+ # # (7:1):Spicy Wasabi - <:sauce:(6:1)>
564
+ # # (6:2)::cheese - <map:(5:1)>
565
+ # # (7:1):Smoked Gouda - <:cheese:(6:2)>
566
+ # # (6:3)::bun - <map:(5:1)>
567
+ # # (7:1):Hawaiian - <:bun:(6:3)>
568
+ # # (2:2)::toppings - <map:(1:1)>
569
+ # # (3:1):Psych::Nodes::Sequence - <:toppings:(2:2)>
570
+ # # (4:1):Mushrooms - <seq:(3:1)>
571
+ # # (4:2):Psych::Nodes::Sequence - <seq:(3:1)>
572
+ # # (5:1):Lettuce - <seq:(4:2)>
573
+ # # (5:2):Onions - <seq:(4:2)>
574
+ # # (5:3):Pickles - <seq:(4:2)>
575
+ # # (5:4):Tomatoes - <seq:(4:2)>
576
+ # # (4:3):Psych::Nodes::Sequence - <seq:(3:1)>
577
+ # # (5:1):Psych::Nodes::Sequence - <seq:(4:3)>
578
+ # # (6:1):Ketchup - <seq:(5:1)>
579
+ # # (6:2):Mustard - <seq:(5:1)>
580
+ # # (5:2):Psych::Nodes::Sequence - <seq:(4:3)>
581
+ # # (6:1):Salt - <seq:(5:2)>
582
+ # # (6:2):Pepper - <seq:(5:2)>
583
+ #
584
+ # @param objects [Object,Array<Object>] the Object(s) to get a visual hierarchy of
585
+ # @param kargs [Hash] the keyword args to pass to {Stylers::HierarchyStyler} and to {dump_stream}
586
+ #
587
+ # @return [String] the visual hierarchy of levels
588
+ #
589
+ # @see Stylers::HierarchyStyler
590
+ # @see dump_stream
591
+ #
592
+ # @since 1.2.0
593
+ def self.hierarchy(*objects,**kargs)
594
+ styler = Stylers::HierarchyStyler.new(**kargs)
595
+
596
+ dump_stream(*objects,stylers: styler,**kargs)
597
+
598
+ return styler.to_s()
599
+ end
600
+
474
601
  # Parse +yaml+ into a Psych::Nodes::Document.
475
602
  #
476
603
  # If you're just going to call to_ruby(), then using this method is unnecessary,
@@ -637,7 +764,7 @@ module Psychgus
637
764
  #
638
765
  # Private methods of Psych are not defined.
639
766
  #
640
- # Because extend is used, do not prefix methods with "self."
767
+ # @note For devs/hacking: because extend is used, do not prefix methods with "self."
641
768
  #
642
769
  # @author Jonathan Bradley Whited (@esotericpig)
643
770
  # @since 1.0.0