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
|
# File 'lib/iruby/formatter.rb', line 27
def table(obj, maxrows: 15, maxcols: 15, **options)
raise ArgumentError, 'Invalid :maxrows' if maxrows && maxrows < 3
raise ArgumentError, 'Invalid :maxcols' if maxcols && maxcols < 3
return obj unless obj.respond_to?(:each)
rows = []
if obj.respond_to?(:keys)
= obj.keys
keys = (0...obj.keys.size).to_a
cols = obj.values.map {|x| [x].flatten(1) }
num_rows = cols.map(&:size).max
rows = []
(0...num_rows).each do |i|
rows << []
(0...cols.size).each do |j|
rows[i][j] = cols[j][i]
end
end
else
keys = nil
array_size = 0
obj.each do |row|
if row.respond_to?(:keys)
keys ||= Set.new
keys.merge(row.keys)
elsif row.respond_to?(:map)
array_size = row.size if array_size < row.size
end
rows << row
end
if keys
= keys.to_a
keys.merge(0...array_size)
else
keys = 0...array_size
end
keys = keys.to_a
end
||= keys if options[:header]
rows1, rows2 = rows, nil
keys1, keys2 = keys, nil
, = , nil
if maxcols && keys.size > maxcols
keys1 = keys[0...maxcols / 2]
keys2 = keys[-maxcols / 2 + 1..-1]
if
= [0...maxcols / 2]
= [-maxcols / 2 + 1..-1]
end
end
if maxrows && rows.size > maxrows
rows1 = rows[0...maxrows / 2]
rows2 = rows[-maxrows / 2 + 1..-1]
end
table = '<table>'
if && options[:header] != false
table << '<tr>' << .map {|k| "<th>#{cell k}</th>" }.join
table << "<th>…</th>" << .map {|k| "<th>#{cell k}</th>" }.join if keys2
table << '</tr>'
end
row_block(table, rows1, keys1, keys2)
if rows2
table << "<tr><td#{keys1.size > 1 ? " colspan='#{keys1.size}'" : ''}>⋮</td>"
table << "<td>⋱</td><td#{keys2.size > 1 ? " colspan='#{keys2.size}'" : ''}>⋮</td>" if keys2
table << '</tr>'
row_block(table, rows2, keys1, keys2)
end
table << '</table>'
end
|