table_puts 0.0.1

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 39cd50a5295a935701a614576d76a68c0190df8f
4
+ data.tar.gz: 82837ec0ae6cf45a7262ae47c7022084a02ae97e
5
+ SHA512:
6
+ metadata.gz: 7a48a404a9e4cdbc03997648bb92b59591b172761cdce18b767fcdefb7237012dca804238732333dab93d8cdebf2bf812eaa1f7dec4a484a9419c0e690c619db
7
+ data.tar.gz: c085e01e392e6eb961b5379bfd6deb4ed3d37f44b92c4968d141b7b2b4869e30b34e515f6a04840ebd685caa4cece60471fe0ad9805a092a118354a87fa9c316
@@ -0,0 +1,28 @@
1
+ # from https://www.viget.com/articles/easy-gem-configuration-variables-with-defaults
2
+
3
+ module Configuration
4
+
5
+ def configuration
6
+ yield self
7
+ end
8
+
9
+ def define_setting(name, default = nil)
10
+ class_variable_set("@@#{name}", default)
11
+
12
+ define_class_method "#{name}=" do |value|
13
+ class_variable_set("@@#{name}", value)
14
+ end
15
+
16
+ define_class_method name do
17
+ class_variable_get("@@#{name}")
18
+ end
19
+ end
20
+
21
+ private
22
+
23
+ def define_class_method(name, &block)
24
+ (class << self; self; end).instance_eval do
25
+ define_method name, &block
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,35 @@
1
+ module TablePuts
2
+ require 'helpers/configuration'
3
+ require 'table_puts/printer'
4
+ require 'csv'
5
+ extend Configuration
6
+
7
+ # Set defaults for column width
8
+ #
9
+ # Can be changed by doing:
10
+ # TablePuts.configuration do |config|
11
+ # config.min_column_width = 10
12
+ # end
13
+ define_setting(:min_column_width, 0)
14
+ define_setting(:max_column_width, 20)
15
+
16
+ # Takes in data in the form of an array of hashes all with the same keys
17
+ # and prints a nice looking table
18
+ def self.call(data, min_width: self.min_column_width, max_width: self.max_column_width)
19
+ Printer.new(data, min_width, max_width).call
20
+ end
21
+
22
+ # Takes in the file path of a CSV and prints a nice looking table
23
+ def self.csv(path, min_width: self.min_column_width, max_width: self.max_column_width)
24
+ Printer.new(read_csv(path), min_width, max_width).call
25
+ end
26
+
27
+ private
28
+
29
+ # Transforms CSV into an array of hashes
30
+ def self.read_csv(path)
31
+ csv_data = CSV.open(path).read
32
+ keys = csv_data.shift
33
+ csv_data.map { |items| items.map.with_index { |item, i| [keys[i], item] }.to_h }
34
+ end
35
+ end
@@ -0,0 +1,97 @@
1
+ class TablePuts::Printer
2
+ attr_reader :data, :transposed, :min_width, :max_width
3
+
4
+ def initialize(data, min_width, max_width)
5
+ @data = data
6
+ @transposed = transpose_data
7
+ @min_width = min_width
8
+ @max_width = max_width
9
+ check_widths(min_width, max_width)
10
+ end
11
+
12
+ def call
13
+ puts break_string
14
+ puts header
15
+ puts break_string
16
+ puts rows
17
+ puts break_string
18
+ end
19
+
20
+ # Transforms data into a single hash with each value containing an array of
21
+ # the values from each hash - for example:
22
+ #
23
+ # [ { x: 1, y: 2 }, { x: 3 }, { y: 4 } ]
24
+ # becomes
25
+ # { x: [1, 3], y: [2, 4] }
26
+ #
27
+ def transpose_data
28
+ transposed_data = {}
29
+ data.first.keys.map { |key| transposed_data[key] = [] }
30
+
31
+ data.each do |hash|
32
+ hash.each do |key,value|
33
+ transposed_data[key] << value
34
+ end
35
+ end
36
+ transposed_data
37
+ end
38
+
39
+ def header
40
+ transposed.keys.map.with_index do |key, i|
41
+ key_string = abbreviate(key.to_s).ljust(column_widths[i])
42
+
43
+ "| #{ key_string } "
44
+ end.join + "|"
45
+ end
46
+
47
+ def rows
48
+ justification = calculate_column_justification
49
+ data.map do |row|
50
+ row.map.with_index do |(key, value), i|
51
+ justify = "#{ justification[i] }just".to_sym
52
+ value_string = abbreviate(value.to_s).send(justify, (column_widths[i]))
53
+
54
+ "| #{ value_string } "
55
+ end.join + "|"
56
+ end
57
+ end
58
+
59
+ def break_string
60
+ @break_string ||= column_widths.map { |size| "+-#{ '-'*size }-" }.join + "+"
61
+ end
62
+
63
+ # An array of how many characters wide each column should be
64
+ #
65
+ # You can set a minimum and maximum width for all columns
66
+ # by passing in min_width and max_width
67
+ def column_widths
68
+ @column_widths ||= transposed.map do |value_array|
69
+ largest_width_in_column = value_array.flatten.map { |entry| entry.to_s.length }.max
70
+ [[largest_width_in_column, max_width].min, min_width].max
71
+ end
72
+ end
73
+
74
+ # Computes how we should justify the values in each column
75
+ #
76
+ # If all values in a column contain a number or are nil, then we right justify
77
+ # Otherwise, left justify
78
+ #
79
+ # Returns an array of 'r's and 'l's for each column
80
+ def calculate_column_justification
81
+ transposed.map do |(key, values)|
82
+ values.all? { |entry| entry.to_s.match(/\d/) || entry.nil? } ? 'r' : 'l'
83
+ end
84
+ end
85
+
86
+ def abbreviate(string)
87
+ string == string[0...max_width] ? string : string[0...max_width-3] + "..."
88
+ end
89
+
90
+ def check_widths(min, max)
91
+ if min > max
92
+ puts "WARNING: max_width is greater than min_width"
93
+ puts " This may cause unexpected output"
94
+ puts " min_width: #{ min_width }\tmax_width: #{ max_width }"
95
+ end
96
+ end
97
+ end
metadata ADDED
@@ -0,0 +1,46 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: table_puts
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Ryan Fauver
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-01-15 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description:
14
+ email: ryan.fauver@gmail.com
15
+ executables: []
16
+ extensions: []
17
+ extra_rdoc_files: []
18
+ files:
19
+ - lib/helpers/configuration.rb
20
+ - lib/table_puts.rb
21
+ - lib/table_puts/printer.rb
22
+ homepage: https://github.com/rfauver/TablePuts
23
+ licenses:
24
+ - MIT
25
+ metadata: {}
26
+ post_install_message:
27
+ rdoc_options: []
28
+ require_paths:
29
+ - lib
30
+ required_ruby_version: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: '0'
35
+ required_rubygems_version: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ requirements: []
41
+ rubyforge_project:
42
+ rubygems_version: 2.5.1
43
+ signing_key:
44
+ specification_version: 4
45
+ summary: Print nice tables in a ruby console
46
+ test_files: []