Class: Terminal::Table

Inherits:
Object show all
Defined in:
lib/terminal-table/cell.rb,
lib/terminal-table/table.rb,
lib/terminal-table/heading.rb,
lib/terminal-table/version.rb,
lib/terminal-table/table_helper.rb

Defined Under Namespace

Modules: TableHelper Classes: Cell, Heading

Constant Summary collapse

Error =

– Exceptions ++

Class.new StandardError
VERSION =
'1.4.2'

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = {}, &block) ⇒ Table

Generates a ASCII table with the given options.



29
30
31
32
33
# File 'lib/terminal-table/table.rb', line 29

def initialize options = {}, &block
  @headings = options.fetch :headings, []
  @rows = options.fetch :rows, []
  yield_or_eval &block if block
end

Instance Attribute Details

#headingsObject

Headings array.



19
20
21
# File 'lib/terminal-table/table.rb', line 19

def headings
  @headings
end

#rowsObject

Return rows without separator rows.



24
25
26
# File 'lib/terminal-table/table.rb', line 24

def rows
  @rows
end

Instance Method Details

#==(other) ⇒ Object

Check if other is equal to self. other is considered equal if it contains the same headings and rows.



285
286
287
288
289
# File 'lib/terminal-table/table.rb', line 285

def == other
  if other.respond_to? :headings and other.respond_to? :rows
    headings == other.headings and rows == other.rows
  end
end

#add_row(row) ⇒ Object Also known as: <<

Add a row.



111
112
113
# File 'lib/terminal-table/table.rb', line 111

def add_row row
  @rows << row
end

#add_separatorObject

Add a separator.



119
120
121
# File 'lib/terminal-table/table.rb', line 119

def add_separator
  @rows << :separator
end

#align_column(n, alignment) ⇒ Object

Align column n to the given alignment of :center, :left, or :right.



253
254
255
256
257
258
# File 'lib/terminal-table/table.rb', line 253

def align_column n, alignment
  r = rows
  column(n).each_with_index do |col, i|
    r[i][n] = { :value => col, :alignment => alignment } unless Hash === col
  end
end

#all_rowsObject

Return rows including separator rows.



277
278
279
# File 'lib/terminal-table/table.rb', line 277

def all_rows
  @rows
end

#column(n) ⇒ Object

Return column n.



133
134
135
# File 'lib/terminal-table/table.rb', line 133

def column n
  rows.map { |row| row[n] }.compact 
end

#column_with_headings(n) ⇒ Object

Return n column including headings.



140
141
142
# File 'lib/terminal-table/table.rb', line 140

def column_with_headings n
  headings_with_rows.map { |row| row_with_hash(row)[n] }.compact
end

#columnsObject

Return columns.



178
179
180
# File 'lib/terminal-table/table.rb', line 178

def columns 
  (0...number_of_columns).map { |n| column n } 
end

#has_headings?Boolean

Weither or not any headings are present, since they are optional.

Returns:

  • (Boolean)


126
127
128
# File 'lib/terminal-table/table.rb', line 126

def has_headings?
  not headings.empty?
end

#headings_with_rowsObject

Return headings combined with rows.



263
264
265
# File 'lib/terminal-table/table.rb', line 263

def headings_with_rows
  [headings] + rows
end

#length_of_column(n) ⇒ Object

Return length of column n.



238
239
240
# File 'lib/terminal-table/table.rb', line 238

def length_of_column n
  length_of_largest_cell_in_column n      
end

#length_of_largest_cell_in_column(n) ⇒ Object

Return the length of the largest cell found within column n.



185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
# File 'lib/terminal-table/table.rb', line 185

def length_of_largest_cell_in_column n
  column_with_headings(n).map do |cell|
    if cell.is_a? Hash
      if cell[:colspan] && cell[:colspan] > 1
        if (cell[:value].to_s.length <= length_of_single_columns_where_multicolumn_is(cell[:start_index],cell[:colspan]))
          0
        else
          spacing_length = (3 * (cell[:colspan] - 1))
          length_in_columns = (cell[:value].to_s.length - spacing_length)
          (length_in_columns.to_f / cell[:colspan]).ceil
        end
      else
        cell[:value].to_s.length
      end
    else
      cell.to_s.length
    end
  end.sort.last
end

#length_of_largest_single_column_cell_in_column(n) ⇒ Object

Returns the length of the largest single column cell found within column n.



208
209
210
211
212
213
214
215
216
217
218
219
220
# File 'lib/terminal-table/table.rb', line 208

def length_of_largest_single_column_cell_in_column n
  column_with_headings(n).map do |cell|
    if cell.is_a? Hash
      if cell[:colspan] && cell[:colspan] > 1
        0
      else
        cell[:value].to_s.length
      end
    else
      cell.to_s.length
    end
  end.sort.last
end

#length_of_single_columns_where_multicolumn_is(n, length) ⇒ Object

Returns the length of the single columns starting from n and going through length columns.



225
226
227
228
229
230
231
232
233
# File 'lib/terminal-table/table.rb', line 225

def length_of_single_columns_where_multicolumn_is(n,length)
  total_length = 0
  spacing_length = (3 * (length - 1))
  total_length = total_length + spacing_length
  n.upto(n + length - 1) do |i|
    total_length = total_length + length_of_largest_single_column_cell_in_column(i)
  end
  return total_length
end

#number_of_columnsObject

Return total number of columns available.

Raises:



245
246
247
248
# File 'lib/terminal-table/table.rb', line 245

def number_of_columns
  return rows.first.length unless rows.empty?
  raise Error, 'your table needs some rows'
end

#renderObject Also known as: to_s

Render the table.



38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/terminal-table/table.rb', line 38

def render
  buffer = [separator, "\n"]
  if has_headings?
    buffer << render_headings
    buffer << "\n" << separator << "\n"
  end
  buffer << @rows.map do |row| 
    render_row(row)
  end.join("\n")
  buffer << "\n" << separator << "\n"
  buffer.join
end

#render_cell(cell, i) ⇒ Object

Render the given cell at index i.



86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/terminal-table/table.rb', line 86

def render_cell cell, i
  width = 0
  if cell.is_a?(Hash) and !cell[:colspan].nil?
    i.upto(i + cell[:colspan] - 1) do |col|
      width += length_of_column(col)
    end
    width += (cell[:colspan] - 1) * (Y.length + 2)
  else
    width = length_of_column(i)
  end
  Cell.new(width, cell).render
end

#render_headingsObject

Render headings.



55
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/terminal-table/table.rb', line 55

def render_headings
  Y + headings.map_with_index do |heading, i|
    width = 0
    if heading.is_a?(Hash) and !heading[:colspan].nil?
      i.upto(i + heading[:colspan] - 1) do |col|
        width += length_of_column(col)
      end
      width += (heading[:colspan] - 1) * (Y.length + 2)
    else
      width = length_of_column(i)
    end
    Heading.new( width, heading).render
  end.join(Y) + Y
end

#render_row(row) ⇒ Object

Render the given row.



73
74
75
76
77
78
79
80
81
# File 'lib/terminal-table/table.rb', line 73

def render_row row
  if row == :separator
    separator
  else
    Y + row.map_with_index do |cell, i|
      render_cell(cell, row_to_index(row, i))
    end.join(Y) + Y
  end
end

#row_to_index(row, index) ⇒ Object



162
163
164
165
166
167
168
169
170
171
172
173
# File 'lib/terminal-table/table.rb', line 162

def row_to_index row, index
  new_index = -1
  0.upto(index) do |i|
    column = row[i]
    if column.is_a?(Hash) && column[:colspan] && column[:colspan] > 1 && index != i
      new_index = new_index + column[:colspan]
    else
      new_index += 1
    end
  end
  return new_index
end

#row_with_hash(row) ⇒ Object



144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
# File 'lib/terminal-table/table.rb', line 144

def row_with_hash row
  # this method duplicates the multi-column columns in each column they are in
  index = 0
  row.inject [] do |columns, column|
    if column.is_a?(Hash) && column[:colspan] && column[:colspan] > 1
      column[:start_index] = index
      column[:colspan].times do
        columns << column
        index += 1
      end
    else
      columns << column
      index += 1
    end
    columns
  end
end

#separatorObject

Create a separator based on colum lengths.



102
103
104
105
106
# File 'lib/terminal-table/table.rb', line 102

def separator
  I + columns.collect_with_index do |col, i| 
    X * (length_of_column(i) + 2) 
  end.join(I) + I 
end