module Strings::Align

Responsible for text alignment

Constants

NEWLINE
SPACE

Public Class Methods

align(text, width, direction: :left, **options) click to toggle source

Aligns text within the width.

If the text is greater than the width then unmodified string is returned.

@param [String] text

the text to align lines of

@param [Integer] width

the maximum width to align to

@example

text = "the madness of men"

Strings::Align.align(22, :left)
# => "the madness of men      "

Strings::Align.align(22, :center)
# => "   the madness of men   "

Strings::Align(22, :right)
# => "      the madness of men"

Strings::Align.align(22, :center, fill: '*)
# => "***the madness of men***"

@api public

# File lib/strings/align.rb, line 39
def align(text, width, direction: :left, **options)
  return text if width.nil?
  method = to_alignment(direction)
  send(method, text, width, options)
end
align_center(text, width, fill: SPACE, separator: NEWLINE) click to toggle source

Centers text within the width

@return [String]

@api public

# File lib/strings/align.rb, line 83
def align_center(text, width, fill: SPACE, separator: NEWLINE)
  return text if width.nil?
  each_line(text, separator) do |line|
    width_diff = width - display_width(line)
    if width_diff > 0
      right_count = (width_diff.to_f / 2).ceil
      left_count  =  width_diff - right_count
      [fill * left_count, line, fill * right_count].join
    else
      line
    end
  end
end
align_left(text, width, fill: SPACE, separator: NEWLINE) click to toggle source

Aligns text to the left at given length

@return [String]

@api public

# File lib/strings/align.rb, line 65
def align_left(text, width, fill: SPACE, separator: NEWLINE)
  return if width.nil?
  each_line(text, separator) do |line|
    width_diff = width - display_width(line)
    if width_diff > 0
      line + fill * width_diff
    else
      line
    end
  end
end
align_right(text, width, fill: SPACE, separator: NEWLINE) click to toggle source

Aligns text to the right at given length

@return [String]

@api public

# File lib/strings/align.rb, line 103
def align_right(text, width, fill: SPACE, separator: NEWLINE)
  return text if width.nil?
  each_line(text, separator) do |line|
    width_diff = width - display_width(line)
    if width_diff > 0
      fill * width_diff + line
    else
      line
    end
  end
end
display_width(string) click to toggle source

Visible width of a string

@api private

# File lib/strings/align.rb, line 135
def display_width(string)
  Unicode::DisplayWidth.of(Strings::ANSI.sanitize(string))
end
each_line(text, separator) { |text| ... } click to toggle source

Enumerate text line by line

@param [String] text

@return [String]

@api private

# File lib/strings/align.rb, line 123
def each_line(text, separator)
  lines = text.split(separator)
  return yield(text) if text.empty?
  lines.reduce([]) do |aligned, line|
    aligned << yield(line)
  end.join(separator)
end
to_alignment(direction) click to toggle source

Convert direction to method name

@api private

# File lib/strings/align.rb, line 49
def to_alignment(direction)
  case direction.to_sym
  when :left   then :align_left
  when :right  then :align_right
  when :center then :align_center
  else
    raise ArgumentError, "Unknown alignment `#{direction}`."
  end
end

Private Instance Methods

align(text, width, direction: :left, **options) click to toggle source

Aligns text within the width.

If the text is greater than the width then unmodified string is returned.

@param [String] text

the text to align lines of

@param [Integer] width

the maximum width to align to

@example

text = "the madness of men"

Strings::Align.align(22, :left)
# => "the madness of men      "

Strings::Align.align(22, :center)
# => "   the madness of men   "

Strings::Align(22, :right)
# => "      the madness of men"

Strings::Align.align(22, :center, fill: '*)
# => "***the madness of men***"

@api public

# File lib/strings/align.rb, line 39
def align(text, width, direction: :left, **options)
  return text if width.nil?
  method = to_alignment(direction)
  send(method, text, width, options)
end
align_center(text, width, fill: SPACE, separator: NEWLINE) click to toggle source

Centers text within the width

@return [String]

@api public

# File lib/strings/align.rb, line 83
def align_center(text, width, fill: SPACE, separator: NEWLINE)
  return text if width.nil?
  each_line(text, separator) do |line|
    width_diff = width - display_width(line)
    if width_diff > 0
      right_count = (width_diff.to_f / 2).ceil
      left_count  =  width_diff - right_count
      [fill * left_count, line, fill * right_count].join
    else
      line
    end
  end
end
align_left(text, width, fill: SPACE, separator: NEWLINE) click to toggle source

Aligns text to the left at given length

@return [String]

@api public

# File lib/strings/align.rb, line 65
def align_left(text, width, fill: SPACE, separator: NEWLINE)
  return if width.nil?
  each_line(text, separator) do |line|
    width_diff = width - display_width(line)
    if width_diff > 0
      line + fill * width_diff
    else
      line
    end
  end
end
align_right(text, width, fill: SPACE, separator: NEWLINE) click to toggle source

Aligns text to the right at given length

@return [String]

@api public

# File lib/strings/align.rb, line 103
def align_right(text, width, fill: SPACE, separator: NEWLINE)
  return text if width.nil?
  each_line(text, separator) do |line|
    width_diff = width - display_width(line)
    if width_diff > 0
      fill * width_diff + line
    else
      line
    end
  end
end
display_width(string) click to toggle source

Visible width of a string

@api private

# File lib/strings/align.rb, line 135
def display_width(string)
  Unicode::DisplayWidth.of(Strings::ANSI.sanitize(string))
end
each_line(text, separator) { |text| ... } click to toggle source

Enumerate text line by line

@param [String] text

@return [String]

@api private

# File lib/strings/align.rb, line 123
def each_line(text, separator)
  lines = text.split(separator)
  return yield(text) if text.empty?
  lines.reduce([]) do |aligned, line|
    aligned << yield(line)
  end.join(separator)
end
to_alignment(direction) click to toggle source

Convert direction to method name

@api private

# File lib/strings/align.rb, line 49
def to_alignment(direction)
  case direction.to_sym
  when :left   then :align_left
  when :right  then :align_right
  when :center then :align_center
  else
    raise ArgumentError, "Unknown alignment `#{direction}`."
  end
end