class HighLine::ListRenderer
This class is a utility for quickly and easily laying out lists to be used by HighLine.
Attributes
@return [HighLine] context
Items list @return [Array]
@return [Symbol] the current mode the List is being rendered @see initialize for more details see mode parameter of initialize
Changes the behaviour of some modes. Example, in :inline mode the option is treated as the 'end separator' (defaults to “ or ”) @return option parameter that changes the behaviour of some modes.
Public Class Methods
The only required parameters are items and highline. @param items [Array] the Array of items to list @param mode [Symbol] controls how that list is formed @param option has different effects, depending on the mode. @param highline [HighLine] a HighLine instance to direct the output to.
Recognized modes are:
:columns_across
-
items will be placed in columns, flowing from left to right. If given, option is the number of columns to be used. When absent, columns will be determined based on wrap_at or a default of 80 characters.
:columns_down
-
Identical to
:columns_across
, save flow goes down. :uneven_columns_across
-
Like
:columns_across
but each column is sized independently. :uneven_columns_down
-
Like
:columns_down
but each column is sized independently. :inline
-
All items are placed on a single line. The last two items are separated by option or a default of “ or ”. All other items are separated by “, ”.
:rows
-
The default mode. Each of the items is placed on its own line. The option parameter is ignored in this mode.
Each member of the items Array is passed through ERb and thus can contain their own expansions. Color escape expansions do not contribute to the final field width.
# File lib/highline/list_renderer.rb, line 61 def initialize(items, mode = :rows, option = nil, highline) @highline = highline @mode = mode @option = option @items = render_list_items(items) end
Public Instance Methods
Render the list using the appropriate mode and options. @return [String] rendered list as String
# File lib/highline/list_renderer.rb, line 70 def render return "" if items.empty? case mode when :inline list_inline_mode when :columns_across list_columns_across_mode when :columns_down list_columns_down_mode when :uneven_columns_across list_uneven_columns_mode when :uneven_columns_down list_uneven_columns_down_mode else list_default_mode end end
Private Instance Methods
# File lib/highline/list_renderer.rb, line 211 def actual_length(text) HighLine::Wrapper.actual_length text end
# File lib/highline/list_renderer.rb, line 194 def actual_lengths_for(line) line.map do |item| actual_length(item) end end
# File lib/highline/list_renderer.rb, line 242 def col_count option || col_count_calculate end
# File lib/highline/list_renderer.rb, line 237 def col_count_calculate (line_size_limit + row_join_str_size) / (items_max_length + row_join_str_size) end
# File lib/highline/list_renderer.rb, line 179 def get_col_widths(lines) lines = transpose(lines) get_segment_widths(lines) end
# File lib/highline/list_renderer.rb, line 184 def get_row_widths(lines) get_segment_widths(lines) end
# File lib/highline/list_renderer.rb, line 188 def get_segment_widths(lines) lines.map do |col| actual_lengths_for(col).max end end
# File lib/highline/list_renderer.rb, line 206 def inside_line_size_limit?(widths) line_size = widths.reduce(0) { |sum, n| sum + n + row_join_str_size } line_size <= line_size_limit + row_join_str_size end
# File lib/highline/list_renderer.rb, line 215 def items_max_length @items_max_length ||= max_length(items) end
# File lib/highline/list_renderer.rb, line 223 def line_size_limit @line_size_limit ||= (highline.wrap_at || 80) end
# File lib/highline/list_renderer.rb, line 119 def list_columns_across_mode HighLine::List.new(right_padded_items, cols: col_count).to_s end
# File lib/highline/list_renderer.rb, line 123 def list_columns_down_mode HighLine::List.new( right_padded_items, cols: col_count, col_down: true ).to_s end
# File lib/highline/list_renderer.rb, line 105 def list_default_mode items.map { |i| "#{i}\n" }.join end
# File lib/highline/list_renderer.rb, line 109 def list_inline_mode end_separator = option || " or " if items.size == 1 items.first else items[0..-2].join(", ") + "#{end_separator}#{items.last}" end end
# File lib/highline/list_renderer.rb, line 147 def list_uneven_columns_down_mode list = HighLine::List.new(items, col_down: true) list_uneven_columns_mode(list) end
# File lib/highline/list_renderer.rb, line 131 def list_uneven_columns_mode(list = nil) list ||= HighLine::List.new(items) col_max = option || items.size col_max.downto(1) do |column_count| list.cols = column_count widths = get_col_widths(list) if column_count == 1 || # last guess inside_line_size_limit?(widths) || # good guess option # defined by user return pad_uneven_rows(list, widths) end end end
# File lib/highline/list_renderer.rb, line 219 def max_length(items) items.map { |item| actual_length(item) }.max end
# File lib/highline/list_renderer.rb, line 252 def pad_char " " end
# File lib/highline/list_renderer.rb, line 152 def pad_uneven_rows(list, widths) right_padded_list = Array(list).map do |row| right_pad_row(row.compact, widths) end stringfy_list(right_padded_list) end
# File lib/highline/list_renderer.rb, line 91 def render_list_items(items) items.to_ary.map do |item| item = String(item) template = if ERB.instance_method(:initialize).parameters.assoc(:key) # Ruby 2.6+ ERB.new(item, trim_mode: "%") else ERB.new(item, nil, "%") end template_renderer = HighLine::TemplateRenderer.new(template, self, highline) template_renderer.render end end
# File lib/highline/list_renderer.rb, line 173 def right_pad_field(field, width) field = String(field) # nil protection pad_size = width - actual_length(field) field + (pad_char * pad_size) end
# File lib/highline/list_renderer.rb, line 167 def right_pad_row(row, widths) row.zip(widths).map do |field, width| right_pad_field(field, width) end end
# File lib/highline/list_renderer.rb, line 246 def right_padded_items items.map do |item| right_pad_field(item, items_max_length) end end
# File lib/highline/list_renderer.rb, line 256 def row_count (items.count / col_count.to_f).ceil end
# File lib/highline/list_renderer.rb, line 233 def row_join_str_size row_join_string.size end
# File lib/highline/list_renderer.rb, line 227 def row_join_string @row_join_string ||= " " end
# File lib/highline/list_renderer.rb, line 163 def row_to_s(row) row.compact.join(row_join_string) + "\n" end
# File lib/highline/list_renderer.rb, line 159 def stringfy_list(list) list.map { |row| row_to_s(row) }.join end
# File lib/highline/list_renderer.rb, line 200 def transpose(lines) lines = Array(lines) first_line = lines.shift first_line.zip(*lines) end