Wrapping strings

I have a string containing multiple lines that I would like to put
into a C++ file as a comment:
desc = ""
while (line = gets) !~ /^\.$/
  desc += "#{line}"
end

I'd like to precede each line with a "// " to make it a comment, and
I'd like to wrap each line by the 78th character.

I don't suppose there is any way to do this quick and simple like?

I figure I need to pull out the carriage returns, but then I can't
think of anything pretty after that. Any tips?

-Ben

Ben <benbelly@gmail.com> writes:

I have a string containing multiple lines that I would like to put
into a C++ file as a comment:
desc =3D ""
while (line =3D gets) !~ /^\.$/
desc +=3D "#{line}"
end

I'd like to precede each line with a "// " to make it a comment, and
I'd like to wrap each line by the 78th character.

I don't suppose there is any way to do this quick and simple like?

I figure I need to pull out the carriage returns, but then I can't
think of anything pretty after that. Any tips?

I recommend getting the text-format module (available from the RAA
at http://rubyforge.org/projects/text-format or as a gem) and using it.

If that doesn't fit your needs for some reason, you can do it manually.
Something like this should work:

    words = line.split(/\s+/)
    while words do
        line = '// '
        while words && line.length < 78 do
      line += words.shift + ' '
  end
  puts line
    end

···

-Ben

harp:~ > cat a.rb
   require 'alib'

   comment = "foobar " * 42

   indented = ALib::Util::columnize comment, 'indent' => '// ', 'width' => 78

   puts(('.' * 77) << 'v')
   puts indented
   puts(('.' * 77) << '^')

   harp:~ > ruby a.rb
   .............................................................................v
   // foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar
   // foobar foobar
   .............................................................................^

hth.

-a

···

On Tue, 4 Oct 2005, Ben wrote:

I have a string containing multiple lines that I would like to put
into a C++ file as a comment:
desc = ""
while (line = gets) !~ /^\.$/
desc += "#{line}"
end

I'd like to precede each line with a "// " to make it a comment, and I'd
like to wrap each line by the 78th character.

I don't suppose there is any way to do this quick and simple like?

I figure I need to pull out the carriage returns, but then I can't think of
anything pretty after that. Any tips?

--

email :: ara [dot] t [dot] howard [at] noaa [dot] gov
phone :: 303.497.6469
Your life dwells amoung the causes of death
Like a lamp standing in a strong breeze. --Nagarjuna

===============================================================================

Here's a cool hack by Erik Terpstra for word wrapping normal text:

irb(main):001:0> str = 'This is a test of the emergency broadcasting services'
=> "This is a test of the emergency broadcasting services"
irb(main):002:0> str.scan(/(.{1,30})(?:\s+|$)/).flatten.join("\n")
=> "This is a test of the\nemergency broadcasting\nservices"

Hope that gives you some ideas.

James Edward Gray II

···

On Oct 3, 2005, at 9:25 PM, Ben wrote:

I have a string containing multiple lines that I would like to put
into a C++ file as a comment:
desc = ""
while (line = gets) !~ /^\.$/
  desc += "#{line}"
end

I'd like to precede each line with a "// " to make it a comment, and
I'd like to wrap each line by the 78th character.

I don't suppose there is any way to do this quick and simple like?

Mark J. Reed <mreed@thereeds.org> writes:

I have a string containing multiple lines that I would like to put
into a C++ file as a comment:
desc =3D ""
while (line =3D gets) !~ /^\.$/
desc +=3D "#{line}"
end

[snippy-snip]

   words = line.split(/\s+/)

Wrong Variable Syndrome. That should be desc.split, not line.split.

···

   while words do
       line = '// '
       while words && line.length < 78 do
    line += words.shift + ' '
end
puts line
   end

Thanks to e all who replied. I took Ara's idea to make it generic,
and the basic look from Mark, and this is what I came up with:

def TextWrap(lines, prefix = '', postfix = '', wrapat = 78, rightAlign = nil)
  if prefix.size + postfix.size > wrapat then
    raise RuntimeError, "prefix length + postfix length > wrapat"
  end
  wrapped =
  words = lines.split(/\s+/)
  while words.size > 0 do
    line = prefix
    if (words[0].length + prefix.length + postfix.length) > wrapat then
      # A single long word can cause problems
      line += words.shift
    else
      while (words.size > 0) &&
            ((line.length + words[0].length + postfix.length) <= wrapat) do
        line += words.shift + ' '
      end
    end
    if rightAlign then
      padlength = wrapat - (line.length + postfix.length)
      line += " " * padlength if padlength > 0
    end
    line += postfix
    wrapped << line
  end
  wrapped
end

It won't stand up to abuse, but it will do anything I need it to for a
while. I made a couple changes from what you suggested, Mark.

I need to check against words.size, not just words since shifting all
the values out does not make the array nil. Also, I added the word
length and the postfix length to the line length to make sure
everything will fit within the wrap boundary before adding the word.
There is some ugliness to handle very long words.

Can it be prettied up? I have avoided dynamic languages in the past
because my primary use for them is text processing, which I hate and
try not to think about. :slight_smile:

-Ben

···

On 10/3/05, Mark J. Reed <mreed@thereeds.org> wrote:

Mark J. Reed <mreed@thereeds.org> writes:

> while words do
> line = '// '
> while words && line.length < 78 do
> line += words.shift + ' '
> end
> puts line
> end