class HighLine::Table

Represent a columnar layout of items with wrapping and flexible layout.

Constants

Width

Attributes

items[R]

Public Class Methods

new(items=nil,options={},&mapper) click to toggle source
# File lib/rhc/highline_extensions.rb, line 290
def initialize(items=nil,options={},&mapper)
  @items, @options, @mapper = items, options, mapper
end

Public Instance Methods

color() click to toggle source
# File lib/rhc/highline_extensions.rb, line 294
def color
  opts[:color]
end

Protected Instance Methods

align() click to toggle source
# File lib/rhc/highline_extensions.rb, line 305
def align
  opts[:align] || []
end
allocate_widths_for(available) click to toggle source
# File lib/rhc/highline_extensions.rb, line 352
def allocate_widths_for(available)
  available -= (columns-1) * joiner.length + indent.length
  return column_widths.map{ |w| w.max } if available >= column_widths.inject(0){ |sum, w| sum + w.max } || column_widths.inject(0){ |sum, w| sum + w.min } > available

  fair = available / columns
  column_widths.each do |w|
    if w.set > 0
      available -= w.set
      next
    end
    w.set = if w.max <= fair
        available -= w.max
        w.max
      else
        0
      end
  end

  remaining = column_widths.inject(0){ |sum, w| if w.set == 0; sum += w.max; available -= w.min; end; sum }
  fair = available.to_f / remaining.to_f

  column_widths.
    each do |w| 
      if w.set == 0
        available -= (alloc = (w.max * fair).to_i)
        w.set = alloc + w.min
      end
    end.
    each{ |w| if available > 0 && w.set < w.max; w.set += 1; available -= 1; end }.
    map(&:set)
end
column_widths() click to toggle source
# File lib/rhc/highline_extensions.rb, line 334
def column_widths
  @column_widths ||= begin
    widths = Array.new(columns){ Width.new(0,0,0) }
    (source_rows + headers).each do |row|
      row.each_with_index do |col, i|
        w = widths[i]
        s = col.strip_ansi
        word_length = s.scan(%r\b\S+/).inject(0){ |l, word| l = word.length if l <= word.length; l }
        w.min = word_length unless w.min > word_length
        w.max = s.length unless w.max > s.length
      end
    end
    widths
  end
end
columns() click to toggle source
# File lib/rhc/highline_extensions.rb, line 330
def columns
  @columns ||= source_rows.map(&:length).max || 0
end
header_rows() click to toggle source
# File lib/rhc/highline_extensions.rb, line 405
def header_rows
  @header_rows ||= begin
    headers << widths.map{ |w| '-' * w } if headers.present?
    headers
  end
end
headers() click to toggle source
# File lib/rhc/highline_extensions.rb, line 326
def headers
  @headers ||= opts[:header] ? [Array(opts[:header])] : []
end
heading() click to toggle source
# File lib/rhc/highline_extensions.rb, line 314
def heading
  @heading ||= opts[:heading] ? HighLine::Header.new(opts[:heading], max_width, indent) : nil
end
indent() click to toggle source
# File lib/rhc/highline_extensions.rb, line 311
def indent
  opts[:indent] || ''
end
joiner() click to toggle source
# File lib/rhc/highline_extensions.rb, line 308
def joiner
  opts[:join] || ' '
end
max_width() click to toggle source
# File lib/rhc/highline_extensions.rb, line 401
def max_width
  @max_width ||= opts[:width].is_a?(Array) ? opts[:width].first : (opts[:width] ? opts[:width] : 0)
end
opts() click to toggle source
# File lib/rhc/highline_extensions.rb, line 301
def opts
  @options
end
rows() click to toggle source
# File lib/rhc/highline_extensions.rb, line 412
def rows
  @rows ||= begin
    body = (header_rows + source_rows).inject([]) do |a,row| 
      row = row.zip(widths).map{ |column,w| w && w > 0 ? column.textwrap_ansi(w, false) : [column] }
      (row.map(&:length).max || 0).times do |i|
        s = []
        row.each_with_index do |lines, j|
          cell = lines[i]
          l = cell ? cell.strip_ansi.length : 0
          s << 
              if align[j] == :right 
                "#{' '*(widths[j]-l) if l < widths[j]}#{cell}"
              else
                "#{cell}#{' '*(widths[j]-l) if l < widths[j]}"
              end
        end
        a << "#{indent}#{s.join(joiner).rstrip}"
      end
      a
    end
    
    body = heading.to_a.concat(body) if heading
    body
  end
end
source_rows() click to toggle source
# File lib/rhc/highline_extensions.rb, line 318
def source_rows
  @source_rows ||= begin
    (@mapper ? (items.map &@mapper) : items).each do |row|
      row.map!{ |col| col.is_a?(String) ? col : col.to_s }
    end
  end
end
widths() click to toggle source
# File lib/rhc/highline_extensions.rb, line 384
def widths
  @widths ||= begin
    case w = opts[:width]
    when Array
      column_widths.zip(w[1..-1]).each do |width, col| 
        width.set = col || 0
        width.max = width.set if width.set > width.max
      end
      allocate_widths_for(w.first || 0)
    when Integer
      allocate_widths_for(w)
    else
      column_widths.map{ |w| w.max }
    end
  end
end