class String

def truncate(truncate_to, options = {})

# => "... (continued)"
'And they found that many people were sleeping better.'.truncate(4, omission: '... (continued)')

# => "And they f... (continued)"
'And they found that many people were sleeping better.'.truncate(25, omission: '... (continued)')

are longer than truncate_to:
The total length will not exceed truncate_to unless both +text+ and :omission
The last characters will be replaced with the :omission string (defaults to "...").

# => "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..."
'Once upon a time in a world far far away'.truncate(27, separator: ' ')

Pass a string or regexp :separator to truncate +text+ at a natural break:

# => "Once upon a time in a wo..."
'Once upon a time in a world far far away'.truncate(27)

Truncates a given +text+ to length truncate_to if +text+ is longer than truncate_to:
def truncate(truncate_to, options = {})
  return dup unless length > truncate_to
  omission = options[:omission] || "..."
  length_with_room_for_omission = truncate_to - 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]}#{omission}"
end