xprint 0.7.9
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 +7 -0
- data/lib/version.rb +3 -0
- data/lib/xprint.rb +310 -0
- metadata +46 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 0a2df6a9e5eeff509346a2faa00414a4aa87a6abb1ea6bd426edeb9f9050bda2
|
4
|
+
data.tar.gz: b6cac4edf725cf6cadf55262a013fb63d8f2dd0b4e9d7cf77d0eeef34a33854a
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: e5e8257c53b8577455262226b7cd69ae599c53ee82e63ae031e8124bdeb8bf557a11cbce4d8f43a17b791843a0ae0df0f2982512e7daf56e7c3c4db05a73ae49
|
7
|
+
data.tar.gz: bf0d3df1881063303b08024197ce55313573de893f339f65fd17d5dc24033953a2f963d54d2a0915579ea7e8d289a36db03b5bc07dc17dbcb5efad2d06d301f6
|
data/lib/version.rb
ADDED
data/lib/xprint.rb
ADDED
@@ -0,0 +1,310 @@
|
|
1
|
+
require 'bigdecimal'
|
2
|
+
require 'date'
|
3
|
+
|
4
|
+
module XPrint
|
5
|
+
@data_classes = [
|
6
|
+
String, Integer, Float, TrueClass, FalseClass, NilClass,
|
7
|
+
Symbol
|
8
|
+
]
|
9
|
+
@hash_name_classes = @data_classes + [Proc]
|
10
|
+
@tab = "\t"
|
11
|
+
@indexes = true
|
12
|
+
@full_proc_path = false
|
13
|
+
@braces = true
|
14
|
+
@date_format = '%F'
|
15
|
+
@time_format = '%c'
|
16
|
+
@datetime_format = '%FT%T%:z'
|
17
|
+
@color = false
|
18
|
+
@colors = {
|
19
|
+
attribute: :blue,
|
20
|
+
bigdecimal: :darkcyan,
|
21
|
+
classname: :darkgreen,
|
22
|
+
classobject: :green,
|
23
|
+
date: :red,
|
24
|
+
datetime: :purple,
|
25
|
+
false: :darkred,
|
26
|
+
float: :cyan,
|
27
|
+
index: :darkgrey,
|
28
|
+
integer: :cyan,
|
29
|
+
nil: :darkpurple,
|
30
|
+
proc: :darkyellow,
|
31
|
+
rational: :darkcyan,
|
32
|
+
string: :yellow,
|
33
|
+
symbol: :darkblue,
|
34
|
+
time: :darkblue,
|
35
|
+
true: :darkgreen
|
36
|
+
}
|
37
|
+
@color_codes = {
|
38
|
+
black: "\e[30m",
|
39
|
+
blue: "\e[94m",
|
40
|
+
darkblue: "\e[34m",
|
41
|
+
cyan: "\e[96m",
|
42
|
+
darkcyan: "\e[36m",
|
43
|
+
green: "\e[92m",
|
44
|
+
darkgreen: "\e[32m",
|
45
|
+
grey: "\e[37m",
|
46
|
+
darkgrey: "\e[90m",
|
47
|
+
red: "\e[91m",
|
48
|
+
darkred: "\e[31m",
|
49
|
+
purple: "\e[95m",
|
50
|
+
darkpurple: "\e[35m",
|
51
|
+
yellow: "\e[93m",
|
52
|
+
darkyellow: "\e[33m",
|
53
|
+
reset: "\e[0m"
|
54
|
+
}
|
55
|
+
|
56
|
+
def self.set(**kwargs)
|
57
|
+
set_vars = {
|
58
|
+
tab: ->(data) { @tab = data },
|
59
|
+
indexes: ->(data) { @indexes = data },
|
60
|
+
full_proc_path: ->(data) { @full_proc_path = data },
|
61
|
+
braces: ->(data) { @braces = data },
|
62
|
+
date_format: ->(data) { @date_format = data },
|
63
|
+
time_format: ->(data) { @time_format = data },
|
64
|
+
datetime_format: ->(data) { @datetime_format = data },
|
65
|
+
color: ->(data) { @color = data }
|
66
|
+
}
|
67
|
+
|
68
|
+
kwargs.each do |keyword, arg|
|
69
|
+
if set_vars.key? keyword
|
70
|
+
set_vars[keyword].(arg)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
return
|
75
|
+
end
|
76
|
+
|
77
|
+
def self.set_color_for(**kwargs)
|
78
|
+
kwargs.each do |keyword, arg|
|
79
|
+
@colors[keyword] = arg
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def self.set_color_code_for(**kwargs)
|
84
|
+
kwargs.each do |keyword, arg|
|
85
|
+
@color_codes[keyword] = arg
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def self.xp(*args)
|
90
|
+
args.each do |arg|
|
91
|
+
xpanded_text = self.xpand(arg, tab: @tab)
|
92
|
+
|
93
|
+
unless @braces
|
94
|
+
xpanded_text = self.shift_indentation_down(xpanded_text).lstrip()
|
95
|
+
end
|
96
|
+
|
97
|
+
puts xpanded_text
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
private_class_method def self.color_for(colorname)
|
102
|
+
@color_codes[colorname]
|
103
|
+
end
|
104
|
+
|
105
|
+
private_class_method def self.reset_color()
|
106
|
+
@color_codes[:reset]
|
107
|
+
end
|
108
|
+
|
109
|
+
private_class_method def self.colorize(text, type)
|
110
|
+
if @color
|
111
|
+
item_color = color_for @colors[type]
|
112
|
+
"#{item_color}#{text}#{reset_color}"
|
113
|
+
else
|
114
|
+
text
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
private_class_method def self.shift_indentation_down(text)
|
119
|
+
# Only shift if no
|
120
|
+
return text if text.match?(/^\S/)
|
121
|
+
result = ''
|
122
|
+
|
123
|
+
text.each_line do |line|
|
124
|
+
result += (
|
125
|
+
if line.start_with? @tab
|
126
|
+
line[@tab.length..-1]
|
127
|
+
else
|
128
|
+
line
|
129
|
+
end
|
130
|
+
)
|
131
|
+
end
|
132
|
+
|
133
|
+
return result
|
134
|
+
end
|
135
|
+
|
136
|
+
def self.xpand(x, indent: '', tab: "\t")
|
137
|
+
|
138
|
+
_indent = "#{tab}#{indent}"
|
139
|
+
|
140
|
+
# X is a "primitive" kind of data that has no subitems, so
|
141
|
+
# we can just print it.
|
142
|
+
if x.class == String
|
143
|
+
return colorize(x.inspect, :string)
|
144
|
+
elsif x.class == Integer
|
145
|
+
return colorize(x.inspect, :integer)
|
146
|
+
elsif x.class == Float
|
147
|
+
return colorize(x.inspect, :float)
|
148
|
+
elsif x.class == TrueClass
|
149
|
+
return colorize(x.inspect, :true)
|
150
|
+
elsif x.class == FalseClass
|
151
|
+
return colorize(x.inspect, :false)
|
152
|
+
elsif x.class == NilClass
|
153
|
+
return colorize(x.inspect, :nil)
|
154
|
+
elsif x.class == Symbol
|
155
|
+
return colorize(x.inspect, :symbol)
|
156
|
+
|
157
|
+
# X is a Proc, print more compact version of standard Proc.inspect
|
158
|
+
# text.
|
159
|
+
elsif x.class == Proc
|
160
|
+
type = x.lambda? ? 'Lambda' : 'Proc'
|
161
|
+
source, line = x.source_location
|
162
|
+
source = source.gsub('\\', '/')
|
163
|
+
|
164
|
+
unless @full_proc_path
|
165
|
+
source = source.split('/')[-2..-1].join('/')
|
166
|
+
end
|
167
|
+
|
168
|
+
return colorize("<#{type} @ #{source} [Line #{line}]>", :proc)
|
169
|
+
|
170
|
+
elsif x.class == Class
|
171
|
+
return colorize("<Class #{x}>", :classobject)
|
172
|
+
|
173
|
+
# X is an Array, print list of all items.
|
174
|
+
elsif x.class == Array
|
175
|
+
result = "#{@braces ? '[' : ''}\n"
|
176
|
+
|
177
|
+
x.each_with_index do |item, index|
|
178
|
+
data = xpand(item, indent: _indent, tab: tab)
|
179
|
+
|
180
|
+
result += "#{_indent}"
|
181
|
+
result += "#{colorize("[#{index}]", :index)} " if @indexes
|
182
|
+
result += "#{data}"
|
183
|
+
|
184
|
+
unless index + 1 == x.length
|
185
|
+
result += "#{@braces ? ', ' : ''} \n"
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
result += "\n#{indent}]" if @braces
|
190
|
+
return result
|
191
|
+
|
192
|
+
# X is a Hash, print all keys and values.
|
193
|
+
elsif x.class == Hash
|
194
|
+
result = "#{@braces ? '{' : ''}\n"
|
195
|
+
|
196
|
+
longest_key = (
|
197
|
+
x.keys.filter do |k, v|
|
198
|
+
@hash_name_classes.include? k.class
|
199
|
+
end.
|
200
|
+
map do |k, v|
|
201
|
+
k.to_s.length
|
202
|
+
end.
|
203
|
+
max()
|
204
|
+
)
|
205
|
+
|
206
|
+
longest_key = 0 if longest_key.nil?
|
207
|
+
|
208
|
+
# Color codes throw the text length, so we need to add the
|
209
|
+
# length of the color code and the code to reset the color
|
210
|
+
# that wrap around the colored word.
|
211
|
+
# The color code is like "\e[99m" and the reset "\e[0m",
|
212
|
+
# so the total length to add when using color is 9.
|
213
|
+
longest_key += 9 if @color
|
214
|
+
|
215
|
+
x.each_with_index do |(key, value), index|
|
216
|
+
data_key = "#{xpand(key, indent: _indent, tab: tab)}"
|
217
|
+
|
218
|
+
data_key = (
|
219
|
+
if @hash_name_classes.include? key.class
|
220
|
+
data_key.ljust(longest_key + 1)
|
221
|
+
else
|
222
|
+
data_key.ljust(data_key.length + longest_key)
|
223
|
+
end
|
224
|
+
)
|
225
|
+
|
226
|
+
data_value = xpand(value, indent: _indent, tab: tab)
|
227
|
+
|
228
|
+
result += "#{_indent}#{data_key} => #{data_value}"
|
229
|
+
|
230
|
+
unless index + 1 == x.length
|
231
|
+
result += "#{@braces ? ', ' : ''} \n"
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
235
|
+
result += "\n#{indent}}" if @braces
|
236
|
+
|
237
|
+
return result
|
238
|
+
|
239
|
+
# X is a commonly used special kind of object.
|
240
|
+
elsif x.class == DateTime
|
241
|
+
datetime = x.strftime @datetime_format
|
242
|
+
return colorize("DateTime(#{datetime})", :datetime)
|
243
|
+
|
244
|
+
elsif x.class == Date
|
245
|
+
date = x.strftime @date_format
|
246
|
+
return colorize("Date(#{date})", :date)
|
247
|
+
|
248
|
+
elsif x.class == Time
|
249
|
+
time = x.strftime @time_format
|
250
|
+
return colorize("Time(#{time})", :time)
|
251
|
+
|
252
|
+
elsif x.class == BigDecimal
|
253
|
+
return colorize("BigDecimal(#{x.to_s('f')})", :bigdecimal)
|
254
|
+
|
255
|
+
elsif x.class == Rational
|
256
|
+
return colorize("Rational(#{x})", :rational)
|
257
|
+
|
258
|
+
# X is a Structure; essentially a special case of X being an object.
|
259
|
+
elsif x.is_a? Struct
|
260
|
+
struct_word = colorize('Struct', :classname)
|
261
|
+
classname = colorize(x.class, :classname)
|
262
|
+
result = "#{struct_word} #{classname}#{@braces ? '(' : ''}\n"
|
263
|
+
longest_item = x.members.map { |m| m.to_s.length }.max()
|
264
|
+
|
265
|
+
x.each_pair do |name, value|
|
266
|
+
attr_name = colorize(name.to_s.ljust(longest_item), :attribute)
|
267
|
+
attr_data = xpand(value, indent: _indent, tab: tab)
|
268
|
+
|
269
|
+
result += "#{_indent}#{attr_name} = #{attr_data}\n"
|
270
|
+
end
|
271
|
+
|
272
|
+
result += "#{indent})" if @braces
|
273
|
+
|
274
|
+
return result
|
275
|
+
|
276
|
+
# X is any arbitrary object; print all instance variables.
|
277
|
+
else
|
278
|
+
classname = x.class == Module ? "Module #{x}" : x.class
|
279
|
+
classname = colorize(classname, :classname)
|
280
|
+
result = "#{classname}#{@braces ? '(' : ''}"
|
281
|
+
ivars = x.instance_variables
|
282
|
+
result += "\n" if ivars.length > 0
|
283
|
+
longest_var = ivars.map { |v| v.to_s.length }.max()
|
284
|
+
|
285
|
+
ivars.each_with_index do |var, index|
|
286
|
+
attr_name = var.to_s.ljust(longest_var)
|
287
|
+
attr_name = colorize(attr_name, :attribute)
|
288
|
+
attr_data = xpand(
|
289
|
+
x.instance_variable_get(var),
|
290
|
+
indent: _indent,
|
291
|
+
tab: tab
|
292
|
+
)
|
293
|
+
|
294
|
+
result += "#{_indent}#{attr_name} = #{attr_data}\n"
|
295
|
+
end
|
296
|
+
|
297
|
+
result += "#{ivars.length > 0 ? indent: ''})" if @braces
|
298
|
+
|
299
|
+
return result
|
300
|
+
end
|
301
|
+
end
|
302
|
+
end
|
303
|
+
|
304
|
+
def xp(*args)
|
305
|
+
XPrint::xp(*args)
|
306
|
+
end
|
307
|
+
|
308
|
+
def xpand(item, tab: "\t")
|
309
|
+
XPrint::xpand(item, tab: tab)
|
310
|
+
end
|
metadata
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: xprint
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.7.9
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- JCabr
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2020-07-21 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: Gem that allows for pretty printing data over multiple lines and with
|
14
|
+
indentation, and works with objects as well as basic data types.
|
15
|
+
email:
|
16
|
+
- jcabr.dev@gmail.com
|
17
|
+
executables: []
|
18
|
+
extensions: []
|
19
|
+
extra_rdoc_files: []
|
20
|
+
files:
|
21
|
+
- lib/version.rb
|
22
|
+
- lib/xprint.rb
|
23
|
+
homepage: https://github.com/JCabr/xprint.rb
|
24
|
+
licenses:
|
25
|
+
- MIT
|
26
|
+
metadata: {}
|
27
|
+
post_install_message:
|
28
|
+
rdoc_options: []
|
29
|
+
require_paths:
|
30
|
+
- lib
|
31
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
32
|
+
requirements:
|
33
|
+
- - ">="
|
34
|
+
- !ruby/object:Gem::Version
|
35
|
+
version: '0'
|
36
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
requirements: []
|
42
|
+
rubygems_version: 3.1.2
|
43
|
+
signing_key:
|
44
|
+
specification_version: 4
|
45
|
+
summary: Gem for pretty printing any kind of object.
|
46
|
+
test_files: []
|