Module: Strings::Align

Defined in:
lib/strings/align.rb

Overview

Responsible for text alignment

Constant Summary collapse

NEWLINE =
"\n"
SPACE =
" "
LINE_BREAK =
%r{\r\n|\r|\n}.freeze

Class Method Summary collapse

Class Method Details

.align(text, width, direction: :left, **options) ⇒ Object

Aligns text within the width.

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

Examples:

text = "the madness of men"

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

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

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

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

Parameters:

  • text (String)

    the text to align lines of

  • width (Integer)

    the maximum width to align to



39
40
41
42
43
44
# 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: nil) ⇒ String

Centers text within the width

Returns:

  • (String)


86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/strings/align.rb', line 86

def align_center(text, width, fill: SPACE, separator: nil)
  return text if width.nil?
  sep = separator || text[LINE_BREAK] || NEWLINE

  each_line(text, sep) 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: nil) ⇒ String

Aligns text to the left at given length

Returns:

  • (String)


66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/strings/align.rb', line 66

def align_left(text, width, fill: SPACE, separator: nil)
  return if width.nil?
  sep = separator || text[LINE_BREAK] || NEWLINE

  each_line(text, sep) 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: nil) ⇒ String

Aligns text to the right at given length

Returns:

  • (String)


108
109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/strings/align.rb', line 108

def align_right(text, width, fill: SPACE, separator: nil)
  return text if width.nil?
  sep = separator || text[LINE_BREAK] || NEWLINE

  each_line(text, sep) do |line|
    width_diff = width - display_width(line)
    if width_diff > 0
      fill * width_diff + line
    else
      line
    end
  end
end

.display_width(string) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Visible width of a string



142
143
144
# File 'lib/strings/align.rb', line 142

def display_width(string)
  Unicode::DisplayWidth.of(Strings::ANSI.sanitize(string))
end

.each_line(text, separator) ⇒ String

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Enumerate text line by line

Parameters:

  • text (String)

Returns:

  • (String)


130
131
132
133
134
135
136
# File 'lib/strings/align.rb', line 130

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) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Convert direction to method name



50
51
52
53
54
55
56
57
58
# File 'lib/strings/align.rb', line 50

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