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.
Files changed (4) hide show
  1. checksums.yaml +7 -0
  2. data/lib/version.rb +3 -0
  3. data/lib/xprint.rb +310 -0
  4. metadata +46 -0
@@ -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
@@ -0,0 +1,3 @@
1
+ module XPrint
2
+ VERSION = '0.7.9'
3
+ end
@@ -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: []