# Word\_wrap method for String?

**URL:** <https://rubytalk.org/t/word-wrap-method-for-string/25710>\
**Category:** ruby-talk\
**Created:** [13 March 2006 12:56 UTC](https://rubytalk.org/t/word-wrap-method-for-string/25710 "2006-03-13T12:56:26Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![Jeff\_Coleman](https://avatars.discourse-cdn.com/v4/letter/j/aca169/32.png) [@Jeff\_Coleman](https://rubytalk.org/u/Jeff_Coleman)\
**Post date:** [13 March 2006 12:56 UTC](https://rubytalk.org/t/word-wrap-method-for-string/25710/1 "2006-03-13T12:56:26Z")

</div>

Hi all,

For a text adventure program I'm working on I needed a method to word  
wrap a long string based on spaces or non-word characters so I came up  
with this. I just thought I'd post it to see if there are any thoughts  
or if there might be a better way to do it.

class String  
&nbsp;&nbsp;def word\_wrap(width)  
&nbsp;&nbsp;&nbsp;&nbsp;source = self.dup  
&nbsp;&nbsp;&nbsp;&nbsp;original\_width = width  
&nbsp;&nbsp;&nbsp;&nbsp;while width \< source.length do  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;last\_space = source.rindex( / |\W/, width )  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;source.insert( last\_space, "\n" )  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;source.gsub!(/\n \*/,"\n")  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;width = last\_space + original\_width  
&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;&nbsp;source  
&nbsp;&nbsp;end  
end

Jeff Coleman

> **···**
>
> --  
> Posted via [http://www.ruby-forum.com/](http://www.ruby-forum.com/).

---

<div class="post-metadata">

**Author:** ![Mike12](https://avatars.discourse-cdn.com/v4/letter/m/4491bb/32.png) [@Mike12](https://rubytalk.org/u/Mike12)\
**Post date:** [13 March 2006 13:04 UTC](https://rubytalk.org/t/word-wrap-method-for-string/25710/2 "2006-03-13T13:04:38Z")

</div>

> For a text adventure program I'm working on I needed a method  
> to word wrap a long string based on spaces or non-word  
> characters so I came up with this. I just thought I'd post  
> it to see if there are any thoughts or if there might be a  
> better way to do it.

I wrote one last week, actually

&nbsp;&nbsp;def wrap(wrap\_len=78)  
&nbsp;&nbsp;&nbsp;&nbsp;start\_pos = wrap\_len  
&nbsp;&nbsp;&nbsp;&nbsp;while start\_pos \< @fact.length  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sp = @fact.rindex(' ', start\_pos)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@fact.insert(sp, '|')  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;start\_pos = sp + wrap\_len + 1  
&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;&nbsp;@fact.gsub!(/\|[\s]/, "\n")  
&nbsp;&nbsp;end

I'm far from an expert, so I don't know which method may be better 🙂

-M

---

<div class="post-metadata">

**Author:** ![Lou\_Vanek](https://avatars.discourse-cdn.com/v4/letter/l/c77e96/32.png) [@Lou\_Vanek](https://rubytalk.org/u/Lou_Vanek)\
**Post date:** [13 March 2006 13:16 UTC](https://rubytalk.org/t/word-wrap-method-for-string/25710/3 "2006-03-13T13:16:23Z")

</div>

here's a (partially modded) excerpt from a previous discussion on this topic:

width = 11  
str = 'This is a test of the emergency broadcasting servicings I asseverate'  
p str.scan(/\S.{0,#{width}}\S(?=\s|$)|\S+/)

Jeff Coleman wrote:

> **···**
>
> > Hi all,
> > 
> > For a text adventure program I'm working on I needed a method to word wrap a long string based on spaces or non-word characters so I came up with this. I just thought I'd post it to see if there are any thoughts or if there might be a better way to do it.
> > 
> > class String  
> > &nbsp;&nbsp;def word\_wrap(width)  
> > &nbsp;&nbsp;&nbsp;&nbsp;source = self.dup  
> > &nbsp;&nbsp;&nbsp;&nbsp;original\_width = width  
> > &nbsp;&nbsp;&nbsp;&nbsp;while width \< source.length do  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;last\_space = source.rindex( / |\W/, width )  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;source.insert( last\_space, "\n" )  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;source.gsub!(/\n \*/,"\n")  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;width = last\_space + original\_width  
> > &nbsp;&nbsp;&nbsp;&nbsp;end  
> > &nbsp;&nbsp;&nbsp;&nbsp;source  
> > &nbsp;&nbsp;end  
> > end
> > 
> > Jeff Coleman

---

<div class="post-metadata">

**Author:** ![Daniel\_Harple](https://avatars.discourse-cdn.com/v4/letter/d/5daacb/32.png) [@Daniel\_Harple](https://rubytalk.org/u/Daniel_Harple)\
**Post date:** [13 March 2006 14:28 UTC](https://rubytalk.org/t/word-wrap-method-for-string/25710/4 "2006-03-13T14:28:02Z")

</div>

This one is taken from facets[1]. I use it to wrap lines in TextMate.

def word\_wrap(text, col\_width=80)  
&nbsp;&nbsp;&nbsp;text.gsub!( /(\S{#{col\_width}})(?=\S)/, '\1 ' )  
&nbsp;&nbsp;&nbsp;text.gsub!( /(.{1,#{col\_width}})(?:\s+|$)/, "\\1\n" )  
&nbsp;&nbsp;&nbsp;text  
end

[1] gem install facets

-- Daniel

> **···**
>
> On Mar 13, 2006, at 1:56 PM, Jeff Coleman wrote:
> 
> > For a text adventure program I'm working on I needed a method to word  
> > wrap a long string based on spaces or non-word characters so I came up  
> > with this. I just thought I'd post it to see if there are any thoughts  
> > or if there might be a better way to do it.

---

<div class="post-metadata">

**Author:** ![Jeff\_Coleman](https://avatars.discourse-cdn.com/v4/letter/j/aca169/32.png) [@Jeff\_Coleman](https://rubytalk.org/u/Jeff_Coleman)\
**Post date:** [13 March 2006 13:23 UTC](https://rubytalk.org/t/word-wrap-method-for-string/25710/5 "2006-03-13T13:23:55Z")

</div>

Lou Vanek wrote:

> here's a (partially modded) excerpt from a previous discussion on this  
> topic:
> 
> width = 11  
> str = 'This is a test of the emergency broadcasting servicings I  
> asseverate'  
> p str.scan(/\S.{0,#{width}}\S(?=\s|$)|\S+/)

When I was writing that I just KNEW there must be some one-line solution  
involving regular expressions!

Although I don't quite follow the exact structure of this one, it  
definitely works...

Jeff

> **···**
>
> --  
> Posted via [http://www.ruby-forum.com/\](http://www.ruby-forum.com/%5C).

---

<div class="post-metadata">

**Author:** ![Matthew\_Harris](https://avatars.discourse-cdn.com/v4/letter/m/51bf81/32.png) [@Matthew\_Harris](https://rubytalk.org/u/Matthew_Harris)\
**Post date:** [13 March 2006 13:34 UTC](https://rubytalk.org/t/word-wrap-method-for-string/25710/6 "2006-03-13T13:34:07Z")

</div>

Mike wrote:

> > For a text adventure program I'm working on I needed a method  
> > to word wrap a long string based on spaces or non-word  
> > characters so I came up with this. I just thought I'd post  
> > it to see if there are any thoughts or if there might be a  
> > better way to do it.
> 
> I wrote one last week, actually
> 
> &nbsp;&nbsp;def wrap(wrap\_len=78)  
> &nbsp;&nbsp;&nbsp;&nbsp;start\_pos = wrap\_len  
> &nbsp;&nbsp;&nbsp;&nbsp;while start\_pos \< @fact.length  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sp = @fact.rindex(' ', start\_pos)  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@fact.insert(sp, '|')  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;start\_pos = sp + wrap\_len + 1  
> &nbsp;&nbsp;&nbsp;&nbsp;end  
> &nbsp;&nbsp;&nbsp;&nbsp;@fact.gsub!(/\|[\s]/, "\n")  
> &nbsp;&nbsp;end
> 
> I'm far from an expert, so I don't know which method may be better 🙂
> 
> -M

class String  
&nbsp;&nbsp;# Wrap string by the given length, and join it with the given  
character.  
&nbsp;&nbsp;# The method doesn't distinguish between words, it will only work based  
on  
&nbsp;&nbsp;# the length. The method will also strip and whitespace.

> **···**
>
> #  
> &nbsp;&nbsp;def wrap(length = 80, character = $/)  
> &nbsp;&nbsp;&nbsp;&nbsp;scan(/.{#{length}}|.+/).map { |x| x.strip }.join(character)  
> &nbsp;&nbsp;end  
> end
> 
> puts 'Hello, World! I am quite very long :)'.wrap(15, "\<br\>\n")
> 
> # Output:  
> #  
> # Hello, World! I\<br\>  
> # am quite very\<br\>  
> # long 🙂
> 
> Have fun =)
> 
> - Matt
> 
> --  
> Posted via [http://www.ruby-forum.com/\](http://www.ruby-forum.com/%5C).

---

<div class="post-metadata">

**Author:** ![W\_James](https://avatars.discourse-cdn.com/v4/letter/w/e274bd/32.png) [@W\_James](https://rubytalk.org/u/W_James)\
**Post date:** [13 March 2006 15:48 UTC](https://rubytalk.org/t/word-wrap-method-for-string/25710/7 "2006-03-13T15:48:45Z")

</div>

Lou Vanek wrote:

> here's a (partially modded) excerpt from a previous discussion on this topic:
> 
> width = 11  
> str = 'This is a test of the emergency broadcasting servicings I asseverate'  
> p str.scan(/\S.{0,#{width}}\S(?=\s|$)|\S+/)

When you modded, you didn't notice that 8 was 2 less than the width.

str =  
'This is a test of the emergency broadcasting servicings I asseverate'  
p str.scan(/\S.{0,#{width-2}}\S(?=\s|$)|\S+/)

---

<div class="post-metadata">

**Author:** ![Lou\_Vanek](https://avatars.discourse-cdn.com/v4/letter/l/c77e96/32.png) [@Lou\_Vanek](https://rubytalk.org/u/Lou_Vanek)\
**Post date:** [13 March 2006 13:46 UTC](https://rubytalk.org/t/word-wrap-method-for-string/25710/8 "2006-03-13T13:46:30Z")

</div>

everthing old is new again.  
you might also want to compare speeds. Yours might be faster.  
-lv

Jeff Coleman wrote:

> **···**
>
> > Lou Vanek wrote:
> > 
> > > here's a (partially modded) excerpt from a previous discussion on this topic:
> > > 
> > > width = 11  
> > > str = 'This is a test of the emergency broadcasting servicings I asseverate'  
> > > p str.scan(/\S.{0,#{width}}\S(?=\s|$)|\S+/)
> > 
> > When I was writing that I just KNEW there must be some one-line solution involving regular expressions!
> > 
> > Although I don't quite follow the exact structure of this one, it definitely works...
> > 
> > Jeff

---

<div class="post-metadata">

**Author:** ![Jeff\_Coleman](https://avatars.discourse-cdn.com/v4/letter/j/aca169/32.png) [@Jeff\_Coleman](https://rubytalk.org/u/Jeff_Coleman)\
**Post date:** [13 March 2006 13:53 UTC](https://rubytalk.org/t/word-wrap-method-for-string/25710/9 "2006-03-13T13:53:56Z")

</div>

Lou Vanek wrote:

> everthing old is new again.  
> you might also want to compare speeds. Yours might be faster.  
> -lv

It's my first time using the profiler, but if I'm reading this  
correctly--

It took my version 27 seconds to do 6000 word\_wraps. Your regexp  
version did the same in 2.4 seconds 🙂

Jeff Coleman

> **···**
>
> --  
> Posted via [http://www.ruby-forum.com/\](http://www.ruby-forum.com/%5C).

---

<div class="post-metadata">

**Author:** ![Lou\_Vanek](https://avatars.discourse-cdn.com/v4/letter/l/c77e96/32.png) [@Lou\_Vanek](https://rubytalk.org/u/Lou_Vanek)\
**Post date:** [13 March 2006 14:07 UTC](https://rubytalk.org/t/word-wrap-method-for-string/25710/10 "2006-03-13T14:07:16Z")

</div>

yahtzee!  
btw, this isn't my regex. Like most things of mine, they're  
either cribbed, borrowed, or outright stolen.  
-lv

Jeff Coleman wrote:

> **···**
>
> > Lou Vanek wrote:
> > 
> > > everthing old is new again.  
> > > you might also want to compare speeds. Yours might be faster.  
> > > -lv
> > 
> > It's my first time using the profiler, but if I'm reading this correctly--
> > 
> > It took my version 27 seconds to do 6000 word\_wraps. Your regexp version did the same in 2.4 seconds 🙂
> > 
> > Jeff Coleman
