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