class ANSI::Columns

Attributes

align[R]

Alignment to apply to cells.

columns[R]

Default number of columns to display. If nil then the number of coumns is estimated from the size of the terminal.

format[R]

Formating to apply to cells.

list[R]

List layout into columns. Each new line is taken to be a row-column cell.

padding[R]

Padding size to apply to cells.

Public Class Methods

new(list, options={}, &format) click to toggle source

Create a column-based layout.

@param [String,Array] list

Multiline String or Array of strings to columnize.

@param [Hash] options

Options to customize columnization.

@option options [Fixnum] :columns

Number of columns.

@option options [Symbol] :align

Column alignment, either :left, :right or :center.

@option options [String,Fixnum] :padding

String or number or spaces to append to each column.

The format block MUST return ANSI codes.

# File lib/ansi/columns.rb, line 26
def initialize(list, options={}, &format)
  self.list = list

  self.columns = options[:columns] || options[:cols]
  self.padding = options[:padding] || 1
  self.align   = options[:align]   || :left
  #self.ansi    = options[:ansi]
  self.format  = format

  #@columns = nil if @columns == 0
end

Public Instance Methods

align=(symbol) click to toggle source

Set alignment ensuring value is a symbol.

@param [#to_sym] symbol

Either `:right`, `:left` or `:center`.

@return [Symbol] The given symbol.

# File lib/ansi/columns.rb, line 90
def align=(symbol)
  symbol = symbol.to_sym
  raise ArgumentError, "invalid alignment -- #{symbol.inspect}"              unless [:left, :right, :center].include?(symbol)
  @align = symbol
end
columns=(integer) click to toggle source

Set column count ensuring value is either an integer or nil. The the value given is zero, it will be taken to mean the same as nil, which means fit-to-screen.

# File lib/ansi/columns.rb, line 63
def columns=(integer)
  integer = integer.to_i
  @columns = (integer.zero? ? nil : integer)
end
format=(procedure) click to toggle source

Set formatting procedure. The procedure must return ANSI codes, suitable for passing to ANSI::String#ansi method.

# File lib/ansi/columns.rb, line 102
def format=(procedure)
  @format = procedure ? procedure.to_proc : nil
end
inspect() click to toggle source
# File lib/ansi/columns.rb, line 39
def inspect
  "#<#{self.class}:#{object_id} #{list.inspect} x #{columns}>"
end
join(cols=nil) click to toggle source
# File lib/ansi/columns.rb, line 116
def join(cols=nil)
  to_s_columns(cols || columns)
end
list=(list) click to toggle source
# File lib/ansi/columns.rb, line 47
def list=(list)
  case list
  when ::String
    @list = list.lines.to_a.map{ |e| e.chomp("\n") }
  when ::Array
    @list = list.map{ |e| e.to_s }
  end
end
padding=(pad) click to toggle source

Set padding to string or number (of spaces).

# File lib/ansi/columns.rb, line 72
def padding=(pad)
  case pad
  when Numeric
    @padding = ' ' * pad.to_i
  else
    @padding = pad.to_s
  end
end
to_s(cols=nil) click to toggle source

Return string in column layout. The number of columns is determined by the `columns` property or overriden by cols argument.

# File lib/ansi/columns.rb, line 111
def to_s(cols=nil)
  to_s_columns(cols || columns)
end

Private Instance Methods

ansi_formatting(cell, col, row) click to toggle source

Used to apply ANSI formatting to each cell.

# File lib/ansi/columns.rb, line 177
def ansi_formatting(cell, col, row)
  if @format
    case @format.arity
    when 0
      f = @format[]
    when 1
      f = @format[cell]
    when 2 
      f = @format[col, row]
    else
      f = @format[cell, col, row]
    end
  else
    f = nil
  end
  [f].flatten.compact
end
template(max, pad) click to toggle source

Aligns the cell left or right.

# File lib/ansi/columns.rb, line 164
def template(max, pad)
  case align
  when :center, 'center'
    offset = " " * (max / 2)
    "#{offset}%#{max}s#{offset}#{pad}"
  when :right, 'right'
    "%#{max}s#{pad}"
  else
    "%-#{max}s#{pad}"
  end
end
to_s_columns(columns=nil) click to toggle source

Layout string lines into columns.

@todo Put in empty strings for blank cells. @todo Centering look like it's off by one to the right.

# File lib/ansi/columns.rb, line 127
def to_s_columns(columns=nil)
  lines = list.to_a
  count = lines.size
  max   = lines.map{ |l| l.size }.max

  if columns.nil?
    width = Terminal.terminal_width
    columns = (width / (max + padding.size)).to_i
  end

  rows = []
  mod = (count / columns.to_f).to_i
  mod += 1 if count % columns != 0

  lines.each_with_index do |line, index|
    (rows[index % mod] ||=[]) << line.strip
  end

  pad = padding
  tmp = template(max, pad)
  str = ""
  rows.each_with_index do |row, ri|
    row.each_with_index do |cell, ci|
      ansi_codes = ansi_formatting(cell, ci, ri)
      if ansi_codes.empty?
        str << (tmp % cell)
      else
        str << (tmp % cell).ansi(*ansi_codes)
      end
    end
    str.rstrip!
    str << "\n"
  end
  str
end