From: Robert Klemme Date: 2004-12-14T05:02:19+09:00 Subject: Re: Help writing a each_unique method "trans. (T. Onoma)" schrieb im Newsbeitrag news:200412131056.58363.transami@runbox.com... > 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. You're welcome. > 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. Err, that plays in a whole different league... > 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 Ah, you use a margin to determine min line length. That makes things a bit more complicated of course. :-) > I never realized how complex something seemingly so simple could be. I guess, that's because of the complexity of our language (no, not Ruby). Kind regards robert