1*0Sstevel@tonic-gate 2*0Sstevel@tonic-gatepackage Text::Tabs; 3*0Sstevel@tonic-gate 4*0Sstevel@tonic-gaterequire Exporter; 5*0Sstevel@tonic-gate 6*0Sstevel@tonic-gate@ISA = (Exporter); 7*0Sstevel@tonic-gate@EXPORT = qw(expand unexpand $tabstop); 8*0Sstevel@tonic-gate 9*0Sstevel@tonic-gateuse vars qw($VERSION $tabstop $debug); 10*0Sstevel@tonic-gate$VERSION = 98.112801; 11*0Sstevel@tonic-gate 12*0Sstevel@tonic-gateuse strict; 13*0Sstevel@tonic-gate 14*0Sstevel@tonic-gateBEGIN { 15*0Sstevel@tonic-gate $tabstop = 8; 16*0Sstevel@tonic-gate $debug = 0; 17*0Sstevel@tonic-gate} 18*0Sstevel@tonic-gate 19*0Sstevel@tonic-gatesub expand 20*0Sstevel@tonic-gate{ 21*0Sstevel@tonic-gate my (@l) = @_; 22*0Sstevel@tonic-gate for $_ (@l) { 23*0Sstevel@tonic-gate 1 while s/(^|\n)([^\t\n]*)(\t+)/ 24*0Sstevel@tonic-gate $1. $2 . (" " x 25*0Sstevel@tonic-gate ($tabstop * length($3) 26*0Sstevel@tonic-gate - (length($2) % $tabstop))) 27*0Sstevel@tonic-gate /sex; 28*0Sstevel@tonic-gate } 29*0Sstevel@tonic-gate return @l if wantarray; 30*0Sstevel@tonic-gate return $l[0]; 31*0Sstevel@tonic-gate} 32*0Sstevel@tonic-gate 33*0Sstevel@tonic-gatesub unexpand 34*0Sstevel@tonic-gate{ 35*0Sstevel@tonic-gate my (@l) = @_; 36*0Sstevel@tonic-gate my @e; 37*0Sstevel@tonic-gate my $x; 38*0Sstevel@tonic-gate my $line; 39*0Sstevel@tonic-gate my @lines; 40*0Sstevel@tonic-gate my $lastbit; 41*0Sstevel@tonic-gate for $x (@l) { 42*0Sstevel@tonic-gate @lines = split("\n", $x, -1); 43*0Sstevel@tonic-gate for $line (@lines) { 44*0Sstevel@tonic-gate $line = expand($line); 45*0Sstevel@tonic-gate @e = split(/(.{$tabstop})/,$line,-1); 46*0Sstevel@tonic-gate $lastbit = pop(@e); 47*0Sstevel@tonic-gate $lastbit = '' unless defined $lastbit; 48*0Sstevel@tonic-gate $lastbit = "\t" 49*0Sstevel@tonic-gate if $lastbit eq " "x$tabstop; 50*0Sstevel@tonic-gate for $_ (@e) { 51*0Sstevel@tonic-gate if ($debug) { 52*0Sstevel@tonic-gate my $x = $_; 53*0Sstevel@tonic-gate $x =~ s/\t/^I\t/gs; 54*0Sstevel@tonic-gate print "sub on '$x'\n"; 55*0Sstevel@tonic-gate } 56*0Sstevel@tonic-gate s/ +$/\t/; 57*0Sstevel@tonic-gate } 58*0Sstevel@tonic-gate $line = join('',@e, $lastbit); 59*0Sstevel@tonic-gate } 60*0Sstevel@tonic-gate $x = join("\n", @lines); 61*0Sstevel@tonic-gate } 62*0Sstevel@tonic-gate return @l if wantarray; 63*0Sstevel@tonic-gate return $l[0]; 64*0Sstevel@tonic-gate} 65*0Sstevel@tonic-gate 66*0Sstevel@tonic-gate1; 67*0Sstevel@tonic-gate__END__ 68*0Sstevel@tonic-gate 69*0Sstevel@tonic-gate 70*0Sstevel@tonic-gate=head1 NAME 71*0Sstevel@tonic-gate 72*0Sstevel@tonic-gateText::Tabs -- expand and unexpand tabs per the unix expand(1) and unexpand(1) 73*0Sstevel@tonic-gate 74*0Sstevel@tonic-gate=head1 SYNOPSIS 75*0Sstevel@tonic-gate 76*0Sstevel@tonic-gate use Text::Tabs; 77*0Sstevel@tonic-gate 78*0Sstevel@tonic-gate $tabstop = 4; 79*0Sstevel@tonic-gate @lines_without_tabs = expand(@lines_with_tabs); 80*0Sstevel@tonic-gate @lines_with_tabs = unexpand(@lines_without_tabs); 81*0Sstevel@tonic-gate 82*0Sstevel@tonic-gate=head1 DESCRIPTION 83*0Sstevel@tonic-gate 84*0Sstevel@tonic-gateText::Tabs does about what the unix utilities expand(1) and unexpand(1) 85*0Sstevel@tonic-gatedo. Given a line with tabs in it, expand will replace the tabs with 86*0Sstevel@tonic-gatethe appropriate number of spaces. Given a line with or without tabs in 87*0Sstevel@tonic-gateit, unexpand will add tabs when it can save bytes by doing so. Invisible 88*0Sstevel@tonic-gatecompression with plain ascii! 89*0Sstevel@tonic-gate 90*0Sstevel@tonic-gate=head1 BUGS 91*0Sstevel@tonic-gate 92*0Sstevel@tonic-gateexpand doesn't handle newlines very quickly -- do not feed it an 93*0Sstevel@tonic-gateentire document in one string. Instead feed it an array of lines. 94*0Sstevel@tonic-gate 95*0Sstevel@tonic-gate=head1 AUTHOR 96*0Sstevel@tonic-gate 97*0Sstevel@tonic-gateDavid Muir Sharnoff <muir@idiom.com> 98