terminal-table 1.7.2 → 3.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.
data/Rakefile CHANGED
@@ -1,8 +1,14 @@
1
- require "bundler/gem_tasks"
1
+ require 'bundler'
2
+ Bundler.setup
3
+ Bundler::GemHelper.install_tasks
2
4
 
3
- desc "Run specs"
4
- task :spec do
5
- sh "bundle exec rspec -f progress"
5
+ require 'rake'
6
+ require 'rspec/core/rake_task'
7
+
8
+ desc "Run all examples"
9
+ RSpec::Core::RakeTask.new(:spec) do |t|
10
+ t.ruby_opts = %w[-w]
11
+ t.rspec_opts = %w[--color]
6
12
  end
7
13
 
8
14
  desc "Default: Run specs"
data/examples/data.csv ADDED
@@ -0,0 +1,4 @@
1
+ First Name,Last Name,Email
2
+ TJ,Holowaychuk,tj@vision-media.ca
3
+ Bob,Someone,bob@vision-media.ca
4
+ Joe,Whatever,joe@vision-media.ca
data/examples/examples.rb CHANGED
File without changes
@@ -0,0 +1,89 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $:.unshift File.dirname(__FILE__) + '/../lib'
4
+ require 'terminal-table/import'
5
+
6
+ Terminal::Table::Style.defaults = { :border => :unicode_round }
7
+ # Terminal::Table::UnicodeThickEdgeBorder.new()
8
+
9
+ puts
10
+ puts table(['a', 'b'], [1, 2], [3, 4])
11
+
12
+ puts
13
+ puts table(['name', 'content'], ['ftp.example.com', '1.1.1.1'], ['www.example.com', '|lalalala|lalala|'])
14
+
15
+ puts
16
+ t = table ['a', 'b']
17
+ t.style = {:padding_left => 2, :width => 80}
18
+ t << [1, 2]
19
+ t << [3, 4]
20
+ t << :separator
21
+ t << [4, 6]
22
+ puts t
23
+
24
+ puts
25
+ user_table = table do |v|
26
+ v.title = "Contact Information"
27
+ v.headings = 'First Name', 'Last Name', 'Email'
28
+ v << %w( TJ Holowaychuk tj@vision-media.ca )
29
+ v << %w( Bob Someone bob@vision-media.ca )
30
+ v << %w( Joe Whatever bob@vision-media.ca )
31
+ end
32
+ puts user_table
33
+
34
+ puts
35
+ user_table = table do |v|
36
+ v.style.width = 80
37
+ v.headings = 'First Name', 'Last Name', 'Email'
38
+ v << %w( TJ Holowaychuk tj@vision-media.ca )
39
+ v << %w( Bob Someone bob@vision-media.ca )
40
+ v << %w( Joe Whatever bob@vision-media.ca )
41
+ end
42
+ puts user_table
43
+
44
+ puts
45
+ user_table = table do
46
+ self.headings = 'First Name', 'Last Name', 'Email'
47
+ add_row ['TJ', 'Holowaychuk', 'tj@vision-media.ca']
48
+ add_row ['Bob', 'Someone', 'bob@vision-media.ca']
49
+ add_row ['Joe', 'Whatever', 'joe@vision-media.ca']
50
+ add_separator
51
+ add_row ['Total', { :value => '3', :colspan => 2, :alignment => :right }]
52
+ align_column 1, :center
53
+ end
54
+ puts user_table
55
+
56
+ puts
57
+ user_table = table do
58
+ self.headings = ['First Name', 'Last Name', {:value => 'Phones', :colspan => 2, :alignment => :center}]
59
+ #add_row ['Bob', 'Someone', '123', '456']
60
+ add_row [{:value => "Bob Someone", :colspan => 3, :alignment => :center}, '123456']
61
+ add_row :separator
62
+ add_row ['TJ', 'Holowaychuk', {:value => "No phones\navaiable", :colspan => 2, :alignment => :center}]
63
+ add_row :separator
64
+ add_row ['Joe', 'Whatever', '4324', '343242']
65
+ end
66
+ puts user_table
67
+
68
+ rows = []
69
+ rows << ['Lines', 100]
70
+ rows << ['Comments', 20]
71
+ rows << ['Ruby', 70]
72
+ rows << ['JavaScript', 30]
73
+ puts table([nil, 'Lines'], *rows)
74
+
75
+ rows = []
76
+ rows << ['Lines', 100]
77
+ rows << ['Comments', 20]
78
+ rows << ['Ruby', 70]
79
+ rows << ['JavaScript', 30]
80
+ puts table(nil, *rows)
81
+
82
+ rows = []
83
+ rows << ['Lines', 100]
84
+ rows << ['Comments', 20]
85
+ rows << ['Ruby', 70]
86
+ rows << ['JavaScript', 30]
87
+ table = table([{ :value => 'Stats', :colspan => 2, :alignment => :center }], *rows)
88
+ table.align_column 1, :right
89
+ puts table
@@ -0,0 +1,34 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # Methods to suppress left/right borders using border_left & border_right
4
+
5
+ require_relative "../lib/terminal-table"
6
+ table = Terminal::Table.new do |t|
7
+ t.headings = ['id', 'name']
8
+ t.rows = [[1, 'One'], [2, 'Two'], [3, 'Three']]
9
+ t.style = { :border_left => false, :border_top => false, :border_bottom => false }
10
+ end
11
+
12
+ puts table
13
+ puts
14
+
15
+ # no right
16
+ table.style = {:border_right => false }
17
+ puts table
18
+ puts
19
+
20
+ # no right
21
+ table.style = {:border_left => true }
22
+ puts table
23
+ puts
24
+
25
+ table.style.border = Terminal::Table::UnicodeBorder.new
26
+ puts table
27
+
28
+
29
+ table.style = {:border_right => false, :border_left => true }
30
+ puts table
31
+
32
+ table.style = {:border_right => true, :border_left => false }
33
+ puts table
34
+
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+ require_relative "../lib/terminal-table"
3
+ puts Terminal::Table.new(headings: ['heading A', 'heading B'], rows: [['a', 'b'], ['a', 'b']], style: {border: Terminal::Table::MarkdownBorder.new})
4
+
@@ -0,0 +1,36 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require_relative '../lib/terminal-table'
4
+
5
+ puts Terminal::Table.new(headings: ['a', 'b', 'c', 'd'], style: { border: :unicode })
6
+
7
+ puts
8
+
9
+ tbl = Terminal::Table.new do |t|
10
+ t.style = { border: :unicode }
11
+ t.add_separator
12
+ t.add_separator
13
+ t.add_row ['x','y','z']
14
+ t.add_separator
15
+ t.add_separator
16
+ end
17
+ puts tbl
18
+
19
+ puts
20
+
21
+ puts Terminal::Table.new(headings: [['a', 'b', 'c', 'd'], ['cat','dog','frog','mouse']], style: { border: :unicode })
22
+
23
+ puts
24
+
25
+ puts Terminal::Table.new(headings: ['a', 'b', 'c', 'd'])
26
+
27
+ puts
28
+
29
+ tbl = Terminal::Table.new do |t|
30
+ t.add_separator
31
+ t.add_separator
32
+ t.add_row ['x','y','z']
33
+ t.add_separator
34
+ t.add_separator
35
+ end
36
+ puts tbl
@@ -0,0 +1,42 @@
1
+ #!/usr/bin/env ruby
2
+ require 'colorize'
3
+ require_relative '../lib/terminal-table.rb'
4
+
5
+ original_sample_data = [
6
+ ["Sep 2016", 33, [-38, -53.52], 46, [-25, -35.21]],
7
+ ["Oct 2016", 35, [2, 6.06], 50, [4, 8.69]]
8
+ ]
9
+
10
+ table = Terminal::Table.new headings: ["Month".cyan,"Monthly IT".cyan,"IT Difference OPM".cyan,
11
+ "Monthly OOT".cyan,"OOT Difference OPM".cyan], rows: original_sample_data
12
+
13
+ table.style = { padding_left: 2, padding_right: 2, border_x: "-".blue, border_y: "|".blue, border_i: "+".blue }
14
+
15
+ puts table
16
+
17
+ puts ""
18
+ puts "^ good table"
19
+ puts "v wonky table"
20
+ puts ""
21
+
22
+ split_column_sample_data = [
23
+ ["Sep 2016", 33, -38, -53.52, 46, -25, -35.21],
24
+ ["Oct 2016", 35, 2, 6.06, 50, 4, 8.69]
25
+ ]
26
+
27
+ table = Terminal::Table.new headings: ["Month".cyan,"Monthly IT".cyan,
28
+ {value: "IT Difference OPM".cyan, colspan: 2}, "Monthly OOT".cyan,
29
+ {value: "OOT Difference OPM".cyan, colspan: 2}], rows: split_column_sample_data
30
+
31
+ table.style = { padding_left: 2, padding_right: 2, border_x: "-".blue, border_y: "|".blue, border_i: "+".blue }
32
+
33
+ puts table
34
+
35
+
36
+ table = Terminal::Table.new headings: ["Month","Monthly IT",
37
+ {value: "IT Difference OPM", colspan: 2}, "Monthly OOT",
38
+ {value: "OOT Difference OPM", colspan: 2}], rows: split_column_sample_data
39
+
40
+ table.style = { padding_left: 2, padding_right: 2, border_x: "-".blue, border_y: "|".cyan, border_i: "+" }
41
+
42
+ puts table
@@ -0,0 +1,34 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "csv"
4
+ $LOAD_PATH << "#{__dir__}/../lib"
5
+ require "terminal-table"
6
+
7
+ #
8
+ # Usage:
9
+ # ./show_csv_table.rb data.csv
10
+ # cat data.csv | ./show_csv_table.rb
11
+ # cat data.csv | ./show_csv_table.rb -
12
+ #
13
+ #
14
+ # Reads a CSV from $stdin if no argument given, or argument is '-'
15
+ # otherwise interprets first cmdline argument as the CSV filename
16
+ #
17
+ use_stdin = ARGV[0].nil? || (ARGV[0] == '-')
18
+ io_object = use_stdin ? $stdin : File.open(ARGV[0], 'r')
19
+ csv = CSV.new(io_object)
20
+
21
+ #
22
+ # Convert to an array for use w/ terminal-table
23
+ # The assumption is that this is a pretty small spreadsheet.
24
+ #
25
+ csv_array = csv.to_a
26
+
27
+ user_table = Terminal::Table.new do |v|
28
+ v.style = { :border => :unicode_round } # >= v3.0.0
29
+ v.title = "Some Title"
30
+ v.headings = csv_array[0]
31
+ v.rows = csv_array[1..-1]
32
+ end
33
+
34
+ puts user_table
@@ -0,0 +1,23 @@
1
+ #!/usr/bin/env ruby
2
+ require_relative "../lib/terminal-table"
3
+
4
+ #
5
+ # An example of how to manually add separators with non-default
6
+ # border_type to enable a footer row.
7
+ #
8
+ table = Terminal::Table.new do |t|
9
+ # set the style
10
+ t.style = { border: :unicode_thick_edge }
11
+
12
+ # header row
13
+ t.headings = ['fruit', 'count']
14
+
15
+ # some row data
16
+ t.add_row ['apples', 7]
17
+ t.add_row ['bananas', 19]
18
+ t.add_separator border_type: :strong
19
+ # footer row
20
+ t.add_row ['total', 26]
21
+ end
22
+
23
+ puts table.render
@@ -21,6 +21,6 @@
21
21
  # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
22
  #++
23
23
 
24
- %w(cell row separator style table table_helper version).each do |file|
25
- require "terminal-table/#{file}"
24
+ %w(cell row separator style table table_helper util version).each do |file|
25
+ require_relative "./terminal-table/#{file}"
26
26
  end
@@ -57,7 +57,7 @@ module Terminal
57
57
  def render(line = 0)
58
58
  left = " " * @table.style.padding_left
59
59
  right = " " * @table.style.padding_right
60
- display_width = Unicode::DisplayWidth.of(escape(lines[line]))
60
+ display_width = Unicode::DisplayWidth.of(Util::ansi_escape(lines[line]))
61
61
  render_width = lines[line].to_s.size - display_width + width
62
62
  align("#{left}#{lines[line]}#{right}", alignment, render_width + @table.cell_padding)
63
63
  end
@@ -68,7 +68,7 @@ module Terminal
68
68
  # removes all ANSI escape sequences (e.g. color)
69
69
 
70
70
  def value_for_column_width_recalc
71
- lines.map{ |s| escape(s) }.max_by{ |s| Unicode::DisplayWidth.of(s) }
71
+ lines.map{ |s| Util::ansi_escape(s) }.max_by{ |s| Unicode::DisplayWidth.of(s) }
72
72
  end
73
73
 
74
74
  ##
@@ -82,12 +82,12 @@ module Terminal
82
82
  inner_width + padding
83
83
  end
84
84
 
85
- ##
86
- # removes all ANSI escape sequences (e.g. color)
87
- def escape(line)
88
- line.to_s.gsub(/\x1b(\[|\(|\))[;?0-9]*[0-9A-Za-z]/, '').
89
- gsub(/\x1b(\[|\(|\))[;?0-9]*[0-9A-Za-z]/, '').
90
- gsub(/(\x03|\x1a)/, '')
85
+ def inspect
86
+ fields = %i[alignment colspan index value width].map do |name|
87
+ val = self.instance_variable_get('@'+name.to_s)
88
+ "@#{name}=#{val.inspect}"
89
+ end.join(', ')
90
+ return "#<#{self.class} #{fields}>"
91
91
  end
92
92
  end
93
93
  end
@@ -12,7 +12,7 @@ module Terminal
12
12
  ##
13
13
  # Initialize with _width_ and _options_.
14
14
 
15
- def initialize table, array = []
15
+ def initialize table, array = [], **_kwargs
16
16
  @cell_index = 0
17
17
  @table = table
18
18
  @cells = []
@@ -36,17 +36,31 @@ module Terminal
36
36
  end
37
37
 
38
38
  def render
39
- y = @table.style.border_y
39
+ vleft, vcenter, vright = @table.style.vertical
40
40
  (0...height).to_a.map do |line|
41
- y + cells.map do |cell|
41
+ vleft + cells.map do |cell|
42
42
  cell.render(line)
43
- end.join(y) + y
43
+ end.join(vcenter) + vright
44
44
  end.join("\n")
45
45
  end
46
46
 
47
47
  def number_of_columns
48
48
  @cells.collect(&:colspan).inject(0, &:+)
49
49
  end
50
+
51
+ # used to find indices where we have table '+' crossings.
52
+ # in cases where the colspan > 1, then we will skip over some numbers
53
+ # if colspan is always 1, then the list should be incrementing by 1.
54
+ #
55
+ # skip 0 entry, because it's the left side.
56
+ # skip last entry, because it's the right side.
57
+ # we only care about "+/T" style crossings.
58
+ def crossings
59
+ idx = 0
60
+ @cells[0...-1].map { |c| idx += c.colspan }
61
+ end
62
+
50
63
  end
64
+
51
65
  end
52
66
  end
@@ -2,13 +2,65 @@ module Terminal
2
2
  class Table
3
3
  class Separator < Row
4
4
 
5
+ ##
6
+ # `prevrow`, `nextrow` contain references to adjacent rows.
7
+ #
8
+ # `border_type` is a symbol used to control which type of border is used
9
+ # on the separator (:top for top-edge, :bot for bottom-edge,
10
+ # :div for interior, and :strong for emphasized-interior)
11
+ #
12
+ # `implicit` is false for user-added separators, and true for
13
+ # implicit/auto-generated separators.
14
+
15
+ def initialize(*args, border_type: :div, implicit: false)
16
+ super
17
+ @prevrow, @nextrow = nil, nil
18
+ @border_type = border_type
19
+ @implicit = implicit
20
+ end
21
+
22
+ attr_accessor :border_type
23
+ attr_reader :implicit
24
+
5
25
  def render
6
- arr_x = (0...@table.number_of_columns).to_a.map do |i|
7
- @table.style.border_x * (@table.column_width(i) + @table.cell_padding)
26
+ left_edge, ctrflat, ctrud, right_edge, ctrdn, ctrup = @table.style.horizontal(border_type)
27
+
28
+ prev_crossings = @prevrow.respond_to?(:crossings) ? @prevrow.crossings : []
29
+ next_crossings = @nextrow.respond_to?(:crossings) ? @nextrow.crossings : []
30
+ rval = [left_edge]
31
+ numcols = @table.number_of_columns
32
+ (0...numcols).each do |idx|
33
+ rval << ctrflat * (@table.column_width(idx) + @table.cell_padding)
34
+ pcinc = prev_crossings.include?(idx+1)
35
+ ncinc = next_crossings.include?(idx+1)
36
+ border_center = if pcinc && ncinc
37
+ ctrud
38
+ elsif pcinc
39
+ ctrup
40
+ elsif ncinc
41
+ ctrdn
42
+ elsif !ctrud.empty?
43
+ # special case if the center-up-down intersection is empty
44
+ # which happens when verticals/intersections are removed. in that case
45
+ # we do not want to replace with a flat element so return empty-string in else block
46
+ ctrflat
47
+ else
48
+ ''
49
+ end
50
+ rval << border_center if idx < numcols-1
8
51
  end
9
- border_i = @table.style.border_i
10
- border_i + arr_x.join(border_i) + border_i
52
+
53
+ rval << right_edge
54
+ rval.join
55
+ end
56
+
57
+ # Save off neighboring rows, so that we can use them later in determining
58
+ # which types of table edges to use.
59
+ def save_adjacent_rows(prevrow, nextrow)
60
+ @prevrow = prevrow
61
+ @nextrow = nextrow
11
62
  end
63
+
12
64
  end
13
65
  end
14
66
  end