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 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118
|
require_relative "column_printer"
require_relative "terminal"
class Thor
module Shell
class TablePrinter < ColumnPrinter
BORDER_SEPARATOR = :separator
def initialize(stdout, options = {})
super
@formats = []
@maximas = []
@colwidth = options[:colwidth]
@truncate = options[:truncate] == true ? Terminal.terminal_width : options[:truncate]
@padding = 1
end
def print(array)
return if array.empty?
prepare(array)
print_border_separator if options[:borders]
array.each do |row|
if options[:borders] && row == BORDER_SEPARATOR
print_border_separator
next
end
sentence = "".dup
row.each_with_index do |column, index|
sentence << format_cell(column, row.size, index)
end
sentence = truncate(sentence)
sentence << "|" if options[:borders]
stdout.puts indentation + sentence
end
print_border_separator if options[:borders]
end
private
def prepare(array)
array = array.reject{|row| row == BORDER_SEPARATOR }
@formats << "%-#{@colwidth + 2}s".dup if @colwidth
start = @colwidth ? 1 : 0
colcount = array.max { |a, b| a.size <=> b.size }.size
start.upto(colcount - 1) do |index|
maxima = array.map { |row| row[index] ? row[index].to_s.size : 0 }.max
@maximas << maxima
@formats << if options[:borders]
"%-#{maxima}s".dup
elsif index == colcount - 1
# Don't output 2 trailing spaces when printing the last column
"%-s".dup
else
"%-#{maxima + 2}s".dup
end
end
@formats << "%s"
end
def format_cell(column, row_size, index)
maxima = @maximas[index]
f = if column.is_a?(Numeric)
if options[:borders]
# With borders we handle padding separately
"%#{maxima}s"
elsif index == row_size - 1
# Don't output 2 trailing spaces when printing the last column
"%#{maxima}s"
else
"%#{maxima}s "
end
else
@formats[index]
end
cell = "".dup
cell << "|" + " " * @padding if options[:borders]
cell << f % column.to_s
cell << " " * @padding if options[:borders]
cell
end
def print_border_separator
separator = @maximas.map do |maxima|
"+" + "-" * (maxima + 2 * @padding)
end
stdout.puts indentation + separator.join + "+"
end
def truncate(string)
return string unless @truncate
chars = string.chars.to_a
if chars.length <= @truncate
chars.join
else
chars[0, @truncate - 3 - @indent].join + "..."
end
end
def indentation
" " * @indent
end
end
end
end
|