views:

288

answers:

2

I wonder if there's a plugin to enable a sort of smart truncation. I need to truncate my text with a precision of a word or of a sentence.

For example:

Post.my_message.smart_truncate(
    "Once upon a time in a world far far away. And they found that many people
     were sleeping better.", :sentences => 1)
# => Once upon a time in a world far far away.

or

Post.my_message.smart_truncate(
    "Once upon a time in a world far far away. And they found that many people
     were sleeping better.", :words => 12)
# => Once upon a time in a world far far away. And they ...
+4  A: 

I haven't seen such a plugin, but there was a similar question that could serve as the basis for a lib or helper function.

The way you show the function seems to put it as an extension to String: unless you really want to be able to do this outside of a view, I'd be inclined to go for a function in application_helper.rb. Something like this, perhaps?

module ApplicationHelper

  def smart_truncate(s, opts = {})
    opts = {:words => 12}.merge(opts)
    if opts[:sentences]
      return s.split(/\./)[0, opts[:sentences]].map{|s| s.strip}.join('. ') + '.'
    end
    a = s.split(/\s/) # or /[ ]+/ to only split on spaces
    n = opts[:words]
    a[0...n].join(' ') + (a.size > n ? '...' : '')
  end
end

smart_truncate("a b c. d e f. g h i.", :sentences => 2) #=> "a b c. d e f."
smart_truncate("apple blueberry cherry plum", :words => 3) #=> "apple blueberry cherry..."
Mike Woodhouse
Oh, that was a really good answer! Thanks a lot!Now I see a real reason to increase my knowledge in regular expressions.
gmile
A: 

This will truncate at the word boundary based on the char_limit length specified. So it will not truncate the sentence at weird places

def smart_truncate(text, char_limit)
    size =0
    text.split().reject do |token|
      size+=token.size()
      size>char_limit
    end.join(" ")+(text.size()>char_limit? " "+ "..." : "" )
end
soulofpeace