xref: /openbsd-src/gnu/usr.bin/perl/cpan/Text-Tabs/lib/Text/Wrap.pm (revision ff0e7be1ebbcc809ea8ad2b6dafe215824da9e46)
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