blob: 525f9ce5bbc504e7a65c894502009ce1ff781cd0 (
plain)
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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
|
require_relative "column_printer"
require_relative "terminal"
class Bundler::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
as_unicode do
chars = string.chars.to_a
if chars.length <= @truncate
chars.join
else
chars[0, @truncate - 3 - @indent].join + "..."
end
end
end
def indentation
" " * @indent
end
if "".respond_to?(:encode)
def as_unicode
yield
end
else
def as_unicode
old = $KCODE # rubocop:disable Style/GlobalVars
$KCODE = "U" # rubocop:disable Style/GlobalVars
yield
ensure
$KCODE = old # rubocop:disable Style/GlobalVars
end
end
end
end
end
|