Method: String#truncate_bytes

Defined in:
lib/simple_ext/string/filters.rb

#truncate_bytes(truncate_at, omission: "…") ⇒ Object

Truncates text to at most bytesize bytes in length without breaking string encoding by splitting multibyte characters or breaking grapheme clusters (“perceptual characters”) by truncating at combining characters.

>> "🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪".size
=> 20
>> "🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪".bytesize
=> 80
>> "🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪".truncate_bytes(20)
=> "🔪🔪🔪🔪…"

The truncated text ends with the :omission string, defaulting to “…”, for a total length not exceeding bytesize.



95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/simple_ext/string/filters.rb', line 95

def truncate_bytes(truncate_at, omission: "")
  omission ||= ""

  case
  when bytesize <= truncate_at
    dup
  when omission.bytesize > truncate_at
    raise ArgumentError, "Omission #{omission.inspect} is #{omission.bytesize}, larger than the truncation length of #{truncate_at} bytes"
  when omission.bytesize == truncate_at
    omission.dup
  else
    self.class.new.tap do |cut|
      cut_at = truncate_at - omission.bytesize

      scan(/\X/) do |grapheme|
        if cut.bytesize + grapheme.bytesize <= cut_at
          cut << grapheme
        else
          break
        end
      end

      cut << omission
    end
  end
end