xprint 0.6.0 → 0.9.4

Sign up to get free protection for your applications and to get access to all the features.
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: []