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