galileo 0.1.0
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 +7 -0
- data/.gitignore +18 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +33 -0
- data/Rakefile +1 -0
- data/bin/galileo +9 -0
- data/galileo.gemspec +29 -0
- data/lib/galileo/version.rb +3 -0
- data/lib/galileo.rb +136 -0
- data/lib/terminal-table/.DS_Store +0 -0
- data/lib/terminal-table/Gemfile +7 -0
- data/lib/terminal-table/History.rdoc +48 -0
- data/lib/terminal-table/Manifest +24 -0
- data/lib/terminal-table/README.rdoc +240 -0
- data/lib/terminal-table/Rakefile +15 -0
- data/lib/terminal-table/Todo.rdoc +14 -0
- data/lib/terminal-table/examples/examples.rb +83 -0
- data/lib/terminal-table/lib/terminal-table/cell.rb +98 -0
- data/lib/terminal-table/lib/terminal-table/core_ext.rb +8 -0
- data/lib/terminal-table/lib/terminal-table/row.rb +53 -0
- data/lib/terminal-table/lib/terminal-table/separator.rb +14 -0
- data/lib/terminal-table/lib/terminal-table/style.rb +65 -0
- data/lib/terminal-table/lib/terminal-table/table.rb +261 -0
- data/lib/terminal-table/lib/terminal-table/table_helper.rb +9 -0
- data/lib/terminal-table/lib/terminal-table/version.rb +5 -0
- data/lib/terminal-table/lib/terminal-table.rb +13 -0
- data/lib/terminal-table/spec/cell_spec.rb +60 -0
- data/lib/terminal-table/spec/core_ext_spec.rb +18 -0
- data/lib/terminal-table/spec/import_spec.rb +11 -0
- data/lib/terminal-table/spec/row_spec.rb +25 -0
- data/lib/terminal-table/spec/spec.opts +1 -0
- data/lib/terminal-table/spec/spec_helper.rb +8 -0
- data/lib/terminal-table/spec/table_spec.rb +544 -0
- data/lib/terminal-table/tasks/docs.rake +13 -0
- data/lib/terminal-table/tasks/gemspec.rake +3 -0
- data/lib/terminal-table/tasks/spec.rake +25 -0
- data/lib/terminal-table/terminal-table.gemspec +30 -0
- data/lib/time/time-ago-in-words.rb +32 -0
- metadata +181 -0
@@ -0,0 +1,83 @@
|
|
1
|
+
$:.unshift File.dirname(__FILE__) + '/../lib'
|
2
|
+
require 'terminal-table/import'
|
3
|
+
|
4
|
+
puts
|
5
|
+
puts table(['a', 'b'], [1, 2], [3, 4])
|
6
|
+
|
7
|
+
puts
|
8
|
+
puts table(['name', 'content'], ['ftp.example.com', '1.1.1.1'], ['www.example.com', '|lalalala|lalala|'])
|
9
|
+
|
10
|
+
puts
|
11
|
+
t = table ['a', 'b']
|
12
|
+
t.style = {:padding_left => 2, :width => 80}
|
13
|
+
t << [1, 2]
|
14
|
+
t << [3, 4]
|
15
|
+
t << :separator
|
16
|
+
t << [4, 6]
|
17
|
+
puts t
|
18
|
+
|
19
|
+
puts
|
20
|
+
user_table = table do |v|
|
21
|
+
v.title = "Contact Information"
|
22
|
+
v.headings = 'First Name', 'Last Name', 'Email'
|
23
|
+
v << %w( TJ Holowaychuk tj@vision-media.ca )
|
24
|
+
v << %w( Bob Someone bob@vision-media.ca )
|
25
|
+
v << %w( Joe Whatever bob@vision-media.ca )
|
26
|
+
end
|
27
|
+
puts user_table
|
28
|
+
|
29
|
+
puts
|
30
|
+
user_table = table do |v|
|
31
|
+
v.style.width = 80
|
32
|
+
v.headings = 'First Name', 'Last Name', 'Email'
|
33
|
+
v << %w( TJ Holowaychuk tj@vision-media.ca )
|
34
|
+
v << %w( Bob Someone bob@vision-media.ca )
|
35
|
+
v << %w( Joe Whatever bob@vision-media.ca )
|
36
|
+
end
|
37
|
+
puts user_table
|
38
|
+
|
39
|
+
puts
|
40
|
+
user_table = table do
|
41
|
+
self.headings = 'First Name', 'Last Name', 'Email'
|
42
|
+
add_row ['TJ', 'Holowaychuk', 'tj@vision-media.ca']
|
43
|
+
add_row ['Bob', 'Someone', 'bob@vision-media.ca']
|
44
|
+
add_row ['Joe', 'Whatever', 'joe@vision-media.ca']
|
45
|
+
add_separator
|
46
|
+
add_row ['Total', { :value => '3', :colspan => 2, :alignment => :right }]
|
47
|
+
align_column 1, :center
|
48
|
+
end
|
49
|
+
puts user_table
|
50
|
+
|
51
|
+
puts
|
52
|
+
user_table = table do
|
53
|
+
self.headings = ['First Name', 'Last Name', {:value => 'Phones', :colspan => 2, :alignment => :center}]
|
54
|
+
add_row ['Bob', 'Someone', '123', '456']
|
55
|
+
add_row :separator
|
56
|
+
add_row ['TJ', 'Holowaychuk', {:value => "No phones\navaiable", :colspan => 2, :alignment => :center}]
|
57
|
+
add_row :separator
|
58
|
+
add_row ['Joe', 'Whatever', '4324', '343242']
|
59
|
+
end
|
60
|
+
puts user_table
|
61
|
+
|
62
|
+
rows = []
|
63
|
+
rows << ['Lines', 100]
|
64
|
+
rows << ['Comments', 20]
|
65
|
+
rows << ['Ruby', 70]
|
66
|
+
rows << ['JavaScript', 30]
|
67
|
+
puts table([nil, 'Lines'], *rows)
|
68
|
+
|
69
|
+
rows = []
|
70
|
+
rows << ['Lines', 100]
|
71
|
+
rows << ['Comments', 20]
|
72
|
+
rows << ['Ruby', 70]
|
73
|
+
rows << ['JavaScript', 30]
|
74
|
+
puts table(nil, *rows)
|
75
|
+
|
76
|
+
rows = []
|
77
|
+
rows << ['Lines', 100]
|
78
|
+
rows << ['Comments', 20]
|
79
|
+
rows << ['Ruby', 70]
|
80
|
+
rows << ['JavaScript', 30]
|
81
|
+
table = table([{ :value => 'Stats', :colspan => 2, :alignment => :center }], *rows)
|
82
|
+
table.align_column 1, :right
|
83
|
+
puts table
|
@@ -0,0 +1,98 @@
|
|
1
|
+
|
2
|
+
module Terminal
|
3
|
+
class Table
|
4
|
+
class Cell
|
5
|
+
|
6
|
+
##
|
7
|
+
# Cell width.
|
8
|
+
|
9
|
+
attr_reader :width
|
10
|
+
|
11
|
+
##
|
12
|
+
# Cell value.
|
13
|
+
|
14
|
+
attr_reader :value
|
15
|
+
|
16
|
+
##
|
17
|
+
# Column span.
|
18
|
+
|
19
|
+
attr_reader :colspan
|
20
|
+
|
21
|
+
##
|
22
|
+
# Initialize with _options_.
|
23
|
+
|
24
|
+
def initialize options = nil
|
25
|
+
@value, options = options, {} unless Hash === options
|
26
|
+
@value = options.fetch :value, value
|
27
|
+
@alignment = options.fetch :alignment, nil
|
28
|
+
@colspan = options.fetch :colspan, 1
|
29
|
+
@width = options.fetch :width, @value.to_s.size
|
30
|
+
@index = options.fetch :index
|
31
|
+
@table = options.fetch :table
|
32
|
+
end
|
33
|
+
|
34
|
+
def alignment?
|
35
|
+
!@alignment.nil?
|
36
|
+
end
|
37
|
+
|
38
|
+
def alignment
|
39
|
+
@alignment || @table.style.alignment || :left
|
40
|
+
end
|
41
|
+
|
42
|
+
def alignment=(val)
|
43
|
+
supported = %w(left center right)
|
44
|
+
if supported.include?(val.to_s)
|
45
|
+
@alignment = val
|
46
|
+
else
|
47
|
+
raise "Aligment must be one of: #{supported.join(' ')}"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def lines
|
52
|
+
@value.to_s.split(/\n/)
|
53
|
+
end
|
54
|
+
|
55
|
+
##
|
56
|
+
# Render the cell.
|
57
|
+
|
58
|
+
def render(line = 0)
|
59
|
+
left = " " * @table.style.padding_left
|
60
|
+
right = " " * @table.style.padding_right
|
61
|
+
render_width = lines[line].to_s.size - escape(lines[line]).size + width
|
62
|
+
"#{left}#{lines[line]}#{right}".align(alignment, render_width + @table.cell_padding)
|
63
|
+
end
|
64
|
+
alias :to_s :render
|
65
|
+
|
66
|
+
##
|
67
|
+
# Returns the longest line in the cell and
|
68
|
+
# removes all ANSI escape sequences (e.g. color)
|
69
|
+
|
70
|
+
def value_for_column_width_recalc
|
71
|
+
lines.map{ |s| escape(s) }.max_by{ |s| s.size }
|
72
|
+
end
|
73
|
+
|
74
|
+
##
|
75
|
+
# Returns the width of this cell
|
76
|
+
|
77
|
+
def width
|
78
|
+
padding = (colspan - 1) * @table.cell_spacing
|
79
|
+
inner_width = (1..@colspan).to_a.inject(0) do |w, counter|
|
80
|
+
w + @table.column_width(@index + counter - 1)
|
81
|
+
end
|
82
|
+
inner_width + padding
|
83
|
+
end
|
84
|
+
|
85
|
+
def wrap(width)
|
86
|
+
@value.gsub!(/(.{1,#{width}})( +|$\n?)|(.{1,#{width}})/, "\\1\\3\n")
|
87
|
+
end
|
88
|
+
|
89
|
+
##
|
90
|
+
# removes all ANSI escape sequences (e.g. color)
|
91
|
+
def escape(line)
|
92
|
+
line.to_s.gsub(/\x1b(\[|\(|\))[;?0-9]*[0-9A-Za-z]/, '').
|
93
|
+
gsub(/\x1b(\[|\(|\))[;?0-9]*[0-9A-Za-z]/, '').
|
94
|
+
gsub(/(\x03|\x1a)/, '')
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module Terminal
|
2
|
+
class Table
|
3
|
+
class Row
|
4
|
+
|
5
|
+
##
|
6
|
+
# Row cells
|
7
|
+
|
8
|
+
attr_reader :cells
|
9
|
+
|
10
|
+
attr_reader :table
|
11
|
+
|
12
|
+
##
|
13
|
+
# Initialize with _width_ and _options_.
|
14
|
+
|
15
|
+
def initialize table, array = []
|
16
|
+
@cell_index = 0
|
17
|
+
@table = table
|
18
|
+
@cells = []
|
19
|
+
array.each { |item| self << item }
|
20
|
+
end
|
21
|
+
|
22
|
+
def add_cell item
|
23
|
+
options = item.is_a?(Hash) ? item : {:value => item}
|
24
|
+
cell = Cell.new(options.merge(:index => @cell_index, :table => @table))
|
25
|
+
@cell_index += cell.colspan
|
26
|
+
@cells << cell
|
27
|
+
end
|
28
|
+
alias << add_cell
|
29
|
+
|
30
|
+
def [] index
|
31
|
+
cells[index]
|
32
|
+
end
|
33
|
+
|
34
|
+
def height
|
35
|
+
cells.map { |c| c.lines.count }.max
|
36
|
+
end
|
37
|
+
|
38
|
+
def wrap_cell(index, width)
|
39
|
+
return if @cells.nil? or @cells[index].nil?
|
40
|
+
@cells[index].wrap(width)
|
41
|
+
end
|
42
|
+
|
43
|
+
def render
|
44
|
+
y = @table.style.border_y
|
45
|
+
(0...height).to_a.map do |line|
|
46
|
+
y + cells.map do |cell|
|
47
|
+
cell.render(line)
|
48
|
+
end.join(y) + y
|
49
|
+
end.join("\n")
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Terminal
|
2
|
+
class Table
|
3
|
+
class Separator < Row
|
4
|
+
|
5
|
+
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)
|
8
|
+
end
|
9
|
+
border_i = @table.style.border_i
|
10
|
+
border_i + arr_x.join(border_i) + border_i
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
|
2
|
+
module Terminal
|
3
|
+
class Table
|
4
|
+
# A Style object holds all the formatting information for a Table object
|
5
|
+
#
|
6
|
+
# To create a table with a certain style, use either the constructor
|
7
|
+
# option <tt>:style</tt>, the Table#style object or the Table#style= method
|
8
|
+
#
|
9
|
+
# All these examples have the same effect:
|
10
|
+
#
|
11
|
+
# # by constructor
|
12
|
+
# @table = Table.new(:style => {:padding_left => 2, :width => 40})
|
13
|
+
#
|
14
|
+
# # by object
|
15
|
+
# @table.style.padding_left = 2
|
16
|
+
# @table.style.width = 40
|
17
|
+
#
|
18
|
+
# # by method
|
19
|
+
# @table.style = {:padding_left => 2, :width => 40}
|
20
|
+
#
|
21
|
+
# To set a default style for all tables created afterwards use Style.defaults=
|
22
|
+
#
|
23
|
+
# Terminal::Table::Style.defaults = {:width => 80}
|
24
|
+
#
|
25
|
+
class Style
|
26
|
+
@@defaults = {
|
27
|
+
:border_x => "-", :border_y => "|", :border_i => "+",
|
28
|
+
:padding_left => 1, :padding_right => 1,
|
29
|
+
:width => nil, :alignment => nil,
|
30
|
+
:wrap => true, :wrap_minimum_width => 4
|
31
|
+
}
|
32
|
+
|
33
|
+
attr_accessor :border_x
|
34
|
+
attr_accessor :border_y
|
35
|
+
attr_accessor :border_i
|
36
|
+
|
37
|
+
attr_accessor :padding_left
|
38
|
+
attr_accessor :padding_right
|
39
|
+
|
40
|
+
attr_accessor :width
|
41
|
+
attr_accessor :alignment
|
42
|
+
attr_accessor :wrap
|
43
|
+
attr_accessor :wrap_minimum_width
|
44
|
+
|
45
|
+
|
46
|
+
def initialize options = {}
|
47
|
+
apply self.class.defaults.merge(options)
|
48
|
+
end
|
49
|
+
|
50
|
+
def apply options
|
51
|
+
options.each { |m, v| __send__ "#{m}=", v }
|
52
|
+
end
|
53
|
+
|
54
|
+
class << self
|
55
|
+
def defaults
|
56
|
+
@@defaults
|
57
|
+
end
|
58
|
+
|
59
|
+
def defaults= options
|
60
|
+
@@defaults = defaults.merge(options)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,261 @@
|
|
1
|
+
|
2
|
+
module Terminal
|
3
|
+
class Table
|
4
|
+
|
5
|
+
attr_reader :title
|
6
|
+
attr_reader :headings
|
7
|
+
|
8
|
+
##
|
9
|
+
# Generates a ASCII table with the given _options_.
|
10
|
+
|
11
|
+
def initialize options = {}, &block
|
12
|
+
@column_widths = []
|
13
|
+
self.style = options.fetch :style, {}
|
14
|
+
self.headings = options.fetch :headings, []
|
15
|
+
self.rows = options.fetch :rows, []
|
16
|
+
self.title = options.fetch :title, nil
|
17
|
+
yield_or_eval(&block) if block
|
18
|
+
end
|
19
|
+
|
20
|
+
##
|
21
|
+
# Align column _n_ to the given _alignment_ of :center, :left, or :right.
|
22
|
+
|
23
|
+
def align_column n, alignment
|
24
|
+
r = rows
|
25
|
+
column(n).each_with_index do |col, i|
|
26
|
+
cell = r[i][n]
|
27
|
+
cell.alignment = alignment unless cell.alignment?
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
##
|
32
|
+
# Add a row.
|
33
|
+
|
34
|
+
def add_row array
|
35
|
+
row = array == :separator ? Separator.new(self) : Row.new(self, array)
|
36
|
+
@rows << row
|
37
|
+
recalc_column_widths row
|
38
|
+
end
|
39
|
+
alias :<< :add_row
|
40
|
+
|
41
|
+
##
|
42
|
+
# Add a separator.
|
43
|
+
|
44
|
+
def add_separator
|
45
|
+
self << :separator
|
46
|
+
end
|
47
|
+
|
48
|
+
def cell_spacing
|
49
|
+
cell_padding + style.border_y.length
|
50
|
+
end
|
51
|
+
|
52
|
+
def cell_padding
|
53
|
+
style.padding_left + style.padding_right
|
54
|
+
end
|
55
|
+
|
56
|
+
##
|
57
|
+
# Return column _n_.
|
58
|
+
|
59
|
+
def column n, method = :value, array = rows
|
60
|
+
array.map { |row|
|
61
|
+
cell = row[n]
|
62
|
+
cell && method ? cell.__send__(method) : cell
|
63
|
+
}.compact
|
64
|
+
end
|
65
|
+
|
66
|
+
##
|
67
|
+
# Return _n_ column including headings.
|
68
|
+
|
69
|
+
def column_with_headings n, method = :value
|
70
|
+
column n, method, headings_with_rows
|
71
|
+
end
|
72
|
+
|
73
|
+
##
|
74
|
+
# Return columns.
|
75
|
+
|
76
|
+
def columns
|
77
|
+
(0...number_of_columns).map { |n| column n }
|
78
|
+
end
|
79
|
+
|
80
|
+
##
|
81
|
+
# Return length of column _n_.
|
82
|
+
|
83
|
+
def column_width n
|
84
|
+
width = @column_widths[n] || 0
|
85
|
+
width + additional_column_widths[n].to_i
|
86
|
+
end
|
87
|
+
alias length_of_column column_width # for legacy support
|
88
|
+
|
89
|
+
##
|
90
|
+
# Return total number of columns available.
|
91
|
+
|
92
|
+
def number_of_columns
|
93
|
+
headings_with_rows.map { |r| r.cells.size }.max
|
94
|
+
end
|
95
|
+
|
96
|
+
##
|
97
|
+
# Set the headings
|
98
|
+
|
99
|
+
def headings= array
|
100
|
+
@headings = Row.new(self, array)
|
101
|
+
recalc_column_widths @headings
|
102
|
+
end
|
103
|
+
|
104
|
+
##
|
105
|
+
# Render the table.
|
106
|
+
|
107
|
+
def render
|
108
|
+
adjust_widths
|
109
|
+
separator = Separator.new(self)
|
110
|
+
buffer = [separator]
|
111
|
+
unless @title.nil?
|
112
|
+
buffer << Row.new(self, [title_cell_options])
|
113
|
+
buffer << separator
|
114
|
+
end
|
115
|
+
unless @headings.cells.empty?
|
116
|
+
buffer << @headings
|
117
|
+
buffer << separator
|
118
|
+
end
|
119
|
+
buffer += @rows
|
120
|
+
buffer << separator
|
121
|
+
buffer.map { |r| r.render }.join("\n")
|
122
|
+
end
|
123
|
+
alias :to_s :render
|
124
|
+
|
125
|
+
##
|
126
|
+
# Return rows without separator rows.
|
127
|
+
|
128
|
+
def rows
|
129
|
+
@rows.reject { |row| row.is_a? Separator }
|
130
|
+
end
|
131
|
+
|
132
|
+
def rows= array
|
133
|
+
@rows = []
|
134
|
+
array.each { |arr| self << arr }
|
135
|
+
end
|
136
|
+
|
137
|
+
def style=(options)
|
138
|
+
style.apply options
|
139
|
+
end
|
140
|
+
|
141
|
+
def style
|
142
|
+
@style ||= Style.new
|
143
|
+
end
|
144
|
+
|
145
|
+
def title=(title)
|
146
|
+
@title = title
|
147
|
+
recalc_column_widths Row.new(self, [title_cell_options])
|
148
|
+
end
|
149
|
+
|
150
|
+
##
|
151
|
+
# Check if _other_ is equal to self. _other_ is considered equal
|
152
|
+
# if it contains the same headings and rows.
|
153
|
+
|
154
|
+
def == other
|
155
|
+
if other.respond_to? :render and other.respond_to? :rows
|
156
|
+
self.headings == other.headings and self.rows == other.rows
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
private
|
161
|
+
|
162
|
+
def columns_width
|
163
|
+
@column_widths.inject(0) { |s, i| s + i + cell_spacing } + style.border_y.length
|
164
|
+
end
|
165
|
+
|
166
|
+
def wrap_column(index, new_width)
|
167
|
+
@rows.each do |row|
|
168
|
+
row.wrap_cell(index, new_width)
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
def adjust_widths
|
173
|
+
return if style.wrap == false or style.width.nil? or style.width > columns_width
|
174
|
+
|
175
|
+
# Make a column index to column size mapping, then sort it
|
176
|
+
current_index = -1
|
177
|
+
total_column_widths = @column_widths.map { |s| current_index +=1; [current_index, s + cell_spacing] }
|
178
|
+
total_column_widths = total_column_widths.sort_by { |a,b| b }
|
179
|
+
|
180
|
+
packed_length = 0
|
181
|
+
current_index = 0
|
182
|
+
# Pack the smallest first, but make sure the remaining space is enough for
|
183
|
+
# the rest of the columns to have at least style.wrap_minimum_width spaces
|
184
|
+
# to wrap into.
|
185
|
+
while (style.width - (packed_length + total_column_widths[current_index][1] + style.border_y.length)) >
|
186
|
+
(style.wrap_minimum_width * (total_column_widths.size - current_index - 1)) do
|
187
|
+
packed_length += total_column_widths[current_index][1]
|
188
|
+
current_index += 1
|
189
|
+
end
|
190
|
+
|
191
|
+
# Calculate the remaining space and figure out how big to wrap the other columns to
|
192
|
+
remaining_space = style.width - packed_length - style.border_y.length
|
193
|
+
trim_to = (remaining_space / (total_column_widths.size - current_index)) - cell_spacing
|
194
|
+
trim_to -= (1 + style.padding_left + style.padding_right)
|
195
|
+
if trim_to < 1
|
196
|
+
raise "Cannot fit a #{total_column_widths.size} column table in width #{style.width}."
|
197
|
+
end
|
198
|
+
|
199
|
+
# The remaining columns are then wrapped
|
200
|
+
(current_index...total_column_widths.size).each do |i|
|
201
|
+
wrap_column(total_column_widths[i][0], trim_to)
|
202
|
+
@column_widths[total_column_widths[i][0]] = trim_to + cell_spacing
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
def additional_column_widths
|
207
|
+
return [] if style.width.nil?
|
208
|
+
spacing = style.width - columns_width
|
209
|
+
if spacing < 0
|
210
|
+
raise "Table width exceeds wanted width of #{style.width} characters."
|
211
|
+
else
|
212
|
+
per_col = spacing / number_of_columns
|
213
|
+
arr = (1...number_of_columns).to_a.map { |i| per_col }
|
214
|
+
other_cols = arr.inject(0) { |s, i| s + i }
|
215
|
+
arr << spacing - other_cols
|
216
|
+
arr
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
220
|
+
def recalc_column_widths row
|
221
|
+
return if row.is_a? Separator
|
222
|
+
i = 0
|
223
|
+
row.cells.each do |cell|
|
224
|
+
colspan = cell.colspan
|
225
|
+
cell_value = cell.value_for_column_width_recalc
|
226
|
+
colspan.downto(1) do |j|
|
227
|
+
cell_length = cell_value.to_s.length
|
228
|
+
if colspan > 1
|
229
|
+
spacing_length = cell_spacing * (colspan - 1)
|
230
|
+
length_in_columns = (cell_length - spacing_length)
|
231
|
+
cell_length = (length_in_columns.to_f / colspan).ceil
|
232
|
+
end
|
233
|
+
if @column_widths[i].to_i < cell_length
|
234
|
+
@column_widths[i] = cell_length
|
235
|
+
end
|
236
|
+
i = i + 1
|
237
|
+
end
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|
241
|
+
##
|
242
|
+
# Return headings combined with rows.
|
243
|
+
|
244
|
+
def headings_with_rows
|
245
|
+
[@headings] + rows
|
246
|
+
end
|
247
|
+
|
248
|
+
def yield_or_eval &block
|
249
|
+
return unless block
|
250
|
+
if block.arity > 0
|
251
|
+
yield self
|
252
|
+
else
|
253
|
+
self.instance_eval(&block)
|
254
|
+
end
|
255
|
+
end
|
256
|
+
|
257
|
+
def title_cell_options
|
258
|
+
{:value => @title, :alignment => :center, :colspan => number_of_columns}
|
259
|
+
end
|
260
|
+
end
|
261
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# require "terminal-table/cell"
|
2
|
+
# require "terminal-table/core_ext"
|
3
|
+
# require "terminal-table/row"
|
4
|
+
# require "terminal-table/separator"
|
5
|
+
# require "terminal-table/style"
|
6
|
+
# require "terminal-table/table_helper"
|
7
|
+
# require "terminal-table/table"
|
8
|
+
# require "terminal-table/version"
|
9
|
+
|
10
|
+
$:.unshift File.dirname(__FILE__)
|
11
|
+
%w(version core_ext table cell row separator style table_helper).each do |file|
|
12
|
+
require "terminal-table/#{file}"
|
13
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'term/ansicolor'
|
3
|
+
|
4
|
+
class String; include Term::ANSIColor; end
|
5
|
+
|
6
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
7
|
+
|
8
|
+
describe Terminal::Table do
|
9
|
+
Cell = Terminal::Table::Cell
|
10
|
+
|
11
|
+
it "should default alignment to the left" do
|
12
|
+
cell = Cell.new :value => 'foo', :table => Terminal::Table.new, :index => 0
|
13
|
+
cell.value.should == 'foo'
|
14
|
+
cell.alignment.should == :left
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should allow overriding of alignment" do
|
18
|
+
cell = Cell.new :value => 'foo', :alignment => :center, :table => Terminal::Table.new, :index => 0
|
19
|
+
cell.value.should == 'foo'
|
20
|
+
cell.alignment.should == :center
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should allow :left, :right and :center for alignment" do
|
24
|
+
@cell = Cell.new :value => 'foo', :table => Terminal::Table.new, :index => 0
|
25
|
+
@cell.alignment = :left
|
26
|
+
@cell.alignment = :right
|
27
|
+
@cell.alignment = :center
|
28
|
+
lambda { @cell.alignment = "foo" }.should raise_error
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should allow multiline content" do
|
32
|
+
cell = Cell.new :value => "barrissimo\n"+"foo".yellow, :table => Terminal::Table.new, :index => 0
|
33
|
+
cell.value.should == "barrissimo\n"+"foo".yellow
|
34
|
+
cell.lines.should == ['barrissimo','foo'.yellow]
|
35
|
+
cell.value_for_column_width_recalc.should == 'barrissimo'
|
36
|
+
cell.render(0).should == " barrissimo "
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should allow colorized content" do
|
40
|
+
cell = Cell.new :value => "foo".red, :table => Terminal::Table.new, :index => 0
|
41
|
+
cell.value.should == "\e[31mfoo\e[0m"
|
42
|
+
cell.value_for_column_width_recalc.should == 'foo'
|
43
|
+
cell.render.should == " \e[31mfoo\e[0m "
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should render padding properly" do
|
47
|
+
@table = Terminal::Table.new(:rows => [['foo', '2'], ['3', '4']], :style => {:padding_right => 3})
|
48
|
+
cell = @table.rows.first.cells.first
|
49
|
+
cell.value.should == 'foo'
|
50
|
+
cell.alignment.should == :left
|
51
|
+
cell.render.should == " foo "
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should not ignore pipe characters" do
|
55
|
+
cell = Cell.new :value => "f|o|o", :table => Terminal::Table.new, :index => 0
|
56
|
+
cell.value.should == "f|o|o"
|
57
|
+
cell.value_for_column_width_recalc.should == 'f|o|o'
|
58
|
+
cell.render.should == " f|o|o "
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
|
2
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
3
|
+
|
4
|
+
describe String do
|
5
|
+
describe "#align" do
|
6
|
+
it "should center" do
|
7
|
+
'foo'.align(:center, 10).should == ' foo '
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should align left" do
|
11
|
+
'foo'.align(:left, 10).should == 'foo '
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should align right" do
|
15
|
+
'foo'.align(:right, 10).should == ' foo'
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|