File Coverage

blib/lib/Text/ANSI/Tabs.pm
Criterion Covered Total %
statement 45 49 91.8
branch 9 12 75.0
condition n/a
subroutine 10 11 90.9
pod 3 3 100.0
total 67 75 89.3


line stmt bran cond sub pod time code
1             package Text::ANSI::Tabs;
2             our $VERSION = "1.01";
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.01
24              
25             =cut
26              
27 4     4   176388 use v5.14;
  4         32  
28 4     4   558 use utf8;
  4         15  
  4         17  
29 4     4   83 use warnings;
  4         6  
  4         88  
30 4     4   1975 use Data::Dumper;
  4         23302  
  4         329  
31              
32             BEGIN {
33 4     4   18 *ansi_expand = \&expand;
34 4         79 *ansi_unexpand = \&unexpand;
35             }
36              
37 4     4   23 use Exporter qw(import);
  4         7  
  4         246  
38             our @EXPORT_OK = qw(
39             &ansi_expand &ansi_unexpand $tabstop
40             &configure
41             );
42             our %EXPORT_TAGS = ( all => [ @EXPORT_OK ] );
43              
44 4     4   1757 use Text::ANSI::Fold();
  4         204147  
  4         2070  
45              
46             my $fold = Text::ANSI::Fold->new;
47              
48             our $tabstop = 8;
49             our $REMOVE_REDUNDANT = 1;
50              
51             my $reset_re = qr{ \e \[ [0;]* m }x;
52             my $erase_re = qr{ \e \[ [\d;]* K }x;
53             my $end_re = qr{ $reset_re | $erase_re }x;
54             my $csi_re = qr{
55             # see ECMA-48 5.4 Control sequences
56             \e \[ # csi
57             [\x30-\x3f]* # parameter bytes
58             [\x20-\x2f]* # intermediate bytes
59             [\x40-\x7e] # final byte
60             }x;
61              
62             sub configure {
63 0     0 1 0 my $class = shift;
64 0         0 $fold->configure(@_);
65             }
66              
67             sub expand {
68 132 50   132 1 65341 my @opt = ref $_[0] eq 'ARRAY' ? @{+shift} : ();
  0         0  
69 132         279 my @param = (width => -1, expand => 1, tabstop => $tabstop, @opt);
70             my @l = map {
71 132         230 s{^ (?>.*\t) (?: [^\e\n]* $end_re+ )? }{
  152         4598  
72 148         3978 ($fold->fold(${^MATCH}, @param))[0];
73             }xmgepr;
74             } @_;
75 132 100       52214 wantarray ? @l : $l[0];
76             }
77              
78             sub unexpand {
79 66 50   66 1 33977 my @opt = ref $_[0] eq 'ARRAY' ? @{+shift} : ();
  0         0  
80             my @l = map {
81 66         132 s{ ^(.*[ ].*) }{ _unexpand($1) }xmger
  76         309  
  74         138  
82             } @_;
83 66 50       136 if ($REMOVE_REDUNDANT) {
84 66         100 for (@l) {
85 76         865 1 while s/ (?$csi_re+) [^\e\n]* \K $end_re+ \g{c} //xg;
86             }
87             }
88 66 100       262 wantarray ? @l : $l[0];
89             }
90              
91             sub _unexpand {
92 74     74   138 local $_ = shift;
93 74         103 my $ret = '';
94 74         88 my $margin = 0;
95 74         182 while (/ /) {
96 136         189 my $width = $tabstop + $margin;
97 136         302 my($a, $b, $w) = $fold->fold($_, width => $width);
98 136 100       34824 if ($w == $width) {
99 116         612 $a =~ s/([ ]+)(?= $end_re* $)/\t/x;
100             }
101 136         197 $margin = $width - $w;
102 136         169 $ret .= $a;
103 136         331 $_ = $b;
104             }
105 74         333 $ret . $_;
106             }
107              
108             1;
109              
110             __END__