terminal-table 1.2.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.
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
+