This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Doc patches: assorted minor nits
[perl5.git] / lib / Text / Tabs.pm
index c90d1aa..b26f8f4 100644 (file)
@@ -1,12 +1,3 @@
-#
-# expand and unexpand tabs as per the unix expand and 
-# unexpand programs.
-#
-# expand and unexpand operate on arrays of lines.  Do not
-# feed strings that contain newlines to them.
-#
-# David Muir Sharnoff <muir@idiom.com>
-# 
 
 package Text::Tabs;
 
@@ -15,33 +6,92 @@ require Exporter;
 @ISA = (Exporter);
 @EXPORT = qw(expand unexpand $tabstop);
 
-$tabstop = 8;
+use vars qw($VERSION $tabstop $debug);
+$VERSION = 98.112801;
+
+use strict;
+
+BEGIN  {
+       $tabstop = 8;
+       $debug = 0;
+}
 
 sub expand
 {
-       my @l = @_;
+       my (@l) = @_;
        for $_ (@l) {
-               1 while s/^([^\t]*)(\t+)/
-                       $1 . (" " x 
-                               ($tabstop * length($2)
-                               - (length($1) % $tabstop)))
-                       /e;
+               1 while s/(^|\n)([^\t\n]*)(\t+)/
+                       $1. $2 . (" " x 
+                               ($tabstop * length($3)
+                               - (length($2) % $tabstop)))
+                       /sex;
        }
-       return @l;
+       return @l if wantarray;
+       return $l[0];
 }
 
 sub unexpand
 {
-       my @l = &expand(@_);
+       my (@l) = @_;
        my @e;
+       my $x;
+       my $line;
+       my @lines;
+       my $lastbit;
        for $x (@l) {
-               @e = split(/(.{$tabstop})/,$x);
-               for $_ (@e) {
-                       s/  +$/\t/;
+               @lines = split("\n", $x, -1);
+               for $line (@lines) {
+                       $line = expand($line);
+                       @e = split(/(.{$tabstop})/,$line,-1);
+                       $lastbit = pop(@e);
+                       $lastbit = '' unless defined $lastbit;
+                       $lastbit = "\t"
+                               if $lastbit eq " "x$tabstop;
+                       for $_ (@e) {
+                               if ($debug) {
+                                       my $x = $_;
+                                       $x =~ s/\t/^I\t/gs;
+                                       print "sub on '$x'\n";
+                               }
+                               s/  +$/\t/;
+                       }
+                       $line = join('',@e, $lastbit);
                }
-               $x = join('',@e);
+               $x = join("\n", @lines);
        }
-       return @l;
+       return @l if wantarray;
+       return $l[0];
 }
 
 1;
+__END__
+
+
+=head1 NAME
+
+Text::Tabs -- expand and unexpand tabs per the unix expand(1) and unexpand(1)
+
+=head1 SYNOPSIS
+
+  use Text::Tabs;
+
+  $tabstop = 4;
+  @lines_without_tabs = expand(@lines_with_tabs);
+  @lines_with_tabs = unexpand(@lines_without_tabs);
+
+=head1 DESCRIPTION
+
+Text::Tabs does about what the unix utilities expand(1) and unexpand(1)
+do.  Given a line with tabs in it, expand will replace the tabs with
+the appropriate number of spaces.  Given a line with or without tabs in
+it, unexpand will add tabs when it can save bytes by doing so.  Invisible
+compression with plain ascii!
+
+=head1 BUGS
+
+expand doesn't handle newlines very quickly -- do not feed it an
+entire document in one string.  Instead feed it an array of lines.
+
+=head1 AUTHOR
+
+David Muir Sharnoff <muir@idiom.com>