Class: Text::Table

Inherits:
Object
  • Object
show all
Defined in:
lib/text-table/row.rb,
lib/text-table/cell.rb,
lib/text-table/table.rb,
lib/text-table/version.rb

Defined Under Namespace

Classes: Cell, Row

Constant Summary collapse

VERSION =
'1.2.4'

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) {|_self| ... } ⇒ Table

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 <tt>:left</tt>, <tt>:center</tt> and <tt>:right</tt>.

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 <tt>:separator</tt> 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

Yields:

  • (_self)

Yield Parameters:

  • _self (Text::Table)

    the object that the method was called on



120
121
122
123
124
125
126
127
128
129
# File 'lib/text-table/table.rb', line 120

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

Instance Attribute Details

#boundary_intersectionObject

The boundary intersection. Default is “+



26
27
28
# File 'lib/text-table/table.rb', line 26

def boundary_intersection
  @boundary_intersection
end

#footObject

An array representing the foot of the table



14
15
16
# File 'lib/text-table/table.rb', line 14

def foot
  @foot
end

#headObject

An array of table headers



6
7
8
# File 'lib/text-table/table.rb', line 6

def head
  @head
end

#horizontal_boundaryObject

The horizontal boundary. Default is “|



22
23
24
# File 'lib/text-table/table.rb', line 22

def horizontal_boundary
  @horizontal_boundary
end

#horizontal_paddingObject

The amount of padding (spaces) added to the left and right of cell contents. Default is 1



30
31
32
# File 'lib/text-table/table.rb', line 30

def horizontal_padding
  @horizontal_padding
end

#rowsObject

An array of arrays (rows or separators)



10
11
12
# File 'lib/text-table/table.rb', line 10

def rows
  @rows
end

#vertical_boundaryObject

The vertical boundary. Default is “-



18
19
20
# File 'lib/text-table/table.rb', line 18

def vertical_boundary
  @vertical_boundary
end

Instance Method Details

#align_column(column_number, alignment) ⇒ Object

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 <tt>align_column</tt>.


196
197
198
199
200
201
202
203
204
205
206
207
208
209
# File 'lib/text-table/table.rb', line 196

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

#all_text_table_rowsObject

:nodoc:



146
147
148
149
150
151
# File 'lib/text-table/table.rb', line 146

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

#column_widthsObject

:nodoc:



153
154
155
156
157
158
# File 'lib/text-table/table.rb', line 153

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

#hashify(cell, defaults = {}) ⇒ Object

:nodoc:



211
212
213
# File 'lib/text-table/table.rb', line 211

def hashify(cell, defaults = {}) #:nodoc:
  defaults.merge(cell.is_a?(Hash) ? cell : {:value => cell})
end

#inspectObject



215
216
217
# File 'lib/text-table/table.rb', line 215

def inspect
  "#<#{self.class}:0x#{self.__id__.to_s(16)}>"
end

#separatorObject

:nodoc:



160
161
162
163
164
# File 'lib/text-table/table.rb', line 160

def separator #:nodoc:
  ([@boundary_intersection] * 2).join(
    column_widths.map {|column_width| @vertical_boundary * (column_width + 2*@horizontal_padding)}.join(@boundary_intersection)
  ) + "\n"
end

#text_table_footObject

:nodoc:



142
143
144
# File 'lib/text-table/table.rb', line 142

def text_table_foot #:nodoc:
  Row.new(foot, self) if foot
end

#text_table_headObject

:nodoc:



135
136
137
138
139
140
# File 'lib/text-table/table.rb', line 135

def text_table_head #:nodoc:
  Row.new(
    head.map {|h| hashify(h, {:align => :center})},
    self
  ) if head
end

#text_table_rowsObject

:nodoc:



131
132
133
# File 'lib/text-table/table.rb', line 131

def text_table_rows #:nodoc:
  rows.to_a.map {|row_input| Row.new(row_input, self)}
end

#to_sObject

Renders a pretty plain-text table.



168
169
170
171
172
173
# File 'lib/text-table/table.rb', line 168

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