Class: String

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

Overview

Replaces part of the text with a gap.

Author

Yegor Bugayenko ([email protected])

Copyright

Copyright © 2025 Yegor Bugayenko

License

MIT

Instance Method Summary collapse

Instance Method Details

#ellipsized(*args) ⇒ String

Truncates a string to specified maximum length, inserting a gap in the middle if necessary. The resulting string will never be longer than the specified maximum length. The original string is returned if it is already shorter than or equal to the maximum length.

Examples:

Basic usage with default parameters

"Hello, world!".ellipsized
# => "Hello, world!"

Truncate a long string

"This is a very long string that needs to be truncated".ellipsized(20)
# => "This is...truncated"

Custom gap

"Another very long string example".ellipsized(15, '***')
# => "Anoth***example"

Custom align

"Another very long string example".ellipsized(15, '...', :left)
# => "...tring example"

Edge cases

"".ellipsized      # => ""
"Short".ellipsized # => "Short"
"xyz".ellipsized(0) # => ""
"xyz".ellipsized(2, '...') # => "xy"


60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/ellipsized.rb', line 60

def ellipsized(*args)
  raise "Unsupported number of arguments: #{args.length}" if args.length > 3

  max = gap = align = nil
  args.each do |arg|
    raise "Unsupported argument type: #{arg}" unless [
      Integer,
      String,
      Symbol
    ].include?(arg.class)

    case arg
    when Integer
      max = arg
      raise "Max length (#{max}) is negative" if max.negative?
      return '' if max.zero?
    when String
      gap = arg
    when Symbol
      align = arg
      raise "Unsupported align: #{align}" unless
        i[left center right].include?(align) # rubocop:disable Performance/CollectionLiteralInLoop
    end
  end
  max ||= 64
  gap ||= '...'
  align ||= :center

  return '' if empty?
  return self if length <= max
  return self[0..(max - 1)] if gap.length >= max

  case align
  when :left
    "#{gap}#{self[(length - max + gap.length)..]}"
  when :center
    head = tail = (max - gap.length) / 2
    head += 1 if head + tail + gap.length < max
    head = max if head > max
    "#{self[0, head]}#{gap}#{self[-tail, tail]}"
  when :right
    "#{self[0, max - gap.length]}#{gap}"
  end
end