Class: Toys::WrappableString

Inherits:
Object
  • Object
show all
Defined in:
lib/toys/wrappable_string.rb

Overview

A string intended for word-wrapped display.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(string = "") ⇒ WrappableString

Create a wrapped string.

Parameters:

  • string (String, Array<String>) (defaults to: "")

    The string or array of string fragments



34
35
36
# File 'lib/toys/wrappable_string.rb', line 34

def initialize(string = "")
  @fragments = string.is_a?(::Array) ? string.map(&:to_s) : string.to_s.split
end

Instance Attribute Details

#fragmentsArray<String> (readonly)

Returns the string fragments, i.e. the individual "words" for wrapping.

Returns:

  • (Array<String>)


43
44
45
# File 'lib/toys/wrappable_string.rb', line 43

def fragments
  @fragments
end

Class Method Details

.make(obj) ⇒ Toys::WrappableString

Make the given object a WrappableString. If the object is already a WrappableString, return it. Otherwise, treat it as a string or an array of strings and wrap it in a WrappableString.

Parameters:

Returns:



148
149
150
# File 'lib/toys/wrappable_string.rb', line 148

def self.make(obj)
  obj.is_a?(WrappableString) ? obj : WrappableString.new(obj)
end

.make_array(objs) ⇒ Array<Toys::WrappableString>

Make the given object an array of WrappableString.

Parameters:

Returns:



158
159
160
# File 'lib/toys/wrappable_string.rb', line 158

def self.make_array(objs)
  Array(objs).map { |obj| make(obj) }
end

.wrap_lines(strs, width, width2 = nil) ⇒ Array<String>

Wraps an array of lines to the given width.

Parameters:

  • strs (Array<WrappableString>)

    Array of strings to wrap.

  • width (Integer, nil)

    Width in characters, or nil for infinite.

  • width2 (Integer, nil) (defaults to: nil)

    Width in characters for the second and subsequent lines, or nil to use the same as width.

Returns:

  • (Array<String>)

    Wrapped lines



128
129
130
131
132
133
134
135
136
137
# File 'lib/toys/wrappable_string.rb', line 128

def self.wrap_lines(strs, width, width2 = nil)
  result = Array(strs).map do |s|
    s = make(s)
    lines = s.empty? ? [""] : s.wrap(width, width2)
    width = width2 if width2
    lines
  end.flatten
  result = [] if result.all?(&:empty?)
  result
end

Instance Method Details

#+(other) ⇒ WrappableString

Returns a new WrappaableString whose content is the concatenation of this WrappableString with another WrappableString.

Parameters:

Returns:



52
53
54
55
# File 'lib/toys/wrappable_string.rb', line 52

def +(other)
  other = WrappableString.new(other) unless other.is_a?(WrappableString)
  WrappableString.new(fragments + other.fragments)
end

#empty?Boolean

Returns true if the string is empty (i.e. has no fragments)

Returns:

  • (Boolean)


61
62
63
# File 'lib/toys/wrappable_string.rb', line 61

def empty?
  @fragments.empty?
end

#stringString Also known as: to_s

Returns the string without any wrapping

Returns:

  • (String)


69
70
71
# File 'lib/toys/wrappable_string.rb', line 69

def string
  @fragments.join(" ")
end

#wrap(width, width2 = nil) ⇒ Array<String>

Wraps the string to the given width.

Parameters:

  • width (Integer, nil)

    Width in characters, or nil for infinite.

  • width2 (Integer, nil) (defaults to: nil)

    Width in characters for the second and subsequent lines, or nil to use the same as width.

Returns:

  • (Array<String>)

    Wrapped lines



95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/toys/wrappable_string.rb', line 95

def wrap(width, width2 = nil)
  lines = []
  line = ""
  line_len = 0
  fragments.each do |frag|
    frag_len = frag.gsub(/\e\[\d+(;\d+)*m/, "").size
    if line_len.zero?
      line = frag
      line_len = frag_len
    elsif width && line_len + 1 + frag_len > width
      lines << line
      line = frag
      line_len = frag_len
      width = width2 if width2
    else
      line_len += frag_len + 1
      line = "#{line} #{frag}"
    end
  end
  lines << line if line_len.positive?
  lines
end