File Coverage

blib/lib/Text/ANSI/Tabs.pm
Criterion Covered Total %
statement 53 58 91.3
branch 14 22 63.6
condition 1 3 33.3
subroutine 11 12 91.6
pod 3 4 75.0
total 82 99 82.8


line stmt bran cond sub pod time code
1             package Text::ANSI::Tabs;
2             our $VERSION = "1.06";
3              
4             =encoding utf-8
5              
6             =head1 NAME
7              
8             Text::ANSI::Tabs - Tab expand and unexpand with ANSI sequence
9              
10             =head1 SYNOPSIS
11              
12             use Text::ANSI::Tabs qw(:all);
13             use Text::ANSI::Tabs qw(ansi_expand ansi_unexpand);
14             ansi_expand($text);
15             ansi_unexpand($text);
16              
17             use Text::ANSI::Tabs;
18             Text::ANSI::Tabs::expand($text);
19             Text::ANSI::Tabs::unexpand($text);
20              
21             =head1 VERSION
22              
23             Version 1.06
24              
25             =cut
26              
27 5     5   976686 use v5.14;
  5         22  
28 5     5   805 use utf8;
  5         390  
  5         55  
29 5     5   209 use warnings;
  5         13  
  5         249  
30 5     5   3447 use Data::Dumper;
  5         54290  
  5         634  
31              
32             BEGIN {
33 5     5   28 *ansi_expand = \&expand;
34 5         162 *ansi_unexpand = \&unexpand;
35             }
36              
37 5     5   39 use Exporter qw(import);
  5         8  
  5         463  
38             our @EXPORT_OK = qw(
39             &ansi_expand &ansi_unexpand $tabstop
40             &configure
41             );
42             our %EXPORT_TAGS = ( all => [ @EXPORT_OK ] );
43              
44 5         5751 use Text::ANSI::Fold qw(
45             $csi_re
46             $reset_re
47             $erase_re
48 5     5   3259 );
  5         355716  
49             my $end_re = qr{ $reset_re | $erase_re }x;
50              
51             my $fold = Text::ANSI::Fold->new;
52              
53             our $tabstop = 8;
54             our $min_space = 2;
55             our $REMOVE_REDUNDANT = 1;
56              
57             sub configure {
58 1     1 1 1014 my $class = shift;
59 1 50       6 @_ % 2 and die "invalid parameter.\n";
60 1         3 my @fold_opt;
61 1         8 while (my($k, $v) = splice(@_, 0, 2)) {
62 1 50       7 if ($k eq 'tabstop') {
    50          
63 0         0 $tabstop = $v;
64             }
65             elsif ($k eq 'minimum') {
66 1 50 33     14 $v =~ /^\d+$/ and $v > 0
67             or die "$v: invalid value for minimum space.\n";
68 1         8 $min_space = $v;
69             } else {
70 0         0 push @fold_opt, $k => $v;
71             }
72             }
73 1 50       3 $fold->configure(@fold_opt) if @fold_opt;
74 1         4 return $fold;
75             }
76              
77             sub IsEOL {
78 0     0 0 0 <<"END";
79             0000\t0000
80             000A\t000D
81             2028\t2029
82             END
83             }
84              
85             sub expand {
86             $fold->configure(width => -1, expand => 1, tabstop => $tabstop,
87 136 50   136 1 772206 ref $_[0] eq 'ARRAY' ? @{+shift} : ());
  0         0  
88             my @l = map {
89 136         5094 s{^ (?>.*\t) (?: [^\e\n]* $end_re+ )? }{
  156         13787  
90 152         10953 join '', $fold->text(${^MATCH})->chops();
91             }xmgepr;
92             } @_;
93 136 100       115900 wantarray ? @l : $l[0];
94             }
95              
96             sub unexpand {
97 76 50   76 1 334152 my @opt = ref $_[0] eq 'ARRAY' ? @{+shift} : ();
  0         0  
98             my @l = map {
99 76         201 s{ ^(.*[ ].*) }{ _unexpand($1) }xmger
  88         634  
  88         256  
100             } @_;
101 76 50       232 if ($REMOVE_REDUNDANT) {
102 76         187 for (@l) {
103 88         1910 1 while s/ (?$csi_re+) [^\e\n]* \K $end_re+ \g{c} //xg;
104             }
105             }
106 76 100       495 wantarray ? @l : $l[0];
107             }
108              
109             sub _unexpand {
110 88     88   258 local $_ = shift;
111 88         163 my $ret = '';
112 88         163 my $margin = 0;
113 88         351 while (/ /) {
114 156         367 my $width = $tabstop + $margin;
115 156         645 my($a, $b, $w) = $fold->fold($_, width => $width);
116 156 100       95645 if ($w == $width) {
117 136         1632 $a =~ s/([ ]{$min_space,})(?= $end_re* $)/\t/x;
118             }
119 156         366 $margin = $width - $w;
120 156         377 $ret .= $a;
121 156         658 $_ = $b;
122             }
123 88         824 $ret . $_;
124             }
125              
126             1;
127              
128             __END__