On Monday 13 December 2004 10:37 am, Robert Klemme wrote:
| What about
|
| class String
|   def word_wrap!(n = 80)
|     raise ArgumentError, "Wrap margin too low: #{n}" if n <= 2
|     gsub!( Regexp.new( "(.{1,#{n-1}}\\w)\\b\\s*" ), "\\1\n")
|   end
|
|   def word_wrap(n = 80)
|     c = dup
|     c.word_wrap! n
|     c
|   end
| end

Thanks, robert. That's a nice basic approach, and for the lack of something 
better I think I will used. But it would be nice to have something a little 
more robust. Something that can determine when to divide and hyphenate a word 
if it is just too long.

Like I said, mine is far from perfect but I'll show it anyway:

  def word_wrap(max_width=nil, margin=6)
    max_width ||= 80
    max_width -= 1
    min_width = max_width - margin
    blocks = []; scan(/(.*)(\n\s+\n|\Z)/m){ blocks << $~ }
    complete = ''
    blocks.each{ |block|
      str = ''; line = ''
      body = block[1].gsub(/\s+/, ' ')
      padding = block[2].to_s
      words = body.split(/\s+/)
      i = 0
      words.each { |word|
        line << word
        while line.length > max_width
          clean_break = line.index(/\s\S*?$/)
          clean_break = 0 unless clean_break
          if clean_break < min_width
            remaining = line[max_width..-1]
            str << line.slice(0,max_width)
            str << '-' if /^[a-zA-Z0-9]/ =~ remaining
            str << "\n"
            line = line[max_width..-1]
          else
            str << line.slice(0,clean_break)
            str << " \n"
            line = line[(clean_break + 1)..-1]
          end
        end
        line << ' '
      }
      str << line.chomp(' ')
      complete << str << padding
    }  
    complete << "\n"
  end

I never realized how complex something seemingly so simple could be.

Thanks,
T.