Question

Yes, I'm re-writing cowsay :)

#!/usr/bin/perl

use Text::Wrap;
$Text::Wrap::columns = 40;

my $FORTUNE = "The very long sentence that will be outputted by another command and it can be very long so it is word-wrapped The very long sentence that will be outputted by another command and it can be very long so it is word-wrapped";

my $TOP = " _______________________________________
/                                       \\
";
my $BOTTOM = "\\_______________________________________/
";

print $TOP;
print wrap('| ', '| ', $FORTUNE) . "\n";
print $BOTTOM;

Produces this

 _______________________________________
/                                       \
| The very long sentence that will be
| outputted by another command and it
| can be very long so it is
| word-wrapped The very long sentence
| that will be outputted by another
| command and it can be very long so it
| is word-wrapped
\_______________________________________/

How can I get this ?

 _______________________________________
/                                       \
| The very long sentence that will be   |
| outputted by another command and it   |
| can be very long so it is             |
| word-wrapped The very long sentence   |
| that will be outputted by another     |
| command and it can be very long so it |
| is word-wrapped                       |
\_______________________________________/
Was it helpful?

Solution

I could not find a way in the documentation, but you can apply a small hack if you save the string. It is possible to assign a new line ending by using a package variable:

$Text::Wrap::separator = "|$/";

You also need to prevent the module from expanding tabs and messing with the character count:

$Text::Wrap::unexpand = 0;

This is simply a pipe | followed by the input record separator $/ (newline most often). This will add a pipe to the end of the line, but no padding space, which will have to be added manually:

my $text = wrap('| ', '| ', $FORTUNE) . "\n";
$text =~ s/(^.+)\K\|/' ' x ($Text::Wrap::columns - length($1)) . '|'/gem;
print $text;

This will match the beginning of each line, ending with a |, add the padding space by multiplying a space by columns minus length of matched string. We use the /m modifier to make ^ match newlines inside the string. .+ by itself will not match newlines, which means each match will be an entire line. The /e modifier will "eval" the replacement part as code, not a string.

Note that it is somewhat of a quick hack, so bugs are possible.

OTHER TIPS

If you're willing to download a more powerful module, you can use Text::Format. It has a lot more options for customizing, but the most relevant one is rightFill which fills the rest of the columns in each line with spaces.

Unfortunately, you can't customize the left and right sides with non-space characters. You can use a workaround by doing regex substitutions, just as Text::NWrap does in its source code.

#!/usr/bin/env perl

use utf8;
use Text::Format;

chop(my $FORTUNE = "The very long sentence that will be outputted by another command and it can be very long so it is word-wrapped " x 2);

my $TOP =  "/" . '‾'x39 . "\\\n";
my $BOTTOM = "\\_______________________________________/\n";

my $formatter = Text::Format->new({ columns => 37, firstIndent => 0, rightFill => 1 });
my $text = $formatter->format($FORTUNE);
$text =~ s/^/| /mg;
$text =~ s/\n/ |\n/mg;

print $TOP;
print $text;
print $BOTTOM;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top