xref: /openbsd-src/gnu/usr.bin/perl/cpan/Text-Tabs/lib/Text/Tabs.pm (revision 3d61058aa5c692477b6d18acfbbdb653a9930ff9)
1eac174f2Safresh1use strict; use warnings;
2eac174f2Safresh1
3b39c5158Smillertpackage Text::Tabs;
4b39c5158Smillert
5eac174f2Safresh1BEGIN { require Exporter; *import = \&Exporter::import }
6b39c5158Smillert
7eac174f2Safresh1our @EXPORT = qw( expand unexpand $tabstop );
8b39c5158Smillert
9*3d61058aSafresh1our $VERSION = '2024.001';
10eac174f2Safresh1our $SUBVERSION = 'modern'; # back-compat vestige
11b39c5158Smillert
12eac174f2Safresh1our $tabstop = 8;
1391f110e0Safresh1
14b39c5158Smillertsub expand {
15b39c5158Smillert	my @l;
16b39c5158Smillert	my $pad;
17b39c5158Smillert	for ( @_ ) {
18eac174f2Safresh1		defined or do { push @l, ''; next };
19b39c5158Smillert		my $s = '';
20b39c5158Smillert		for (split(/^/m, $_, -1)) {
21eac174f2Safresh1			my $offs;
22eac174f2Safresh1			for (split(/\t/, $_, -1)) {
23eac174f2Safresh1				if (defined $offs) {
24eac174f2Safresh1					$pad = $tabstop - $offs % $tabstop;
25eac174f2Safresh1					$s .= " " x $pad;
26eac174f2Safresh1				}
27b39c5158Smillert				$s .= $_;
28*3d61058aSafresh1				$offs = /^\pM/ + ( () = /\PM/g );
29eac174f2Safresh1			}
30b39c5158Smillert		}
31b39c5158Smillert		push(@l, $s);
32b39c5158Smillert	}
33b39c5158Smillert	return @l if wantarray;
34b39c5158Smillert	return $l[0];
35b39c5158Smillert}
36b39c5158Smillert
37b39c5158Smillertsub unexpand
38b39c5158Smillert{
39b39c5158Smillert	my (@l) = @_;
40b39c5158Smillert	my @e;
41b39c5158Smillert	my $x;
42b39c5158Smillert	my $line;
43b39c5158Smillert	my @lines;
44b39c5158Smillert	my $lastbit;
45b39c5158Smillert	my $ts_as_space = " " x $tabstop;
46b39c5158Smillert	for $x (@l) {
47eac174f2Safresh1		defined $x or next;
48b39c5158Smillert		@lines = split("\n", $x, -1);
49b39c5158Smillert		for $line (@lines) {
50b39c5158Smillert			$line = expand($line);
51*3d61058aSafresh1			@e = split(/((?:\PM\pM*|^\pM+){$tabstop})/,$line,-1);
52b39c5158Smillert			$lastbit = pop(@e);
53b39c5158Smillert			$lastbit = ''
54b39c5158Smillert				unless defined $lastbit;
55b39c5158Smillert			$lastbit = "\t"
56b39c5158Smillert				if $lastbit eq $ts_as_space;
57b39c5158Smillert			for $_ (@e) {
58b39c5158Smillert				s/  +$/\t/;
59b39c5158Smillert			}
60b39c5158Smillert			$line = join('',@e, $lastbit);
61b39c5158Smillert		}
62b39c5158Smillert		$x = join("\n", @lines);
63b39c5158Smillert	}
64b39c5158Smillert	return @l if wantarray;
65b39c5158Smillert	return $l[0];
66b39c5158Smillert}
67b39c5158Smillert
68b39c5158Smillert1;
69eac174f2Safresh1
70b39c5158Smillert__END__
71b39c5158Smillert
72b39c5158Smillert=head1 NAME
73b39c5158Smillert
7491f110e0Safresh1Text::Tabs - expand and unexpand tabs like unix expand(1) and unexpand(1)
75b39c5158Smillert
76b39c5158Smillert=head1 SYNOPSIS
77b39c5158Smillert
78b39c5158Smillert  use Text::Tabs;
79b39c5158Smillert
80b39c5158Smillert  $tabstop = 4;  # default = 8
81b39c5158Smillert  @lines_without_tabs = expand(@lines_with_tabs);
82b39c5158Smillert  @lines_with_tabs = unexpand(@lines_without_tabs);
83b39c5158Smillert
84b39c5158Smillert=head1 DESCRIPTION
85b39c5158Smillert
8691f110e0Safresh1Text::Tabs does most of what the unix utilities expand(1) and unexpand(1)
8791f110e0Safresh1do.  Given a line with tabs in it, C<expand> replaces those tabs with
88b39c5158Smillertthe appropriate number of spaces.  Given a line with or without tabs in
8991f110e0Safresh1it, C<unexpand> adds tabs when it can save bytes by doing so,
9091f110e0Safresh1like the C<unexpand -a> command.
9191f110e0Safresh1
9291f110e0Safresh1Unlike the old unix utilities, this module correctly accounts for
9391f110e0Safresh1any Unicode combining characters (such as diacriticals) that may occur
9491f110e0Safresh1in each line for both expansion and unexpansion.  These are overstrike
9591f110e0Safresh1characters that do not increment the logical position.  Make sure
9691f110e0Safresh1you have the appropriate Unicode settings enabled.
9791f110e0Safresh1
9891f110e0Safresh1=head1 EXPORTS
9991f110e0Safresh1
10091f110e0Safresh1The following are exported:
10191f110e0Safresh1
10291f110e0Safresh1=over 4
10391f110e0Safresh1
10491f110e0Safresh1=item expand
10591f110e0Safresh1
10691f110e0Safresh1=item unexpand
10791f110e0Safresh1
10891f110e0Safresh1=item $tabstop
10991f110e0Safresh1
11091f110e0Safresh1The C<$tabstop> variable controls how many column positions apart each
11191f110e0Safresh1tabstop is.  The default is 8.
11291f110e0Safresh1
11391f110e0Safresh1Please note that C<local($tabstop)> doesn't do the right thing and if you want
11491f110e0Safresh1to use C<local> to override C<$tabstop>, you need to use
11591f110e0Safresh1C<local($Text::Tabs::tabstop)>.
11691f110e0Safresh1
11791f110e0Safresh1=back
118b39c5158Smillert
119b39c5158Smillert=head1 EXAMPLE
120b39c5158Smillert
121b39c5158Smillert  #!perl
122b39c5158Smillert  # unexpand -a
123b39c5158Smillert  use Text::Tabs;
124b39c5158Smillert
125b39c5158Smillert  while (<>) {
126b39c5158Smillert    print unexpand $_;
127b39c5158Smillert  }
128b39c5158Smillert
129e9ce3842Safresh1Instead of the shell's C<expand> command, use:
130b39c5158Smillert
131b39c5158Smillert  perl -MText::Tabs -n -e 'print expand $_'
132b39c5158Smillert
13391f110e0Safresh1Instead of the shell's C<unexpand -a> command, use:
134b39c5158Smillert
135b39c5158Smillert  perl -MText::Tabs -n -e 'print unexpand $_'
136b39c5158Smillert
13791f110e0Safresh1=head1 BUGS
13891f110e0Safresh1
13991f110e0Safresh1Text::Tabs handles only tabs (C<"\t">) and combining characters (C</\pM/>).  It doesn't
14091f110e0Safresh1count backwards for backspaces (C<"\t">), omit other non-printing control characters (C</\pC/>),
14191f110e0Safresh1or otherwise deal with any other zero-, half-, and full-width characters.
14291f110e0Safresh1
143b39c5158Smillert=head1 LICENSE
144b39c5158Smillert
145b39c5158SmillertCopyright (C) 1996-2002,2005,2006 David Muir Sharnoff.
146b39c5158SmillertCopyright (C) 2005 Aristotle Pagaltzis
147e9ce3842Safresh1Copyright (C) 2012-2013 Google, Inc.
148b39c5158SmillertThis module may be modified, used, copied, and redistributed at your own risk.
149e9ce3842Safresh1Although allowed by the preceding license, please do not publicly
150e9ce3842Safresh1redistribute modified versions of this code with the name "Text::Tabs"
151e9ce3842Safresh1unless it passes the unmodified Text::Tabs test suite.
152