Represent a columnar layout of items with wrapping and flexible layout.
# File lib/rhc/highline_extensions.rb, line 304 def initialize(items=nil,options={},&mapper) @items, @options, @mapper = items, options, mapper end
# File lib/rhc/highline_extensions.rb, line 308 def color opts[:color] end
# File lib/rhc/highline_extensions.rb, line 319 def align opts[:align] || [] end
# File lib/rhc/highline_extensions.rb, line 372 def allocate_widths_for(available) available -= (columns-1) * joiner.length + indent.length return column_widths.map{ |w| w.max } if available >= column_widths.inject(0){ |sum, w| sum + w.max } || column_widths.inject(0){ |sum, w| sum + w.min } > available fair = available / columns column_widths.each do |w| if w.set > 0 available -= w.set next end w.set = if w.max <= fair available -= w.max w.max else 0 end end remaining = column_widths.inject(0) do |sum, w| if w.set == 0 sum += w.max available -= w.min end sum end fair = available.to_f / remaining.to_f column_widths. each do |w| if w.set == 0 alloc = (w.max * fair).to_i overflow = alloc + w.min - w.max if overflow > 0 alloc -= overflow end available -= alloc w.set = alloc + w.min end end. each do |w| next unless available > 0 gap = w.max - w.set if gap > 0 left = [gap,available].min available -= left w.set += left end end.map(&:set) end
# File lib/rhc/highline_extensions.rb, line 354 def column_widths @column_widths ||= begin widths = Array.new(columns){ Width.new(0,0,0) } (source_rows + headers).each do |row| row.each_with_index do |col, i| w = widths[i] s = col.strip_ansi word_length = s.scan(%r\b\S+/).inject(0){ |l, word| l = word.length if l <= word.length; l } w.min = word_length unless w.min > word_length w.max = s.length unless w.max > s.length end end widths end end
# File lib/rhc/highline_extensions.rb, line 350 def columns @columns ||= source_rows.map(&:length).max || 0 end
# File lib/rhc/highline_extensions.rb, line 443 def header_rows @header_rows ||= begin headers << widths.map{ |w| '-' * w } if headers.present? headers end end
# File lib/rhc/highline_extensions.rb, line 346 def headers @headers ||= opts[:header] ? [Array(opts[:header])] : [] end
# File lib/rhc/highline_extensions.rb, line 328 def heading @heading ||= opts[:heading] ? HighLine::Header.new(opts[:heading], max_width, indent) : nil end
# File lib/rhc/highline_extensions.rb, line 325 def indent opts[:indent] || '' end
# File lib/rhc/highline_extensions.rb, line 322 def joiner opts[:join] || ' ' end
# File lib/rhc/highline_extensions.rb, line 439 def max_width @max_width ||= opts[:width].is_a?(Array) ? opts[:width].first : (opts[:width] ? opts[:width] : 0) end
# File lib/rhc/highline_extensions.rb, line 315 def opts @options end
# File lib/rhc/highline_extensions.rb, line 450 def rows @rows ||= begin body = (header_rows + source_rows).inject([]) do |a,row| row = row.zip(widths).map{ |column,w| w && w > 0 ? column.textwrap_ansi(w, false) : [column] } (row.map(&:length).max || 0).times do |i| s = [] row.each_with_index do |lines, j| cell = lines[i] l = cell ? cell.strip_ansi.length : 0 s << if align[j] == :right "#{' '*(widths[j]-l) if l < widths[j]}#{cell}" else "#{cell}#{' '*(widths[j]-l) if l < widths[j]}" end end a << "#{indent}#{s.join(joiner).rstrip}" end a end body = heading.to_a.concat(body) if heading body end end
# File lib/rhc/highline_extensions.rb, line 332 def source_rows @source_rows ||= begin (@mapper ? (items.map &@mapper) : items).each do |row| row.map! do |col| case col when Array then col.join("\n") when String then col else col.to_s end end end end end
# File lib/rhc/highline_extensions.rb, line 422 def widths @widths ||= begin case w = opts[:width] when Array column_widths.zip(w[1..-1]).each do |width, col| width.set = col || 0 width.max = width.set if width.set > width.max end allocate_widths_for(w.first || 0) when Integer allocate_widths_for(w) else column_widths.map{ |w| w.max } end end end