lib/hirb/helpers/table.rb in hirb-0.3.6 vs lib/hirb/helpers/table.rb in hirb-0.4.0
- old
+ new
@@ -1,5 +1,6 @@
+# -*- encoding : utf-8 -*-
require 'hirb/helpers/table/filters'
require 'hirb/helpers/table/resizer'
module Hirb
# Base Table class from which other table classes inherit.
@@ -60,10 +61,18 @@
class Helpers::Table
BORDER_LENGTH = 3 # " | " and "-+-" are the borders
MIN_FIELD_LENGTH = 3
class TooManyFieldsForWidthError < StandardError; end
+ CHARS = {
+ :top => {:left => '+', :center => '+', :right => '+', :horizontal => '-',
+ :vertical => {:outside => '|', :inside => '|'} },
+ :middle => {:left => '+', :center => '+', :right => '+', :horizontal => '-'},
+ :bottom => {:left => '+', :center => '+', :right => '+', :horizontal => '-',
+ :vertical => {:outside => '|', :inside => '|'} }
+ }
+
class << self
# Main method which returns a formatted table.
# ==== Options:
# [*:fields*] An array which overrides the default fields and can be used to indicate field order.
@@ -84,10 +93,11 @@
# [*:header_filter*] A filter, like one in :filters, that is applied to all headers after the :headers option.
# [*:filter_any*] When set to true, any cell defaults to being filtered by its class in :filter_classes.
# Default Hirb::Helpers::Table.filter_any().
# [*:filter_classes*] Hash which maps classes to filters. Default is Hirb::Helpers::Table.filter_classes().
# [*:vertical*] When set to true, renders a vertical table using Hirb::Helpers::VerticalTable. Default is false.
+ # [*:unicode*] When set to true, renders a unicode table using Hirb::Helpers::UnicodeTable. Default is false.
# [*:all_fields*] When set to true, renders fields in all rows. Valid only in rows that are hashes. Default is false.
# [*:description*] When set to true, renders row count description at bottom. Default is true.
# [*:escape_special_chars*] When set to true, escapes special characters \n,\t,\r so they don't disrupt tables. Default is false for
# vertical tables and true for anything else.
# Examples:
@@ -97,13 +107,14 @@
# 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[:vertical] ? Helpers::VerticalTable.render(rows, options) :
+ options[:unicode] ? Helpers::UnicodeTable.render(rows, options) :
new(rows, options).render
rescue TooManyFieldsForWidthError
- $stderr.puts "", "** Error: Too many fields for the current width. Configure your width " +
+ $stderr.puts "", "** Hirb Warning: Too many fields for the current width. Configure your width " +
"and/or fields to avoid this error. Defaulting to a vertical table. **"
Helpers::VerticalTable.render(rows, options)
end
# A hash which maps a cell value's class to a filter. This serves to set a default filter per field if all of its
@@ -115,10 +126,14 @@
# Holds last table object created
attr_accessor :last_table
end
self.filter_classes = { Array=>:comma_join, Hash=>:inspect }
+ def chars
+ self.class.const_get(:CHARS)
+ end
+
#:stopdoc:
attr_accessor :width, :max_fields, :field_lengths, :fields
def initialize(rows, options={})
raise ArgumentError, "Table must be an array of hashes or array of arrays" unless rows.is_a?(Array) &&
(rows[0].is_a?(Hash) or rows[0].is_a?(Array) or rows.empty?)
@@ -196,26 +211,30 @@
body << render_table_description if @options[:description]
body.join("\n")
end
def render_header
- @headers ? render_table_header : [render_border]
+ @headers ? render_table_header : [render_border(:top)]
end
def render_footer
- [render_border]
+ [render_border(:bottom)]
end
def render_table_header
- title_row = '| ' + @fields.map {|f|
- format_cell(@headers[f], @field_lengths[f])
- }.join(' | ') + ' |'
- [render_border, title_row, render_border]
+ title_row = chars[:top][:vertical][:outside] + ' ' +
+ @fields.map {|f| format_cell(@headers[f], @field_lengths[f]) }.
+ join(' ' + chars[:top][:vertical][:inside] +' ') +
+ ' ' + chars[:top][:vertical][:outside]
+ [render_border(:top), title_row, render_border(:middle)]
end
- def render_border
- '+-' + @fields.map {|f| '-' * @field_lengths[f] }.join('-+-') + '-+'
+ def render_border(which)
+ chars[which][:left] + chars[which][:horizontal] +
+ @fields.map {|f| chars[which][:horizontal] * @field_lengths[f] }.
+ join(chars[which][:horizontal] + chars[which][:center] + chars[which][:horizontal]) +
+ chars[which][:horizontal] + chars[which][:right]
end
def format_cell(value, cell_width)
text = String.size(value) > cell_width ?
(
@@ -224,12 +243,12 @@
String.ljust(text, cell_width)
end
def render_rows
@rows.map do |row|
- row = '| ' + @fields.map {|f|
+ row = chars[:bottom][:vertical][:outside] + ' ' + @fields.map {|f|
format_cell(row[f], @field_lengths[f])
- }.join(' | ') + ' |'
+ }.join(' ' +chars[:bottom][:vertical][:inside] + ' ') + ' ' + chars[:bottom][:vertical][:outside]
end
end
def render_table_description
(@rows.length == 0) ? "0 rows in set" :