1use strict; use warnings; 2 3package Text::Wrap; 4 5use warnings::register; 6 7BEGIN { require Exporter; *import = \&Exporter::import } 8 9our @EXPORT = qw( wrap fill ); 10our @EXPORT_OK = qw( $columns $break $huge ); 11 12our $VERSION = '2021.0814'; 13our $SUBVERSION = 'modern'; # back-compat vestige 14 15our $columns = 76; # <= screen width 16our $break = '(?=\s)(?:\r\n|\PM\pM*)'; 17our $huge = 'wrap'; # alternatively: 'die' or 'overflow' 18our $unexpand = 1; 19our $tabstop = 8; 20our $separator = "\n"; 21our $separator2 = undef; 22 23sub _xlen { () = $_[0] =~ /\PM/g } 24 25use Text::Tabs qw(expand unexpand); 26 27sub wrap 28{ 29 my ($ip, $xp, @t) = map +( defined $_ ? $_ : '' ), @_; 30 31 local($Text::Tabs::tabstop) = $tabstop; 32 my $r = ""; 33 my $tail = pop(@t); 34 my $t = expand(join("", (map { /\s+\z/ ? ( $_ ) : ($_, ' ') } @t), $tail)); 35 my $lead = $ip; 36 my $nll = $columns - _xlen(expand($xp)) - 1; 37 if ($nll <= 0 && $xp ne '') { 38 my $nc = _xlen(expand($xp)) + 2; 39 warnings::warnif "Increasing \$Text::Wrap::columns from $columns to $nc to accommodate length of subsequent tab"; 40 $columns = $nc; 41 $nll = 1; 42 } 43 my $ll = $columns - _xlen(expand($ip)) - 1; 44 $ll = 0 if $ll < 0; 45 my $nl = ""; 46 my $remainder = ""; 47 48 use re 'taint'; 49 50 pos($t) = 0; 51 while ($t !~ /\G(?:$break)*\Z/gc) { 52 if ($t =~ /\G((?:(?!\n)\PM\pM*){0,$ll})($break|\n+|\z)/xmgc) { 53 $r .= $unexpand 54 ? unexpand($nl . $lead . $1) 55 : $nl . $lead . $1; 56 $remainder = $2; 57 } elsif ($huge eq 'wrap' && $t =~ /\G((?:(?!\n)\PM\pM*){$ll})/gc) { 58 $r .= $unexpand 59 ? unexpand($nl . $lead . $1) 60 : $nl . $lead . $1; 61 $remainder = defined($separator2) ? $separator2 : $separator; 62 } elsif ($huge eq 'overflow' && $t =~ /\G((?:(?!\n)\PM\pM*)*?)($break|\n+|\z)/xmgc) { 63 $r .= $unexpand 64 ? unexpand($nl . $lead . $1) 65 : $nl . $lead . $1; 66 $remainder = $2; 67 } elsif ($huge eq 'die') { 68 die "couldn't wrap '$t'"; 69 } elsif ($columns < 2) { 70 warnings::warnif "Increasing \$Text::Wrap::columns from $columns to 2"; 71 $columns = 2; 72 return @_; 73 } else { 74 die "This shouldn't happen"; 75 } 76 77 $lead = $xp; 78 $ll = $nll; 79 $nl = defined($separator2) 80 ? ($remainder eq "\n" 81 ? "\n" 82 : $separator2) 83 : $separator; 84 } 85 $r .= $remainder; 86 87 $r .= $lead . substr($t, pos($t), length($t) - pos($t)) 88 if pos($t) ne length($t); 89 90 return $r; 91} 92 93sub fill 94{ 95 my ($ip, $xp, @raw) = map +( defined $_ ? $_ : '' ), @_; 96 my @para; 97 my $pp; 98 99 for $pp (split(/\n\s+/, join("\n",@raw))) { 100 $pp =~ s/\s+/ /g; 101 my $x = wrap($ip, $xp, $pp); 102 push(@para, $x); 103 } 104 105 # if paragraph_indent is the same as line_indent, 106 # separate paragraphs with blank lines 107 108 my $ps = ($ip eq $xp) ? "\n\n" : "\n"; 109 return join ($ps, @para); 110} 111 1121; 113 114__END__ 115 116=head1 NAME 117 118Text::Wrap - line wrapping to form simple paragraphs 119 120=head1 SYNOPSIS 121 122B<Example 1> 123 124 use Text::Wrap; 125 126 $initial_tab = "\t"; # Tab before first line 127 $subsequent_tab = ""; # All other lines flush left 128 129 print wrap($initial_tab, $subsequent_tab, @text); 130 print fill($initial_tab, $subsequent_tab, @text); 131 132 $lines = wrap($initial_tab, $subsequent_tab, @text); 133 134 @paragraphs = fill($initial_tab, $subsequent_tab, @text); 135 136B<Example 2> 137 138 use Text::Wrap qw(wrap $columns $huge); 139 140 $columns = 132; # Wrap at 132 characters 141 $huge = 'die'; 142 $huge = 'wrap'; 143 $huge = 'overflow'; 144 145B<Example 3> 146 147 use Text::Wrap; 148 149 $Text::Wrap::columns = 72; 150 print wrap('', '', @text); 151 152=head1 DESCRIPTION 153 154C<Text::Wrap::wrap()> is a very simple paragraph formatter. It formats a 155single paragraph at a time by breaking lines at word boundaries. 156Indentation is controlled for the first line (C<$initial_tab>) and 157all subsequent lines (C<$subsequent_tab>) independently. Please note: 158C<$initial_tab> and C<$subsequent_tab> are the literal strings that will 159be used: it is unlikely you would want to pass in a number. 160 161C<Text::Wrap::fill()> is a simple multi-paragraph formatter. It formats 162each paragraph separately and then joins them together when it's done. It 163will destroy any whitespace in the original text. It breaks text into 164paragraphs by looking for whitespace after a newline. In other respects, 165it acts like wrap(). 166 167C<wrap()> compresses trailing whitespace into one newline, and C<fill()> 168deletes all trailing whitespace. 169 170Both C<wrap()> and C<fill()> return a single string. 171 172Unlike the old Unix fmt(1) utility, this module correctly accounts for 173any Unicode combining characters (such as diacriticals) that may occur 174in each line for both expansion and unexpansion. These are overstrike 175characters that do not increment the logical position. Make sure 176you have the appropriate Unicode settings enabled. 177 178=head1 OVERRIDES 179 180C<Text::Wrap::wrap()> has a number of variables that control its behavior. 181Because other modules might be using C<Text::Wrap::wrap()> it is suggested 182that you leave these variables alone! If you can't do that, then 183use C<local($Text::Wrap::VARIABLE) = YOURVALUE> when you change the 184values so that the original value is restored. This C<local()> trick 185will not work if you import the variable into your own namespace. 186 187Lines are wrapped at C<$Text::Wrap::columns> columns (default value: 76). 188C<$Text::Wrap::columns> should be set to the full width of your output 189device. In fact, every resulting line will have length of no more than 190C<$columns - 1>. 191 192It is possible to control which characters terminate words by 193modifying C<$Text::Wrap::break>. Set this to a string such as 194C<'[\s:]'> (to break before spaces or colons) or a pre-compiled regexp 195such as C<qr/[\s']/> (to break before spaces or apostrophes). The 196default is simply C<'\s'>; that is, words are terminated by spaces. 197(This means, among other things, that trailing punctuation such as 198full stops or commas stay with the word they are "attached" to.) 199Setting C<$Text::Wrap::break> to a regular expression that doesn't 200eat any characters (perhaps just a forward look-ahead assertion) will 201cause warnings. 202 203Beginner note: In example 2, above C<$columns> is imported into 204the local namespace, and set locally. In example 3, 205C<$Text::Wrap::columns> is set in its own namespace without importing it. 206 207C<Text::Wrap::wrap()> starts its work by expanding all the tabs in its 208input into spaces. The last thing it does it to turn spaces back 209into tabs. If you do not want tabs in your results, set 210C<$Text::Wrap::unexpand> to a false value. Likewise if you do not 211want to use 8-character tabstops, set C<$Text::Wrap::tabstop> to 212the number of characters you do want for your tabstops. 213 214If you want to separate your lines with something other than C<\n> 215then set C<$Text::Wrap::separator> to your preference. This replaces 216all newlines with C<$Text::Wrap::separator>. If you just want to 217preserve existing newlines but add new breaks with something else, set 218C<$Text::Wrap::separator2> instead. 219 220When words that are longer than C<$columns> are encountered, they 221are broken up. C<wrap()> adds a C<"\n"> at column C<$columns>. 222This behavior can be overridden by setting C<$huge> to 223'die' or to 'overflow'. When set to 'die', large words will cause 224C<die()> to be called. When set to 'overflow', large words will be 225left intact. 226 227Historical notes: 'die' used to be the default value of 228C<$huge>. Now, 'wrap' is the default value. 229 230=head1 EXAMPLES 231 232Code: 233 234 print wrap("\t","",<<END); 235 This is a bit of text that forms 236 a normal book-style indented paragraph 237 END 238 239Result: 240 241 " This is a bit of text that forms 242 a normal book-style indented paragraph 243 " 244 245Code: 246 247 $Text::Wrap::columns=20; 248 $Text::Wrap::separator="|"; 249 print wrap("","","This is a bit of text that forms a normal book-style paragraph"); 250 251Result: 252 253 "This is a bit of|text that forms a|normal book-style|paragraph" 254 255=head1 SEE ALSO 256 257For correct handling of East Asian half- and full-width characters, 258see L<Text::WrapI18N>. For more detailed controls: L<Text::Format>. 259 260=head1 AUTHOR 261 262David Muir Sharnoff <cpan@dave.sharnoff.org> with help from Tim Pierce and 263many many others. 264 265=head1 LICENSE 266 267Copyright (C) 1996-2009 David Muir Sharnoff. 268Copyright (C) 2012-2013 Google, Inc. 269This module may be modified, used, copied, and redistributed at your own risk. 270Although allowed by the preceding license, please do not publicly 271redistribute modified versions of this code with the name "Text::Wrap" 272unless it passes the unmodified Text::Wrap test suite. 273