tabled 0.0.1 → 0.0.4

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c9ad158738f50082bbcc59da4ab6e84e6d1d3a336bd4168623c72a037144df34
4
- data.tar.gz: 679b46c1e778597edcb871484106aaeaccc70a8153ad75749f8116eae563adbe
3
+ metadata.gz: 82a764f542f7d1d83f41e21d66e3e4407e0add51f3c78d56998804061c7a53f5
4
+ data.tar.gz: d50b8c1c7b9f015599c9eaffba00bcefac673e4f7271499cd50c3f600b249512
5
5
  SHA512:
6
- metadata.gz: cc7dc1ee13cd9f4085ada67db778e79153f4bec054501d745694644155186fff9a46335120f384c796c42d55cf69d641d358865a74c7fd7edbc86835b67dfed6
7
- data.tar.gz: 5eda9d7584f0bd89813ff666f840d281e56fd1f5cc2617eedf8b7366da258b830a3774752b74ccbdb87921fb35e5a70a0651736f4c45c1287af5055c428d0193
6
+ metadata.gz: 73f29421ca05bd0ef6557ecabb1b01e83608d80ff6ad21ab6ccdf1a7a2c1938f223ee9def3efb4df9cd2935d1c5eabb0bd8fd0c8e22f9033606ad3f55ead540c
7
+ data.tar.gz: 492de196716a4c3d39d789780b2f216474cb7de4e06da59125aed7eda50b1064e7bd1102c0dca8b066045501d0df4e0a531956e13035e3b6de02c2de32c931eb
@@ -17,13 +17,25 @@ permissions:
17
17
  contents: read
18
18
 
19
19
  jobs:
20
+ linters:
21
+ runs-on: ubuntu-latest
22
+ strategy:
23
+ matrix:
24
+ ruby-version: ['3.0']
25
+ steps:
26
+ - uses: actions/checkout@v3
27
+ - name: Set up Ruby
28
+ uses: ruby/setup-ruby@2b019609e2b0f1ea1a2bc8ca11cb82ab46ada124
29
+ with:
30
+ ruby-version: ${{ matrix.ruby-version }}
31
+ bundler-cache: true # runs 'bundle install' and caches installed gems automatically
32
+ - name: Run tests
33
+ run: bundle exec rubocop
20
34
  test:
21
-
22
35
  runs-on: ubuntu-latest
23
36
  strategy:
24
37
  matrix:
25
38
  ruby-version: ['2.6', '2.7', '3.0']
26
-
27
39
  steps:
28
40
  - uses: actions/checkout@v3
29
41
  - name: Set up Ruby
data/.gitignore CHANGED
@@ -1,3 +1,4 @@
1
1
  .byebug_history
2
2
  coverage
3
- .idea
3
+ .idea
4
+ *.gem
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --require spec_helper
data/.rubocop.yml ADDED
@@ -0,0 +1,7 @@
1
+ inherit_from: .rubocop_todo.yml
2
+
3
+ require:
4
+ - rubocop-rspec
5
+
6
+ AllCops:
7
+ NewCops: enable
data/.rubocop_todo.yml ADDED
@@ -0,0 +1,69 @@
1
+ # This configuration was generated by
2
+ # `rubocop --auto-gen-config --auto-gen-only-exclude`
3
+ # on 2022-06-24 15:05:43 UTC using RuboCop version 1.29.1.
4
+ # The point is for the user to remove these configuration records
5
+ # one by one as the offenses are removed from the code base.
6
+ # Note that changes in the inspected code, or installation of new
7
+ # versions of RuboCop, may require this file to be generated again.
8
+
9
+ # Offense count: 1
10
+ # Configuration parameters: Include.
11
+ # Include: **/*.gemspec
12
+ Gemspec/RequiredRubyVersion:
13
+ Exclude:
14
+ - 'tabled.gemspec'
15
+
16
+ # Offense count: 3
17
+ # Configuration parameters: IgnoredMethods, CountRepeatedAttributes, Max.
18
+ Metrics/AbcSize:
19
+ Exclude:
20
+ - 'lib/content_shaper.rb'
21
+ - 'lib/helpers.rb'
22
+
23
+ # Offense count: 3
24
+ # Configuration parameters: CountComments, Max, CountAsOne, ExcludedMethods, IgnoredMethods.
25
+ # IgnoredMethods: refine
26
+ Metrics/BlockLength:
27
+ Exclude:
28
+ - '**/*.gemspec'
29
+ - 'spec/framed/tabled_spec.rb'
30
+ - 'spec/non_framed/tabled_spec.rb'
31
+
32
+ # Offense count: 1
33
+ # Configuration parameters: IgnoredMethods, Max.
34
+ Metrics/CyclomaticComplexity:
35
+ Exclude:
36
+ - 'lib/helpers.rb'
37
+
38
+ # Offense count: 5
39
+ # Configuration parameters: CountComments, Max, CountAsOne, ExcludedMethods, IgnoredMethods.
40
+ Metrics/MethodLength:
41
+ Exclude:
42
+ - 'lib/content_shaper.rb'
43
+ - 'lib/helpers.rb'
44
+ - 'spec/factories/factory_data.rb'
45
+
46
+ # Offense count: 1
47
+ # Configuration parameters: IgnoredMethods, Max.
48
+ Metrics/PerceivedComplexity:
49
+ Exclude:
50
+ - 'lib/helpers.rb'
51
+
52
+ # Offense count: 1
53
+ # Configuration parameters: Max, CountAsOne.
54
+ RSpec/ExampleLength:
55
+ Exclude:
56
+ - 'spec/framed/tabled_spec.rb'
57
+
58
+ # Offense count: 9
59
+ # Configuration parameters: AllowedConstants.
60
+ Style/Documentation:
61
+ Exclude:
62
+ - 'spec/**/*'
63
+ - 'test/**/*'
64
+ - 'bin/tabled'
65
+ - 'lib/content_shaper.rb'
66
+ - 'lib/helpers.rb'
67
+ - 'lib/parsers/csv_parser.rb'
68
+ - 'lib/tabled.rb'
69
+ - 'lib/template.rb'
data/CHANGELOG.md ADDED
@@ -0,0 +1,11 @@
1
+ ### Version 0.0.3 (May 23, 2022)
2
+ 1. Printing titles of columns
3
+ 2. Fixing layout (amount of spaces for row separators)
4
+
5
+ ### Version 0.0.2 (May 16, 2022)
6
+ 1. Rendering footers of rows
7
+ 2. Adding optional frame to tables
8
+ 3. Adding row separator
9
+
10
+ ### Version 0.0.1 (May 11, 2022)
11
+ 1. Basic rendering tables to console
data/Gemfile CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  source 'http://rubygems.org'
2
4
 
3
- gemspec
5
+ gemspec
data/Gemfile.lock CHANGED
@@ -1,14 +1,23 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- tabled (0.0.1)
4
+ tabled (0.0.4)
5
+ dry-cli
5
6
 
6
7
  GEM
7
8
  remote: http://rubygems.org/
8
9
  specs:
10
+ ast (2.4.2)
9
11
  byebug (11.1.3)
10
12
  diff-lcs (1.5.0)
11
13
  docile (1.4.0)
14
+ dry-cli (0.7.0)
15
+ parallel (1.22.1)
16
+ parser (3.1.2.0)
17
+ ast (~> 2.4.1)
18
+ rainbow (3.1.1)
19
+ regexp_parser (2.4.0)
20
+ rexml (3.2.5)
12
21
  rspec (3.11.0)
13
22
  rspec-core (~> 3.11.0)
14
23
  rspec-expectations (~> 3.11.0)
@@ -22,12 +31,27 @@ GEM
22
31
  diff-lcs (>= 1.2.0, < 2.0)
23
32
  rspec-support (~> 3.11.0)
24
33
  rspec-support (3.11.0)
34
+ rubocop (1.29.1)
35
+ parallel (~> 1.10)
36
+ parser (>= 3.1.0.0)
37
+ rainbow (>= 2.2.2, < 4.0)
38
+ regexp_parser (>= 1.8, < 3.0)
39
+ rexml (>= 3.2.5, < 4.0)
40
+ rubocop-ast (>= 1.17.0, < 2.0)
41
+ ruby-progressbar (~> 1.7)
42
+ unicode-display_width (>= 1.4.0, < 3.0)
43
+ rubocop-ast (1.18.0)
44
+ parser (>= 3.1.1.0)
45
+ rubocop-rspec (2.10.0)
46
+ rubocop (~> 1.19)
47
+ ruby-progressbar (1.11.0)
25
48
  simplecov (0.21.2)
26
49
  docile (~> 1.1)
27
50
  simplecov-html (~> 0.11)
28
51
  simplecov_json_formatter (~> 0.1)
29
52
  simplecov-html (0.12.3)
30
53
  simplecov_json_formatter (0.1.4)
54
+ unicode-display_width (2.1.0)
31
55
 
32
56
  PLATFORMS
33
57
  ruby
@@ -35,6 +59,8 @@ PLATFORMS
35
59
  DEPENDENCIES
36
60
  byebug
37
61
  rspec
62
+ rubocop
63
+ rubocop-rspec
38
64
  simplecov
39
65
  tabled!
40
66
 
data/README.md ADDED
@@ -0,0 +1,73 @@
1
+
2
+ [![Gem Version](https://badge.fury.io/rb/tabled.svg)](https://badge.fury.io/rb/tabled) ![CI is pasing for ruby 2.6 - 3.0](https://github.com/rukomoynikov/tabled/actions/workflows/linters.yml/badge.svg) ![Downloads](https://badgen.net/rubygems/dt/tabled)
3
+
4
+
5
+ # Description
6
+ Library can be used to render your data to a console. Though it's quite simple, but has many features.
7
+
8
+ # How to use
9
+ 1. Install the gem `bundle add tabled` or `gem install tabled`
10
+ 2. Add to the application `require 'tabled''`
11
+ 3. Pass to the application array of rows. Each row may have any amount of columns and optional footer text.
12
+
13
+ ### Params for Tabled instance
14
+ Tabled accepts two params. Data which is prohibited and options.
15
+ Available options:
16
+ 1. `framed` - optional, default is true
17
+ 2. `row_separator` - optional, default is `-`. Can be `nil` if you don't need separate rows.
18
+ 3. `titles` - optional parameter with list of columns titles
19
+
20
+ More examples in [demo.rb](./demo.rb)
21
+
22
+ ### Simple data structure
23
+ ```ruby
24
+ data = [
25
+ ["Helena", "20 years", "Female"],
26
+ ["John", "18 years", "Male"],
27
+ ["Alan", "23 years", "Male"],
28
+ ]
29
+
30
+ Tabled.new(data, framed: false,
31
+ row_separator: nil).print_to_console
32
+ ```
33
+
34
+ Result
35
+ ```shell
36
+ Helena 20 years Female
37
+ John 18 years Male
38
+ Alan 23 years Male
39
+ ```
40
+
41
+ ### Using footer inside a row
42
+ ```ruby
43
+ data = [
44
+ ["Helena", "20 years", "Female"],
45
+ ["John", "18 years", "Male", { footer: "Legendary assassin John Wick (Keanu Reeves)." }],
46
+ ["Alan", "23 years", "Male"],
47
+ ]
48
+
49
+ Tabled.new(data, row_separator: nil).print_to_console
50
+ ```
51
+
52
+ Result
53
+ ```shell
54
+ ----------------------------------------------------------------
55
+ | Helena 20 years Female |
56
+ | John 18 years Male |
57
+ | Legendary assassin John Wick (Keanu Reeves). |
58
+ | Alan 23 years Male |
59
+ ----------------------------------------------------------------
60
+ ```
61
+
62
+ # Printing CSV files to console
63
+ As a part of the gem `tabled` binary is included. So, you can basicaly run it like:
64
+ ```shell
65
+ tabled print path_to_csv_file
66
+ ```
67
+
68
+ # Contributing
69
+ 1. Fork it ( http://github.com/rukomoynikov/tabled/fork )
70
+ 2. Create your feature branch (git checkout -b my-new-feature)
71
+ 3. Commit your changes (git commit -am 'Add some feature')
72
+ 4. Push to the branch (git push origin my-new-feature)
73
+ 5. Create new Pull Request
data/bin/tabled ADDED
@@ -0,0 +1,32 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require_relative '../lib/tabled'
5
+ require_relative '../lib/parsers/csv_parser'
6
+ require 'dry/cli'
7
+ require 'pathname'
8
+
9
+ module TabledCli
10
+ module CLI
11
+ module Commands
12
+ extend Dry::CLI::Registry
13
+
14
+ class Print < Dry::CLI::Command
15
+ desc 'Printing CSV to console'
16
+
17
+ argument :input, desc: 'Input file to print'
18
+
19
+ def call(input: nil, **)
20
+ return p 'File must be provided' if input.nil?
21
+ return p 'File doesn\'t exist' unless File.exist?(Pathname.new(input))
22
+
23
+ Tabled.new(Tabled::CSVParser.parse(Pathname.new(input))).print_to_console
24
+ end
25
+ end
26
+
27
+ register 'print', Print, aliases: ['p', '-p', '--print']
28
+ end
29
+ end
30
+ end
31
+
32
+ Dry::CLI.new(TabledCli::CLI::Commands).call
data/demo.rb ADDED
@@ -0,0 +1,186 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative './lib/tabled'
4
+
5
+ STAR_WARS_CHARACTERS = [
6
+ {
7
+ name: 'Luke Skywalker',
8
+ height: '172',
9
+ mass: '77',
10
+ hair_color: 'blond',
11
+ skin_color: 'fair',
12
+ eye_color: 'blue',
13
+ birth_year: '19BBY',
14
+ gender: 'male'
15
+ },
16
+ {
17
+ name: 'C-3PO',
18
+ height: '167',
19
+ mass: '75',
20
+ hair_color: 'n/a',
21
+ skin_color: 'gold',
22
+ eye_color: 'yellow',
23
+ birth_year: '112BBY',
24
+ gender: 'n/a'
25
+ },
26
+ {
27
+ name: 'R2-D2',
28
+ height: '96',
29
+ mass: '32',
30
+ hair_color: 'n/a',
31
+ skin_color: 'white, blue',
32
+ eye_color: 'red',
33
+ birth_year: '33BBY',
34
+ gender: 'n/a'
35
+ },
36
+ {
37
+ name: 'Darth Vader',
38
+ height: '202',
39
+ mass: '136',
40
+ hair_color: 'none',
41
+ skin_color: 'white',
42
+ eye_color: 'yellow',
43
+ birth_year: '41.9BBY',
44
+ gender: 'male'
45
+ },
46
+ {
47
+ name: 'Leia Organa',
48
+ height: '150',
49
+ mass: '49',
50
+ hair_color: 'brown',
51
+ skin_color: 'light',
52
+ eye_color: 'brown',
53
+ birth_year: '19BBY',
54
+ gender: 'female'
55
+ },
56
+ {
57
+ name: 'Owen Lars',
58
+ height: '178',
59
+ mass: '120',
60
+ hair_color: 'brown, grey',
61
+ skin_color: 'light',
62
+ eye_color: 'blue',
63
+ birth_year: '52BBY',
64
+ gender: 'male'
65
+ },
66
+ {
67
+ name: 'Beru Whitesun lars',
68
+ height: '165',
69
+ mass: '75',
70
+ hair_color: 'brown',
71
+ skin_color: 'light',
72
+ eye_color: 'blue',
73
+ birth_year: '47BBY',
74
+ gender: 'female'
75
+ },
76
+ {
77
+ name: 'R5-D4',
78
+ height: '97',
79
+ mass: '32',
80
+ hair_color: 'n/a',
81
+ skin_color: 'white, red',
82
+ eye_color: 'red',
83
+ birth_year: 'unknown',
84
+ gender: 'n/a'
85
+ },
86
+ {
87
+ name: 'Biggs Darklighter',
88
+ height: '183',
89
+ mass: '84',
90
+ hair_color: 'black',
91
+ skin_color: 'light',
92
+ eye_color: 'brown',
93
+ birth_year: '24BBY',
94
+ gender: 'male'
95
+ },
96
+ {
97
+ name: 'Obi-Wan Kenobi',
98
+ height: '182',
99
+ mass: '77',
100
+ hair_color: 'auburn, white',
101
+ skin_color: 'fair',
102
+ eye_color: 'blue-gray',
103
+ birth_year: '57BBY',
104
+ gender: 'male'
105
+ }
106
+ ].freeze
107
+
108
+ print "Printing without any params: \n"
109
+
110
+ data = STAR_WARS_CHARACTERS.map do |character|
111
+ [character[:name], character[:height], character[:gender]]
112
+ end
113
+
114
+ Tabled.new(data).print_to_console
115
+
116
+ # ---------------------------------
117
+ # | Luke Skywalker 172 male |
118
+ # ---------------------------------
119
+ # | C-3PO 167 n/a |
120
+ # ---------------------------------
121
+ # | R2-D2 96 n/a |
122
+ # ---------------------------------
123
+ # | Darth Vader 202 male |
124
+ # ---------------------------------
125
+ # | Leia Organa 150 female |
126
+ # ---------------------------------
127
+ # | Owen Lars 178 male |
128
+ # ---------------------------------
129
+ # | Beru Whitesun lars 165 female |
130
+ # ---------------------------------
131
+ # | R5-D4 97 n/a |
132
+ # ---------------------------------
133
+ # | Biggs Darklighter 183 male |
134
+ # ---------------------------------
135
+ # | Obi-Wan Kenobi 182 male |
136
+ # ---------------------------------
137
+
138
+ print "\n\n############################\n\n"
139
+ print "Printing without frame: \n"
140
+
141
+ data = STAR_WARS_CHARACTERS.map do |character|
142
+ [character[:name], character[:height], character[:gender]]
143
+ end
144
+
145
+ Tabled.new(data, framed: false).print_to_console
146
+
147
+ # Luke Skywalker 172 male
148
+ # ---------------------------------
149
+ # C-3PO 167 n/a
150
+ # ---------------------------------
151
+ # R2-D2 96 n/a
152
+ # ---------------------------------
153
+ # Darth Vader 202 male
154
+ # ---------------------------------
155
+ # Leia Organa 150 female
156
+ # ---------------------------------
157
+ # Owen Lars 178 male
158
+ # ---------------------------------
159
+ # Beru Whitesun lars 165 female
160
+ # ---------------------------------
161
+ # R5-D4 97 n/a
162
+ # ---------------------------------
163
+ # Biggs Darklighter 183 male
164
+ # ---------------------------------
165
+ # Obi-Wan Kenobi 182 male
166
+ # ---------------------------------
167
+
168
+ print "\n\n############################\n\n"
169
+ print "Printing without frame: and row separator\n"
170
+
171
+ data = STAR_WARS_CHARACTERS.map do |character|
172
+ [character[:name], character[:height], character[:gender], { footer: 'One very long footer! Be carefull' }]
173
+ end
174
+
175
+ Tabled.new(data, titles: %w[Name Height Gender]).print_to_console
176
+
177
+ # Luke Skywalker 172 male
178
+ # C-3PO 167 n/a
179
+ # R2-D2 96 n/a
180
+ # Darth Vader 202 male
181
+ # Leia Organa 150 female
182
+ # Owen Lars 178 male
183
+ # Beru Whitesun lars 165 female
184
+ # R5-D4 97 n/a
185
+ # Biggs Darklighter 183 male
186
+ # Obi-Wan Kenobi 182 male
@@ -0,0 +1,71 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Tabled
4
+ class ContentShaper
5
+ attr_accessor :data, :options, :columns_width
6
+
7
+ def initialize(data, columns_width, options)
8
+ @data = data
9
+ @columns_width = columns_width
10
+ @options = options
11
+ end
12
+
13
+ def shape
14
+ content = []
15
+
16
+ unless options[:titles].empty?
17
+ content << Tabled::Template::Titles.render(options[:titles], columns_width, options[:framed])
18
+ content << (options[:row_separator].to_s * row_length) unless options[:row_separator].nil?
19
+ end
20
+
21
+ content.concat(
22
+ data
23
+ .each_with_object([]) do |row, enumerator|
24
+ enumerator << Tabled::Template::Row.render(row, columns_width, options[:framed])
25
+ enumerator << Tabled::Template::RowFooter.render(row, columns_width, options[:framed])
26
+
27
+ # Row separator
28
+ enumerator << (options[:row_separator].to_s * row_length) unless options[:row_separator].nil?
29
+ end
30
+ .compact
31
+ )
32
+
33
+ content = add_left_and_right_borders(content)
34
+ add_top_bottom_borders(content)
35
+ end
36
+
37
+ private
38
+
39
+ def row_length
40
+ @row_length ||= columns_width.sum
41
+ end
42
+
43
+ def add_left_and_right_borders(content)
44
+ return content unless options[:framed]
45
+
46
+ content.each_with_object([]) do |row, enumerator|
47
+ # For a row separator all symbols are the same
48
+ row_is_separator = row.chars.uniq.size == 1
49
+
50
+ enumerator << if row_is_separator && !options[:row_separator].nil?
51
+ (options[:row_separator] * 2) + row + options[:row_separator]
52
+ else
53
+ "| #{row}|"
54
+ end
55
+ end
56
+ end
57
+
58
+ def add_top_bottom_borders(content)
59
+ # Top and bottom borders
60
+ if options[:framed]
61
+ [
62
+ '-' * (row_length + 3),
63
+ options[:row_separator] ? content[0..-2] : content,
64
+ '-' * (row_length + 3)
65
+ ].flatten
66
+ else
67
+ content
68
+ end
69
+ end
70
+ end
71
+ end
data/lib/helpers.rb ADDED
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Tabled
4
+ class Helpers
5
+ # Calculates columns size
6
+ def self.calculate_columns_width(data:, options:)
7
+ columns_width = []
8
+
9
+ data.each do |row|
10
+ # [0..-2] Due to reason last item is always hash with row params
11
+ row[0..-2].each_with_index do |column, index|
12
+ columns_width[index] = column.to_s.size if column.to_s.size > (columns_width[index] || 0)
13
+ end
14
+ end
15
+
16
+ # If titles longer than data use titles column width
17
+ columns_width.each_with_index do |_column_size, index|
18
+ title_size = options[:titles].fetch(index, '').size
19
+
20
+ columns_width[index] = title_size > columns_width[index] ? title_size : columns_width[index]
21
+ end
22
+
23
+ # Add 1 space in the end of each column
24
+ columns_width = columns_width.map { |column_width| column_width + 1 }
25
+ # Space in the last column is extra when table isn't framed
26
+ columns_width[-1] = columns_width[-1] - 1 unless options[:framed]
27
+
28
+ # Add to the last column footer spaces if needed
29
+ longest_footer_size = # longest footers
30
+ data.map do |row|
31
+ row.last.fetch(:footer, '')
32
+ end.max.to_s.size + 1
33
+ last_col_spaces = longest_footer_size - columns_width.sum # spaces required to the end
34
+ columns_width[-1] = columns_width.last + last_col_spaces if last_col_spaces.positive?
35
+
36
+ columns_width
37
+ end
38
+
39
+ # Add hash as a last element of the row
40
+ def self.convert_to_required_structure(data)
41
+ data.map do |row|
42
+ row << {} unless row.last.is_a?(Hash)
43
+ row
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'csv'
4
+ class Tabled
5
+ class CSVParser
6
+ def self.parse(file_path)
7
+ ::CSV.read(file_path)
8
+ end
9
+ end
10
+ end
data/lib/tabled.rb CHANGED
@@ -1,55 +1,22 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'byebug'
2
- require 'template'
4
+ require_relative './template'
5
+ require_relative './helpers'
6
+ require_relative './content_shaper'
3
7
 
4
8
  class Tabled
5
- DEFAULT_OPTIONS = { borders: false }
9
+ DEFAULT_OPTIONS = { framed: true, row_separator: '-', titles: [] }.freeze
6
10
  attr_accessor :data, :columns_width, :content, :options
7
11
 
8
12
  def initialize(data, **options)
9
13
  @options = DEFAULT_OPTIONS.merge(options)
10
- @data = data
11
- @columns_width = []
12
-
13
- convert_to_required_structure
14
- calculate_columns_width
15
- prepare_content
14
+ @data = Tabled::Helpers.convert_to_required_structure(data)
15
+ @columns_width = Tabled::Helpers.calculate_columns_width(data: data, options: @options)
16
+ @content = Tabled::ContentShaper.new(data, @columns_width, @options).shape
16
17
  end
17
18
 
18
-
19
19
  def print_to_console
20
20
  print content.join("\n")
21
21
  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
- end
22
+ end
data/lib/template.rb CHANGED
@@ -1,24 +1,37 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Tabled
2
4
  class Template
3
5
  class Row
4
- def self.render(row, columns_width, options)
5
- row[0..-2].map.with_index { |column, index|
6
+ # | Luke Skywalker 172 male |
7
+ def self.render(row, columns_width, _is_framed)
8
+ row[0..-2].map.with_index do |column, index|
6
9
  spaces = ' ' * (columns_width[index] - column.to_s.size)
7
10
  column.to_s + spaces
8
- }.join('')
11
+ end.join
12
+ end
13
+ end
14
+
15
+ class Titles
16
+ # ------------------------------------
17
+ # | Name Height Gender |
18
+ # ------------------------------------
19
+ def self.render(row, columns_width, _is_framed)
20
+ row.map.with_index do |column, index|
21
+ spaces = ' ' * (columns_width[index] - column.to_s.size)
22
+ column.to_s + spaces
23
+ end.join
9
24
  end
10
25
  end
11
- end
12
- end
13
26
 
14
- class Tabled
15
- class Template
16
27
  class RowFooter
17
- def self.render(row)
28
+ def self.render(row, columns_width, _is_framed)
18
29
  return nil unless row.last.fetch(:footer, false)
19
30
 
20
- row.last.fetch(:footer)
31
+ footer = row.last.fetch(:footer)
32
+ required_spaces = columns_width.sum - footer.size
33
+ footer + (' ' * required_spaces)
21
34
  end
22
35
  end
23
36
  end
24
- end
37
+ end
data/tabled.gemspec CHANGED
@@ -1,19 +1,27 @@
1
+ # frozen_string_literal: true
2
+
1
3
  Gem::Specification.new do |s|
2
4
  s.name = 'tabled'
3
- s.version = '0.0.1'
4
- s.summary = "Library for rendering pretty tables in console"
5
- s.description = "This library can be used to render your data to a console. It's quite simple and has many features"
6
- s.authors = ["Max Rukomoynikov"]
5
+ s.version = '0.0.4'
6
+ s.summary = 'Library for rendering pretty tables in console'
7
+ s.description = 'Library can be used to render your data to a console. Being quite simple it has many features.'
8
+ s.authors = ['Max Rukomoynikov']
7
9
  s.email = 'rukomoynikov@gmail.com'
10
+ s.executables << 'tabled'
8
11
  s.files =
9
12
  Dir.chdir(File.expand_path(__dir__)) do
10
13
  `git ls-files -z`.split("\x0").reject { |f| f.match(%r{\A(?:test|spec|features)/}) }
11
14
  end
12
15
  s.homepage = 'https://rubygems.org/gems/tabled'
13
- s.metadata = { "source_code_uri" => "https://github.com/Rukomoynikov/tabled" }
14
- s.license = 'MIT'
16
+ s.metadata = { 'source_code_uri' => 'https://github.com/Rukomoynikov/tabled',
17
+ 'rubygems_mfa_required' => 'true' }
18
+ s.license = 'MIT'
19
+
20
+ s.add_dependency 'dry-cli'
15
21
 
16
- s.add_development_dependency "byebug"
17
- s.add_development_dependency "rspec"
18
- s.add_development_dependency "simplecov"
19
- end
22
+ s.add_development_dependency 'byebug'
23
+ s.add_development_dependency 'rspec'
24
+ s.add_development_dependency 'rubocop'
25
+ s.add_development_dependency 'rubocop-rspec'
26
+ s.add_development_dependency 'simplecov'
27
+ end
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tabled
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.4
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 00:00:00.000000000 Z
11
+ date: 2022-06-24 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: dry-cli
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: byebug
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -38,6 +52,34 @@ dependencies:
38
52
  - - ">="
39
53
  - !ruby/object:Gem::Version
40
54
  version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rubocop
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rubocop-rspec
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
41
83
  - !ruby/object:Gem::Dependency
42
84
  name: simplecov
43
85
  requirement: !ruby/object:Gem::Requirement
@@ -52,17 +94,28 @@ dependencies:
52
94
  - - ">="
53
95
  - !ruby/object:Gem::Version
54
96
  version: '0'
55
- description: This library can be used to render your data to a console. It's quite
56
- simple and has many features
97
+ description: Library can be used to render your data to a console. Being quite simple
98
+ it has many features.
57
99
  email: rukomoynikov@gmail.com
58
- executables: []
100
+ executables:
101
+ - tabled
59
102
  extensions: []
60
103
  extra_rdoc_files: []
61
104
  files:
62
105
  - ".github/workflows/linters.yml"
63
106
  - ".gitignore"
107
+ - ".rspec"
108
+ - ".rubocop.yml"
109
+ - ".rubocop_todo.yml"
110
+ - CHANGELOG.md
64
111
  - Gemfile
65
112
  - Gemfile.lock
113
+ - README.md
114
+ - bin/tabled
115
+ - demo.rb
116
+ - lib/content_shaper.rb
117
+ - lib/helpers.rb
118
+ - lib/parsers/csv_parser.rb
66
119
  - lib/tabled.rb
67
120
  - lib/template.rb
68
121
  - tabled.gemspec
@@ -71,6 +124,7 @@ licenses:
71
124
  - MIT
72
125
  metadata:
73
126
  source_code_uri: https://github.com/Rukomoynikov/tabled
127
+ rubygems_mfa_required: 'true'
74
128
  post_install_message:
75
129
  rdoc_options: []
76
130
  require_paths:
@@ -86,7 +140,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
86
140
  - !ruby/object:Gem::Version
87
141
  version: '0'
88
142
  requirements: []
89
- rubygems_version: 3.2.3
143
+ rubygems_version: 3.1.6
90
144
  signing_key:
91
145
  specification_version: 4
92
146
  summary: Library for rendering pretty tables in console