tabled 0.0.1 → 0.0.2
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 +4 -4
- data/.rspec +1 -0
- data/README.md +56 -0
- data/demo.rb +130 -0
- data/lib/content_shaper.rb +68 -0
- data/lib/helpers.rb +31 -0
- data/lib/tabled.rb +7 -41
- data/lib/template.rb +5 -7
- data/tabled.gemspec +1 -1
- metadata +7 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a9bea1975c1f4f3cf411a90414b7497ac7a580dd0138ff42cf47f1019c42b21e
|
4
|
+
data.tar.gz: 6b623b51a521cc9c1e6459420dce36080cfc0382269e4dddf5cd7849a0d55f73
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 68fb74f92e12cb02a9b3c565e67fe482d4ee667bfeae7a9864c0ae2a9317ca0834a77edfe6f6757a83a9a14ae87b7f49703e43f314460954a064d2e8c56ce19b
|
7
|
+
data.tar.gz: 59f967d55a04ef8695b3cfbbbcf06333c0c71a93644a260ffc94259152355e169cfb8d23ef6150ee258617837379ff8811c224b3184aabde920fc142035f6fe2
|
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--format documentation
|
data/README.md
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
[](https://badge.fury.io/rb/tabled) 
|
2
|
+
|
3
|
+
|
4
|
+
# Description
|
5
|
+
This library can be used to render your data to a console. It's quite simple and has many features
|
6
|
+
|
7
|
+
# How to use
|
8
|
+
1. Install the gem `bundle add tabled` or `gem install tabled`
|
9
|
+
2. Add to the application `require 'tabled''`
|
10
|
+
3. Pass to the application array of rows. Each row may have any amount of columns and optional footer text.
|
11
|
+
|
12
|
+
### Simple data structure
|
13
|
+
```ruby
|
14
|
+
data = [
|
15
|
+
["Helena", "20 years", "Female"],
|
16
|
+
["John", "18 years", "Male"],
|
17
|
+
["Alan", "23 years", "Male"],
|
18
|
+
]
|
19
|
+
|
20
|
+
Tabled.new(data).print_to_console
|
21
|
+
```
|
22
|
+
|
23
|
+
Result
|
24
|
+
```shell
|
25
|
+
Helena 20 years Female
|
26
|
+
John 18 years Male
|
27
|
+
Alan 23 years Male
|
28
|
+
```
|
29
|
+
|
30
|
+
### Using footer inside a row
|
31
|
+
```ruby
|
32
|
+
data = [
|
33
|
+
["Helena", "20 years", "Female"],
|
34
|
+
["John", "18 years", "Male", { footer: "Legendary assassin John Wick (Keanu Reeves) retired from his violent career after marrying the love of his life." }],
|
35
|
+
["Alan", "23 years", "Male"],
|
36
|
+
]
|
37
|
+
|
38
|
+
Tabled.new(data).print_to_console
|
39
|
+
```
|
40
|
+
|
41
|
+
Result
|
42
|
+
```shell
|
43
|
+
Helena 20 years Female
|
44
|
+
|
45
|
+
John 18 years Male
|
46
|
+
Legendary assassin John Wick.
|
47
|
+
|
48
|
+
Alan 23 years Male
|
49
|
+
```
|
50
|
+
|
51
|
+
# Contributing
|
52
|
+
1. Fork it ( http://github.com/rodhilton/console_table/fork )
|
53
|
+
2. Create your feature branch (git checkout -b my-new-feature)
|
54
|
+
3. Commit your changes (git commit -am 'Add some feature')
|
55
|
+
4. Push to the branch (git push origin my-new-feature)
|
56
|
+
5. Create new Pull Request
|
data/demo.rb
ADDED
@@ -0,0 +1,130 @@
|
|
1
|
+
require_relative './lib/tabled'
|
2
|
+
|
3
|
+
STAR_WARS_CHARACTERS = [
|
4
|
+
{
|
5
|
+
"name": "Luke Skywalker",
|
6
|
+
"height": "172",
|
7
|
+
"mass": "77",
|
8
|
+
"hair_color": "blond",
|
9
|
+
"skin_color": "fair",
|
10
|
+
"eye_color": "blue",
|
11
|
+
"birth_year": "19BBY",
|
12
|
+
"gender": "male",
|
13
|
+
},
|
14
|
+
{
|
15
|
+
"name": "C-3PO",
|
16
|
+
"height": "167",
|
17
|
+
"mass": "75",
|
18
|
+
"hair_color": "n/a",
|
19
|
+
"skin_color": "gold",
|
20
|
+
"eye_color": "yellow",
|
21
|
+
"birth_year": "112BBY",
|
22
|
+
"gender": "n/a",
|
23
|
+
},
|
24
|
+
{
|
25
|
+
"name": "R2-D2",
|
26
|
+
"height": "96",
|
27
|
+
"mass": "32",
|
28
|
+
"hair_color": "n/a",
|
29
|
+
"skin_color": "white, blue",
|
30
|
+
"eye_color": "red",
|
31
|
+
"birth_year": "33BBY",
|
32
|
+
"gender": "n/a",
|
33
|
+
},
|
34
|
+
{
|
35
|
+
"name": "Darth Vader",
|
36
|
+
"height": "202",
|
37
|
+
"mass": "136",
|
38
|
+
"hair_color": "none",
|
39
|
+
"skin_color": "white",
|
40
|
+
"eye_color": "yellow",
|
41
|
+
"birth_year": "41.9BBY",
|
42
|
+
"gender": "male",
|
43
|
+
},
|
44
|
+
{
|
45
|
+
"name": "Leia Organa",
|
46
|
+
"height": "150",
|
47
|
+
"mass": "49",
|
48
|
+
"hair_color": "brown",
|
49
|
+
"skin_color": "light",
|
50
|
+
"eye_color": "brown",
|
51
|
+
"birth_year": "19BBY",
|
52
|
+
"gender": "female",
|
53
|
+
},
|
54
|
+
{
|
55
|
+
"name": "Owen Lars",
|
56
|
+
"height": "178",
|
57
|
+
"mass": "120",
|
58
|
+
"hair_color": "brown, grey",
|
59
|
+
"skin_color": "light",
|
60
|
+
"eye_color": "blue",
|
61
|
+
"birth_year": "52BBY",
|
62
|
+
"gender": "male",
|
63
|
+
},
|
64
|
+
{
|
65
|
+
"name": "Beru Whitesun lars",
|
66
|
+
"height": "165",
|
67
|
+
"mass": "75",
|
68
|
+
"hair_color": "brown",
|
69
|
+
"skin_color": "light",
|
70
|
+
"eye_color": "blue",
|
71
|
+
"birth_year": "47BBY",
|
72
|
+
"gender": "female",
|
73
|
+
},
|
74
|
+
{
|
75
|
+
"name": "R5-D4",
|
76
|
+
"height": "97",
|
77
|
+
"mass": "32",
|
78
|
+
"hair_color": "n/a",
|
79
|
+
"skin_color": "white, red",
|
80
|
+
"eye_color": "red",
|
81
|
+
"birth_year": "unknown",
|
82
|
+
"gender": "n/a",
|
83
|
+
},
|
84
|
+
{
|
85
|
+
"name": "Biggs Darklighter",
|
86
|
+
"height": "183",
|
87
|
+
"mass": "84",
|
88
|
+
"hair_color": "black",
|
89
|
+
"skin_color": "light",
|
90
|
+
"eye_color": "brown",
|
91
|
+
"birth_year": "24BBY",
|
92
|
+
"gender": "male",
|
93
|
+
},
|
94
|
+
{
|
95
|
+
"name": "Obi-Wan Kenobi",
|
96
|
+
"height": "182",
|
97
|
+
"mass": "77",
|
98
|
+
"hair_color": "auburn, white",
|
99
|
+
"skin_color": "fair",
|
100
|
+
"eye_color": "blue-gray",
|
101
|
+
"birth_year": "57BBY",
|
102
|
+
"gender": "male",
|
103
|
+
}
|
104
|
+
]
|
105
|
+
|
106
|
+
print "Printing without any params: \n"
|
107
|
+
|
108
|
+
data = STAR_WARS_CHARACTERS.map { |character|
|
109
|
+
[character[:name], character[:height], character[:gender]]
|
110
|
+
}
|
111
|
+
|
112
|
+
Tabled.new(data).print_to_console
|
113
|
+
|
114
|
+
print "\n\n############################\n\n"
|
115
|
+
print "Printing without frame: \n"
|
116
|
+
|
117
|
+
data = STAR_WARS_CHARACTERS.map { |character|
|
118
|
+
[character[:name], character[:height], character[:gender]]
|
119
|
+
}
|
120
|
+
|
121
|
+
Tabled.new(data, framed: false).print_to_console
|
122
|
+
|
123
|
+
print "\n\n############################\n\n"
|
124
|
+
print "Printing without frame: and row separator\n"
|
125
|
+
|
126
|
+
data = STAR_WARS_CHARACTERS.map { |character|
|
127
|
+
[character[:name], character[:height], character[:gender]]
|
128
|
+
}
|
129
|
+
|
130
|
+
Tabled.new(data, framed: false, row_separator: nil).print_to_console
|
@@ -0,0 +1,68 @@
|
|
1
|
+
class Tabled
|
2
|
+
class ContentShaper
|
3
|
+
attr_accessor :data, :options, :columns_width
|
4
|
+
|
5
|
+
def initialize(data, columns_width, options)
|
6
|
+
@data = data
|
7
|
+
@columns_width = columns_width
|
8
|
+
@options = options
|
9
|
+
end
|
10
|
+
|
11
|
+
def shape
|
12
|
+
content =
|
13
|
+
data
|
14
|
+
.inject([]) { |enumerator, row|
|
15
|
+
enumerator << Tabled::Template::Row.render(row, columns_width, options[:framed])
|
16
|
+
enumerator << Tabled::Template::RowFooter.render(row, columns_width, options[:framed])
|
17
|
+
|
18
|
+
# Row separator
|
19
|
+
unless options[:row_separator].nil?
|
20
|
+
enumerator << options[:row_separator].to_s * row_length
|
21
|
+
end
|
22
|
+
|
23
|
+
enumerator
|
24
|
+
}
|
25
|
+
.compact
|
26
|
+
|
27
|
+
content = add_left_and_right_borders(content)
|
28
|
+
content = add_top_bottom_borders(content)
|
29
|
+
|
30
|
+
content
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def row_length
|
36
|
+
@row_length ||= columns_width.sum
|
37
|
+
end
|
38
|
+
|
39
|
+
def add_left_and_right_borders(content)
|
40
|
+
content.inject([]) { |enumerator, row|
|
41
|
+
# For a row separator all symbols are the same
|
42
|
+
row_is_separator = row.split('').uniq.size == 1
|
43
|
+
if row_is_separator && !options[:row_separator].nil?
|
44
|
+
enumerator << (options[:row_separator] * 2) + row + options[:row_separator]
|
45
|
+
elsif !options[:framed]
|
46
|
+
enumerator << row
|
47
|
+
else
|
48
|
+
enumerator << ('| ' if options[:framed]) + row + ('|' if options[:framed])
|
49
|
+
end
|
50
|
+
|
51
|
+
enumerator
|
52
|
+
}
|
53
|
+
end
|
54
|
+
|
55
|
+
def add_top_bottom_borders(content)
|
56
|
+
# Top and bottom borders
|
57
|
+
if options[:framed]
|
58
|
+
[
|
59
|
+
'-' * (row_length + 3),
|
60
|
+
options[:row_separator] ? content[0..-2] : content,
|
61
|
+
'-' * (row_length + 3)
|
62
|
+
].flatten
|
63
|
+
else
|
64
|
+
content
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
data/lib/helpers.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
class Tabled
|
2
|
+
class Helpers
|
3
|
+
# Calculates columns size
|
4
|
+
def self.calculate_columns_width(data)
|
5
|
+
columns_width = []
|
6
|
+
|
7
|
+
data.each do |row|
|
8
|
+
row_without_params = row[0..-2]
|
9
|
+
row_without_params.each_with_index { |column, index|
|
10
|
+
is_column_last = row_without_params.count == index + 1
|
11
|
+
if is_column_last
|
12
|
+
possible_new_value = [row.last.fetch(:footer, '').to_s.size, column.to_s.size].sort.last
|
13
|
+
columns_width[index] = possible_new_value if possible_new_value > (columns_width[index] || 0)
|
14
|
+
else
|
15
|
+
columns_width[index] = column.to_s.size if column.to_s.size > (columns_width[index] || 0)
|
16
|
+
end
|
17
|
+
}
|
18
|
+
end
|
19
|
+
|
20
|
+
columns_width.map { |column_width| column_width + 1 }
|
21
|
+
end
|
22
|
+
|
23
|
+
# Add hash as a last element of the row
|
24
|
+
def self.convert_to_required_structure(data)
|
25
|
+
data.map { |row|
|
26
|
+
row << {} unless row.last.is_a?(Hash)
|
27
|
+
row
|
28
|
+
}
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/lib/tabled.rb
CHANGED
@@ -1,55 +1,21 @@
|
|
1
1
|
require 'byebug'
|
2
|
-
|
2
|
+
require_relative './template'
|
3
|
+
require_relative './helpers'
|
4
|
+
require_relative './content_shaper'
|
3
5
|
|
4
6
|
class Tabled
|
5
|
-
DEFAULT_OPTIONS = {
|
7
|
+
DEFAULT_OPTIONS = { framed: true, row_separator: '-' }
|
6
8
|
attr_accessor :data, :columns_width, :content, :options
|
7
9
|
|
8
10
|
def initialize(data, **options)
|
9
11
|
@options = DEFAULT_OPTIONS.merge(options)
|
10
|
-
@data = data
|
11
|
-
@columns_width =
|
12
|
-
|
13
|
-
convert_to_required_structure
|
14
|
-
calculate_columns_width
|
15
|
-
prepare_content
|
12
|
+
@data = Tabled::Helpers.convert_to_required_structure(data)
|
13
|
+
@columns_width = Tabled::Helpers.calculate_columns_width(data)
|
14
|
+
@content = Tabled::ContentShaper.new(data, @columns_width, @options).shape()
|
16
15
|
end
|
17
16
|
|
18
17
|
|
19
18
|
def print_to_console
|
20
19
|
print content.join("\n")
|
21
20
|
end
|
22
|
-
|
23
|
-
private
|
24
|
-
|
25
|
-
def convert_to_required_structure
|
26
|
-
self.data = data.map { |row|
|
27
|
-
row << {} unless row.last.is_a?(Hash)
|
28
|
-
row
|
29
|
-
}
|
30
|
-
end
|
31
|
-
|
32
|
-
def calculate_columns_width
|
33
|
-
data.each do |row|
|
34
|
-
row_without_params = row[0..-2]
|
35
|
-
row_without_params.each_with_index { |column, index|
|
36
|
-
is_column_last = row_without_params.count == index + 1
|
37
|
-
if is_column_last
|
38
|
-
possible_new_value = [row.last.fetch(:footer, '').to_s.size, column.to_s.size].sort.last
|
39
|
-
self.columns_width[index] = possible_new_value if possible_new_value > (self.columns_width[index] || 0)
|
40
|
-
else
|
41
|
-
self.columns_width[index] = column.to_s.size if column.to_s.size > (self.columns_width[index] || 0)
|
42
|
-
end
|
43
|
-
}
|
44
|
-
end
|
45
|
-
|
46
|
-
self.columns_width = columns_width.map { |column_width| column_width + 1 }
|
47
|
-
end
|
48
|
-
|
49
|
-
def prepare_content
|
50
|
-
self.content = data.inject([]) { |enumerator, row|
|
51
|
-
enumerator << Tabled::Template::Row.render(row, columns_width, options)
|
52
|
-
enumerator << Tabled::Template::RowFooter.render(row)
|
53
|
-
}.compact
|
54
|
-
end
|
55
21
|
end
|
data/lib/template.rb
CHANGED
@@ -1,23 +1,21 @@
|
|
1
1
|
class Tabled
|
2
2
|
class Template
|
3
3
|
class Row
|
4
|
-
def self.render(row, columns_width,
|
4
|
+
def self.render(row, columns_width, is_framed)
|
5
5
|
row[0..-2].map.with_index { |column, index|
|
6
6
|
spaces = ' ' * (columns_width[index] - column.to_s.size)
|
7
7
|
column.to_s + spaces
|
8
8
|
}.join('')
|
9
9
|
end
|
10
10
|
end
|
11
|
-
end
|
12
|
-
end
|
13
11
|
|
14
|
-
class Tabled
|
15
|
-
class Template
|
16
12
|
class RowFooter
|
17
|
-
def self.render(row)
|
13
|
+
def self.render(row, columns_width, is_framed)
|
18
14
|
return nil unless row.last.fetch(:footer, false)
|
19
15
|
|
20
|
-
row.last.fetch(:footer)
|
16
|
+
footer = row.last.fetch(:footer)
|
17
|
+
required_spaces = columns_width.sum() - footer.size
|
18
|
+
footer + (' ' * required_spaces)
|
21
19
|
end
|
22
20
|
end
|
23
21
|
end
|
data/tabled.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = 'tabled'
|
3
|
-
s.version = '0.0.
|
3
|
+
s.version = '0.0.2'
|
4
4
|
s.summary = "Library for rendering pretty tables in console"
|
5
5
|
s.description = "This library can be used to render your data to a console. It's quite simple and has many features"
|
6
6
|
s.authors = ["Max Rukomoynikov"]
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tabled
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Max Rukomoynikov
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-05-
|
11
|
+
date: 2022-05-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: byebug
|
@@ -61,8 +61,13 @@ extra_rdoc_files: []
|
|
61
61
|
files:
|
62
62
|
- ".github/workflows/linters.yml"
|
63
63
|
- ".gitignore"
|
64
|
+
- ".rspec"
|
64
65
|
- Gemfile
|
65
66
|
- Gemfile.lock
|
67
|
+
- README.md
|
68
|
+
- demo.rb
|
69
|
+
- lib/content_shaper.rb
|
70
|
+
- lib/helpers.rb
|
66
71
|
- lib/tabled.rb
|
67
72
|
- lib/template.rb
|
68
73
|
- tabled.gemspec
|