lib/hirb/helpers/table.rb in hirb-0.2.10 vs lib/hirb/helpers/table.rb in hirb-0.3.0

- old
+ new

@@ -66,11 +66,11 @@ # Main method which returns a formatted table. # ==== Options: # [*:fields*] An array which overrides the default fields and can be used to indicate field order. # [*:headers*] A hash of fields and their header names. Fields that aren't specified here default to their name. - # This option can also be an array but only for array rows. + # When set to false, headers are hidden. Can also be an array but only for array rows. # [*:max_fields*] A hash of fields and their maximum allowed lengths. Maximum length can also be a percentage of the total width # (decimal less than one). When a field exceeds it's maximum then it's # truncated and has a ... appended to it. Fields that aren't specified have no maximum. # [*:max_width*] The maximum allowed width of all fields put together including field borders. Only valid when :resize is true. # Default is Hirb::View.width. @@ -88,21 +88,20 @@ # [*: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. # [*: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. - # [*:return_rows*] When set to true, returns rows that have been initialized but not rendered. Default is false. # Examples: # Hirb::Helpers::Table.render [[1,2], [2,3]] # Hirb::Helpers::Table.render [[1,2], [2,3]], :max_fields=>{0=>10}, :header_filter=>:capitalize # Hirb::Helpers::Table.render [['a',1], ['b',2]], :change_fields=>%w{letters numbers}, :max_fields=>{'numbers'=>0.4} # 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[:return_rows] ? new(rows, options).instance_variable_get("@rows") : new(rows, options).render + 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. **" Helpers::VerticalTable.render(rows, options) end @@ -119,10 +118,12 @@ self.filter_classes = { Array=>:comma_join, Hash=>:inspect } #: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?) @options = {:description=>true, :filters=>{}, :change_fields=>{}, :escape_special_chars=>true, :filter_any=>Helpers::Table.filter_any, :resize=>true}.merge(options) @fields = set_fields(rows) @rows = set_rows(rows) @headers = set_headers @@ -132,23 +133,22 @@ end Helpers::Table.last_table = self end def set_fields(rows) - fields = if @options[:fields] - @options[:fields].dup + @options[:change_fields] = array_to_indices_hash(@options[:change_fields]) if @options[:change_fields].is_a?(Array) + return @options[:fields].dup if @options[:fields] + + fields = 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 - 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 + rows[0].is_a?(Array) ? (0..rows[0].length - 1).to_a : [] end - @options[:change_fields] = array_to_indices_hash(@options[:change_fields]) if @options[:change_fields].is_a?(Array) + @options[:change_fields].each do |oldf, newf| - (index = fields.index(oldf)) ? fields[index] = newf : fields << newf + (index = fields.index(oldf)) && fields[index] = newf end fields end def set_rows(rows) @@ -265,10 +265,11 @@ @width ||= @options[:max_width] || View.width 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] = String.size(v); h} : {} + field_lengths = @headers ? @headers.inject({}) {|h,(k,v)| h[k] = String.size(v); h} : + @fields.inject({}) {|h,e| h[e] = 1; h } @rows.each do |row| @fields.each do |field| len = String.size(row[field]) field_lengths[field] = len if len > field_lengths[field].to_i end