module ArrayFitToRefinement

Public Instance Methods

compress_to(string_length_goal, ignore_ansi_codes:) click to toggle source

Warning: Still not going to work nicely if a string ends in an ansi code!

# File lib/refinements/array_fit_to_refinement.rb, line 32
def compress_to(string_length_goal, ignore_ansi_codes:)
  working_array = self.map(&:to_s)
  original_string_count = self.count
  spacers = [''] * (original_string_count - 1)
  length_method = ignore_ansi_codes ? :ansiless_length : :length

  ## Ensure the strings are short enough to fit:
  slider = 0
  while working_array.join('').send(length_method) > string_length_goal
    longest_string_length = working_array.map { |s| s.send(length_method) }.max
    slider_index = slider % working_array.count
    if working_array[slider_index].send(length_method) >= longest_string_length
      length_less_one = working_array[slider_index].send(length_method) - 1
      clipped_by_one = working_array[slider_index].clip_at(
                         length_less_one,
                         ignore_ansi_codes: ignore_ansi_codes
                       )
      working_array[slider_index] = clipped_by_one
    end
    slider += 1
  end

  working_array.zip(spacers).flatten.compact
end
expand_to(string_length_goal, ignore_ansi_codes:, fill:) click to toggle source
# File lib/refinements/array_fit_to_refinement.rb, line 57
def expand_to(string_length_goal, ignore_ansi_codes:, fill:)
  original_string_count = self.count
  working_array = self.map(&:to_s)
  spacers = [''] * (original_string_count - 1)
  length_method = ignore_ansi_codes ? :ansiless_length : :length

  ## Ensure the spacers are large enough to fill out to string_length_goal
  space_to_fill = string_length_goal - working_array.join('').send(length_method)
  first_pass_spacer_length = space_to_fill / spacers.count
  spacers.map! { fill * first_pass_spacer_length }

  ## Distribute the remaining space evenly among the last n spacers
  remaining_space = space_to_fill - spacers.join('').send(length_method)
  if remaining_space.positive?
    spacers =
      spacers[0...-remaining_space] +
      spacers[-remaining_space..-1].map! { |spacer| spacer + ' ' } #each { |task| task.working_length += 1 }
  end

  working_array.zip(spacers).flatten.compact
end
fit_to(string_length_goal, fill: ' ', ignore_ansi_codes: true) click to toggle source

Warning: Still not going to work nicely if a string ends in an ansi code!

# File lib/refinements/array_fit_to_refinement.rb, line 6
def fit_to(string_length_goal, fill: ' ', ignore_ansi_codes: true)
  string_array = self.map(&:to_s) # This also acts to dup
  length_method = ignore_ansi_codes ? :ansiless_length : :length
  length_result = string_array.join('').send(length_method)

  if string_array.count < 2
    return nonplural_solution(string_length_goal,
                              length_result,
                              fill: fill,
                              ignore_ansi_codes: ignore_ansi_codes)
  end

  if length_result > string_length_goal
    string_array.compress_to(string_length_goal,
                             ignore_ansi_codes: ignore_ansi_codes)
  elsif length_result < string_length_goal
    string_array.expand_to(string_length_goal,
                           ignore_ansi_codes: ignore_ansi_codes,
                           fill: fill)
  else # If it joins to the right length already, we still want to return the expected number of strings.
    spacers = [''] * (string_array.count - 1)
    string_array.zip(spacers).flatten.compact
  end
end
nonplural_solution(string_length_goal, length_result, fill:, ignore_ansi_codes:) click to toggle source
# File lib/refinements/array_fit_to_refinement.rb, line 81
def nonplural_solution(string_length_goal,
                       length_result,
                       fill:,
                       ignore_ansi_codes:)
  return [fill * string_length_goal] if self.empty?

  string_array = self.map(&:to_s) # This also acts to dup

  if length_result > string_length_goal
    string_array.compress_to(string_length_goal,
                             ignore_ansi_codes: ignore_ansi_codes)
  elsif length_result < string_length_goal
    remaining_space = string_length_goal - length_result
    string_array.append(fill * remaining_space)
  else # If it joins to the right length already, we still want to return the expected number of strings.
    self + ['']
  end
end