xprint 0.5.3 → 0.9.3

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 +4 -4
  2. data/lib/version.rb +1 -1
  3. data/lib/xprint.rb +256 -34
  4. metadata +4 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 12a4f14b974b337adf700aefab2e12d0d49464715c07d9fcf4968043a4e1dc94
4
- data.tar.gz: d7c45cd128a2b48d930ce4b0f3c0991351e858d2bcc9fa1aa08ad0d3c62ad9d1
3
+ metadata.gz: cb5466745989b6f6b023b74f46af89fd0dfb6ff6c10ced23260209bb288aa80d
4
+ data.tar.gz: e434c017113835cf167843c788eff0ae215336ec0922fcb14ff3e0b4da8092cc
5
5
  SHA512:
6
- metadata.gz: 846e1a5db4a0754d459eb0fa0a5036def3ff3e501046fd67617db49b8ec44837c0120e49b6ecd7c3ed07696359db302a81a0b3cecb5e4a7663922ca3229bde84
7
- data.tar.gz: fef4e604bc0cd065117a9d08862b6ba2196f9dd20ee6393a0f956263fcbea81f4f27d658aefa184fa79bde9d6b1643defb2099b60692c88b0a27ea7afc617239
6
+ metadata.gz: af1bf6ed25d0ec37d81e06cb1dec4d4608b4f4cf6e247aa072df8673014dc4f0a6411b0db2edfe6dd32289353d3662c6368eb3148b277edb69182bb756ef0b93
7
+ data.tar.gz: 8465b18e98ec0d5c71e3e0536d86db8789c7b8625017627175570c883801ce77e951d3e4fc03f5ef949ac61cd1c15c6f123de514718149d28185315971d4544b
@@ -1,3 +1,3 @@
1
1
  module XPrint
2
- VERSION = '0.5.3'
2
+ VERSION = '0.9.3'
3
3
  end
@@ -1,44 +1,199 @@
1
+ require 'bigdecimal'
2
+ require 'date'
3
+ require 'yaml'
4
+
1
5
  module XPrint
2
- @data_classes = [
6
+ @data_classes = [
3
7
  String, Integer, Float, TrueClass, FalseClass, NilClass,
4
- Symbol
8
+ Symbol, Date, Time, DateTime, BigDecimal, Rational
5
9
  ]
6
10
  @hash_name_classes = @data_classes + [Proc]
7
- @tab = "\t"
8
- @show_indexes = true
9
- @full_proc_path = false
11
+ @tab = " "
12
+ @indexes = true
13
+ @full_proc_path = false
14
+ @braces = true
15
+ @date_format = '%F'
16
+ @time_format = '%c'
17
+ @datetime_format = '%FT%T%:z'
18
+ @hash_separator = ' => '
19
+ @commas = true
20
+ @color = true
21
+ @colors = {
22
+ attribute: :blue,
23
+ bigdecimal: :darkcyan,
24
+ classname: :darkgreen,
25
+ classobject: :green,
26
+ comma: :default,
27
+ curly_brace: :default,
28
+ date: :red,
29
+ datetime: :purple,
30
+ equals: :default,
31
+ false: :darkred,
32
+ float: :cyan,
33
+ hash_separator: :default,
34
+ index: :darkgrey,
35
+ integer: :cyan,
36
+ module: :green,
37
+ nil: :darkpurple,
38
+ parentheses: :default,
39
+ proc: :darkyellow,
40
+ rational: :darkcyan,
41
+ string: :yellow,
42
+ struct: :green,
43
+ square_brace: :default,
44
+ symbol: :darkblue,
45
+ time: :darkblue,
46
+ true: :darkgreen
47
+ }
48
+ @color_codes = {
49
+ black: "\e[30m",
50
+ blue: "\e[94m",
51
+ darkblue: "\e[34m",
52
+ cyan: "\e[96m",
53
+ darkcyan: "\e[36m",
54
+ green: "\e[92m",
55
+ darkgreen: "\e[32m",
56
+ grey: "\e[37m",
57
+ darkgrey: "\e[90m",
58
+ red: "\e[91m",
59
+ darkred: "\e[31m",
60
+ purple: "\e[95m",
61
+ darkpurple: "\e[35m",
62
+ yellow: "\e[93m",
63
+ darkyellow: "\e[33m",
64
+ default: "\e[0m"
65
+ }
10
66
 
11
67
  def self.set(**kwargs)
12
- @tab = kwargs[:tab] unless kwargs[:tab].nil?
13
- @show_indexes = kwargs[:show_indexes] unless kwargs[:show_indexes].nil?
68
+ kwargs.each do |keyword, arg|
69
+ self.instance_variable_set "@#{keyword}", arg
70
+ end
71
+
72
+ return
73
+ end
74
+
75
+ def self.load_file(config)
76
+ config_data = YAML.load( File.read config )
77
+ config_data = self.symbolize_keys(config_data)
78
+
79
+ if config_data.key? :general
80
+ self.set **config_data[:general]
81
+ end
82
+
83
+ if config_data.key? :colors
84
+ color_data = config_data[:colors]
85
+
86
+ color_data.each do |name, color|
87
+ color_data[name] = color.to_sym
88
+ end
89
+
90
+ self.set_color_for **config_data[:colors]
91
+ end
14
92
 
15
- unless @full_proc_path.nil?
16
- @full_proc_path = kwargs[:full_proc_path]
93
+ if config_data.key? :'color codes'
94
+ self.set_color_code_for **config_data[:'color codes']
17
95
  end
18
96
  end
19
97
 
20
- def self.tab()
21
- @tab
98
+ def self.load(config)
99
+ calling_file = caller_locations.first.absolute_path
100
+ base_dir = File.dirname calling_file
101
+ relative_config = File.expand_path config, base_dir
102
+
103
+ self.load_file relative_config
104
+ end
105
+
106
+ private_class_method def self.symbolize_keys(hash)
107
+ hash.inject({}) do |result, (key, value)|
108
+ new_key = key.to_sym
109
+ new_value = value.is_a?(Hash) ? symbolize_keys(value) : value
110
+
111
+ result[new_key] = new_value
112
+
113
+ result
114
+ end
22
115
  end
23
116
 
24
- def self.show_indexes()
25
- @show_indexes
117
+ def self.set_color_for(**kwargs)
118
+ kwargs.each do |keyword, arg|
119
+ @colors[keyword] = arg
120
+ end
121
+ end
122
+
123
+ def self.set_color_code_for(**kwargs)
124
+ kwargs.each do |keyword, arg|
125
+ @color_codes[keyword] = arg
126
+ end
26
127
  end
27
128
 
28
129
  def self.xp(*args)
29
130
  args.each do |arg|
30
- puts self.xpand(arg, tab: @tab)
131
+ xpanded_text = self.xpand(arg, tab: @tab)
132
+
133
+ unless @braces
134
+ xpanded_text = self.shift_indentation_down(xpanded_text).lstrip()
135
+ end
136
+
137
+ puts xpanded_text
138
+ end
139
+ end
140
+
141
+ private_class_method def self.color_for(colorname)
142
+ @color_codes[colorname]
143
+ end
144
+
145
+ private_class_method def self.reset_color()
146
+ @color_codes[:default]
147
+ end
148
+
149
+ private_class_method def self.colorize(text, type)
150
+ if @color
151
+ item_color = color_for @colors[type]
152
+ "#{item_color}#{text}#{reset_color}"
153
+ else
154
+ text
31
155
  end
32
156
  end
33
157
 
34
- def self.xpand(x, indent: '', tab: "\t")
158
+ private_class_method def self.shift_indentation_down(text)
159
+ # Only shift if no
160
+ return text if text.match?(/^\S/)
161
+ result = ''
162
+
163
+ text.each_line do |line|
164
+ result += (
165
+ if line.start_with? @tab
166
+ line[@tab.length..-1]
167
+ else
168
+ line
169
+ end
170
+ )
171
+ end
172
+
173
+ return result
174
+ end
175
+
176
+ def self.xpand(x, indent: '', tab: ' ')
35
177
 
36
178
  _indent = "#{tab}#{indent}"
37
-
179
+
38
180
  # X is a "primitive" kind of data that has no subitems, so
39
181
  # we can just print it.
40
- if @data_classes.include? x.class
41
- return x.inspect
182
+ if x.class == String
183
+ return colorize(x.inspect, :string)
184
+ elsif x.class == Integer
185
+ return colorize(x.inspect, :integer)
186
+ elsif x.class == Float
187
+ return colorize(x.inspect, :float)
188
+ elsif x.class == TrueClass
189
+ return colorize(x.inspect, :true)
190
+ elsif x.class == FalseClass
191
+ return colorize(x.inspect, :false)
192
+ elsif x.class == NilClass
193
+ return colorize(x.inspect, :nil)
194
+ elsif x.class == Symbol
195
+ return colorize(x.inspect, :symbol)
196
+
42
197
  # X is a Proc, print more compact version of standard Proc.inspect
43
198
  # text.
44
199
  elsif x.class == Proc
@@ -50,28 +205,42 @@ module XPrint
50
205
  source = source.split('/')[-2..-1].join('/')
51
206
  end
52
207
 
53
- return "<#{type} @ #{source} [Line #{line}]>"
208
+ return colorize("<#{type} @ #{source} [Line #{line}]>", :proc)
209
+
210
+ elsif x.class == Class
211
+ return colorize("<Class #{x}>", :classobject)
212
+
54
213
  # X is an Array, print list of all items.
55
214
  elsif x.class == Array
56
- result = "[\n"
215
+ result = "#{@braces ? colorize('[', :square_brace) : ''}\n"
216
+ comma = colorize(',', :comma)
57
217
 
58
218
  x.each_with_index do |item, index|
59
219
  data = xpand(item, indent: _indent, tab: tab)
60
220
 
61
221
  result += "#{_indent}"
62
- result += "[#{index}] " if @show_indexes
222
+ if @indexes
223
+ adjustment = x.length.to_s.length + 3
224
+ # Account for characters used for color coding.
225
+ adjustment += 9 if @color
226
+
227
+ result += "#{colorize("[#{index}]", :index)} ".
228
+ ljust(adjustment)
229
+ end
63
230
  result += "#{data}"
64
231
 
65
232
  unless index + 1 == x.length
66
- result += ", \n"
233
+ result += "#{@commas ? "#{comma} " : ''} \n"
67
234
  end
68
235
  end
69
236
 
70
- result += "\n#{indent}]"
237
+ result += "\n#{indent}#{colorize(']', :square_brace)}" if @braces
71
238
  return result
239
+
72
240
  # X is a Hash, print all keys and values.
73
241
  elsif x.class == Hash
74
- result = "{\n"
242
+ comma = colorize(',', :comma)
243
+ result = "#{@braces ? colorize('{', :curly_brace) : ''}\n"
75
244
 
76
245
  longest_key = (
77
246
  x.keys.filter do |k, v|
@@ -84,6 +253,13 @@ module XPrint
84
253
  )
85
254
 
86
255
  longest_key = 0 if longest_key.nil?
256
+
257
+ # Color codes throw the text length, so we need to add the
258
+ # length of the color code and the code to reset the color
259
+ # that wrap around the colored word.
260
+ # The color code is like "\e[99m" and the reset "\e[0m",
261
+ # so the total length to add when using color is 9.
262
+ longest_key += 9 if @color
87
263
 
88
264
  x.each_with_index do |(key, value), index|
89
265
  data_key = "#{xpand(key, indent: _indent, tab: tab)}"
@@ -98,49 +274,95 @@ module XPrint
98
274
 
99
275
  data_value = xpand(value, indent: _indent, tab: tab)
100
276
 
101
- result += "#{_indent}#{data_key} => #{data_value}"
277
+ hash_separator = colorize(@hash_separator, :hash_separator)
278
+ result += "#{_indent}#{data_key}#{hash_separator}#{data_value}"
102
279
 
103
280
  unless index + 1 == x.length
104
- result += ", \n"
281
+ result += "#{@commas ? "#{comma} " : ''} \n"
105
282
  end
106
283
  end
107
284
 
108
- result += "\n#{indent}}"
285
+ result += "\n#{indent}#{colorize('}', :curly_brace)}" if @braces
109
286
 
110
287
  return result
288
+
289
+ # X is a commonly used special kind of object.
290
+ elsif x.class == DateTime
291
+ datetime = x.strftime @datetime_format
292
+ p1 = colorize('(', :parentheses)
293
+ p2 = colorize(')', :parentheses)
294
+ return colorize("DateTime#{p1}#{datetime}#{p2}", :datetime)
295
+
296
+ elsif x.class == Date
297
+ date = x.strftime @date_format
298
+ p1 = colorize('(', :parentheses)
299
+ p2 = colorize(')', :parentheses)
300
+ return colorize("Date#{p1}#{date}#{p2}", :date)
301
+
302
+ elsif x.class == Time
303
+ time = x.strftime @time_format
304
+ p1 = colorize('(', :parentheses)
305
+ p2 = colorize(')', :parentheses)
306
+ return colorize("Time#{p1}#{time}#{p2}", :time)
307
+
308
+ elsif x.class == BigDecimal
309
+ p1 = colorize('(', :parentheses)
310
+ p2 = colorize(')', :parentheses)
311
+ return colorize("BigDecimal#{p1}#{x.to_s('f')}#{p2}", :bigdecimal)
312
+
313
+ elsif x.class == Rational
314
+ p1 = colorize('(', :parentheses)
315
+ p2 = colorize(')', :parentheses)
316
+ return colorize("Rational#{p1}#{x}#{p2}", :rational)
317
+
111
318
  # X is a Structure; essentially a special case of X being an object.
112
319
  elsif x.is_a? Struct
113
- result = "Struct #{x.class}(\n"
320
+ struct_word = colorize('Struct', :struct)
321
+ classname = colorize(x.class, :struct)
322
+ p1 = colorize('(', :parentheses)
323
+ p2 = colorize(')', :parentheses)
324
+ result = "#{struct_word} #{classname}#{@braces ? p1 : ''}\n"
114
325
  longest_item = x.members.map { |m| m.to_s.length }.max()
326
+ eq_sign = colorize('=', :equals)
115
327
 
116
328
  x.each_pair do |name, value|
117
- attr_name = name.to_s.ljust(longest_item)
329
+ attr_name = colorize(name.to_s.ljust(longest_item), :attribute)
118
330
  attr_data = xpand(value, indent: _indent, tab: tab)
119
331
 
120
- result += "#{_indent}#{attr_name} = #{attr_data}\n"
332
+ result += "#{_indent}#{attr_name} #{eq_sign} #{attr_data}\n"
121
333
  end
122
334
 
123
- result += "#{indent})"
335
+ result += "#{indent}#{p2}" if @braces
124
336
 
125
337
  return result
338
+
126
339
  # X is any arbitrary object; print all instance variables.
127
340
  else
128
- result = "#{x.class}(\n"
341
+ p1 = colorize('(', :parentheses)
342
+ p2 = colorize(')', :parentheses)
343
+
344
+ is_module = x.class == Module
345
+ classname = is_module ? "Module #{x}" : x.class
346
+ classname = colorize(classname, is_module ? :module : :classname)
347
+ result = "#{classname}#{@braces ? p1 : ''}"
129
348
  ivars = x.instance_variables
349
+ result += "\n" if ivars.length > 0
130
350
  longest_var = ivars.map { |v| v.to_s.length }.max()
351
+ eq_sign = colorize('=', :equals)
131
352
 
132
353
  ivars.each_with_index do |var, index|
133
354
  attr_name = var.to_s.ljust(longest_var)
355
+ attr_name = colorize(attr_name, :attribute)
134
356
  attr_data = xpand(
135
357
  x.instance_variable_get(var),
136
358
  indent: _indent,
137
359
  tab: tab
138
360
  )
139
361
 
140
- result += "#{_indent}#{attr_name} = #{attr_data}\n"
362
+ result += "#{_indent}#{attr_name} #{eq_sign} #{attr_data}\n"
141
363
  end
142
364
 
143
- result += "#{indent})"
365
+ result += "#{ivars.length > 0 ? indent: ''}#{p2}" if @braces
144
366
 
145
367
  return result
146
368
  end
metadata CHANGED
@@ -1,17 +1,18 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: xprint
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.3
4
+ version: 0.9.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - JCabr
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-07-20 00:00:00.000000000 Z
11
+ date: 2020-07-22 00:00:00.000000000 Z
12
12
  dependencies: []
13
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.
14
+ indentation, and works with objects as well as basic data types. Also allows color,
15
+ and loading settings via a YAML config file.
15
16
  email:
16
17
  - jcabr.dev@gmail.com
17
18
  executables: []