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]