Forum: Ruby word_wrap method for String?

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
59ea1b450935b9d70abfec4186b7a4d5?d=identicon&s=25 Jeff Coleman (progressions)
on 2006-03-13 13:56
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
  def word_wrap(width)
    source = self.dup
    original_width = width
    while width < source.length do
      last_space = source.rindex( / |\W/, width )
      source.insert( last_space, "\n" )
      source.gsub!(/\n */,"\n")
      width = last_space + original_width
    end
    source
  end
end

Jeff Coleman
Be3f276f615e29a7c605efd1d3bc3cae?d=identicon&s=25 Mike (Guest)
on 2006-03-13 14:06
(Received via mailing list)
> 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

  def wrap(wrap_len=78)
    start_pos = wrap_len
    while start_pos < @fact.length
      sp = @fact.rindex(' ', start_pos)
      @fact.insert(sp, '|')
      start_pos = sp + wrap_len + 1
    end
    @fact.gsub!(/\|[\s]/, "\n")
  end

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

-M
Ce60c4f78a63b0695e4dafc4bd7964f7?d=identicon&s=25 Lou Vanek (Guest)
on 2006-03-13 14:19
(Received via mailing list)
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+/)
59ea1b450935b9d70abfec4186b7a4d5?d=identicon&s=25 Jeff Coleman (progressions)
on 2006-03-13 14:23
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
04a0f1074e1b621746954ccc73eec7d7?d=identicon&s=25 Matthew Harris (kuja)
on 2006-03-13 14:33
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
>
>   def wrap(wrap_len=78)
>     start_pos = wrap_len
>     while start_pos < @fact.length
>       sp = @fact.rindex(' ', start_pos)
>       @fact.insert(sp, '|')
>       start_pos = sp + wrap_len + 1
>     end
>     @fact.gsub!(/\|[\s]/, "\n")
>   end
>
> I'm far from an expert, so I don't know which method may be better :)
>
> -M

class String
	# Wrap string by the given length, and join it with the given
character.
	# The method doesn't distinguish between words, it will only work based
on
	# the length. The method will also strip and whitespace.
	#
	def wrap(length = 80, character = $/)
		scan(/.{#{length}}|.+/).map { |x| x.strip }.join(character)
	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
Ce60c4f78a63b0695e4dafc4bd7964f7?d=identicon&s=25 Lou Vanek (Guest)
on 2006-03-13 14:46
(Received via mailing list)
everthing old is new again.
you might also want to compare speeds. Yours might be faster.
-lv
59ea1b450935b9d70abfec4186b7a4d5?d=identicon&s=25 Jeff Coleman (progressions)
on 2006-03-13 14:53
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
Ce60c4f78a63b0695e4dafc4bd7964f7?d=identicon&s=25 Lou Vanek (Guest)
on 2006-03-13 15:08
(Received via mailing list)
yahtzee!
btw, this isn't my regex. Like most things of mine, they're
either cribbed, borrowed, or outright stolen.
-lv
9358cc96c46055cd68d4a76a9aefe026?d=identicon&s=25 Daniel Harple (Guest)
on 2006-03-13 15:29
(Received via mailing list)
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.

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

def word_wrap(text, col_width=80)
   text.gsub!( /(\S{#{col_width}})(?=\S)/, '\1 ' )
   text.gsub!( /(.{1,#{col_width}})(?:\s+|$)/, "\\1\n" )
   text
end

[1] gem install facets

-- Daniel
2ee1a7960cc761a6e92efb5000c0f2c9?d=identicon&s=25 William James (Guest)
on 2006-03-13 16:49
(Received via mailing list)
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+/)
This topic is locked and can not be replied to.