text-table-1.2.4/0000755000004100000410000000000012474517022013623 5ustar www-datawww-datatext-table-1.2.4/Gemfile0000644000004100000410000000004712474517022015117 0ustar www-datawww-datasource 'https://rubygems.org' gemspec text-table-1.2.4/text-table.gemspec0000644000004100000410000000147212474517022017245 0ustar www-datawww-datarequire 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.rdoc0000644000004100000410000000105612474517022015765 0ustar www-datawww-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/0000755000004100000410000000000012474517022014555 5ustar www-datawww-datatext-table-1.2.4/spec/spec_helper.rb0000644000004100000410000000033512474517022017374 0ustar www-datawww-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.rb0000644000004100000410000000116012474517022017031 0ustar www-datawww-datarequire '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.rb0000644000004100000410000000051212474517022020762 0ustar www-datawww-datarequire '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/0000755000004100000410000000000012474517022017100 5ustar www-datawww-datatext-table-1.2.4/spec/integration/alignment_spec.rb0000644000004100000410000001147312474517022022423 0ustar www-datawww-datarequire '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.rb0000644000004100000410000000062412474517022022742 0ustar www-datawww-datarequire '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.rb0000644000004100000410000001506712474517022023151 0ustar www-datawww-datarequire '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.rb0000644000004100000410000000303312474517022021567 0ustar www-datawww-datarequire '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.rb0000644000004100000410000000713612474517022022601 0ustar www-datawww-datarequire '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.rb0000644000004100000410000000401012474517022020226 0ustar www-datawww-datarequire '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.rdoc0000644000004100000410000001266312474517022015441 0ustar www-datawww-data= text-table {Gem Version}[https://rubygems.org/gems/text-table] {Build Status}[http://travis-ci.org/aptinio/text-table] {Code Climate}[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.yml0000644000004100000410000000023612474517022015735 0ustar www-datawww-datalanguage: 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/0000755000004100000410000000000012474517022014371 5ustar www-datawww-datatext-table-1.2.4/lib/text-table.rb0000644000004100000410000000016512474517022016771 0ustar www-datawww-data%w(table row cell enumerable symbol).each do |lib| require File.join(File.dirname(__FILE__), 'text-table', lib) endtext-table-1.2.4/lib/text-table/0000755000004100000410000000000012474517022016442 5ustar www-datawww-datatext-table-1.2.4/lib/text-table/table.rb0000644000004100000410000001502212474517022020056 0ustar www-datawww-datamodule 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.rb0000644000004100000410000000007212474517022020453 0ustar www-datawww-datamodule Text class Table VERSION = '1.2.4' end end text-table-1.2.4/lib/text-table/enumerable.rb0000644000004100000410000000402312474517022021105 0ustar www-datawww-datamodule 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 endtext-table-1.2.4/lib/text-table/row.rb0000644000004100000410000000160712474517022017602 0ustar www-datawww-datamodule 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 endtext-table-1.2.4/lib/text-table/symbol.rb0000644000004100000410000000072712474517022020302 0ustar www-datawww-dataunless :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 endtext-table-1.2.4/lib/text-table/cell.rb0000644000004100000410000000247112474517022017712 0ustar www-datawww-datamodule 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 endtext-table-1.2.4/metadata.yml0000644000004100000410000000443612474517022016135 0ustar www-datawww-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/.gitignore0000644000004100000410000000006412474517022015613 0ustar www-datawww-databin/ .bundle/ doc/ Gemfile.lock tmp/ vendor/bundle/ text-table-1.2.4/LICENSE0000644000004100000410000000203712474517022014632 0ustar www-datawww-dataCopyright (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/.document0000644000004100000410000000005712474517022015444 0ustar www-datawww-dataCHANGELOG.rdoc lib/**/*.rb README.rdoc LICENSE