termtable 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 581a5dfb715ea7eaa47ae23d6da376276673c819
4
+ data.tar.gz: f1af2c524a24227dac39693ff4075221fc7d7324
5
+ SHA512:
6
+ metadata.gz: 2b97cb4bf4fc1b4eed5e8f562d0bd884466e316f149801b0afbc5689cca51358ddd8a7e089ec7f08f941fc868d2c5e47ab9b8644ba1a0ba0aa8444e836f7fb6c
7
+ data.tar.gz: e9de018cf87eb659e1afb57b81e474d5bfceccb7f9631e96d88199a3f35217289bb9be6028ccb6771353983d868f564a038e7f605e8a593b53924ba11642c274
data/.gitignore ADDED
@@ -0,0 +1,12 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.gem
11
+
12
+ .rspec_status
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/.rubocop.yml ADDED
@@ -0,0 +1,5 @@
1
+ Metrics:
2
+ Enabled: false
3
+
4
+ Style/Documentation:
5
+ Enabled: false
data/.travis.yml ADDED
@@ -0,0 +1,5 @@
1
+ sudo: false
2
+ language: ruby
3
+ rvm:
4
+ - 2.4.2
5
+ before_install: gem install bundler -v 1.16.1
data/Gemfile ADDED
@@ -0,0 +1,14 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'rake'
4
+
5
+ group :development do
6
+ gem 'pry'
7
+ end
8
+
9
+ group :test do
10
+ gem 'rspec'
11
+ gem 'rubocop'
12
+ end
13
+
14
+ gemspec
data/README.md ADDED
@@ -0,0 +1,97 @@
1
+ # Termtable
2
+
3
+ ## Installation
4
+
5
+ Add this line to your application's Gemfile:
6
+
7
+ ```ruby
8
+ gem 'termtable'
9
+ ```
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install termtable
18
+
19
+ ## Usage
20
+
21
+ A table instance can take a 2 dimensional array for the rows.
22
+
23
+ ```ruby
24
+ table = Termtable::Table.new [[1, 2, 3], [4, 5, 6]]
25
+ ```
26
+
27
+ This can also be given as a hash with a rows key.
28
+
29
+ ```ruby
30
+ table = Termtable::Table.new rows: [[1, 2, 3], [4, 5, 6]]
31
+
32
+ puts table.render
33
+
34
+ +--+--+--+
35
+ |1 |2 |3 |
36
+ |4 |5 |6 |
37
+ +--+--+--+
38
+ ```
39
+
40
+ ### Headers
41
+
42
+ Headers can be given as the first array
43
+
44
+ ```ruby
45
+ Termtable::Table.new ['Header A', 'Header B'], [['a1', 'a2'], ['b1', 'b2']]
46
+ ```
47
+
48
+ Also as a headers key
49
+
50
+ ```ruby
51
+ Termtable::Table.new headers: ['Header A', 'Header B'], rows: [['a1', 'a2'], ['b1', 'b2']]
52
+
53
+ +---------+---------+
54
+ |Header A |Header B |
55
+ +---------+---------+
56
+ |a1 |a2 |
57
+ |b1 |b2 |
58
+ +---------+---------+
59
+ ```
60
+
61
+ ### Padding
62
+
63
+ It is possible to pass a padding argument to the render method
64
+
65
+ ```ruby
66
+ table = Termtable::Table.new rows: [['a1', 'a2'], ['b1', 12345]]
67
+ puts table.render(padding: 3)
68
+
69
+ +-----+--------+
70
+ |a1 |a2 |
71
+ |b1 |12345 |
72
+ +-----+--------+
73
+ ```
74
+
75
+ ### Alignment
76
+
77
+ It is possible to pass an alignment argument to render
78
+
79
+ ```ruby
80
+ table = Termtable::Table.new rows: [['a1', 'a2'], ['b1', 123456]]
81
+ puts table.render(alignment: 'center')
82
+
83
+ +----+--------+
84
+ | a1 | a2 |
85
+ | b1 | 123456 |
86
+ +----+--------+
87
+ ```
88
+
89
+ ## Development
90
+
91
+ To run the tests
92
+
93
+ $ rake
94
+
95
+ ## Contributing
96
+
97
+ Bug reports and pull requests are welcome on GitHub at https://github.com/nikkypx/termtable.
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+ require 'rubocop/rake_task'
4
+
5
+ RuboCop::RakeTask.new
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ task default: %i[spec rubocop]
data/bin/console ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bundler/setup'
4
+ require 'termtable'
5
+ require 'pry'
6
+
7
+ Pry.start
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
data/lib/termtable.rb ADDED
@@ -0,0 +1,13 @@
1
+ require 'termtable/border'
2
+ require 'termtable/cell'
3
+ require 'termtable/core_ext/array'
4
+ require 'termtable/error'
5
+ require 'termtable/header'
6
+ require 'termtable/render'
7
+ require 'termtable/row'
8
+ require 'termtable/table'
9
+ require 'termtable/version'
10
+
11
+ module Termtable
12
+ Array.include(CoreExt::Array)
13
+ end
@@ -0,0 +1,13 @@
1
+ module Termtable
2
+ class Border
3
+ def initialize(**opts)
4
+ @columns = opts.delete(:columns)
5
+ @style = opts.delete(:style) || '-'
6
+ @corner = opts.delete(:corners) || '+'
7
+ end
8
+
9
+ def render
10
+ @corner + @columns.map { |col| @style * col }.join(@corner) << @corner
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,51 @@
1
+ module Termtable
2
+ class Cell
3
+ attr_reader :value
4
+ attr_accessor :max_column_size,
5
+ :padding,
6
+ :alignment,
7
+ :total_padding
8
+
9
+ def initialize(value)
10
+ @value = value.to_s
11
+ end
12
+
13
+ def expand?
14
+ max_column_size != value.to_s.size + total_padding
15
+ end
16
+
17
+ def left_padding
18
+ count = case alignment
19
+ when 'right'
20
+ expand? ? max_column_size - value.to_s.size : padding
21
+ when 'center'
22
+ expand? ? (max_column_size - value.to_s.size) / 2 : padding
23
+ else
24
+ 0
25
+ end
26
+ ' ' * count
27
+ end
28
+
29
+ def right_padding
30
+ count = case alignment
31
+ when 'right'
32
+ 0
33
+ when 'center'
34
+ if expand? && max_column_size.even?
35
+ (max_column_size - value.to_s.size) / 2
36
+ elsif expand? && max_column_size.odd?
37
+ (max_column_size - value.to_s.size) / 2 + 1
38
+ else
39
+ padding
40
+ end
41
+ else
42
+ expand? ? max_column_size - value.to_s.size : padding
43
+ end
44
+ ' ' * count
45
+ end
46
+
47
+ def render
48
+ "#{left_padding}#{value}#{right_padding}"
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,14 @@
1
+ module Termtable
2
+ module CoreExt
3
+ module Array
4
+ def depth
5
+ __depth__(self)
6
+ end
7
+
8
+ def __depth__(array)
9
+ return 0 if array == array.flatten
10
+ 1 + __depth__(array.flatten(1))
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,5 @@
1
+ module Termtable
2
+ class Error < StandardError
3
+ InitializationError = Class.new(self)
4
+ end
5
+ end
@@ -0,0 +1,13 @@
1
+ module Termtable
2
+ class Header
3
+ attr_reader :cells
4
+
5
+ def initialize(header)
6
+ @cells = header.map { |value| Cell.new(value) }
7
+ end
8
+
9
+ def render
10
+ '|' + cells.map(&:render).join('|') << '|'
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,53 @@
1
+ module Termtable
2
+ class Render
3
+ DEFAULT_PADDING = 1
4
+ DEFAULT_ALIGNMENT = 'left'.freeze
5
+
6
+ def initialize(rows, opts)
7
+ @rows = rows
8
+ @padding = opts.delete(:padding) || DEFAULT_PADDING
9
+ @alignment = opts.delete(:alignment) || DEFAULT_ALIGNMENT
10
+ @border_options = opts.delete(:border)
11
+ @column_lengths = column_widths(rows)
12
+ end
13
+
14
+ def set_metadata!
15
+ @rows.each do |row|
16
+ row.cells.each_with_index do |cell, idx|
17
+ cell.max_column_size = @column_lengths[idx]
18
+ cell.padding = @padding
19
+ cell.alignment = @alignment
20
+ cell.total_padding = total_padding
21
+ end
22
+ end
23
+ end
24
+
25
+ def set_borders!
26
+ @rows.unshift(Termtable::Border.new(columns: @column_lengths))
27
+ @rows.push(Termtable::Border.new(columns: @column_lengths))
28
+ end
29
+
30
+ def set_headers_border!
31
+ @rows.insert(2, Termtable::Border.new(columns: @column_lengths)) if @rows[1].is_a?(Termtable::Header)
32
+ end
33
+
34
+ def total_padding
35
+ @alignment == 'center' ? @padding * 2 : @padding
36
+ end
37
+
38
+ def column_widths(rows)
39
+ column_values = rows.map { |r| r.cells.map(&:value) }.transpose
40
+ column_values.map do |col|
41
+ col.max_by(&:length).size + total_padding
42
+ end
43
+ end
44
+
45
+ def exec
46
+ set_metadata!
47
+ set_borders!
48
+ set_headers_border!
49
+
50
+ @rows.map(&:render).join("\n")
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,13 @@
1
+ module Termtable
2
+ class Row
3
+ attr_reader :cells
4
+
5
+ def initialize(row)
6
+ @cells = row.map { |value| Cell.new(value) }
7
+ end
8
+
9
+ def render
10
+ '|' + cells.map(&:render).join('|') << '|'
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,46 @@
1
+ module Termtable
2
+ class Table
3
+ def initialize(*args)
4
+ if args.first.is_a?(Array) && args.depth == 1
5
+ raise Termtable::Error::InitializationError, '2d array required for initialization'
6
+ end
7
+
8
+ if args.empty?
9
+ @rows = []
10
+
11
+ yield(self) if block_given?
12
+ else
13
+ if args.first.is_a?(Hash)
14
+ headers = args.first.delete(:headers)
15
+ @rows = args.first.delete(:rows)
16
+ elsif args.size == 2
17
+ headers, @rows = args
18
+ else
19
+ @rows = args.first
20
+ end
21
+
22
+ buffer_jagged_array!
23
+
24
+ @rows = @rows.map { |row| Row.new(row) }
25
+ @rows.unshift(Header.new(headers)) unless headers.nil?
26
+ end
27
+ end
28
+
29
+ def buffer_jagged_array!
30
+ max = @rows.map(&:size).max
31
+ @rows.map { |row| (max - row.size).times { row << ' ' } }
32
+ end
33
+
34
+ def row_count
35
+ @rows.size
36
+ end
37
+
38
+ def <<(row)
39
+ @rows << Row.new(row)
40
+ end
41
+
42
+ def render(**opts)
43
+ Render.new(@rows, opts).exec
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,3 @@
1
+ module Termtable
2
+ VERSION = '0.1.0'.freeze
3
+ end
data/termtable.gemspec ADDED
@@ -0,0 +1,22 @@
1
+ lib = File.expand_path('lib', __dir__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require 'termtable/version'
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = 'termtable'
7
+ spec.version = Termtable::VERSION
8
+ spec.authors = ['Nicholas Palaniuk']
9
+ spec.email = ['npalaniuk+github@gmail.com']
10
+ spec.summary = 'Table generator for the terminal'
11
+ spec.description = 'Table generator for the terminal'
12
+ spec.homepage = 'https://github.com/nikkypx/termtable'
13
+
14
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
15
+ f.match(%r{^(test|spec|features)/})
16
+ end
17
+ spec.bindir = 'exe'
18
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
19
+ spec.require_paths = ['lib']
20
+
21
+ spec.add_development_dependency 'bundler'
22
+ end
metadata ADDED
@@ -0,0 +1,78 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: termtable
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Nicholas Palaniuk
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2018-09-15 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ description: Table generator for the terminal
28
+ email:
29
+ - npalaniuk+github@gmail.com
30
+ executables: []
31
+ extensions: []
32
+ extra_rdoc_files: []
33
+ files:
34
+ - ".gitignore"
35
+ - ".rspec"
36
+ - ".rubocop.yml"
37
+ - ".travis.yml"
38
+ - Gemfile
39
+ - Gemfile.lock
40
+ - README.md
41
+ - Rakefile
42
+ - bin/console
43
+ - bin/setup
44
+ - lib/termtable.rb
45
+ - lib/termtable/border.rb
46
+ - lib/termtable/cell.rb
47
+ - lib/termtable/core_ext/array.rb
48
+ - lib/termtable/error.rb
49
+ - lib/termtable/header.rb
50
+ - lib/termtable/render.rb
51
+ - lib/termtable/row.rb
52
+ - lib/termtable/table.rb
53
+ - lib/termtable/version.rb
54
+ - termtable.gemspec
55
+ homepage: https://github.com/nikkypx/termtable
56
+ licenses: []
57
+ metadata: {}
58
+ post_install_message:
59
+ rdoc_options: []
60
+ require_paths:
61
+ - lib
62
+ required_ruby_version: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ version: '0'
67
+ required_rubygems_version: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ version: '0'
72
+ requirements: []
73
+ rubyforge_project:
74
+ rubygems_version: 2.6.13
75
+ signing_key:
76
+ specification_version: 4
77
+ summary: Table generator for the terminal
78
+ test_files: []