terminal-table 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/History.rdoc ADDED
@@ -0,0 +1,26 @@
1
+
2
+ === 1.2.0 / 2009-08-06
3
+
4
+ * Added colspan support to table
5
+
6
+ === 1.1.0 / 2009-08-06
7
+
8
+ * Added colspan support to table
9
+
10
+ === 1.1.0 / 2009-07-13
11
+
12
+ * Added Table#==
13
+
14
+ === 1.0.5 / 2009-03-14
15
+
16
+ * Allowing nil to be passed to table for headings
17
+ * Revised doc to show that rows can be splatted now
18
+ * Misc refactoring
19
+
20
+ === 1.0.3 / 2009-01-15
21
+
22
+ * Moved yield or eval to Terminal::Table initialize where it belongs
23
+
24
+ === 1.0.0 / 2009-01-13
25
+
26
+ * Initial release
data/Manifest ADDED
@@ -0,0 +1,25 @@
1
+ examples/examples.rb
2
+ History.rdoc
3
+ lib/terminal-table/cell.rb
4
+ lib/terminal-table/core_ext.rb
5
+ lib/terminal-table/heading.rb
6
+ lib/terminal-table/import.rb
7
+ lib/terminal-table/table.rb
8
+ lib/terminal-table/table_helper.rb
9
+ lib/terminal-table/version.rb
10
+ lib/terminal-table.rb
11
+ Manifest
12
+ Rakefile
13
+ README.rdoc
14
+ spec/cell_spec.rb
15
+ spec/core_ext_spec.rb
16
+ spec/import_spec.rb
17
+ spec/spec.opts
18
+ spec/spec_helper.rb
19
+ spec/table_helper_spec.rb
20
+ spec/table_spec.rb
21
+ tasks/docs.rake
22
+ tasks/gemspec.rake
23
+ tasks/spec.rake
24
+ terminal-table.gemspec
25
+ Todo.rdoc
data/README.rdoc ADDED
@@ -0,0 +1,151 @@
1
+
2
+ = Terminal Table
3
+
4
+ Simple, feature rich ASCII table generator.
5
+
6
+ == Installation:
7
+
8
+ Install [Gemcutter](http://gemcutter.org) then execute:
9
+ $ sudo gem install terminal-table
10
+
11
+ == Features:
12
+
13
+ * Fast
14
+ * Simple
15
+ * Optional headings
16
+ * Alignment of columns, headings, or cells
17
+ * Supports column span
18
+ * Easy modification of table strings (+, -, |)
19
+
20
+ == Examples:
21
+
22
+ require 'rubygems'
23
+ require 'terminal-table/import'
24
+
25
+ puts table(['a', 'b'], [1, 2], [3, 4])
26
+
27
+ t = table ['a', 'b']
28
+ t << [1, 2]
29
+ t << [3, 4]
30
+ puts t
31
+
32
+ user_table = table do |t|
33
+ t.headings = 'First Name', 'Last Name', 'Email'
34
+ t << ['TJ', 'Holowaychuk', 'tj@vision-media.ca']
35
+ t << ['Bob', 'Someone', 'bob@vision-media.ca']
36
+ t << ['Joe', 'Whatever', 'joe@vision-media.ca']
37
+ end
38
+ puts user_table
39
+
40
+ user_table = table do
41
+ self.headings = 'First Name', 'Last Name', 'Email'
42
+ add_row ['TJ', 'Holowaychuk', { :value => 'tj@vision-media.ca', :align => :right }]
43
+ add_row ['Bob', 'Someone', 'bob@vision-media.ca']
44
+ add_row ['Joe', 'Whatever', 'joe@vision-media.ca']
45
+ align_column 1, :center
46
+ end
47
+ puts user_table
48
+
49
+ puts
50
+ user_table = table do
51
+ self.headings = ['First Name', 'Last Name', {:value => 'Phones', :colspan => 2, :alignment => :center}]
52
+ add_row ['Bob', 'Someone', '123', '456']
53
+ add_row ['TJ', 'Holowaychuk', {:value => "No phones", :colspan => 2, :alignment => :center}]
54
+ add_row ['Joe', 'Whatever', '4324', '343242']
55
+ end
56
+ puts user_table
57
+
58
+ rows = []
59
+ rows << ['Lines', 100]
60
+ rows << ['Comments', 20]
61
+ rows << ['Ruby', 70]
62
+ rows << ['JavaScript', 30]
63
+ puts table([nil, 'Lines'], *rows)
64
+
65
+ rows = []
66
+ rows << ['Lines', 100]
67
+ rows << ['Comments', 20]
68
+ rows << ['Ruby', 70]
69
+ rows << ['JavaScript', 30]
70
+ puts table(nil, *rows)
71
+
72
+ == Results:
73
+
74
+ +---+---+
75
+ | a | b |
76
+ +---+---+
77
+ | 1 | 2 |
78
+ | 3 | 4 |
79
+ +---+---+
80
+
81
+ +---+---+
82
+ | a | b |
83
+ +---+---+
84
+ | 1 | 2 |
85
+ | 3 | 4 |
86
+ +---+---+
87
+
88
+ +------------+-------------+---------------------+
89
+ | First Name | Last Name | Email |
90
+ +------------+-------------+---------------------+
91
+ | TJ | Holowaychuk | tj@vision-media.ca |
92
+ | Bob | Someone | bob@vision-media.ca |
93
+ | Joe | Whatever | joe@vision-media.ca |
94
+ +------------+-------------+---------------------+
95
+
96
+ +------------+-----------------------------+---------------------+
97
+ | First Name | Last Name | Email |
98
+ +------------+-----------------------------+---------------------+
99
+ | TJ | Holowaychuk | tj@vision-media.ca |
100
+ | Bob | Someone | bob@vision-media.ca |
101
+ | Joe | Whatever | joe@vision-media.ca |
102
+ +------------+-----------------------------+---------------------+
103
+
104
+ +------------+-------------+-----------+--------+
105
+ | First Name | Last Name | Phones |
106
+ +------------+-------------+-----------+--------+
107
+ | Bob | Someone | 123 | 456 |
108
+ | TJ | Holowaychuk | No phones |
109
+ | Joe | Whatever | 4324 | 343242 |
110
+ +------------+-------------+-----------+--------+
111
+
112
+ +------------+-------+
113
+ | | Lines |
114
+ +------------+-------+
115
+ | Lines | 100 |
116
+ | Comments | 20 |
117
+ | Ruby | 70 |
118
+ | JavaScript | 30 |
119
+ +------------+-------+
120
+
121
+ +------------+-----+
122
+ | Lines | 100 |
123
+ | Comments | 20 |
124
+ | Ruby | 70 |
125
+ | JavaScript | 30 |
126
+ +------------+-----+
127
+
128
+ == License:
129
+
130
+ (The MIT License)
131
+
132
+ Copyright (c) 2008-2009 TJ Holowaychuk <tj@vision-media.ca>
133
+
134
+ Permission is hereby granted, free of charge, to any person obtaining
135
+ a copy of this software and associated documentation files (the
136
+ 'Software'), to deal in the Software without restriction, including
137
+ without limitation the rights to use, copy, modify, merge, publish,
138
+ distribute, sublicense, an d/or sell copies of the Software, and to
139
+ permit persons to whom the Software is furnished to do so, subject to
140
+ the following conditions:
141
+
142
+ The above copyright notice and this permission notice shall be
143
+ included in all copies or substantial portions of the Software.
144
+
145
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
146
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
147
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
148
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
149
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
150
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
151
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,15 @@
1
+
2
+ require 'rubygems'
3
+ require 'rake'
4
+ require 'echoe'
5
+ require './lib/terminal-table.rb'
6
+
7
+ Echoe.new("terminal-table", Terminal::Table::VERSION) do |p|
8
+ p.author = "TJ Holowaychuk"
9
+ p.email = "tj@vision-media.ca"
10
+ p.summary = "Simple, feature rich ascii table generation library"
11
+ p.url = "http://github.com/visionmedia/terminal-table"
12
+ p.runtime_dependencies = []
13
+ end
14
+
15
+ Dir['tasks/**/*.rake'].sort.each { |lib| load lib }
data/Todo.rdoc ADDED
@@ -0,0 +1,15 @@
1
+
2
+ == Major:
3
+
4
+ * Nothing
5
+
6
+ == Minor:
7
+
8
+ * Programmatically add seperator rows
9
+ * Arbitrary dimensions
10
+ * Add multi-column sorting
11
+ * Change; pre-create Cell and Heading objects to clean up Table a bit
12
+
13
+ == Brainstorming:
14
+
15
+ * Nothing
@@ -0,0 +1,66 @@
1
+
2
+ $:.unshift File.dirname(__FILE__) + '/../lib'
3
+ require 'terminal-table/import'
4
+
5
+ puts
6
+ puts table(['a', 'b'], [1, 2], [3, 4])
7
+
8
+ puts
9
+ t = table ['a', 'b']
10
+ t << [1, 2]
11
+ t << [3, 4]
12
+ puts t
13
+
14
+ puts
15
+ user_table = table do |t|
16
+ t.headings = 'First Name', 'Last Name', 'Email'
17
+ t << %w( TJ Holowaychuk tj@vision-media.ca )
18
+ t << %w( Bob Someone bob@vision-media.ca )
19
+ t << %w( Joe Whatever bob@vision-media.ca )
20
+ end
21
+ puts user_table
22
+
23
+ puts
24
+ user_table = table do
25
+ self.headings = 'First Name', 'Last Name', 'Email'
26
+ add_row ['TJ', 'Holowaychuk', ['tj@vision-media.ca', :right]]
27
+ add_row ['Bob', 'Someone', 'bob@vision-media.ca']
28
+ add_row ['Joe', 'Whatever', 'joe@vision-media.ca']
29
+ align_column 1, :center
30
+ end
31
+ puts user_table
32
+
33
+ puts
34
+ user_table = table do
35
+ self.headings = ['First Name', 'Last Name', {:value => 'Phones', :colspan => 2, :alignment => :center}]
36
+ add_row ['Bob', 'Someone', '123', '456']
37
+ add_row ['TJ', 'Holowaychuk', {:value => "No phones", :colspan => 2, :alignment => :center}]
38
+ add_row ['Joe', 'Whatever', '4324', '343242']
39
+ end
40
+ puts user_table
41
+
42
+ rows = []
43
+ rows << ['Lines', 100]
44
+ rows << ['Comments', 20]
45
+ rows << ['Ruby', 70]
46
+ rows << ['JavaScript', 30]
47
+ puts table([nil, 'Lines'], *rows)
48
+
49
+ rows = []
50
+ rows << ['Lines', 100]
51
+ rows << ['Comments', 20]
52
+ rows << ['Ruby', 70]
53
+ rows << ['JavaScript', 30]
54
+ puts table(nil, *rows)
55
+
56
+
57
+ Terminal::Table::X = '='
58
+ Terminal::Table::Y = '!'
59
+ Terminal::Table::I = '*'
60
+
61
+ rows = []
62
+ rows << [nil, nil, nil]
63
+ rows << [nil, ':)', nil]
64
+ rows << [nil, nil, nil]
65
+ puts table(nil, *rows)
66
+
@@ -0,0 +1,31 @@
1
+ #--
2
+ # Copyright (c) 2008-2009 TJ Holowaychuk <tj@vision-media.ca>
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # "Software"), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
+ # permit persons to whom the Software is furnished to do so, subject to
10
+ # the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ #++
23
+
24
+ $:.unshift File.dirname(__FILE__)
25
+
26
+ require 'terminal-table/version'
27
+ require 'terminal-table/core_ext'
28
+ require 'terminal-table/table'
29
+ require 'terminal-table/cell'
30
+ require 'terminal-table/heading'
31
+ require 'terminal-table/table_helper'
@@ -0,0 +1,32 @@
1
+
2
+ module Terminal
3
+ class Table
4
+ class Cell
5
+
6
+ attr_accessor :value, :alignment, :colspan
7
+
8
+ def initialize width, params
9
+ @width = width
10
+ @alignment = :left
11
+ @colspan = 1
12
+
13
+ if params.is_a? Hash
14
+ @value = params[:value]
15
+ @alignment = params[:alignment] unless params[:alignment].nil?
16
+ @colspan = params[:colspan] unless params[:colspan].nil?
17
+ else
18
+ @value = params
19
+ end
20
+ end
21
+
22
+ def render
23
+ " #{value.to_s} ".align alignment, @width + 2
24
+ end
25
+ alias :to_s :render
26
+
27
+ def length
28
+ @value.to_s.length + 2
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,39 @@
1
+
2
+ class String
3
+
4
+ ##
5
+ # Align to +position+, which may be :left, :right, or :center.
6
+
7
+ def align position, length
8
+ send position, length
9
+ end
10
+ alias_method :left, :ljust
11
+ alias_method :right, :rjust
12
+
13
+ end
14
+
15
+ module Enumerable
16
+ def map_with_index &block
17
+ result = []
18
+ each_with_index { |v, i| result << yield(v, i) }
19
+ result
20
+ end
21
+ alias :collect_with_index :map_with_index
22
+ end
23
+
24
+ class Object
25
+
26
+ ##
27
+ # Yields or instance_eval's a +block+ depending on the arity of a block
28
+ # in order to support both types of block syntax for DSL's.
29
+
30
+ def yield_or_eval &block
31
+ return unless block
32
+ if block.arity > 0
33
+ yield self
34
+ else
35
+ self.instance_eval &block
36
+ end
37
+ end
38
+
39
+ end
@@ -0,0 +1,10 @@
1
+
2
+ module Terminal
3
+ class Table
4
+ class Heading < Cell
5
+ def initialize width, params
6
+ super
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,5 @@
1
+ require 'terminal-table'
2
+
3
+ class Object
4
+ include Terminal::Table::TableHelper
5
+ end
@@ -0,0 +1,191 @@
1
+
2
+ module Terminal
3
+
4
+ ##
5
+ # Generates an ASCII table for terminal usage.
6
+ #
7
+ # This class can be used in many ways, however ultimately you should
8
+ # require 'terminal-table/import' (which requires terminal-table itself) to use
9
+ # the Kernel helper method which is easier, and cleaner to use. View Object#table
10
+ # for examples.
11
+ #
12
+ # === Examples:
13
+ #
14
+ # table = Terminal::Table.new
15
+ # table.headings = ['Characters', { :value => 'Nums', :align => :right }]
16
+ # table << [{ :value => 'a', :align => :center }, 1]
17
+ # table << ['b', 222222222222222]
18
+ # table << ['c', 3]
19
+ # puts table.render # or simply puts table
20
+ #
21
+ # +------------+-----------------+
22
+ # | Characters | Nums |
23
+ # +------------+-----------------+
24
+ # | a | 1 |
25
+ # | b | 222222222222222 |
26
+ # | c | 3 |
27
+ # +------------+-----------------+
28
+ #
29
+
30
+ class Table
31
+
32
+ #--
33
+ # Exceptions
34
+ #++
35
+
36
+ class Error < StandardError; end
37
+
38
+ ##
39
+ # Table characters, x axis, y axis, and intersection.
40
+
41
+ X, Y, I = '-', '|', '+'
42
+
43
+ attr_accessor :headings, :rows
44
+
45
+ ##
46
+ # Generates a ASCII table.
47
+
48
+ def initialize options = {}, &block
49
+ @headings = options.fetch :headings, []
50
+ @rows = options.fetch :rows, []
51
+ yield_or_eval &block if block_given?
52
+ end
53
+
54
+ ##
55
+ # Render the table. Often you will simply call _puts_ with an
56
+ # instance in order to output it to the terminal.
57
+
58
+ def render
59
+ buffer = seperator << "\n"
60
+ if has_headings?
61
+ buffer << Y + headings.map_with_index do |heading, i|
62
+ width = 0
63
+ if heading.is_a?(Hash) and !heading[:colspan].nil?
64
+ i.upto(i + heading[:colspan] - 1) do |col|
65
+ width += length_of_column(col)
66
+ end
67
+ width += (heading[:colspan] - 1) * (Y.length + 2)
68
+ else
69
+ width = length_of_column(i)
70
+ end
71
+ Heading.new( width, heading).render
72
+ end.join(Y) + Y
73
+ buffer << "\n#{seperator}\n"
74
+ end
75
+ buffer << rows.map do |row|
76
+ Y + row.map_with_index do |cell, i|
77
+ width = 0
78
+ if cell.is_a?(Hash) and !cell[:colspan].nil?
79
+ i.upto(i + cell[:colspan] - 1) do |col|
80
+ width += length_of_column(col)
81
+ end
82
+ width += (cell[:colspan] - 1) * (Y.length + 2)
83
+ else
84
+ width = length_of_column(i)
85
+ end
86
+ Cell.new(width, cell).render
87
+ end.join(Y) + Y
88
+ end.join("\n")
89
+ buffer << "\n#{seperator}\n"
90
+ end
91
+ alias :to_s :render
92
+
93
+ ##
94
+ # Create a seperator based on colum lengths.
95
+
96
+ def seperator
97
+ I + columns.collect_with_index do |col, i|
98
+ X * (length_of_column(i) + 2)
99
+ end.join(I) + I
100
+ end
101
+
102
+ ##
103
+ # Add a row.
104
+
105
+ def add_row row
106
+ rows << row
107
+ end
108
+ alias :<< :add_row
109
+
110
+ ##
111
+ # Weither or not any headings are present, since they are optional.
112
+
113
+ def has_headings?
114
+ !headings.empty?
115
+ end
116
+
117
+ ##
118
+ # Return +n+ column.
119
+
120
+ def column n
121
+ rows.map { |row| row[n] }.compact
122
+ end
123
+
124
+ ##
125
+ # Return +n+ column including headings.
126
+
127
+ def column_with_headings n
128
+ headings_with_rows.map { |row| row[n] }.compact
129
+ end
130
+
131
+ ##
132
+ # Return columns.
133
+
134
+ def columns
135
+ (0..number_of_columns-1).map { |n| column n }
136
+ end
137
+
138
+ ##
139
+ # Return the largest cell found within column +n+.
140
+
141
+ def largest_cell_in_column n
142
+ column_with_headings(n).sort_by { |cell| Cell.new(0, cell).length }.last
143
+ end
144
+
145
+ ##
146
+ # Return length of column +n+.
147
+
148
+ def length_of_column n
149
+ largest_cell = largest_cell_in_column(n)
150
+ if largest_cell.is_a? Hash
151
+ largest_cell[:value].length# - 2
152
+ else
153
+ largest_cell.to_s.length
154
+ end
155
+ end
156
+
157
+ ##
158
+ # Return total number of columns available.
159
+
160
+ def number_of_columns
161
+ return rows.first.length unless rows.empty?
162
+ raise Error, 'your table needs some rows.'
163
+ end
164
+
165
+ ##
166
+ # Align column +n+ to +alignment+ of :center, :left, or :right.
167
+
168
+ def align_column n, alignment
169
+ column(n).each_with_index do |col, i|
170
+ @rows[i][n] = {:value => col, :alignment => alignment} unless col.is_a? Hash
171
+ end
172
+ end
173
+
174
+ ##
175
+ # Return headings combined with rows.
176
+
177
+ def headings_with_rows
178
+ [headings] + rows
179
+ end
180
+
181
+ ##
182
+ # Check if +other+ is equal to self. +other+ is considered equal
183
+ # if it contains the same headings and rows.
184
+
185
+ def == other
186
+ if other.respond_to?(:headings) && other.respond_to?(:rows)
187
+ headings == other.headings && rows == other.rows
188
+ end
189
+ end
190
+ end
191
+ end
@@ -0,0 +1,53 @@
1
+ module Terminal
2
+ class Table
3
+ module TableHelper
4
+ ##
5
+ # Generates a Terminal::Table object.
6
+ #
7
+ # === Examples:
8
+ #
9
+ # puts table(['a', 'b'], [1, 2], [3, 4])
10
+ #
11
+ # # OR
12
+ #
13
+ # t = table ['a', 'b']
14
+ # t << [1, 2]
15
+ # t << [3, 4]
16
+ # puts t
17
+ #
18
+ # # OR
19
+ #
20
+ # user_table = table do |t|
21
+ # t.headings = 'First Name', 'Last Name', 'Email'
22
+ # t << ['TJ', 'Holowaychuk', 'tj@vision-media.ca']
23
+ # t << ['Bob', 'Someone', 'bob@vision-media.ca']
24
+ # t << ['Joe', 'Whatever', 'joe@vision-media.ca']
25
+ # end
26
+ # puts user_table
27
+ #
28
+ # # OR
29
+ #
30
+ # user_table = table do
31
+ # self.headings = 'First Name', 'Last Name', 'Email'
32
+ # add_row ['TJ', 'Holowaychuk', 'tj@vision-media.ca']
33
+ # add_row ['Bob', 'Someone', 'bob@vision-media.ca']
34
+ # add_row ['Joe', 'Whatever', 'joe@vision-media.ca']
35
+ # end
36
+ # puts user_table
37
+ #
38
+ # # OR
39
+ #
40
+ # rows = []
41
+ # rows << ['Lines', 100]
42
+ # rows << ['Comments', 20]
43
+ # rows << ['Ruby', 70]
44
+ # rows << ['JavaScript', 30]
45
+ # puts table(nil, *rows)
46
+ #
47
+
48
+ def table headings = [], *rows, &block
49
+ Terminal::Table.new :headings => headings.to_a, :rows => rows, &block
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,6 @@
1
+
2
+ module Terminal
3
+ class Table
4
+ VERSION = '1.2.0'
5
+ end
6
+ end
data/spec/cell_spec.rb ADDED
@@ -0,0 +1,19 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/spec_helper")
2
+
3
+ describe Terminal::Table do
4
+
5
+ Cell = Terminal::Table::Cell
6
+
7
+ it "should default alignment to the left" do
8
+ cell = Cell.new 0, 'foo'
9
+ cell.value.should == 'foo'
10
+ cell.alignment.should == :left
11
+ end
12
+
13
+ it "should override alignment" do
14
+ cell = Cell.new 0, {:value => 'foo', :alignment => :center}
15
+ cell.value.should == 'foo'
16
+ cell.alignment.should == :center
17
+ end
18
+
19
+ end
@@ -0,0 +1,19 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/spec_helper")
2
+
3
+ describe String do
4
+
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
+
19
+ end
@@ -0,0 +1,11 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/spec_helper")
2
+ require "terminal-table/import"
3
+
4
+ describe Object do
5
+ describe "#table" do
6
+ it "should allow creation of a terminal table" do
7
+ table(['foo', 'bar'], ['a', 'b'], [1, 2]).
8
+ should be_instance_of(Terminal::Table)
9
+ end
10
+ end
11
+ end
data/spec/spec.opts ADDED
@@ -0,0 +1 @@
1
+ --color
@@ -0,0 +1,8 @@
1
+
2
+ require File.expand_path(File.dirname(__FILE__) + "/../lib/terminal-table")
3
+
4
+ class String
5
+ def deindent
6
+ gsub /^ */, ''
7
+ end
8
+ end
@@ -0,0 +1,18 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/spec_helper")
2
+
3
+ module Terminal
4
+ describe Table::TableHelper do
5
+ before do
6
+ @obj = Class.new do
7
+ include Table::TableHelper
8
+ end.new
9
+ end
10
+
11
+ describe "#table" do
12
+ it "should allow creation of a terminal table" do
13
+ table = @obj.table(['foo', 'bar'], ['a', 'b'], [1, 2])
14
+ table.should be_instance_of(Terminal::Table)
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,296 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/spec_helper")
2
+
3
+ module Terminal
4
+ describe Table do
5
+ before :each do
6
+ @table = Table.new
7
+ end
8
+
9
+ it "should select columns" do
10
+ @table << ['foo', 'bar']
11
+ @table << ['big foo', 'big foo bar']
12
+ @table.column(1).should == ['bar', 'big foo bar']
13
+ end
14
+
15
+ it "should count columns" do
16
+ @table << [1, 2, 3]
17
+ @table.number_of_columns.should == 3
18
+ end
19
+
20
+ it "should iterate columns" do
21
+ @table << [1, 2, 3]
22
+ @table << [4, 5, 6]
23
+ @table.columns.should == [[1, 4], [2, 5], [3, 6]]
24
+ end
25
+
26
+ it "should select columns" do
27
+ @table.headings = ['one', 'two']
28
+ @table << ['foo', 'bar']
29
+ @table << ['big foo', 'big foo bar']
30
+ @table.column(1).should == ['bar', 'big foo bar']
31
+ end
32
+
33
+ it "should select columns when using hashes" do
34
+ @table.headings = ['one', 'two']
35
+ @table.rows = [[{ :value => 'a', :align => :left }, 1], ['b', 2], ['c', 3]]
36
+ @table.column(0).should == [{ :value => 'a', :align => :left }, 'b', 'c']
37
+ end
38
+
39
+ it "should select largest cell in a column" do
40
+ @table << ['foo', 'bar']
41
+ @table << ['big foo', 'big foo bar']
42
+ @table.largest_cell_in_column(1).should == 'big foo bar'
43
+ end
44
+
45
+ it "should find column length" do
46
+ @table << ['foo', 'bar', 'a']
47
+ @table << ['big foo', 'big foo bar']
48
+ @table.length_of_column(1).should == 11
49
+ end
50
+
51
+ it "should find column length with headings" do
52
+ @table.headings = ['one', 'super long heading']
53
+ @table << ['foo', 'bar', 'a']
54
+ @table << ['big foo', 'big foo bar']
55
+ @table.length_of_column(1).should == 18
56
+ end
57
+
58
+ it "should render seperators" do
59
+ @table.headings = ['Char', 'Num']
60
+ @table << ['a', 1]
61
+ @table.seperator.should == '+------+-----+'
62
+ end
63
+
64
+ it "should bitch and complain when you have no rows" do
65
+ lambda { @table.render }.should raise_error(Terminal::Table::Error)
66
+ end
67
+
68
+ it "should render properly" do
69
+ @table.headings = ['Char', 'Num']
70
+ @table << ['a', 1]
71
+ @table << ['b', 2]
72
+ @table << ['c', 3]
73
+ @table.render.should == <<-EOF.deindent
74
+ +------+-----+
75
+ | Char | Num |
76
+ +------+-----+
77
+ | a | 1 |
78
+ | b | 2 |
79
+ | c | 3 |
80
+ +------+-----+
81
+ EOF
82
+ end
83
+
84
+ it "should render properly without headings" do
85
+ @table << ['a', 1]
86
+ @table << ['b', 2]
87
+ @table << ['c', 3]
88
+ @table.render.should == <<-EOF.deindent
89
+ +---+---+
90
+ | a | 1 |
91
+ | b | 2 |
92
+ | c | 3 |
93
+ +---+---+
94
+ EOF
95
+ end
96
+
97
+ it "should render properly using block syntax" do
98
+ table = Terminal::Table.new do |t|
99
+ t << ['a', 1]
100
+ t << ['b', 2]
101
+ t << ['c', 3]
102
+ end
103
+ table.render.should == <<-EOF.deindent
104
+ +---+---+
105
+ | a | 1 |
106
+ | b | 2 |
107
+ | c | 3 |
108
+ +---+---+
109
+ EOF
110
+ end
111
+
112
+ it "should render properly using instance_eval block syntax" do
113
+ table = Terminal::Table.new do
114
+ add_row ['a', 1]
115
+ add_row ['b', 2]
116
+ add_row ['c', 3]
117
+ end
118
+ table.render.should == <<-EOF.deindent
119
+ +---+---+
120
+ | a | 1 |
121
+ | b | 2 |
122
+ | c | 3 |
123
+ +---+---+
124
+ EOF
125
+ end
126
+
127
+ it "should allows a hash of options for creation" do
128
+ headings = ['Char', 'Num']
129
+ rows = [['a', 1], ['b', 2], ['c', 3]]
130
+ Terminal::Table.new(:rows => rows, :headings => headings).render.should == <<-EOF.deindent
131
+ +------+-----+
132
+ | Char | Num |
133
+ +------+-----+
134
+ | a | 1 |
135
+ | b | 2 |
136
+ | c | 3 |
137
+ +------+-----+
138
+ EOF
139
+ end
140
+
141
+ it "should flex for large cells" do
142
+ @table.headings = ['Just some characters', 'Num']
143
+ @table.rows = [['a', 1], ['b', 2], ['c', 3]]
144
+ @table.render.should == <<-EOF.deindent
145
+ +----------------------+-----+
146
+ | Just some characters | Num |
147
+ +----------------------+-----+
148
+ | a | 1 |
149
+ | b | 2 |
150
+ | c | 3 |
151
+ +----------------------+-----+
152
+ EOF
153
+ end
154
+
155
+ it "should allow alignment of headings and cells" do
156
+ @table.headings = ['Characters', {:value => 'Nums', :alignment => :right} ]
157
+ @table << [{:value => 'a', :alignment => :center}, 1]
158
+ @table << ['b', 222222222222222]
159
+ @table << ['c', 3]
160
+ @table.render.should == <<-EOF.deindent
161
+ +------------+-----------------+
162
+ | Characters | Nums |
163
+ +------------+-----------------+
164
+ | a | 1 |
165
+ | b | 222222222222222 |
166
+ | c | 3 |
167
+ +------------+-----------------+
168
+ EOF
169
+
170
+ end
171
+
172
+ it "should align columns, but allow specifics to remain" do
173
+ @table.headings = ['Just some characters', 'Num']
174
+ @table.rows = [[{:value => 'a', :alignment => :left}, 1], ['b', 2], ['c', 3]]
175
+ @table.align_column 0, :center
176
+ @table.align_column 1, :right
177
+ @table.render.should == <<-EOF.deindent
178
+ +----------------------+-----+
179
+ | Just some characters | Num |
180
+ +----------------------+-----+
181
+ | a | 1 |
182
+ | b | 2 |
183
+ | c | 3 |
184
+ +----------------------+-----+
185
+ EOF
186
+ end
187
+
188
+ describe "#==" do
189
+ it "should be equal to itself" do
190
+ t = Table.new
191
+ t.should == t
192
+ end
193
+
194
+ it "should be equal with two empty tables" do
195
+ table_one = Table.new
196
+ table_two = Table.new
197
+
198
+ table_one.should == table_two
199
+ table_two.should == table_one
200
+ end
201
+
202
+ it "should not be equal with different headings" do
203
+ table_one = Table.new
204
+ table_two = Table.new
205
+
206
+ table_one.headings << "a"
207
+
208
+ table_one.should_not == table_two
209
+ table_two.should_not == table_one
210
+ end
211
+
212
+ it "should not be equal with different rows" do
213
+ table_one = Table.new
214
+ table_two = Table.new
215
+
216
+ table_one.rows << "a"
217
+
218
+ table_one.should_not == table_two
219
+ table_two.should_not == table_one
220
+ end
221
+
222
+ it "should not be equal if the other object does not respond_to? :headings" do
223
+ table_one = Table.new
224
+ table_two = Object.new
225
+ table_two.stub!(:rows).and_return([])
226
+ table_one.should_not == table_two
227
+ end
228
+
229
+ it "should not be equal if the other object does not respond_to? :rows" do
230
+ table_one = Table.new
231
+ table_two = Object.new
232
+ table_two.stub!(:rows).and_return([])
233
+ table_one.should_not == table_two
234
+ end
235
+ end
236
+
237
+ it "should handle colspan inside heading" do
238
+ @table.headings = ['one', { :value => 'two', :alignment => :center, :colspan => 2}]
239
+ @table.rows = [['a', 1, 2], ['b', 3, 4], ['c', 3, 4]]
240
+ @table.render.should == <<-EOF.deindent
241
+ +-----+-----+---+
242
+ | one | two |
243
+ +-----+-----+---+
244
+ | a | 1 | 2 |
245
+ | b | 3 | 4 |
246
+ | c | 3 | 4 |
247
+ +-----+-----+---+
248
+ EOF
249
+ end
250
+
251
+ it "should handle colspan inside cells" do
252
+ @table.headings = ['one', 'two', 'three']
253
+ @table.rows = [['a', 1, 2], ['b', 3, 4], ['c', {:value => "joined", :colspan => 2,:alignment => :center}]]
254
+ @table.render.should == <<-EOF.deindent
255
+ +-----+--------+-------+
256
+ | one | two | three |
257
+ +-----+--------+-------+
258
+ | a | 1 | 2 |
259
+ | b | 3 | 4 |
260
+ | c | joined |
261
+ +-----+--------+-------+
262
+ EOF
263
+ end
264
+
265
+
266
+ it "should handle colspan 1" do
267
+ @table.headings = ['name', { :value => 'values', :colspan => 1}]
268
+ @table.rows = [['a', 1], ['b', 4], ['c', 7]]
269
+ @table.render.should == <<-EOF.deindent
270
+ +------+--------+
271
+ | name | values |
272
+ +------+--------+
273
+ | a | 1 |
274
+ | b | 4 |
275
+ | c | 7 |
276
+ +------+--------+
277
+ EOF
278
+ end
279
+
280
+ it "should handle big colspan" do
281
+ @table.headings = ['name', { :value => 'values', :alignment => :right, :colspan => 3}]
282
+ @table.headings = ['name', { :value => 'values', :colspan => 3}]
283
+ @table.rows = [['a', 1, 2, 3], ['b', 4, 5, 6], ['c', 7, 8, 9]]
284
+
285
+ @table.render.should == <<-EOF.deindent
286
+ +------+--------+---+---+
287
+ | name | values |
288
+ +------+--------+---+---+
289
+ | a | 1 | 2 | 3 |
290
+ | b | 4 | 5 | 6 |
291
+ | c | 7 | 8 | 9 |
292
+ +------+--------+---+---+
293
+ EOF
294
+ end
295
+ end
296
+ end
data/tasks/docs.rake ADDED
@@ -0,0 +1,13 @@
1
+
2
+ namespace :docs do
3
+
4
+ desc 'Remove rdoc products'
5
+ task :remove => [:clobber_docs]
6
+
7
+ desc 'Build docs, and open in browser for viewing (specify BROWSER)'
8
+ task :open => [:docs] do
9
+ browser = ENV["BROWSER"] || "safari"
10
+ sh "open -a #{browser} doc/index.html"
11
+ end
12
+
13
+ end
@@ -0,0 +1,3 @@
1
+
2
+ desc 'Build gemspec file'
3
+ task :gemspec => [:build_gemspec]
data/tasks/spec.rake ADDED
@@ -0,0 +1,25 @@
1
+
2
+ require 'spec/rake/spectask'
3
+
4
+ desc "Run all specifications"
5
+ Spec::Rake::SpecTask.new(:spec) do |t|
6
+ t.libs << "lib"
7
+ t.spec_opts = ["--color", "--require", "spec/spec_helper.rb"]
8
+ end
9
+
10
+ namespace :spec do
11
+
12
+ desc "Run all specifications verbosely"
13
+ Spec::Rake::SpecTask.new(:verbose) do |t|
14
+ t.libs << "lib"
15
+ t.spec_opts = ["--color", "--format", "specdoc", "--require", "spec/spec_helper.rb"]
16
+ end
17
+
18
+ desc "Run specific specification verbosely (specify SPEC)"
19
+ Spec::Rake::SpecTask.new(:select) do |t|
20
+ t.libs << "lib"
21
+ t.spec_files = [ENV["SPEC"]]
22
+ t.spec_opts = ["--color", "--format", "specdoc", "--require", "spec/spec_helper.rb"]
23
+ end
24
+
25
+ end
@@ -0,0 +1,30 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{terminal-table}
5
+ s.version = "1.2.0"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["TJ Holowaychuk"]
9
+ s.date = %q{2009-10-10}
10
+ s.description = %q{Simple, feature rich ascii table generation library}
11
+ s.email = %q{tj@vision-media.ca}
12
+ s.extra_rdoc_files = ["lib/terminal-table/cell.rb", "lib/terminal-table/core_ext.rb", "lib/terminal-table/heading.rb", "lib/terminal-table/import.rb", "lib/terminal-table/table.rb", "lib/terminal-table/table_helper.rb", "lib/terminal-table/version.rb", "lib/terminal-table.rb", "README.rdoc", "tasks/docs.rake", "tasks/gemspec.rake", "tasks/spec.rake"]
13
+ s.files = ["examples/examples.rb", "History.rdoc", "lib/terminal-table/cell.rb", "lib/terminal-table/core_ext.rb", "lib/terminal-table/heading.rb", "lib/terminal-table/import.rb", "lib/terminal-table/table.rb", "lib/terminal-table/table_helper.rb", "lib/terminal-table/version.rb", "lib/terminal-table.rb", "Manifest", "Rakefile", "README.rdoc", "spec/cell_spec.rb", "spec/core_ext_spec.rb", "spec/import_spec.rb", "spec/spec.opts", "spec/spec_helper.rb", "spec/table_helper_spec.rb", "spec/table_spec.rb", "tasks/docs.rake", "tasks/gemspec.rake", "tasks/spec.rake", "terminal-table.gemspec", "Todo.rdoc"]
14
+ s.homepage = %q{http://github.com/visionmedia/terminal-table}
15
+ s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Terminal-table", "--main", "README.rdoc"]
16
+ s.require_paths = ["lib"]
17
+ s.rubyforge_project = %q{terminal-table}
18
+ s.rubygems_version = %q{1.3.5}
19
+ s.summary = %q{Simple, feature rich ascii table generation library}
20
+
21
+ if s.respond_to? :specification_version then
22
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
23
+ s.specification_version = 3
24
+
25
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
26
+ else
27
+ end
28
+ else
29
+ end
30
+ end
metadata ADDED
@@ -0,0 +1,95 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: terminal-table
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.2.0
5
+ platform: ruby
6
+ authors:
7
+ - TJ Holowaychuk
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-10-10 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: Simple, feature rich ascii table generation library
17
+ email: tj@vision-media.ca
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - lib/terminal-table/cell.rb
24
+ - lib/terminal-table/core_ext.rb
25
+ - lib/terminal-table/heading.rb
26
+ - lib/terminal-table/import.rb
27
+ - lib/terminal-table/table.rb
28
+ - lib/terminal-table/table_helper.rb
29
+ - lib/terminal-table/version.rb
30
+ - lib/terminal-table.rb
31
+ - README.rdoc
32
+ - tasks/docs.rake
33
+ - tasks/gemspec.rake
34
+ - tasks/spec.rake
35
+ files:
36
+ - examples/examples.rb
37
+ - History.rdoc
38
+ - lib/terminal-table/cell.rb
39
+ - lib/terminal-table/core_ext.rb
40
+ - lib/terminal-table/heading.rb
41
+ - lib/terminal-table/import.rb
42
+ - lib/terminal-table/table.rb
43
+ - lib/terminal-table/table_helper.rb
44
+ - lib/terminal-table/version.rb
45
+ - lib/terminal-table.rb
46
+ - Manifest
47
+ - Rakefile
48
+ - README.rdoc
49
+ - spec/cell_spec.rb
50
+ - spec/core_ext_spec.rb
51
+ - spec/import_spec.rb
52
+ - spec/spec.opts
53
+ - spec/spec_helper.rb
54
+ - spec/table_helper_spec.rb
55
+ - spec/table_spec.rb
56
+ - tasks/docs.rake
57
+ - tasks/gemspec.rake
58
+ - tasks/spec.rake
59
+ - terminal-table.gemspec
60
+ - Todo.rdoc
61
+ has_rdoc: true
62
+ homepage: http://github.com/visionmedia/terminal-table
63
+ licenses: []
64
+
65
+ post_install_message:
66
+ rdoc_options:
67
+ - --line-numbers
68
+ - --inline-source
69
+ - --title
70
+ - Terminal-table
71
+ - --main
72
+ - README.rdoc
73
+ require_paths:
74
+ - lib
75
+ required_ruby_version: !ruby/object:Gem::Requirement
76
+ requirements:
77
+ - - ">="
78
+ - !ruby/object:Gem::Version
79
+ version: "0"
80
+ version:
81
+ required_rubygems_version: !ruby/object:Gem::Requirement
82
+ requirements:
83
+ - - ">="
84
+ - !ruby/object:Gem::Version
85
+ version: "1.2"
86
+ version:
87
+ requirements: []
88
+
89
+ rubyforge_project: terminal-table
90
+ rubygems_version: 1.3.5
91
+ signing_key:
92
+ specification_version: 3
93
+ summary: Simple, feature rich ascii table generation library
94
+ test_files: []
95
+