class String
# Returns the string, first removing all whitespace on both ends of
# the string, and then changing remaining consecutive whitespace
# groups into one space each.
#
# %{ Multi-line
# string }.squish # => "Multi-line string"
# " foo bar \n \t boo".squish # => "foo bar boo"
def squish
dup.squish!
end
# Performs a destructive squish. See String#squish.
def squish!
strip!
gsub!(/\s+/, ' ')
self
end
# Truncates a given +text+ after a given length if +text+ is longer than length:
#
# 'Once upon a time in a world far far away'.truncate(27)
# # => "Once upon a time in a wo..."
#
# Pass a string or regexp :separator to truncate +text+ at a natural break:
#
# 'Once upon a time in a world far far away'.truncate(27, :separator => ' ')
# # => "Once upon a time in a..."
#
# 'Once upon a time in a world far far away'.truncate(27, :separator => /\s/)
# # => "Once upon a time in a..."
#
# The last characters will be replaced with the :omission string (defaults to "...")
# for a total length not exceeding length:
#
# 'And they found that many people were sleeping better.'.truncate(25, :omission => '... (continued)')
# # => "And they f... (continued)"
def truncate(truncate_at, options = {})
return dup unless length > truncate_at
options[:omission] ||= '...'
length_with_room_for_omission = truncate_at - options[:omission].length
stop = \
if options[:separator]
rindex(options[:separator], length_with_room_for_omission) || length_with_room_for_omission
else
length_with_room_for_omission
end
self[0...stop] + options[:omission]
end
end