File Coverage

blib/lib/Syntax/Feature/Qs.pm
Criterion Covered Total %
statement 57 57 100.0
branch n/a
condition n/a
subroutine 14 14 100.0
pod 0 1 0.0
total 71 72 98.6


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