xprint 0.6.0 → 0.9.4

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