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.
- checksums.yaml +7 -0
- data/lib/helpers/configuration.rb +28 -0
- data/lib/table_puts.rb +35 -0
- data/lib/table_puts/printer.rb +97 -0
- metadata +46 -0
checksums.yaml
ADDED
|
@@ -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
|
data/lib/table_puts.rb
ADDED
|
@@ -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: []
|