text-table-1.2.4/ 0000755 0000041 0000041 00000000000 12474517022 013623 5 ustar www-data www-data text-table-1.2.4/Gemfile 0000644 0000041 0000041 00000000047 12474517022 015117 0 ustar www-data www-data source 'https://rubygems.org'
gemspec
text-table-1.2.4/text-table.gemspec 0000644 0000041 0000041 00000001472 12474517022 017245 0 ustar www-data www-data require File.expand_path('../lib/text-table/version', __FILE__)
Gem::Specification.new do |gem|
gem.name = 'text-table'
gem.version = Text::Table::VERSION
gem.authors = ['Aaron Tinio']
gem.email = 'aptinio@gmail.com'
gem.summary = 'A feature-rich, easy-to-use plain text table formatter.'
gem.description = %w[
Allows you to easily create and format plain text tables,
useful when working with the terminal or when you want to quickly print
formatted tables to a dot-matrix printer.
].join ' '
gem.homepage = 'https://github.com/aptinio/text-table'
gem.require_paths = ['lib']
gem.files = `git ls-files`.split($/)
gem.test_files = `git ls-files -- spec/*`.split($/)
gem.extra_rdoc_files = %w[LICENSE README.rdoc]
gem.add_development_dependency 'rspec', '~> 2'
gem.license = 'MIT'
end
text-table-1.2.4/CHANGELOG.rdoc 0000644 0000041 0000041 00000001056 12474517022 015765 0 ustar www-data www-data === 1.2.3 (2013-04-15)
* Fixed performance issue with large number of rows (thanks Kaoru Maeda)
=== 1.2.2 (2010-03-29)
* Fixed Ruby 1.9 warnings on shadowed outer local variables (thanks Claudio Bustos)
=== 1.2.1 (2010-01-05)
* Initialize a Text::Table with an empty array for its rows as default.
=== 1.2.0 (2010-01-05)
* Added an easy way to align columns.
* Fixed compatibility with Ruby 1.8.6
=== 1.1.0 (2009-12-28)
* Centered headers by default.
* Revamped specs and made them more extensive.
=== 1.0.1 (2009-12-21)
* Initial stable release.
text-table-1.2.4/spec/ 0000755 0000041 0000041 00000000000 12474517022 014555 5 ustar www-data www-data text-table-1.2.4/spec/spec_helper.rb 0000644 0000041 0000041 00000000335 12474517022 017374 0 ustar www-data www-data $LOAD_PATH.unshift(File.dirname(__FILE__))
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
require 'text-table'
require 'rspec'
require 'rspec/autorun'
def deindent(table)
table.gsub(/^\s*/, '')
end
text-table-1.2.4/spec/cell_spec.rb 0000644 0000041 0000041 00000001160 12474517022 017031 0 ustar www-data www-data require 'spec_helper'
describe Text::Table::Cell do
before(:each) do
@table = Text::Table.new :rows => [[1, {:value => 2, :colspan => 2}, 3]]
@cell = @table.text_table_rows.first.cells.first
end
it "should be left justified by default" do
@cell.align.should == :left
end
it "should span 1 column by default" do
@cell.colspan == 1
end
it "should return correct column index" do
@table.text_table_rows.first.cells[0].column_index.should == 0
@table.text_table_rows.first.cells[1].column_index.should == 1
@table.text_table_rows.first.cells[2].column_index.should == 3
end
end
text-table-1.2.4/spec/integration_helper.rb 0000644 0000041 0000041 00000000512 12474517022 020762 0 ustar www-data www-data require 'spec_helper'
RSpec.configure do |config|
config.before do
@head = %w( a bb ccc dddd )
@rows = [
%w( aa bbb cccc d ),
%w( aaa bbbb c dd ),
]
@foot = %w( aaaa b cc ddd )
@table = Text::Table.new :rows => @rows, :head => @head, :foot => @foot
end
end
text-table-1.2.4/spec/integration/ 0000755 0000041 0000041 00000000000 12474517022 017100 5 ustar www-data www-data text-table-1.2.4/spec/integration/alignment_spec.rb 0000644 0000041 0000041 00000011473 12474517022 022423 0 ustar www-data www-data require 'integration_helper'
describe Text::Table do
let(:table) { Text::Table.new :rows => rows, :head => head, :foot => foot }
let(:rows) { @rows }
let(:head) { @head }
let(:foot) { @foot }
subject { table.to_s }
describe 'header alignment' do
let(:head) { @head.map { |heading| { :value => heading, :align => align } } }
let(:foot) { nil }
context 'when left' do
let(:align) { :left }
it { should == deindent(%q{
+-----+------+------+------+
| a | bb | ccc | dddd |
+-----+------+------+------+
| aa | bbb | cccc | d |
| aaa | bbbb | c | dd |
+-----+------+------+------+
}) }
end
context 'when center' do
let(:align) { :center }
it { should == deindent(%q{
+-----+------+------+------+
| a | bb | ccc | dddd |
+-----+------+------+------+
| aa | bbb | cccc | d |
| aaa | bbbb | c | dd |
+-----+------+------+------+
}) }
end
context 'when right' do
let(:align) { :right }
it { should == deindent(%q{
+-----+------+------+------+
| a | bb | ccc | dddd |
+-----+------+------+------+
| aa | bbb | cccc | d |
| aaa | bbbb | c | dd |
+-----+------+------+------+
}) }
end
end
describe 'cell alignment' do
let(:rows) { @rows.map { |row| row.map { |cell| { :value => cell, :align => align } } } }
context 'when left' do
let(:align) { :left }
it { should == deindent(%q{
+------+------+------+------+
| a | bb | ccc | dddd |
+------+------+------+------+
| aa | bbb | cccc | d |
| aaa | bbbb | c | dd |
+------+------+------+------+
| aaaa | b | cc | ddd |
+------+------+------+------+
}) }
end
context 'when center' do
let(:align) { :center }
it { should == deindent(%q{
+------+------+------+------+
| a | bb | ccc | dddd |
+------+------+------+------+
| aa | bbb | cccc | d |
| aaa | bbbb | c | dd |
+------+------+------+------+
| aaaa | b | cc | ddd |
+------+------+------+------+
}) }
end
context 'when right' do
let(:align) { :right }
it { should == deindent(%q{
+------+------+------+------+
| a | bb | ccc | dddd |
+------+------+------+------+
| aa | bbb | cccc | d |
| aaa | bbbb | c | dd |
+------+------+------+------+
| aaaa | b | cc | ddd |
+------+------+------+------+
}) }
end
end
describe 'footer alignment' do
let(:head) { nil }
let(:foot) { @foot.map { |footing| { :value => footing, :align => align } } }
context 'when left' do
let(:align) { :left }
it { should == deindent(%q{
+------+------+------+-----+
| aa | bbb | cccc | d |
| aaa | bbbb | c | dd |
+------+------+------+-----+
| aaaa | b | cc | ddd |
+------+------+------+-----+
}) }
end
context 'when center' do
let(:align) { :center }
it { should == deindent(%q{
+------+------+------+-----+
| aa | bbb | cccc | d |
| aaa | bbbb | c | dd |
+------+------+------+-----+
| aaaa | b | cc | ddd |
+------+------+------+-----+
}) }
end
context 'when right' do
let(:align) { :right }
it { should == deindent(%q{
+------+------+------+-----+
| aa | bbb | cccc | d |
| aaa | bbbb | c | dd |
+------+------+------+-----+
| aaaa | b | cc | ddd |
+------+------+------+-----+
}) }
end
end
describe 'table-wide alignment' do
context 'of columns' do
before do
table.rows[1][2] = {:value => 'c', :align => :center}
table.rows << [{:value => 'x', :colspan => 2}, 'c', 'd']
table.rows << :separator
table.rows << ['a', 'b', {:value => 'x', :colspan => 2}]
table.align_column 2, :right
table.align_column 3, :right
end
it { should == deindent(%q{
+------+------+------+------+
| a | bb | ccc | dddd |
+------+------+------+------+
| aa | bbb | cccc | d |
| aaa | bbbb | c | dd |
| x | c | d |
+------+------+------+------+
| a | b | x |
+------+------+------+------+
| aaaa | b | cc | ddd |
+------+------+------+------+
}) }
end
context 'of rows' do
pending
end
context 'of headers' do
pending
end
context 'of footers' do
pending
end
end
end
text-table-1.2.4/spec/integration/performance_spec.rb 0000644 0000041 0000041 00000000624 12474517022 022742 0 ustar www-data www-data require 'spec_helper'
require 'benchmark'
describe Text::Table, 'performance' do
it 'is linear relative to row count' do
base = time_to_render_num_of_rows 1_000
time = time_to_render_num_of_rows 10_000
time.should_not > base * 20
end
def time_to_render_num_of_rows(num)
GC.start
Benchmark.measure {
Text::Table.new(:rows => Array.new(num)).to_s
}.total
end
end
text-table-1.2.4/spec/integration/column_spans_spec.rb 0000644 0000041 0000041 00000015067 12474517022 023151 0 ustar www-data www-data require 'integration_helper'
describe Text::Table do
subject { table.to_s }
let(:table) { Text::Table.new :rows => @rows, :head => @head, :foot => @foot }
describe 'first column spanned' do
context '2 cells wide' do
before do
table.rows << [{ :value => 'x', :colspan => 2, :align => align }, 'c', 'd']
end
context 'aligned to the left' do
let(:align) { :left }
it { should == deindent(%q{
+------+------+------+------+
| a | bb | ccc | dddd |
+------+------+------+------+
| aa | bbb | cccc | d |
| aaa | bbbb | c | dd |
| x | c | d |
+------+------+------+------+
| aaaa | b | cc | ddd |
+------+------+------+------+
}) }
end
context 'center aligned' do
let(:align) { :center }
it { should == deindent(%q{
+------+------+------+------+
| a | bb | ccc | dddd |
+------+------+------+------+
| aa | bbb | cccc | d |
| aaa | bbbb | c | dd |
| x | c | d |
+------+------+------+------+
| aaaa | b | cc | ddd |
+------+------+------+------+
}) }
end
context 'aligned to the right' do
let(:align) { :right }
it { should == deindent(%q{
+------+------+------+------+
| a | bb | ccc | dddd |
+------+------+------+------+
| aa | bbb | cccc | d |
| aaa | bbbb | c | dd |
| x | c | d |
+------+------+------+------+
| aaaa | b | cc | ddd |
+------+------+------+------+
}) }
end
end
context '3 cells wide' do
before do
table.rows << [{ :value => 'x', :colspan => 3, :align => align }, 'd']
end
context 'aligned to the left' do
let(:align) { :left }
it { should == deindent(%q{
+------+------+------+------+
| a | bb | ccc | dddd |
+------+------+------+------+
| aa | bbb | cccc | d |
| aaa | bbbb | c | dd |
| x | d |
+------+------+------+------+
| aaaa | b | cc | ddd |
+------+------+------+------+
}) }
end
context 'center aligned' do
let(:align) { :center }
it { should == deindent(%q{
+------+------+------+------+
| a | bb | ccc | dddd |
+------+------+------+------+
| aa | bbb | cccc | d |
| aaa | bbbb | c | dd |
| x | d |
+------+------+------+------+
| aaaa | b | cc | ddd |
+------+------+------+------+
}) }
end
context 'aligned to the right' do
let(:align) { :right }
it { should == deindent(%q{
+------+------+------+------+
| a | bb | ccc | dddd |
+------+------+------+------+
| aa | bbb | cccc | d |
| aaa | bbbb | c | dd |
| x | d |
+------+------+------+------+
| aaaa | b | cc | ddd |
+------+------+------+------+
}) }
end
end
end
describe 'last column spanned' do
context '2 cells wide' do
before do
table.rows << ['a', 'b', { :value => 'x', :colspan => 2, :align => align }]
end
context 'aligned to the left' do
let(:align) { :left }
it { should == deindent(%q{
+------+------+------+------+
| a | bb | ccc | dddd |
+------+------+------+------+
| aa | bbb | cccc | d |
| aaa | bbbb | c | dd |
| a | b | x |
+------+------+------+------+
| aaaa | b | cc | ddd |
+------+------+------+------+
}) }
end
context 'center aligned' do
let(:align) { :center }
it { should == deindent(%q{
+------+------+------+------+
| a | bb | ccc | dddd |
+------+------+------+------+
| aa | bbb | cccc | d |
| aaa | bbbb | c | dd |
| a | b | x |
+------+------+------+------+
| aaaa | b | cc | ddd |
+------+------+------+------+
}) }
end
context 'aligned to the right' do
let(:align) { :right }
it { should == deindent(%q{
+------+------+------+------+
| a | bb | ccc | dddd |
+------+------+------+------+
| aa | bbb | cccc | d |
| aaa | bbbb | c | dd |
| a | b | x |
+------+------+------+------+
| aaaa | b | cc | ddd |
+------+------+------+------+
}) }
end
end
context '3 cells wide' do
before do
table.rows << ['a', { :value => 'x', :colspan => 3, :align => align }]
end
context 'aligned to the left' do
let(:align) { :left }
it { should == deindent(%q{
+------+------+------+------+
| a | bb | ccc | dddd |
+------+------+------+------+
| aa | bbb | cccc | d |
| aaa | bbbb | c | dd |
| a | x |
+------+------+------+------+
| aaaa | b | cc | ddd |
+------+------+------+------+
}) }
end
context 'center aligned' do
let(:align) { :center }
it { should == deindent(%q{
+------+------+------+------+
| a | bb | ccc | dddd |
+------+------+------+------+
| aa | bbb | cccc | d |
| aaa | bbbb | c | dd |
| a | x |
+------+------+------+------+
| aaaa | b | cc | ddd |
+------+------+------+------+
}) }
end
context 'aligned to the right' do
let(:align) { :right }
it { should == deindent(%q{
+------+------+------+------+
| a | bb | ccc | dddd |
+------+------+------+------+
| aa | bbb | cccc | d |
| aaa | bbbb | c | dd |
| a | x |
+------+------+------+------+
| aaaa | b | cc | ddd |
+------+------+------+------+
}) }
end
end
end
end
text-table-1.2.4/spec/integration/parts_spec.rb 0000644 0000041 0000041 00000003033 12474517022 021567 0 ustar www-data www-data require 'integration_helper'
describe Text::Table do
let(:table) { Text::Table.new :rows => rows, :head => head, :foot => foot }
let(:rows) { @rows }
let(:head) { nil }
let(:foot) { nil }
subject { table.to_s }
describe 'rows' do
it { should == deindent(%q{
+-----+------+------+----+
| aa | bbb | cccc | d |
| aaa | bbbb | c | dd |
+-----+------+------+----+
}) }
context 'when nothing is passed into the contructor' do
let(:rows) { nil }
it 'is an empty array' do
table.rows.should == []
end
end
context 'with unequal number of cells' do
pending
end
end
describe 'head' do
let(:head) { @head }
it { should == deindent(%q{
+-----+------+------+------+
| a | bb | ccc | dddd |
+-----+------+------+------+
| aa | bbb | cccc | d |
| aaa | bbbb | c | dd |
+-----+------+------+------+
}) }
end
describe 'foot' do
let(:foot) { @foot }
it { should == deindent(%q{
+------+------+------+-----+
| aa | bbb | cccc | d |
| aaa | bbbb | c | dd |
+------+------+------+-----+
| aaaa | b | cc | ddd |
+------+------+------+-----+
}) }
end
describe 'separators' do
let(:rows) { @rows.insert(1, :separator) }
it { should == deindent(%q{
+-----+------+------+----+
| aa | bbb | cccc | d |
+-----+------+------+----+
| aaa | bbbb | c | dd |
+-----+------+------+----+
}) }
end
end
text-table-1.2.4/spec/integration/boundaries_spec.rb 0000644 0000041 0000041 00000007136 12474517022 022601 0 ustar www-data www-data require 'integration_helper'
describe Text::Table do
let(:table) { Text::Table.new :rows => @rows, :head => @head, :foot => @foot,
:horizontal_boundary => horizontal_boundary,
:vertical_boundary => vertical_boundary,
:boundary_intersection => boundary_intersection,
:horizontal_padding => horizontal_padding }
let(:horizontal_boundary) { nil }
let(:vertical_boundary) { nil }
let(:boundary_intersection) { nil }
let(:horizontal_padding) { nil }
subject { table.to_s }
describe 'horizontal boundaries' do
context 'when ":"' do
let(:horizontal_boundary) { ':' }
it { should == deindent(%q{
+------+------+------+------+
: a : bb : ccc : dddd :
+------+------+------+------+
: aa : bbb : cccc : d :
: aaa : bbbb : c : dd :
+------+------+------+------+
: aaaa : b : cc : ddd :
+------+------+------+------+
}) }
end
context 'when "||" and boundary intersection is "++"' do
let(:horizontal_boundary) { '||' }
let(:boundary_intersection) { '++' }
it { should == deindent(%q{
++------++------++------++------++
|| a || bb || ccc || dddd ||
++------++------++------++------++
|| aa || bbb || cccc || d ||
|| aaa || bbbb || c || dd ||
++------++------++------++------++
|| aaaa || b || cc || ddd ||
++------++------++------++------++
}) }
context 'with spanned cells' do
before do
table.rows << :separator
table.rows << [{ :value => 'x', :colspan => 2, :align => :right }, 'c', 'd']
end
it { should == deindent(%q{
++------++------++------++------++
|| a || bb || ccc || dddd ||
++------++------++------++------++
|| aa || bbb || cccc || d ||
|| aaa || bbbb || c || dd ||
++------++------++------++------++
|| x || c || d ||
++------++------++------++------++
|| aaaa || b || cc || ddd ||
++------++------++------++------++
}) }
end
end
end
describe 'vertical boundaries when "="' do
let(:vertical_boundary) { '=' }
it { should == deindent(%q{
+======+======+======+======+
| a | bb | ccc | dddd |
+======+======+======+======+
| aa | bbb | cccc | d |
| aaa | bbbb | c | dd |
+======+======+======+======+
| aaaa | b | cc | ddd |
+======+======+======+======+
}) }
end
describe 'boundary intersections when "*"' do
let(:boundary_intersection) { '*' }
it { should == deindent(%q{
*------*------*------*------*
| a | bb | ccc | dddd |
*------*------*------*------*
| aa | bbb | cccc | d |
| aaa | bbbb | c | dd |
*------*------*------*------*
| aaaa | b | cc | ddd |
*------*------*------*------*
}) }
end
describe 'horizantal padding when 3 spaces' do
let(:horizontal_padding) { 3 }
it { should == deindent(%q{
+----------+----------+----------+----------+
| a | bb | ccc | dddd |
+----------+----------+----------+----------+
| aa | bbb | cccc | d |
| aaa | bbbb | c | dd |
+----------+----------+----------+----------+
| aaaa | b | cc | ddd |
+----------+----------+----------+----------+
}) }
end
end
text-table-1.2.4/spec/enumerable_spec.rb 0000644 0000041 0000041 00000004010 12474517022 020226 0 ustar www-data www-data require 'spec_helper'
describe Enumerable do
describe Array do
before(:each) do
@arr = [
[11, 2, 3333],
[44, 56, 6],
[7, 888, 99],
]
end
it "to Text::Table" do
@arr.to_text_table.to_s.should == deindent(%q{
+----+-----+------+
| 11 | 2 | 3333 |
| 44 | 56 | 6 |
| 7 | 888 | 99 |
+----+-----+------+
})
end
it "to Text::Table using flat array" do
[11, 44, 7].to_text_table.to_s.should == deindent(%q{
+----+
| 11 |
| 44 |
| 7 |
+----+
})
end
it "to Text::Table, setting first row as head" do
@arr.to_text_table(:first_row_is_head => true).to_s.should == deindent(%q{
+----+-----+------+
| 11 | 2 | 3333 |
+----+-----+------+
| 44 | 56 | 6 |
| 7 | 888 | 99 |
+----+-----+------+
})
end
it "to Text::Table, setting last row as foot" do
@arr.to_text_table(:last_row_is_foot => true).to_s.should == deindent(%q{
+----+-----+------+
| 11 | 2 | 3333 |
| 44 | 56 | 6 |
+----+-----+------+
| 7 | 888 | 99 |
+----+-----+------+
})
end
end
describe Hash do
before(:each) do
@hsh = {
:k => 'vv',
'k' => :vv
}
end
it "to Text::Table" do
@hsh.to_text_table.to_s.should == deindent(%q{
+---+----+
| k | vv |
| k | vv |
+---+----+
})
end
it "to Text::Table, setting first row as head" do
@hsh.to_text_table(:first_row_is_head => true).to_s.should == deindent(%q{
+---+----+
| k | vv |
+---+----+
| k | vv |
+---+----+
})
end
it "to Text::Table, setting last row as foot" do
@hsh.to_text_table(:last_row_is_foot => true).to_s.should == deindent(%q{
+---+----+
| k | vv |
+---+----+
| k | vv |
+---+----+
})
end
end
end
text-table-1.2.4/README.rdoc 0000644 0000041 0000041 00000012663 12474517022 015441 0 ustar www-data www-data = text-table
{
}[https://rubygems.org/gems/text-table]
{
}[http://travis-ci.org/aptinio/text-table]
{
}[https://codeclimate.com/github/aptinio/text-table]
A feature-rich, easy-to-use plain text table formatter.
== Introduction
Allows you to easily create and format plain text tables,
useful when working with the terminal
or when you want to quickly print formatted tables to a dot-matrix printer.
Text::Table is compatible with Ruby 1.8.6, 1.8.7 and 1.9.1 and includes a comprehensive test suite.
== Install
gem install text-table
== Examples
require 'text-table'
table = Text::Table.new
table.head = ['A', 'B']
table.rows = [['a1', 'b1']]
table.rows << ['a2', 'b2']
table.to_s
# +----+----+
# | A | B |
# +----+----+
# | a1 | b1 |
# | a2 | b2 |
# +----+----+
You can also pass an options hash when instantiating a Text::Table:
table = Text::Table.new(:head => ['A', 'B'], :rows => [['a1', 'b1'], ['a2', 'b2']])
== Calling the to_table Method
Just call the to_table method (or to_text_table if the former is already defined) on Arrays (and other Enumerables).
array = [
['Student', 'Mid-Terms', 'Finals'],
['Sam', 94, 93],
['Jane', 92, 99],
['Average', 93, 96]
]
puts array.to_table
# +---------+-----------+--------+
# | Student | Mid-Terms | Finals |
# | Sam | 94 | 93 |
# | Jane | 92 | 99 |
# | Average | 93 | 96 |
# +---------+-----------+--------+
You could specify that the first row is the table heading.
puts array.to_table(:first_row_is_head => true)
# +---------+-----------+--------+
# | Student | Mid-Terms | Finals |
# +---------+-----------+--------+
# | Sam | 94 | 93 |
# | Jane | 92 | 99 |
# | Average | 93 | 96 |
# +---------+-----------+--------+
You could also specify that the last row is the table footer.
puts array.to_table(:first_row_is_head => true, :last_row_is_foot => true)
# +---------+-----------+--------+
# | Student | Mid-Terms | Finals |
# +---------+-----------+--------+
# | Sam | 94 | 93 |
# | Jane | 92 | 99 |
# +---------+-----------+--------+
# | Average | 93 | 96 |
# +---------+-----------+--------+
== Aligning Cells and Spanning Columns
Alignment and column span can be specified by passing a cell as a Hash object.
The acceptable aligments are :left, :center and :right.
Cells and footers are aligned to the left by default, while headers are centered by default.
table = Text::Table.new
table.head = ['Heading A', 'Heading B']
table.rows << ['a1', 'b1']
table.rows << ['a2', {:value => 'b2', :align => :right}]
table.rows << ['a3', 'b3']
table.rows << [{:value => 'a4', :colspan => 2, :align => :center}]
puts table
# +-----------+-----------+
# | Heading A | Heading B |
# +-----------+-----------+
# | a1 | b1 |
# | a2 | b2 |
# | a3 | b3 |
# | a4 |
# +-----------+-----------+
There's also an easy way to align columns:
table = Text::Table.new :rows => [%w(a bb), %w(aa bbb), %w(aaa b)]
puts table
# +-----+-----+
# | a | bb |
# | aa | bbb |
# | aaa | b |
# +-----+-----+
table.align_column 2, :right
# +-----+-----+
# | a | bb |
# | aa | bbb |
# | aaa | b |
# +-----+-----+
Note that headers, spanned cells and cells with explicit alignments are not affected by align_column.
== Adding a Separator
You can add a separator by inserting :separator symbols between the rows.
Text::Table.new :rows => [
['a', 'b'],
['c', 'd'],
:separator,
['e', 'f'],
:separator,
['g', 'h']
]
# +---+---+
# | a | b |
# | c | d |
# +---+---+
# | e | f |
# +---+---+
# | g | h |
# +---+---+
== Other Options
Cell padding and table boundaries can be modified.
Text::Table.new :rows => [['a', 'b'], ['c', 'd']],
:horizontal_padding => 3,
:vertical_boundary => '=',
:horizontal_boundary => ':',
:boundary_intersection => 'O'
# O=======O=======O
# : a : b :
# : c : d :
# O=======O=======O
== Special Thanks
This project was inspired by visionmedia's terminal-table, and to a lesser-extent, by prawn, ruport and hirb.
I've decided to start a new project, primarily as an exercise, and to be able to model-out the classes differently.
Thanks to the authors and contributors of these projects.
== Contributors
* Claudio Bustos (clbustos[http://github.com/clbustos])
* Fix Ruby 1.9 warnings on shadowed outer local variables
* Kaoru Maeda (mad-p[https://github.com/mad-p])
* Fixed performance issue with large number of rows
== Copyright
Copyright (c) 2009 Aaron Tinio. See LICENSE for details.
text-table-1.2.4/.travis.yml 0000644 0000041 0000041 00000000236 12474517022 015735 0 ustar www-data www-data language: ruby
rvm:
- "1.8.7"
- "1.9.2"
- "1.9.3"
- "2.0.0"
- jruby-18mode
- jruby-19mode
- rbx-18mode
- rbx-19mode
script: bundle exec rspec
text-table-1.2.4/lib/ 0000755 0000041 0000041 00000000000 12474517022 014371 5 ustar www-data www-data text-table-1.2.4/lib/text-table.rb 0000644 0000041 0000041 00000000165 12474517022 016771 0 ustar www-data www-data %w(table row cell enumerable symbol).each do |lib|
require File.join(File.dirname(__FILE__), 'text-table', lib)
end text-table-1.2.4/lib/text-table/ 0000755 0000041 0000041 00000000000 12474517022 016442 5 ustar www-data www-data text-table-1.2.4/lib/text-table/table.rb 0000644 0000041 0000041 00000015022 12474517022 020056 0 ustar www-data www-data module Text #:nodoc:
class Table
# An array of table headers
#
attr_accessor :head
# An array of arrays (rows or separators)
#
attr_accessor :rows
# An array representing the foot of the table
attr_accessor :foot
# The vertical boundary. Default is "-"
#
attr_accessor :vertical_boundary
# The horizontal boundary. Default is "|"
#
attr_accessor :horizontal_boundary
# The boundary intersection. Default is "+"
#
attr_accessor :boundary_intersection
# The amount of padding (spaces) added to the left and right of cell contents. Default is 1
#
attr_accessor :horizontal_padding
# You could create a Text::Table object by passing an options hash:
#
# table = Text::Table.new(:head => ['A', 'B'], :rows => [['a1', 'b1'], ['a2', 'b2']])
#
# Or by passing a block:
#
# table = Text::Table.new do |t|
# t.head = ['A', 'B']
# t.rows = [['a1', 'b1']]
# t.rows << ['a2', 'b2']
# end
#
# table.to_s
#
# # +----+----+
# # | A | B |
# # +----+----+
# # | a1 | b1 |
# # | a2 | b2 |
# # +----+----+
#
#
# ==== Aligning Cells and Spanning Columns
#
# Alignment and column span can be specified by passing a cell as a Hash object.
#
# The acceptable aligments are :left, :center and :right.
#
# Cells and footers are aligned to the left by default, while headers are centered by default.
#
# table = Text::Table.new do |t|
# t.head = ['Heading A', 'Heading B']
# t.rows << ['a1', 'b1']
# t.rows << ['a2', {:value => 'b2', :align => :right}]
# t.rows << ['a3', 'b3']
# t.rows << [{:value => 'a4', :colspan => 2, :align => :center}]
# end
#
# puts table
#
# # +-----------+-----------+
# # | Heading A | Heading B |
# # +-----------+-----------+
# # | a1 | b1 |
# # | a2 | b2 |
# # | a3 | b3 |
# # | a4 |
# # +-----------+-----------+
#
#
# ==== Adding a Separator
#
# You can add a separator by inserting :separator symbols between the rows.
#
# Text::Table.new :rows => [
# ['a', 'b'],
# ['c', 'd'],
# :separator,
# ['e', 'f'],
# :separator,
# ['g', 'h']
# ]
#
# # +---+---+
# # | a | b |
# # | c | d |
# # +---+---+
# # | e | f |
# # +---+---+
# # | g | h |
# # +---+---+
#
#
# ==== Other Options
#
# Cell padding and table boundaries can be modified.
#
# Text::Table.new :rows => [['a', 'b'], ['c', 'd']],
# :horizontal_padding => 3,
# :vertical_boundary => '=',
# :horizontal_boundary => ':',
# :boundary_intersection => 'O'
#
# # O=======O=======O
# # : a : b :
# # : c : d :
# # O=======O=======O
#
def initialize(options = {})
@vertical_boundary = options[:vertical_boundary ] || '-'
@horizontal_boundary = options[:horizontal_boundary ] || '|'
@boundary_intersection = options[:boundary_intersection] || '+'
@horizontal_padding = options[:horizontal_padding ] || 1
@head = options[:head]
@rows = options[:rows] || []
@foot = options[:foot]
yield self if block_given?
end
def text_table_rows #:nodoc:
rows.to_a.map {|row_input| Row.new(row_input, self)}
end
def text_table_head #:nodoc:
Row.new(
head.map {|h| hashify(h, {:align => :center})},
self
) if head
end
def text_table_foot #:nodoc:
Row.new(foot, self) if foot
end
def all_text_table_rows #:nodoc:
all = text_table_rows
all.unshift text_table_head if head
all << text_table_foot if foot
all
end
def column_widths #:nodoc:
@column_widths ||= \
all_text_table_rows.reject {|row| row.cells == :separator}.map do |row|
row.cells.map {|cell| [(cell.value.length/cell.colspan.to_f).ceil] * cell.colspan}.flatten
end.transpose.map(&:max)
end
def separator #:nodoc:
([@boundary_intersection] * 2).join(
column_widths.map {|column_width| @vertical_boundary * (column_width + 2*@horizontal_padding)}.join(@boundary_intersection)
) + "\n"
end
# Renders a pretty plain-text table.
#
def to_s
rendered_rows = [separator] + text_table_rows.map(&:to_s) + [separator]
rendered_rows.unshift [separator, text_table_head.to_s] if head
rendered_rows << [text_table_foot.to_s, separator] if foot
rendered_rows.join
end
# Aligns the cells and the footer of a column.
#
# table = Text::Table.new :rows => [%w(a bb), %w(aa bbb), %w(aaa b)]
# puts table
#
# # +-----+-----+
# # | a | bb |
# # | aa | bbb |
# # | aaa | b |
# # +-----+-----+
#
# table.align_column 2, :right
#
# # +-----+-----+
# # | a | bb |
# # | aa | bbb |
# # | aaa | b |
# # +-----+-----+
#
# Note that headers, spanned cells and cells with explicit alignments are not affected by align_column.
#
def align_column(column_number, alignment)
set_alignment = Proc.new do |row, column_number_block, alignment_block|
cell = row.find do |cell_row|
row[0...row.index(cell_row)].map {|c| c.is_a?(Hash) ? c[:colspan] || 1 : 1}.inject(0, &:+) == column_number_block - 1
end
row[row.index(cell)] = hashify(cell, {:align => alignment_block}) if cell and not(cell.is_a?(Hash) && cell[:colspan].to_i > 0)
end
rows.each do |row|
next if row == :separator
set_alignment.call(row, column_number, alignment)
end
set_alignment.call(foot, column_number, alignment) if foot
return self
end
def hashify(cell, defaults = {}) #:nodoc:
defaults.merge(cell.is_a?(Hash) ? cell : {:value => cell})
end
def inspect
"#<#{self.class}:0x#{self.__id__.to_s(16)}>"
end
end
end
text-table-1.2.4/lib/text-table/version.rb 0000644 0000041 0000041 00000000072 12474517022 020453 0 ustar www-data www-data module Text
class Table
VERSION = '1.2.4'
end
end
text-table-1.2.4/lib/text-table/enumerable.rb 0000644 0000041 0000041 00000004023 12474517022 021105 0 ustar www-data www-data module Enumerable
# Returns a new Text::Table object with the elements as the rows.
#
# ==== Options
# :first_row_is_head:: when set to true, the first row becomes the table heading
# :last_row_is_foot:: when set to true, the last row becomes the table footer
#
# ==== Examples
#
# require 'rubygems'
# require 'text-table'
#
# array = [
# ['Student', 'Mid-Terms', 'Finals'],
# ['Sam', 94, 93],
# ['Jane', 92, 99],
# ['Average', 93, 96]
# ]
#
# puts array.to_text_table
#
# # +---------+-----------+--------+
# # | Student | Mid-Terms | Finals |
# # | Sam | 94 | 93 |
# # | Jane | 92 | 99 |
# # | Average | 93 | 96 |
# # +---------+-----------+--------+
#
# puts array.to_text_table(:first_row_is_head => true)
#
# # +---------+-----------+--------+
# # | Student | Mid-Terms | Finals |
# # +---------+-----------+--------+
# # | Sam | 94 | 93 |
# # | Jane | 92 | 99 |
# # | Average | 93 | 96 |
# # +---------+-----------+--------+
#
# puts array.to_text_table(:first_row_is_head => true, :last_row_is_foot => true)
#
# # +---------+-----------+--------+
# # | Student | Mid-Terms | Finals |
# # +---------+-----------+--------+
# # | Sam | 94 | 93 |
# # | Jane | 92 | 99 |
# # +---------+-----------+--------+
# # | Average | 93 | 96 |
# # +---------+-----------+--------+
#
def to_text_table(options = {})
table = Text::Table.new :rows => self.to_a.dup
table.head = table.rows.shift if options[:first_row_is_head]
table.foot = table.rows.pop if options[:last_row_is_foot]
table
end
alias_method :to_table, :to_text_table unless method_defined? :to_table
end text-table-1.2.4/lib/text-table/row.rb 0000644 0000041 0000041 00000001607 12474517022 017602 0 ustar www-data www-data module Text #:nodoc:
class Table
# A Text::Table::Row belongs to a Text::Table object and can have many Text::Table::Cell objects.
# It handles the rendering of rows and inserted separators.
#
class Row
attr_reader :table #:nodoc:
attr_reader :cells #:nodoc:
def initialize(row_input, table) #:nodoc:
@table = table
row_input = [row_input].flatten
@cells = row_input.first == :separator ? :separator : row_input.map do |cell_input|
Cell.new(cell_input.is_a?(Hash) ? cell_input.merge(:row => self) : {:value => cell_input}.merge(:row => self))
end
end
def to_s #:nodoc:
if cells == :separator
table.separator
else
([table.horizontal_boundary] * 2).join(
cells.map(&:to_s).join(table.horizontal_boundary)
) + "\n"
end
end
end
end
end text-table-1.2.4/lib/text-table/symbol.rb 0000644 0000041 0000041 00000000727 12474517022 020302 0 ustar www-data www-data unless :to_proc.respond_to?(:to_proc)
class Symbol
# Turns the symbol into a simple proc, which is especially useful for enumerations. Examples:
#
# # The same as people.collect { |p| p.name }
# people.collect(&:name)
#
# # The same as people.select { |p| p.manager? }.collect { |p| p.salary }
# people.select(&:manager?).collect(&:salary)
def to_proc
Proc.new { |*args| args.shift.__send__(self, *args) }
end
end
end text-table-1.2.4/lib/text-table/cell.rb 0000644 0000041 0000041 00000002471 12474517022 017712 0 ustar www-data www-data module Text #:nodoc:
class Table
class Cell
# The object whose to_s method is called when rendering the cell.
#
attr_accessor :value
# Text alignment. Acceptable values are :left (default),
# :center and :right
#
attr_accessor :align
# Positive integer specifying the number of columns spanned
#
attr_accessor :colspan
attr_reader :row #:nodoc:
def initialize(options = {}) #:nodoc:
@value = options[:value].to_s
@row = options[:row]
@align = options[:align ] || :left
@colspan = options[:colspan] || 1
end
def to_s #:nodoc:
([' ' * table.horizontal_padding]*2).join case align
when :left
value.ljust cell_width
when :right
value.rjust cell_width
when :center
value.center cell_width
end
end
def table #:nodoc:
row.table
end
def column_index #:nodoc:
row.cells[0...row.cells.index(self)].map(&:colspan).inject(0, &:+)
end
def cell_width #:nodoc:
(0...colspan).map {|i| table.column_widths[column_index + i]}.inject(&:+) + (colspan - 1)*(2*table.horizontal_padding + table.horizontal_boundary.length)
end
end
end
end text-table-1.2.4/metadata.yml 0000644 0000041 0000041 00000004436 12474517022 016135 0 ustar www-data www-data --- !ruby/object:Gem::Specification
name: text-table
version: !ruby/object:Gem::Version
version: 1.2.4
platform: ruby
authors:
- Aaron Tinio
autorequire:
bindir: bin
cert_chain: []
date: 2015-02-03 00:00:00.000000000 Z
dependencies:
- !ruby/object:Gem::Dependency
name: rspec
requirement: !ruby/object:Gem::Requirement
requirements:
- - "~>"
- !ruby/object:Gem::Version
version: '2'
type: :development
prerelease: false
version_requirements: !ruby/object:Gem::Requirement
requirements:
- - "~>"
- !ruby/object:Gem::Version
version: '2'
description: Allows you to easily create and format plain text tables, useful when
working with the terminal or when you want to quickly print formatted tables to
a dot-matrix printer.
email: aptinio@gmail.com
executables: []
extensions: []
extra_rdoc_files:
- LICENSE
- README.rdoc
files:
- ".document"
- ".gitignore"
- ".travis.yml"
- CHANGELOG.rdoc
- Gemfile
- LICENSE
- README.rdoc
- lib/text-table.rb
- lib/text-table/cell.rb
- lib/text-table/enumerable.rb
- lib/text-table/row.rb
- lib/text-table/symbol.rb
- lib/text-table/table.rb
- lib/text-table/version.rb
- spec/cell_spec.rb
- spec/enumerable_spec.rb
- spec/integration/alignment_spec.rb
- spec/integration/boundaries_spec.rb
- spec/integration/column_spans_spec.rb
- spec/integration/parts_spec.rb
- spec/integration/performance_spec.rb
- spec/integration_helper.rb
- spec/spec_helper.rb
- text-table.gemspec
homepage: https://github.com/aptinio/text-table
licenses:
- MIT
metadata: {}
post_install_message:
rdoc_options: []
require_paths:
- lib
required_ruby_version: !ruby/object:Gem::Requirement
requirements:
- - ">="
- !ruby/object:Gem::Version
version: '0'
required_rubygems_version: !ruby/object:Gem::Requirement
requirements:
- - ">="
- !ruby/object:Gem::Version
version: '0'
requirements: []
rubyforge_project:
rubygems_version: 2.4.5
signing_key:
specification_version: 4
summary: A feature-rich, easy-to-use plain text table formatter.
test_files:
- spec/cell_spec.rb
- spec/enumerable_spec.rb
- spec/integration/alignment_spec.rb
- spec/integration/boundaries_spec.rb
- spec/integration/column_spans_spec.rb
- spec/integration/parts_spec.rb
- spec/integration/performance_spec.rb
- spec/integration_helper.rb
- spec/spec_helper.rb
text-table-1.2.4/.gitignore 0000644 0000041 0000041 00000000064 12474517022 015613 0 ustar www-data www-data bin/
.bundle/
doc/
Gemfile.lock
tmp/
vendor/bundle/
text-table-1.2.4/LICENSE 0000644 0000041 0000041 00000002037 12474517022 014632 0 ustar www-data www-data Copyright (c) 2009 Aaron Tinio
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
text-table-1.2.4/.document 0000644 0000041 0000041 00000000057 12474517022 015444 0 ustar www-data www-data CHANGELOG.rdoc
lib/**/*.rb
README.rdoc
LICENSE