1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
|
require 'unicode/display_width'
module Terminal
class Table
class Cell
##
# Cell value.
attr_reader :value
##
# Column span.
attr_reader :colspan
##
# Initialize with _options_.
def initialize options = nil
@value, options = options, {} unless Hash === options
@value = options.fetch :value, value
@alignment = options.fetch :alignment, nil
@colspan = options.fetch :colspan, 1
@width = options.fetch :width, @value.to_s.size
@index = options.fetch :index
@table = options.fetch :table
end
def alignment?
!@alignment.nil?
end
def alignment
@alignment || @table.style.alignment || :left
end
def alignment=(val)
supported = %w(left center right)
if supported.include?(val.to_s)
@alignment = val
else
raise "Aligment must be one of: #{supported.join(' ')}"
end
end
def align(val, position, length)
positions = { :left => :ljust, :right => :rjust, :center => :center }
val.public_send(positions[position], length)
end
def lines
@value.to_s.split(/\n/)
end
##
# Render the cell.
def render(line = 0)
left = " " * @table.style.padding_left
right = " " * @table.style.padding_right
display_width = Unicode::DisplayWidth.of(Util::ansi_escape(lines[line]))
render_width = lines[line].to_s.size - display_width + width
align("#{left}#{lines[line]}#{right}", alignment, render_width + @table.cell_padding)
end
alias :to_s :render
##
# Returns the longest line in the cell and
# removes all ANSI escape sequences (e.g. color)
def value_for_column_width_recalc
lines.map{ |s| Util::ansi_escape(s) }.max_by{ |s| Unicode::DisplayWidth.of(s) }
end
##
# Returns the width of this cell
def width
padding = (colspan - 1) * @table.cell_spacing
inner_width = (1..@colspan).to_a.inject(0) do |w, counter|
w + @table.column_width(@index + counter - 1)
end
inner_width + padding
end
def inspect
fields = %i[alignment colspan index value width].map do |name|
val = self.instance_variable_get('@'+name.to_s)
"@#{name}=#{val.inspect}"
end.join(', ')
return "#<#{self.class} #{fields}>"
end
end
end
end
|