def truncate(str, truncate_at, omission: '...', separator: nil)
      return str.dup unless str.length > truncate_at

      omission = omission || '...'
      length_with_room_for_omission = truncate_at - omission.length
      stop = \
        if separator
          rindex(separator, length_with_room_for_omission) || length_with_room_for_omission
        else
          length_with_room_for_omission
        end

      "#{str[0, stop]}#{omission}"
    end
def truncate(str, truncate_at, omission: '...', separator: nil)
      return str.dup unless str.length > truncate_at

      omission = omission || '...'
      length_with_room_for_omission = truncate_at - omission.length
      stop = \
        if separator
          rindex(separator, length_with_room_for_omission) || length_with_room_for_omission
        else
          length_with_room_for_omission
        end

      "#{str[0, stop]}#{omission}"
    end
From ActiveSupport (Thanks for Rails Team!)  <https://github.com/rails/rails/tree/master/activesupport>

 Truncates a given +text+ after a given <tt>length</tt> if +text+ is longer than <tt>length</tt>:

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

 Pass a string or regexp <tt>:separator</tt> 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 <tt>:omission</tt> string (defaults to "...")
 for a total length not exceeding <tt>length</tt>:

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