File Coverage

blib/lib/Term/ANSIColor/Concise/Transform.pm
Criterion Covered Total %
statement 53 61 86.8
branch 26 36 72.2
condition 7 15 46.6
subroutine 10 10 100.0
pod 0 3 0.0
total 96 125 76.8


line stmt bran cond sub pod time code
1             # -*- indent-tabs-mode: nil -*-
2              
3             package Term::ANSIColor::Concise::Transform;
4              
5             our $VERSION = "3.02";
6              
7 5     5   90 use v5.14;
  5         30  
8 5     5   28 use warnings;
  5         9  
  5         251  
9 5     5   34 use utf8;
  5         10  
  5         59  
10              
11 5     5   432 use Exporter 'import';
  5         11  
  5         557  
12             our @EXPORT = qw();
13             our @EXPORT_OK = qw(transform $mod_re);
14             our %EXPORT_TAGS = (all => [ @EXPORT_OK ]);
15              
16 5     5   32 use Data::Dumper;
  5         8  
  5         344  
17 5     5   27 use List::Util qw(min max any);
  5         39  
  5         432  
18              
19 5     5   28 use aliased;
  5         7  
  5         29  
20             my $Color = alias 'Term::ANSIColor::Concise::' . ($ENV{TAC_COLOR_PACKAGE} || 'ColorObject');
21 57     57 0 259 sub Color { $Color }
22              
23             sub adjust {
24 22     22 0 1014 my($v, $amnt, $mark, $base) = @_;
25 22 100       110 if ($mark->{'-'}) { $v - $amnt }
  5 100       26  
    100          
    50          
    0          
26 11         82 elsif ($mark->{'+'}) { $v + $amnt }
27 5         19 elsif ($mark->{'='}) { $amnt }
28 1         7 elsif ($mark->{'*'}) { $v * $amnt / 100 }
29 0   0     0 elsif ($mark->{'%'}) { ($v + $amnt) % ($base || 100) }
30             }
31              
32             our $mod_re = qr/(?[-+=*%])(?[A-Za-z])(?\d*)/x;
33              
34             sub transform {
35 31     31 0 88 my($mods, @rgb24) = @_;
36 31         73 my $color = Color->rgb(@rgb24);
37 31         4520 while ($mods =~ /(?$mod_re)/xg) {
38 32   50     565 my($mod, $m, $c, $abs) = ($+{mod}, $+{m}//'', $+{c}, $+{abs}//0);
      50        
39 32         180 my $com = { map { $_ => 1 } $c =~ /./g };
  32         144  
40 32         121 my $mark = { map { $_ => 1 } $m =~ /./g };
  32         98  
41 32         55 $color = do {
42             # Lightness
43 32 100 66     187 if ($com->{l}) {
    100 66        
    100 33        
    50          
    50          
    50          
    100          
    100          
44 12         41 my($h, $s, $l) = $color->hsl;
45 12         47 Color->hsl($h, $s, adjust($l, $abs, $mark));
46             }
47             # Luminance
48             elsif ($com->{y}) {
49 5         27 $color->luminance(adjust($color->luminance, $abs, $mark));
50             }
51             # Saturation
52             elsif ($com->{s}) {
53 5         14 my($h, $s, $l) = $color->hsl;
54 5         12 Color->hsl($h, adjust($s, $abs, $mark), $l);
55             }
56             # Inverse
57             elsif ($com->{i}) {
58 0         0 Color->rgb(map { 255 - $_ } $color->rgb);
  0         0  
59             }
60             # Luminance Grayscale
61             elsif ($com->{g}) {
62 0         0 my($h, $s, $l) = $color->hsl;
63 0         0 my $y = $color->luminance;
64 0         0 my $g = int($y * 255 / 100);
65 0         0 Color->rgb($g, $g, $g)
66             }
67             # Lightness Grayscale
68             elsif ($com->{G}) {
69 0         0 $color->greyscale;
70             }
71             # Rotate Hue
72             elsif ($com->{r} and $color->can('lch')) {
73 3 50       7 my $dig = $com->{c} ? 180 : $abs;
74 3 50       6 $dig = -$dig if $mark->{'-'};
75 3         8 my($l, $c, $h) = $color->lch;
76 3         356 Color->lch($l, $c, ($h + $dig) % 360);
77             }
78             # Hue Shift / Complement
79             elsif ($com->{h} || $com->{c} || $com->{r}) {
80 6         22 my($h, $s, $l) = $color->hsl;
81 6 50       22 my $dig = $com->{c} ? 180 : $abs;
82 6 100       20 $dig = -$dig if $mark->{'-'};
83 6         13 my $c = Color->hsl(($h + $dig) % 360, $s, $l);
84 6 50       889 $com->{r} ? $c->luminance($color->luminance)
85             : $c;
86             }
87             else {
88 1         24 die "$mod: Invalid color adjustment parameter.\n";
89             }
90             };
91             }
92 30         5179 $color->rgb;
93             }
94              
95             1;