On Aug 13, [EMAIL PROTECTED] said:

>It messes up when I need to wrap lines with \n that don't end in a space.
>If there is no space, it places last word on its own line before it
>should wrap.  Otherwise it double \ns the line.

>sub quickWrap {
>       my $data = @_[0];

You shouldn't use an array slice where you mean to use a single array
element.

  my $data = $_[0];

>       my $wrapAt = 75;
>       if (scalar @_ > 1) {
>               $wrapAt = @_[1];
>       }

Again, @_[1] should be $_[1].  And the use of scalar() here is redundant.

  if (@_ > 1) { $wrapAt = $_[1] }

We could have written those first few lines in many different ways.  Here
are two ways I might have written it:

  my $data = shift;
  my $wrap_at = @_ ? shift : 75;

or

  my $data = $_[0];
  my $wrap_at = @_ > 1 ? $_[1] : 75;

>       my $wrappedData ="";

It's not technically required to give $wrappedData a value of "", since
you're adding to it using the .= operator, which is nice enough not to
complain if the variable started out undef.  Just a little note.

>       while ($data =~ /[^|\n][^\n]{$wrapAt,}?[ |$|\n]/) {

Something tells me you're not sure what a character class does.  A
character class is for CHARACTERS.  Therefore, you don't use | in it.  The
class [a|b|c] is the same as [|abc] -- that is, it matches an 'a', an 'b',
a 'c', or a '|'.  Also, you can't match "beginning of line" or "end of
line" in a regex, like you think you're doing with [^|\n] and [ |$|\n].
First of all, the ^ and $ in a regex don't mean the same thing inside a
character class.  Second, ^ and $ don't match characters, they match
locations.  Third, the ^, as the first character of a class, means "match
everything except ...".

So.  Let's give your regex a fixer-upper.  Instead of [^|\n], I have a
feeling you'll want either (?:^|\n) which matches ^ or \n, and doesn't
capture to any $DIGIT variable; or maybe you can use ^ with the /m
modifier on the regex.  Instead of [^\n], you can just use . -- that's
what it was made for.  And instead of [ |$|\n], you'll want (?:\s|$) I
think.

But I think you're doing MUCH more work than needed.  We'll see.

>               $data =~ /([^|\n])([^\n]{1,$wrapAt})( )([\s|\S]*$)/;

This regex looks familiar.  I'm going to suggest a big change in a bit.
Oh, and [\s|\S], which could be [\s\S], is kind of awkward.

>               $wrappedData .= "$`$1$2\n";

EWW.  DON'T USE $`.  It's terrible.

>               $data = "$4";

You don't need those quotes.

>       }
>       return "$wrappedData$data";
>}

Ok, here's my idea:  instead of matching text and putting it in a new
string, why not CHANGE the string we're working on as we match it?  We can
do that using a substitution, the s/// operation.

We want to match UP TO $wrap_at characters, as many as possible, and add a
newline after them, SO LONG as it's in the place of a space.  Here's a
regex I think will do the job for you:

  sub quick_wrap {  # I use the word_word_word style, not wordWordWord
    my $str = shift;
    my $wrap_at = @_ ? shift : 60;

    $str =~ s{(.{1,$wrap_at})\s}{$1\n}g;

    return $str;
  }

The regex matches between 1 and $wrap_at characters (trying to match the
most possible) that are followed by a space.  It replaces this with the
text it matched (and captured to $1) followed by a newline.  Let me know
if this does what you expected.

-- 
Jeff "japhy" Pinyan      [EMAIL PROTECTED]      http://www.pobox.com/~japhy/
RPI Acacia brother #734   http://www.perlmonks.org/   http://www.cpan.org/
<stu> what does y/// stand for?  <tenderpuss> why, yansliterate of course.
[  I'm looking for programming work.  If you like my work, let me know.  ]


-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to