RE: Untested libraries update
[p5sagit/p5-mst-13.2.git] / lib / Text / Wrap.pm
1 package Text::Wrap;
2
3 require Exporter;
4
5 @ISA = qw(Exporter);
6 @EXPORT = qw(wrap fill);
7 @EXPORT_OK = qw($columns $break $huge);
8
9 $VERSION = 2001.0131;
10
11 use vars qw($VERSION $columns $debug $break $huge);
12 use strict;
13
14 BEGIN   {
15         $columns = 76;  # <= screen width
16         $debug = 0;
17         $break = '\s';
18         $huge = 'wrap'; # alternatively: 'die' or 'overflow'
19 }
20
21 use Text::Tabs qw(expand unexpand);
22
23 sub wrap
24 {
25         my ($ip, $xp, @t) = @_;
26
27         my $r = "";
28         my $tail = pop(@t);
29         my $t = expand(join("", (map { /\s+\Z/ ? ( $_ ) : ($_, ' ') } @t), $tail));
30         my $lead = $ip;
31         my $ll = $columns - length(expand($ip)) - 1;
32         my $nll = $columns - length(expand($xp)) - 1;
33         my $nl = "";
34         my $remainder = "";
35
36         pos($t) = 0;
37         while ($t !~ /\G\s*\Z/gc) {
38                 if ($t =~ /\G([^\n]{0,$ll})($break|\Z(?!\n))/xmgc) {
39                         $r .= unexpand($nl . $lead . $1);
40                         $remainder = $2;
41                 } elsif ($huge eq 'wrap' && $t =~ /\G([^\n]{$ll})/gc) {
42                         $r .= unexpand($nl . $lead . $1);
43                         $remainder = "\n";
44                 } elsif ($huge eq 'overflow' && $t =~ /\G([^\n]*?)($break|\Z(?!\n))/xmgc) {
45                         $r .= unexpand($nl . $lead . $1);
46                         $remainder = $2;
47                 } elsif ($huge eq 'die') {
48                         die "couldn't wrap '$t'";
49                 } else {
50                         die "This shouldn't happen";
51                 }
52                         
53                 $lead = $xp;
54                 $ll = $nll;
55                 $nl = "\n";
56         }
57         $r .= $remainder;
58
59         print "-----------$r---------\n" if $debug;
60
61         print "Finish up with '$lead'\n" if $debug;
62
63         $r .= $lead . substr($t, pos($t), length($t)-pos($t))
64                 if pos($t) ne length($t);
65
66         print "-----------$r---------\n" if $debug;;
67
68         return $r;
69 }
70
71 sub fill 
72 {
73         my ($ip, $xp, @raw) = @_;
74         my @para;
75         my $pp;
76
77         for $pp (split(/\n\s+/, join("\n",@raw))) {
78                 $pp =~ s/\s+/ /g;
79                 my $x = wrap($ip, $xp, $pp);
80                 push(@para, $x);
81         }
82
83         # if paragraph_indent is the same as line_indent, 
84         # separate paragraphs with blank lines
85
86         my $ps = ($ip eq $xp) ? "\n\n" : "\n";
87         return join ($ps, @para);
88 }
89
90 1;
91 __END__
92
93 =head1 NAME
94
95 Text::Wrap - line wrapping to form simple paragraphs
96
97 =head1 SYNOPSIS 
98
99 B<Example 1>
100
101         use Text::Wrap
102
103         $initial_tab = "\t";    # Tab before first line
104         $subsequent_tab = "";   # All other lines flush left
105
106         print wrap($initial_tab, $subsequent_tab, @text);
107         print fill($initial_tab, $subsequent_tab, @text);
108
109         @lines = wrap($initial_tab, $subsequent_tab, @text);
110
111         @paragraphs = fill($initial_tab, $subsequent_tab, @text);
112
113 B<Example 2>
114
115         use Text::Wrap qw(wrap $columns $huge);
116
117         $columns = 132;         # Wrap at 132 characters
118         $huge = 'die';
119         $huge = 'wrap';
120         $huge = 'overflow';
121
122 B<Example 3>
123
124         use Text::Wrap
125
126         $Text::Wrap::columns = 72;
127         print wrap('', '', @text);
128
129 =head1 DESCRIPTION
130
131 Text::Wrap::wrap() is a very simple paragraph formatter.  It formats a
132 single paragraph at a time by breaking lines at word boundries.
133 Indentation is controlled for the first line (C<$initial_tab>) and
134 all subsquent lines (C<$subsequent_tab>) independently.  Please note: 
135 C<$initial_tab> and C<$subsequent_tab> are the literal strings that will
136 be used: it is unlikley you would want to pass in a number.
137
138 Lines are wrapped at C<$Text::Wrap::columns> columns.  C<$Text::Wrap::columns>
139 should be set to the full width of your output device.  In fact,
140 every resulting line will have length of no more than C<$columns - 1>.  
141
142 Beginner note: In example 2, above C<$columns> is imported into
143 the local namespace, and set locally.  In example 3,
144 C<$Text::Wrap::columns> is set in its own namespace without importing it.
145
146 When words that are longer than C<$columns> are encountered, they
147 are broken up.  C<wrap()> adds a C<"\n"> at column C<$columns>.
148 This behavior can be overridden by setting C<$huge> to
149 'die' or to 'overflow'.  When set to 'die', large words will cause
150 C<die()> to be called.  When set to 'overflow', large words will be
151 left intact.  
152
153 Text::Wrap::fill() is a simple multi-paragraph formatter.  It formats
154 each paragraph separately and then joins them together when it's done.  It
155 will destory any whitespace in the original text.  It breaks text into
156 paragraphs by looking for whitespace after a newline.  In other respects
157 it acts like wrap().
158
159 When called in list context, C<wrap()> will return a list of lines and 
160 C<fill()> will return a list of paragraphs.
161
162 Historical notes: Older versions of C<wrap()> and C<fill()> always 
163 returned strings.  Also, 'die' used to be the default value of
164 C<$huge>.  Now, 'wrap' is the default value.
165
166 =head1 EXAMPLE
167
168         print wrap("\t","","This is a bit of text that forms 
169                 a normal book-style paragraph");
170
171 =head1 AUTHOR
172
173 David Muir Sharnoff <muir@idiom.com> with help from Tim Pierce and
174 many many others.  
175