xprint 0.5.3 → 0.9.3

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 +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: []