File Coverage

blib/lib/Syntax/Feature/Qs.pm
Criterion Covered Total %
statement 55 55 100.0
branch n/a
condition n/a
subroutine 13 13 100.0
pod 0 1 0.0
total 68 69 98.5


line stmt bran cond sub pod time code
1 1     1   354771 use strict;
  1         4  
  1         51  
2 1     1   6 use warnings;
  1         2  
  1         75  
3              
4             package Syntax::Feature::Qs;
5              
6             our $VERSION = '0.2004'; # VERSION
7             # ABSTRACT: Trim leading whitespace from all lines in a string
8              
9 1     1   1606 use Devel::Declare 0.006007 ();
  1         17404  
  1         46  
10 1     1   11 use B::Hooks::EndOfScope 0.09;
  1         25  
  1         9  
11 1     1   193 use Sub::Install 0.925 qw/install_sub/;
  1         22  
  1         8  
12              
13 1     1   966 use Devel::Declare::Context::Simple;
  1         2623  
  1         47  
14              
15 1     1   10 use namespace::clean;
  1         3  
  1         10  
16              
17             my %quote_op = qw(qs q qqs qq);
18             my @new_ops = keys %quote_op;
19              
20             sub install {
21 1     1 0 11 my $class = shift;
22 1         7 my %args = @_;
23 1         2 my $target = $args{'into'};
24              
25 2         4 Devel::Declare->setup_for($target => {
26             map {
27 1         3 my $name = $_;
28             ($name => {
29             const => sub {
30 17     17   1295 my $context = Devel::Declare::Context::Simple->new;
31 17         128 $context->init(@_);
32 17         199 return $class->_transform($name, $context);
33             },
34 2         26 });
35             } @new_ops
36             });
37 1         47 foreach my $name (@new_ops) {
38 2         99 install_sub {
39             into => $target,
40             as => $name,
41             code => $class->_run_callback,
42             };
43             }
44             on_scope_end {
45 1     1   120 namespace::clean->clean_subroutines($target, @new_ops);
46 1         51 };
47 1         21 return 1;
48             }
49              
50             sub _run_callback {
51             return sub ($) {
52 17     17   1498 my $string = shift;
53 17         103 $string =~ s{^\h+|\h+$}{}gms;
54 17         80 return $string;
55 2     2   17 };
56             }
57              
58             sub _transform {
59 17     17   31 my $class = shift;
60 17         19 my $name = shift;
61 17         19 my $ctx = shift;
62              
63 17         41 $ctx->skip_declarator;
64 17         397 my $length = Devel::Declare::toke_scan_str($ctx->offset);
65 17         173 my $string = Devel::Declare::get_lex_stuff;
66 17         26 Devel::Declare::clear_lex_stuff;
67 17         37 my $linestr = $ctx->get_linestr;
68 17         96 my $quoted = substr $linestr, $ctx->offset, $length;
69 17         70 my $spaced = '';
70 17         74 $quoted =~ m{^(\s*)}sm;
71 17         38 $spaced = $1;
72 17         84 my $new = sprintf '(%s)', join '',
73             $quote_op{$name},
74             $spaced,
75             substr($quoted, length($spaced), 1),
76             $string,
77             substr($quoted, -1, 1);
78 17         45 substr($linestr, $ctx->offset, $length) = $new;
79 17         100 $ctx->set_linestr($linestr);
80 17         323 return 1;
81             }
82              
83             1;
84              
85             __END__