psychgus 1.3.3 → 1.3.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.yardopts +5 -0
- data/CHANGELOG.md +32 -7
- data/Gemfile +15 -18
- data/README.md +43 -47
- data/Rakefile +16 -55
- data/lib/psychgus/blueberry.rb +26 -41
- data/lib/psychgus/ext/core_ext.rb +19 -31
- data/lib/psychgus/ext/node_ext.rb +11 -26
- data/lib/psychgus/ext/yaml_tree_ext.rb +34 -41
- data/lib/psychgus/stylables.rb +76 -91
- data/lib/psychgus/styled_document_stream.rb +12 -27
- data/lib/psychgus/styled_tree_builder.rb +88 -103
- data/lib/psychgus/styler.rb +29 -47
- data/lib/psychgus/stylers.rb +65 -80
- data/lib/psychgus/super_sniffer/parent.rb +38 -56
- data/lib/psychgus/super_sniffer.rb +107 -126
- data/lib/psychgus/version.rb +5 -18
- data/lib/psychgus.rb +166 -186
- data/psychgus.gemspec +37 -51
- data/test/blueberry_test.rb +30 -42
- data/test/psychgus_test.rb +51 -67
- data/test/psychgus_tester.rb +19 -37
- data/test/sniffer_test.rb +18 -33
- data/test/styler_test.rb +20 -32
- data/test/stylers_test.rb +32 -47
- metadata +9 -107
- data/lib/psychgus/ext.rb +0 -32
data/lib/psychgus/stylables.rb
CHANGED
@@ -1,25 +1,13 @@
|
|
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
|
7
|
-
#
|
8
|
-
#
|
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 Bradley Whited
|
7
|
+
#
|
8
|
+
# SPDX-License-Identifier: LGPL-3.0-or-later
|
20
9
|
#++
|
21
10
|
|
22
|
-
|
23
11
|
require 'psychgus/styler'
|
24
12
|
require 'psychgus/super_sniffer'
|
25
13
|
|
@@ -29,27 +17,24 @@ module Psychgus
|
|
29
17
|
###
|
30
18
|
# A collection of commonly-used {Styler} mixins
|
31
19
|
# that can be included in a class instead of {Styler}.
|
32
|
-
#
|
33
|
-
# @author Jonathan Bradley Whited (@esotericpig)
|
34
|
-
# @since 1.2.0
|
35
|
-
#
|
20
|
+
#
|
36
21
|
# @see Stylers
|
37
22
|
# @see Styler
|
38
23
|
###
|
39
24
|
module Stylables
|
40
25
|
###
|
41
26
|
# A helper mixin for Stylables that change a node's style.
|
42
|
-
#
|
27
|
+
#
|
43
28
|
# There is no max level, because a parent's style will override all of its children.
|
44
29
|
###
|
45
30
|
module StyleStylable
|
46
31
|
include Styler
|
47
|
-
|
32
|
+
|
48
33
|
attr_accessor :min_level # @return [Integer] the minimum level (inclusive) to style
|
49
34
|
attr_accessor :new_style # @return [Integer] the new style to set the nodes to
|
50
|
-
|
35
|
+
|
51
36
|
# +max_level+ is not defined because a parent's style will override all of its children.
|
52
|
-
#
|
37
|
+
#
|
53
38
|
# @param min_level [Integer] the minimum level (inclusive) to style
|
54
39
|
# @param new_style [Integer] the new style to set the nodes to
|
55
40
|
# @param kargs [Hash] capture extra keyword args, so no error for undefined args
|
@@ -57,212 +42,212 @@ module Psychgus
|
|
57
42
|
@min_level = min_level
|
58
43
|
@new_style = new_style
|
59
44
|
end
|
60
|
-
|
45
|
+
|
61
46
|
# Change the style of +node+ to {new_style} if it is >= {min_level}.
|
62
47
|
def change_style(sniffer,node)
|
63
48
|
return unless node.respond_to?(:style=)
|
64
|
-
|
49
|
+
|
65
50
|
node.style = @new_style if sniffer.level >= @min_level
|
66
51
|
end
|
67
52
|
end
|
68
53
|
end
|
69
|
-
|
54
|
+
|
70
55
|
module Stylables
|
71
56
|
###
|
72
57
|
# (see Stylers::CapStyler)
|
73
58
|
###
|
74
59
|
module CapStylable
|
75
60
|
include Styler
|
76
|
-
|
61
|
+
|
77
62
|
attr_reader :delim # @return [String,Regexp] the delimiter to split on
|
78
63
|
attr_accessor :each_word # @return [true,false] whether to capitalize each word separated by {delim}
|
79
64
|
attr_accessor :new_delim # @return [nil,String] the replacement for each {delim} if not nil
|
80
|
-
|
65
|
+
|
81
66
|
# @param each_word [true,false] whether to capitalize each word separated by +delim+
|
82
67
|
# @param new_delim [nil,String] the replacement for each +delim+ if not nil
|
83
68
|
# @param delim [String,Regexp] the delimiter to split on
|
84
69
|
# @param kargs [Hash] capture extra keyword args, so no error for undefined args
|
85
70
|
def initialize(each_word: true,new_delim: nil,delim: /[\s_\-]/,**kargs)
|
86
|
-
delim = Regexp.quote(delim.to_s
|
87
|
-
|
88
|
-
@delim = Regexp.new("(#{delim
|
71
|
+
delim = Regexp.quote(delim.to_s) unless delim.is_a?(Regexp)
|
72
|
+
|
73
|
+
@delim = Regexp.new("(#{delim})")
|
89
74
|
@each_word = each_word
|
90
75
|
@new_delim = new_delim
|
91
76
|
end
|
92
|
-
|
77
|
+
|
93
78
|
# Capitalize an individual word (not words).
|
94
|
-
#
|
79
|
+
#
|
95
80
|
# This method can safely be overridden with a new implementation.
|
96
|
-
#
|
81
|
+
#
|
97
82
|
# @param word [nil,String] the word to capitalize
|
98
|
-
#
|
83
|
+
#
|
99
84
|
# @return [String] the capitalized word
|
100
85
|
def cap_word(word)
|
101
|
-
return word if word.nil?
|
102
|
-
|
86
|
+
return word if word.nil? || word.empty?
|
87
|
+
|
103
88
|
# Already capitalized, good for all-capitalized words, like 'BBQ'
|
104
|
-
return word if word[0] == word[0].upcase
|
105
|
-
|
106
|
-
return word.capitalize
|
89
|
+
return word if word[0] == word[0].upcase
|
90
|
+
|
91
|
+
return word.capitalize
|
107
92
|
end
|
108
|
-
|
93
|
+
|
109
94
|
# Capitalize +node.value+.
|
110
|
-
#
|
95
|
+
#
|
111
96
|
# @see cap_word
|
112
97
|
# @see Styler#style_scalar
|
113
98
|
def style_scalar(sniffer,node)
|
114
|
-
if !@each_word || node.value.nil?
|
99
|
+
if !@each_word || node.value.nil? || node.value.empty?
|
115
100
|
node.value = cap_word(node.value)
|
116
101
|
return
|
117
102
|
end
|
118
|
-
|
103
|
+
|
119
104
|
is_delim = false
|
120
|
-
|
121
|
-
node.value = node.value.split(@delim).map
|
105
|
+
|
106
|
+
node.value = node.value.split(@delim).map do |v|
|
122
107
|
if is_delim
|
123
|
-
v = @new_delim unless @new_delim.nil?
|
108
|
+
v = @new_delim unless @new_delim.nil?
|
124
109
|
else
|
125
110
|
v = cap_word(v)
|
126
111
|
end
|
127
|
-
|
112
|
+
|
128
113
|
is_delim = !is_delim
|
129
114
|
v
|
130
|
-
end.join
|
115
|
+
end.join
|
131
116
|
end
|
132
117
|
end
|
133
|
-
|
118
|
+
|
134
119
|
###
|
135
120
|
# (see Stylers::HierarchyStyler)
|
136
121
|
###
|
137
122
|
module HierarchyStylable
|
138
123
|
include Styler
|
139
|
-
|
124
|
+
|
140
125
|
attr_accessor :io # @return [IO] the IO to write to; defaults to StringIO
|
141
126
|
attr_accessor :verbose # @return [true,false] whether to be more verbose (e.g., write child info)
|
142
|
-
|
127
|
+
|
143
128
|
# @param io [IO] the IO to write to
|
144
129
|
# @param verbose [true,false] whether to be more verbose (e.g., write child info)
|
145
130
|
# @param kargs [Hash] capture extra keyword args, so no error for undefined args
|
146
|
-
def initialize(io: StringIO.new
|
131
|
+
def initialize(io: StringIO.new,verbose: false,**kargs)
|
147
132
|
@io = io
|
148
133
|
@verbose = verbose
|
149
134
|
end
|
150
|
-
|
135
|
+
|
151
136
|
# Write the hierarchy of +node+ to {io}.
|
152
|
-
#
|
137
|
+
#
|
153
138
|
# @see Styler#style
|
154
139
|
def style(sniffer,node)
|
155
|
-
@io.print
|
156
|
-
|
140
|
+
@io.print(' ' * (sniffer.level - 1))
|
141
|
+
|
157
142
|
name = node.respond_to?(:value) ? node.value : node.class.name
|
158
143
|
parent = sniffer.parent
|
159
|
-
|
144
|
+
|
160
145
|
@io.print "(#{sniffer.level}:#{sniffer.position}):#{name} - "
|
161
|
-
|
146
|
+
|
162
147
|
if @verbose
|
163
148
|
@io.print parent
|
164
149
|
else
|
165
150
|
@io.print "<#{parent.debug_tag}:(#{parent.level}:#{parent.position})>"
|
166
151
|
end
|
167
|
-
|
152
|
+
|
168
153
|
@io.puts
|
169
154
|
end
|
170
|
-
|
155
|
+
|
171
156
|
# Convert {io} to a String if possible (e.g., StringIO).
|
172
|
-
#
|
157
|
+
#
|
173
158
|
# @return [String] the IO String result or just {io} as a String
|
174
|
-
def to_s
|
175
|
-
return @io.respond_to?(:string) ? @io.string : @io.to_s
|
159
|
+
def to_s
|
160
|
+
return @io.respond_to?(:string) ? @io.string : @io.to_s
|
176
161
|
end
|
177
162
|
end
|
178
|
-
|
163
|
+
|
179
164
|
###
|
180
165
|
# (see Stylers::MapFlowStyler)
|
181
166
|
###
|
182
167
|
module MapFlowStylable
|
183
168
|
include StyleStylable
|
184
|
-
|
169
|
+
|
185
170
|
# (see StyleStylable#initialize)
|
186
171
|
# @!method initialize(min_level=0,new_style: nil,**kargs)
|
187
|
-
#
|
172
|
+
#
|
188
173
|
# If +new_style+ is nil (the default), then {MAPPING_FLOW} will be used.
|
189
174
|
def initialize(*)
|
190
175
|
super
|
191
|
-
|
192
|
-
@new_style = MAPPING_FLOW if @new_style.nil?
|
176
|
+
|
177
|
+
@new_style = MAPPING_FLOW if @new_style.nil?
|
193
178
|
end
|
194
|
-
|
179
|
+
|
195
180
|
# Change the style of a Mapping to FLOW (or to the value of {new_style})
|
196
181
|
# if it is >= {min_level}.
|
197
|
-
#
|
182
|
+
#
|
198
183
|
# @see change_style
|
199
184
|
# @see Styler#style_mapping
|
200
185
|
def style_mapping(sniffer,node)
|
201
186
|
change_style(sniffer,node)
|
202
187
|
end
|
203
188
|
end
|
204
|
-
|
189
|
+
|
205
190
|
###
|
206
191
|
# (see Stylers::NoSymStyler)
|
207
192
|
###
|
208
193
|
module NoSymStylable
|
209
194
|
include Styler
|
210
|
-
|
195
|
+
|
211
196
|
attr_accessor :cap # @return [true,false] whether to capitalize the symbol
|
212
|
-
|
197
|
+
|
213
198
|
alias_method :cap?,:cap
|
214
|
-
|
199
|
+
|
215
200
|
# @param cap [true,false] whether to capitalize the symbol
|
216
201
|
# @param kargs [Hash] capture extra keyword args, so no error for undefined args
|
217
202
|
def initialize(cap: true,**kargs)
|
218
203
|
@cap = cap
|
219
204
|
end
|
220
|
-
|
205
|
+
|
221
206
|
# If +node.value+ is a symbol, change it into a string and capitalize it.
|
222
|
-
#
|
207
|
+
#
|
223
208
|
# @see Styler#style_scalar
|
224
209
|
def style_scalar(sniffer,node)
|
225
|
-
return if node.value.nil?
|
210
|
+
return if node.value.nil? || node.value.empty?
|
226
211
|
return if node.value[0] != ':'
|
227
|
-
|
212
|
+
|
228
213
|
node.value = node.value[1..-1]
|
229
|
-
node.value = node.value.capitalize
|
214
|
+
node.value = node.value.capitalize if @cap
|
230
215
|
end
|
231
216
|
end
|
232
|
-
|
217
|
+
|
233
218
|
###
|
234
219
|
# (see Stylers::NoTagStyler)
|
235
220
|
###
|
236
221
|
module NoTagStylable
|
237
222
|
include Styler
|
238
|
-
|
223
|
+
|
239
224
|
# If +node.tag+ is settable, set it to nil.
|
240
|
-
#
|
225
|
+
#
|
241
226
|
# @see Styler#style
|
242
227
|
def style(sniffer,node)
|
243
228
|
node.tag = nil if node.respond_to?(:tag=)
|
244
229
|
end
|
245
230
|
end
|
246
|
-
|
231
|
+
|
247
232
|
###
|
248
233
|
# (see Stylers::SeqFlowStyler)
|
249
234
|
###
|
250
235
|
module SeqFlowStylable
|
251
236
|
include StyleStylable
|
252
|
-
|
237
|
+
|
253
238
|
# (see StyleStylable#initialize)
|
254
239
|
# @!method initialize(min_level=0,new_style: nil,**kargs)
|
255
|
-
#
|
240
|
+
#
|
256
241
|
# If +new_style+ is nil (the default), then {SEQUENCE_FLOW} will be used.
|
257
242
|
def initialize(*)
|
258
243
|
super
|
259
|
-
|
260
|
-
@new_style = SEQUENCE_FLOW if @new_style.nil?
|
244
|
+
|
245
|
+
@new_style = SEQUENCE_FLOW if @new_style.nil?
|
261
246
|
end
|
262
|
-
|
247
|
+
|
263
248
|
# Change the style of a Sequence to FLOW (or to the value of {new_style})
|
264
249
|
# if it is >= {min_level}.
|
265
|
-
#
|
250
|
+
#
|
266
251
|
# @see change_style
|
267
252
|
# @see Styler#style_sequence
|
268
253
|
def style_sequence(sniffer,node)
|
@@ -1,25 +1,13 @@
|
|
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
|
7
|
-
#
|
8
|
-
#
|
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 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/styled_tree_builder'
|
@@ -27,36 +15,33 @@ require 'psychgus/styled_tree_builder'
|
|
27
15
|
module Psychgus
|
28
16
|
###
|
29
17
|
# Use this wherever Psych::Handlers::DocumentStream would have been used, to enable styling.
|
30
|
-
#
|
31
|
-
# @author Jonathan Bradley Whited (@esotericpig)
|
32
|
-
# @since 1.0.0
|
33
|
-
#
|
18
|
+
#
|
34
19
|
# @see Psychgus.parse_stream Psychgus.parse_stream
|
35
20
|
# @see Psych::Handlers::DocumentStream
|
36
21
|
###
|
37
22
|
class StyledDocumentStream < StyledTreeBuilder
|
38
23
|
# Initialize this class with {Styler}(s) and a block.
|
39
|
-
#
|
24
|
+
#
|
40
25
|
# @param stylers [Styler] {Styler}(s) to use for styling this DocumentStream
|
41
26
|
# @param deref_aliases [true,false] whether to dereference aliases; output the actual value
|
42
27
|
# instead of the alias
|
43
28
|
# @param block [Proc] a block to call in {#end_document} to denote a new YAML document
|
44
29
|
def initialize(*stylers,deref_aliases: false,**options,&block)
|
45
30
|
super(*stylers,deref_aliases: deref_aliases,**options)
|
46
|
-
|
31
|
+
|
47
32
|
@block = block
|
48
33
|
end
|
49
|
-
|
34
|
+
|
50
35
|
# This mimics the behavior of Psych::Handlers::DocumentStream#end_document.
|
51
|
-
#
|
36
|
+
#
|
52
37
|
# @see Psych::Handlers::DocumentStream#end_document
|
53
|
-
def end_document(implicit_end=!streaming?
|
38
|
+
def end_document(implicit_end=!streaming?)
|
54
39
|
@last.implicit_end = implicit_end
|
55
40
|
@block.call(pop)
|
56
41
|
end
|
57
|
-
|
42
|
+
|
58
43
|
# This mimics the behavior of Psych::Handlers::DocumentStream#start_document.
|
59
|
-
#
|
44
|
+
#
|
60
45
|
# @see Psych::Handlers::DocumentStream#start_document
|
61
46
|
def start_document(version,tag_directives,implicit)
|
62
47
|
node = Psych::Nodes::Document.new(version,tag_directives,implicit)
|