class Verse::Alignment

A class responsible for text alignment

Attributes

direction[R]
fill[R]
text[R]

The text to align

@ api private

Public Class Methods

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

Align a text to a given direction with the width

@see Verse::Alignment#align

@api public

# File lib/verse/alignment.rb, line 51
def self.align(text, width, direction, options)
  new(text, options).align(width, direction, options)
end
new(text, options = {}) click to toggle source

Initialize an Alignment

@api public

# File lib/verse/alignment.rb, line 13
def initialize(text, options = {})
  @text      = text
  @fill      = options.fetch(:fill) { SPACE }
  @direction = options.fetch(:direction) { :left }
end

Public Instance Methods

align(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.

@example

alignment = Verse::Alignment.new "the madness of men"

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

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

alignment.align(22, :right)
# => "      the madness of men"

@api public

# File lib/verse/alignment.rb, line 73
def align(width, direction = :left, options = {})
  return text unless width

  filler = options.fetch(:fill) { fill }
  method = convert_to_method(direction)
  process_lines { |line| send(method, line, width, filler) }
end
center(width, options = {}) click to toggle source

Centers text within the width

@return [String]

@api public

# File lib/verse/alignment.rb, line 33
def center(width, options = {})
  align(width, :center, options)
end
left(width, options = {}) click to toggle source

Aligns text to the left

@return [String]

@api public

# File lib/verse/alignment.rb, line 24
def left(width, options = {})
  align(width, :left, options)
end
right(width, options = {}) click to toggle source

Aligns text to the right

@return [String]

@api public

# File lib/verse/alignment.rb, line 42
def right(width, options = {})
  align(width, :right, options)
end

Protected Instance Methods

center_justify(text, width, filler) click to toggle source

@api private

# File lib/verse/alignment.rb, line 129
def center_justify(text, width, filler)
  text_width = display_width(text)
  width_diff = width - text_width
  if width_diff > 0
    right_count = (width_diff.to_f / 2).ceil
    left_count  =  width_diff - right_count
    [filler * left_count, text, filler * right_count].join
  else
    text
  end
end
convert_to_method(direction) click to toggle source

@api private

# File lib/verse/alignment.rb, line 89
def convert_to_method(direction)
  case direction.to_sym
  when :left   then :left_justify
  when :right  then :right_justify
  when :center then :center_justify
  else
    raise ArgumentError, "Unknown alignment `#{direction}`."
  end
end
display_width(text) click to toggle source

@api private

# File lib/verse/alignment.rb, line 142
def display_width(text)
  Unicode::DisplayWidth.of(Sanitizer.sanitize(text))
end
left_justify(text, width, filler) click to toggle source

@api private

# File lib/verse/alignment.rb, line 109
def left_justify(text, width, filler)
  width_diff = width - display_width(text)
  if width_diff > 0
    text + filler * width_diff
  else
    text
  end
end
process_lines() { |text| ... } click to toggle source

@api private

# File lib/verse/alignment.rb, line 100
def process_lines
  lines = text.split(NEWLINE)
  return yield(text) if text.empty?
  lines.reduce([]) do |aligned, line|
    aligned << yield(line)
  end.join("\n")
end
right_justify(text, width, filler) click to toggle source

@api private

# File lib/verse/alignment.rb, line 119
def right_justify(text, width, filler)
  width_diff = width - display_width(text)
  if width_diff > 0
    filler * width_diff + text
  else
    text
  end
end