Display the first n words from a string

In my app, a Story has a summary field, and on the page that lists
stories, i want to show the first ‘n’ (eg twenty) words from the summary
(which i would follow with “…”).

Does anyone know a simple way to do this? I can think of complicated
and ugly ways to do it, involving going through the string a char at a
time counting spaces, but i’m guessing there’s a neat rails helper
(since there usually is!).

thanks
max

Hi Max,

On 5 Sep 2007, at 12:06, Max W. wrote:

In my app, a Story has a summary field, and on the page that lists
stories, i want to show the first ‘n’ (eg twenty) words from the
summary
(which i would follow with “…”).

Does anyone know a simple way to do this? I can think of complicated
and ugly ways to do it, involving going through the string a char at a
time counting spaces, but i’m guessing there’s a neat rails helper
(since there usually is!).

I usually go for the roll-your-own method, something like this should
work nicely for you, just pop the method in your application_helper
and call it in your views.

def first_x_words(str,n=20,finish=‘…’)
str.split(’ ')[0,n].inject{|sum,word| sum + ’ ’ + word} + finish
end

my_string = ‘Praesent luptatum zzril delenit augue duis dolore te
feugait nulla facilisi nam! Modo typi qui nunc nobis videntur parum
clari fiant sollemnes?’

p first_x_words(my_string) # => “Praesent luptatum zzril delenit
augue duis dolore te feugait nulla facilisi nam! Modo typi qui nunc
nobis videntur parum clari…”

p first_x_words(my_string, 5, ‘!!!’) # => “Praesent luptatum zzril
delenit augue!!!”

Hope this helps.

Douglas F Shearer
[email protected]

Douglas S. wrote:

def first_x_words(str,n=20,finish=‘…’)
str.split(’ ')[0,n].inject{|sum,word| sum + ’ ’ + word} + finish
end

Hope this helps.

Douglas F Shearer
[email protected]
http://douglasfshearer.com

That’s perfect, thanks Douglas.
(i would never think to use inject as it still confuses me a little!)

cheers
max

Max W. wrote:

Douglas S. wrote:

def first_x_words(str,n=20,finish=‘…’)
str.split(’ ')[0,n].inject{|sum,word| sum + ’ ’ + word} + finish
end

Hope this helps.

Douglas F Shearer
[email protected]
http://douglasfshearer.com

That’s perfect, thanks Douglas.
(i would never think to use inject as it still confuses me a little!)

cheers
max

BTW, i’m just curious - why do you prefer the ellipsis symbol @hellip to
“…”? Is this a convention?

On 5 Sep 2007, at 12:56, Peter De Berdt wrote:

On 05 Sep 2007, at 13:38, Max W. wrote:

BTW, i’m just curious - why do you prefer the ellipsis symbol
@hellip to
“…”? Is this a convention?

… renders correctly across all browsers, even if they don’t
respect the utf-8 encoding defined in the header.

Peter hit that nail on the head. It also looks a bit neater as the
letter-spacing is smaller between the periods of &hellip.

Glad it helped you out.

Douglas F Shearer
[email protected]

On 05 Sep 2007, at 13:38, Max W. wrote:

BTW, i’m just curious - why do you prefer the ellipsis symbol
@hellip to
“…”? Is this a convention?

… renders correctly across all browsers, even if they don’t
respect the utf-8 encoding defined in the header.

Best regards

Peter De Berdt

First of all, split takes a limiter, and its inverse is join:
words = str.split(’ ‘, n + 1)
words[-1] = finish
words.join(’ ')

But is this really what you want? Suppose the book was a discussion
on Mary Poppins? It seems to me that you have space for n characters,
and you need to end at a word break:
letters = str[0…limit - finish.length]
letters.sub!(/ \S*$/)
letters + " " + finish

On Sep 5, 7:08 am, Max W. [email protected]

Douglas S. wrote:

… renders correctly across all browsers, even if they don’t
respect the utf-8 encoding defined in the header.

Peter hit that nail on the head. It also looks a bit neater as the
letter-spacing is smaller between the periods of &hellip.

ahhh. nice tip, thanks guys.

def first_x_words(str,n=20,finish=’…’)
str.split(’ ')[0,n].inject{|sum,word| sum + ’ ’ + word} + finish
end

That’s perfect, thanks Douglas.
(i would never think to use inject as it still confuses me a little!)

No need for inject–you can rewrite that line:
str.split(’ ‘)[0,n].join(’ ') + finish

If, like another poster said, it is a CHARACTER limitation, yet you
still want to break on a word boundary, then replace the line with:
str[0,n].sub(/ ?\S*$/,’’) + finish

  • Mark.

Student wrote:

First of all, split takes a limiter, and its inverse is join:
words = str.split(’ ‘, n + 1)
words[-1] = finish
words.join(’ ')

But is this really what you want? Suppose the book was a discussion
on Mary Poppins? It seems to me that you have space for n characters,
and you need to end at a word break:
letters = str[0…limit - finish.length]
letters.sub!(/ \S*$/)
letters + " " + finish

On Sep 5, 7:08 am, Max W. [email protected]

Your suggestion is actually closer to what i want - thanks! However,
i’m having problems with the regular expression is sub - shouldn’t sub
take two parameters? What exactly is this line meant to be doing?

I put the above into a helper method, and when i call it i get a strange
error:
“wrong number of arguments (1 for 2)”

I’m definitely calling it correctly, and when i take the .sub line out
then it works (except for completing the last word, obviously).

Would you mind explaining this a bit?

thanks a lot
max

Max W. wrote:

In my app, a Story has a summary field, and on the page that lists
stories, i want to show the first ‘n’ (eg twenty) words from the summary
(which i would follow with “…”).

Does anyone know a simple way to do this? I can think of complicated
and ugly ways to do it, involving going through the string a char at a
time counting spaces, but i’m guessing there’s a neat rails helper
(since there usually is!).

thanks
max

Hey Max,
do you not just want the truncate rails helper?

On Sep 5, 6:04 pm, Matthew R. [email protected]
wrote:

Hey Max,
do you not just want the truncate rails helper?

ActionView::Helpers::TextHelper

No, because he wants to break only on word boundaries.

On Sep 5, 2007, at 8:58 AM, Max W. wrote:

and you need to end at a word break:

I put the above into a helper method, and when i call it i get a
strange
error:
“wrong number of arguments (1 for 2)”

I’m definitely calling it correctly, and when i take the .sub line out
then it works (except for completing the last word, obviously).

Would you mind explaining this a bit?

Check out this helper: http://pastie.textmate.org/94218


Benjamin C.
http://www.bencurtis.com/ – blog
http://agilewebdevelopment.com/guides – Rails tutorials

Basically the same thing aside from the encapsulation in a class.
Didn’t see that one when I wrote mine. I went ahead and pluginized
mine, though, since I’ll probaby use it often:

svn://reinh.com/plugins/truncator

truncate, truncate_words, truncate_sentences, truncate_on

Oh, I forgot to mention, it also removes trailing punctuation from the
truncated string to avoid typographical errors like: “Lorem ipsum,…”

inject here is unnecessarily expensive. I try to avoid using inject if
it isn’t really needed.

Using ActionView’s truncate() as a model:

def truncate_words(text, num_words = 6, truncate_string = “…”)
if text.nil? then return end
arr = text.split(’ ‘)
arr.length > num_words ? arr[0…num_words].join(’ ') +
truncate_string : text
end

ReinH
reinh.com

On Sep 5, 6:30 am, Max W. [email protected]

Please unsubscribe me from this google group

Thanks

Joseph Chapman,


Get free emoticon packs and customisation from Windows Live.
http://www.pimpmylive.co.uk

Mohit S. wrote:

Joseph:
To unsubscribe from this group, send email to
[email protected]

Bye!
Mohit.

he’s a spammer, ignore him :slight_smile:

Changing the subject back to something useful.

Joseph:
To unsubscribe from this group, send email to
[email protected]

Bye!
Mohit.