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 62 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 71 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 212 def actual_length(text) HighLine::Wrapper.actual_length text end
# File lib/highline/list_renderer.rb, line 195 def actual_lengths_for(line) line.map do |item| actual_length(item) end end
# File lib/highline/list_renderer.rb, line 243 def col_count option || col_count_calculate end
# File lib/highline/list_renderer.rb, line 238 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 180 def get_col_widths(lines) lines = transpose(lines) get_segment_widths(lines) end
# File lib/highline/list_renderer.rb, line 185 def get_row_widths(lines) get_segment_widths(lines) end
# File lib/highline/list_renderer.rb, line 189 def get_segment_widths(lines) lines.map do |col| actual_lengths_for(col).max end end
# File lib/highline/list_renderer.rb, line 207 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 216 def items_max_length @items_max_length ||= max_length(items) end
# File lib/highline/list_renderer.rb, line 224 def line_size_limit @line_size_limit ||= (highline.wrap_at || 80) end
# File lib/highline/list_renderer.rb, line 120 def list_columns_across_mode HighLine::List.new(right_padded_items, cols: col_count).to_s end
# File lib/highline/list_renderer.rb, line 124 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 106 def list_default_mode items.map { |i| "#{i}\n" }.join end
# File lib/highline/list_renderer.rb, line 110 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 148 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 132 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 220 def max_length(items) items.map { |item| actual_length(item) }.max end
# File lib/highline/list_renderer.rb, line 253 def pad_char " " end
# File lib/highline/list_renderer.rb, line 153 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 92 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 174 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 168 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 247 def right_padded_items items.map do |item| right_pad_field(item, items_max_length) end end
# File lib/highline/list_renderer.rb, line 257 def row_count (items.count / col_count.to_f).ceil end
# File lib/highline/list_renderer.rb, line 234 def row_join_str_size row_join_string.size end
# File lib/highline/list_renderer.rb, line 228 def row_join_string @row_join_string ||= " " end
# File lib/highline/list_renderer.rb, line 164 def row_to_s(row) row.compact.join(row_join_string) + "\n" end
# File lib/highline/list_renderer.rb, line 160 def stringfy_list(list) list.map { |row| row_to_s(row) }.join end
# File lib/highline/list_renderer.rb, line 201 def transpose(lines) lines = Array(lines) first_line = lines.shift first_line.zip(*lines) end