lib/hirb/helpers/table.rb in hirb-0.2.2 vs lib/hirb/helpers/table.rb in hirb-0.2.3
- old
+ new
@@ -22,11 +22,12 @@
# +-----+--------+
#
# By default, the fields/columns are the keys of the first hash.
#--
# derived from http://gist.github.com/72234
-class Hirb::Helpers::Table
+module Hirb
+ class Helpers::Table
BORDER_LENGTH = 3 # " | " and "-+-" are the borders
class TooManyFieldsForWidthError < StandardError; end
class << self
@@ -42,31 +43,31 @@
# This doesn't count field borders as part of the total.
# [:number] When set to true, numbers rows by adding a :hirb_number column as the first column. Default is false.
# [:filters] A hash of fields and the filters that each row in the field must run through. The filter converts the cell's value by applying
# a given proc or an array containing a method and optional arguments to it.
# [:vertical] When set to true, renders a vertical table using Hirb::Helpers::VerticalTable. Default is false.
+ # [:all_fields] When set to true, renders fields in all rows. Valid only in rows that are hashes. Default is false.
# Examples:
# Hirb::Helpers::Table.render [[1,2], [2,3]]
# Hirb::Helpers::Table.render [[1,2], [2,3]], :field_lengths=>{0=>10}
# Hirb::Helpers::Table.render [{:age=>10, :weight=>100}, {:age=>80, :weight=>500}]
# Hirb::Helpers::Table.render [{:age=>10, :weight=>100}, {:age=>80, :weight=>500}], :headers=>{:weight=>"Weight(lbs)"}
# Hirb::Helpers::Table.render [{:age=>10, :weight=>100}, {:age=>80, :weight=>500}], :filters=>{:age=>[:to_f]}
def render(rows, options={})
- options.delete(:vertical) ? Hirb::Helpers::VerticalTable.render(rows, options) : new(rows, options).render
+ options.delete(:vertical) ? Helpers::VerticalTable.render(rows, options) : new(rows, options).render
rescue TooManyFieldsForWidthError
$stderr.puts "", "** Error: Too many fields for the current width. Configure your width " +
"and/or fields to avoid this error. Defaulting to a vertical table. **"
- Hirb::Helpers::VerticalTable.render(rows, options)
+ Helpers::VerticalTable.render(rows, options)
end
end
#:stopdoc:
def initialize(rows, options={})
@options = options
@options[:filters] ||= {}
- @fields = @options[:fields] ? @options[:fields].dup : ((rows[0].is_a?(Hash)) ? rows[0].keys.sort {|a,b| a.to_s <=> b.to_s} :
- rows[0].is_a?(Array) ? (0..rows[0].length - 1).to_a : [])
+ @fields = set_fields(rows)
@rows = setup_rows(rows)
@headers = @fields.inject({}) {|h,e| h[e] = e.to_s; h}
if @options.has_key?(:headers)
@headers = @options[:headers].is_a?(Hash) ? @headers.merge(@options[:headers]) :
(@options[:headers].is_a?(Array) ? array_to_indices_hash(@options[:headers]) : @options[:headers])
@@ -74,11 +75,24 @@
if @options[:number]
@headers[:hirb_number] = "number"
@fields.unshift :hirb_number
end
end
-
+
+ def set_fields(rows)
+ if @options[:fields]
+ @options[:fields].dup
+ else
+ if rows[0].is_a?(Hash)
+ keys = @options[:all_fields] ? rows.map {|e| e.keys}.flatten.uniq : rows[0].keys
+ keys.sort {|a,b| a.to_s <=> b.to_s}
+ else
+ rows[0].is_a?(Array) ? (0..rows[0].length - 1).to_a : []
+ end
+ end
+ end
+
def setup_rows(rows)
rows ||= []
rows = [rows] unless rows.is_a?(Array)
if rows[0].is_a?(Array)
rows = rows.inject([]) {|new_rows, row|
@@ -121,17 +135,17 @@
def render_border
'+-' + @fields.map {|f| '-' * @field_lengths[f] }.join('-+-') + '-+'
end
def format_cell(value, cell_width)
- text = value.length > cell_width ?
+ text = String.size(value) > cell_width ?
(
- (cell_width < 5) ? value.slice(0,cell_width) : value.slice(0, cell_width - 3) + '...'
+ (cell_width < 5) ? String.slice(value, 0, cell_width) : String.slice(value, 0, cell_width - 3) + '...'
) : value
- sprintf("%-#{cell_width}s", text)
+ String.ljust(text, cell_width)
end
-
+
def render_rows
@rows.map do |row|
row = '| ' + @fields.map {|f|
format_cell(row[f], @field_lengths[f])
}.join(' | ') + ' |'
@@ -146,11 +160,11 @@
def setup_field_lengths
@field_lengths = default_field_lengths
if @options[:field_lengths]
@field_lengths.merge!(@options[:field_lengths])
else
- table_max_width = @options.has_key?(:max_width) ? @options[:max_width] : Hirb::View.width
+ table_max_width = @options.has_key?(:max_width) ? @options[:max_width] : View.width
restrict_field_lengths(@field_lengths, table_max_width) if table_max_width
end
end
def restrict_field_lengths(field_lengths, max_width)
@@ -198,14 +212,14 @@
end
end
# find max length for each field; start with the headers
def default_field_lengths
- field_lengths = @headers ? @headers.inject({}) {|h,(k,v)| h[k] = v.length; h} : {}
+ field_lengths = @headers ? @headers.inject({}) {|h,(k,v)| h[k] = String.size(v); h} : {}
@rows.each do |row|
@fields.each do |field|
- len = row[field].length
+ len = String.size(row[field])
field_lengths[field] = len if len > field_lengths[field].to_i
end
end
field_lengths
end
@@ -237,5 +251,6 @@
def array_to_indices_hash(array)
array.inject({}) {|hash,e| hash[hash.size] = e; hash }
end
#:startdoc:
end
+end
\ No newline at end of file