101 lines
1.7 KiB
Perl
101 lines
1.7 KiB
Perl
package Text::Tabs;
|
|
|
|
require Exporter;
|
|
|
|
@ISA = (Exporter);
|
|
@EXPORT = qw(expand unexpand $tabstop);
|
|
|
|
use vars qw($VERSION $SUBVERSION $tabstop $debug);
|
|
$VERSION = 2013.0523;
|
|
$SUBVERSION = 'modern';
|
|
|
|
use strict;
|
|
|
|
use 5.010_000;
|
|
|
|
BEGIN {
|
|
$tabstop = 8;
|
|
$debug = 0;
|
|
}
|
|
|
|
my $CHUNK = qr/\X/;
|
|
|
|
sub _xlen (_) { scalar(() = $_[0] =~ /$CHUNK/g) }
|
|
sub _xpos (_) { _xlen( substr( $_[0], 0, pos($_[0]) ) ) }
|
|
|
|
sub expand {
|
|
my @l;
|
|
my $pad;
|
|
for ( @_ ) {
|
|
my $s = '';
|
|
for (split(/^/m, $_, -1)) {
|
|
my $offs = 0;
|
|
s{\t}{
|
|
# this works on both 5.10 and 5.11
|
|
$pad = $tabstop - (_xlen(${^PREMATCH}) + $offs) % $tabstop;
|
|
# this works on 5.11, but fails on 5.10
|
|
#XXX# $pad = $tabstop - (_xpos() + $offs) % $tabstop;
|
|
$offs += $pad - 1;
|
|
" " x $pad;
|
|
}peg;
|
|
$s .= $_;
|
|
}
|
|
push(@l, $s);
|
|
}
|
|
return @l if wantarray;
|
|
return $l[0];
|
|
}
|
|
|
|
sub unexpand
|
|
{
|
|
my (@l) = @_;
|
|
my @e;
|
|
my $x;
|
|
my $line;
|
|
my @lines;
|
|
my $lastbit;
|
|
my $ts_as_space = " " x $tabstop;
|
|
for $x (@l) {
|
|
@lines = split("\n", $x, -1);
|
|
for $line (@lines) {
|
|
$line = expand($line);
|
|
@e = split(/(${CHUNK}{$tabstop})/,$line,-1);
|
|
$lastbit = pop(@e);
|
|
$lastbit = ''
|
|
unless defined $lastbit;
|
|
$lastbit = "\t"
|
|
if $lastbit eq $ts_as_space;
|
|
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("\n", @lines);
|
|
}
|
|
return @l if wantarray;
|
|
return $l[0];
|
|
}
|
|
|
|
1;
|
|
__END__
|
|
|
|
sub expand
|
|
{
|
|
my (@l) = @_;
|
|
for $_ (@l) {
|
|
1 while s/(^|\n)([^\t\n]*)(\t+)/
|
|
$1. $2 . (" " x
|
|
($tabstop * length($3)
|
|
- (length($2) % $tabstop)))
|
|
/sex;
|
|
}
|
|
return @l if wantarray;
|
|
return $l[0];
|
|
}
|
|
|