File Coverage

blib/lib/Locale/Maketext/Extract/Plugin/PPI.pm
Criterion Covered Total %
statement 46 47 97.8
branch 21 24 87.5
condition 17 24 70.8
subroutine 5 6 83.3
pod 2 2 100.0
total 91 103 88.3


line stmt bran cond sub pod time code
1             package Locale::Maketext::Extract::Plugin::PPI;
2             $Locale::Maketext::Extract::Plugin::PPI::VERSION = '1.00';
3 1     1   15 use strict;
  1         2  
  1         50  
4 1     1   8 use base qw(Locale::Maketext::Extract::Plugin::Base);
  1         2  
  1         226  
5 1     1   7 use PPI();
  1         2  
  1         7927  
6              
7             # ABSTRACT: Perl format parser
8              
9              
10             sub file_types {
11 0     0 1 0 return qw( pm pl cgi );
12             }
13              
14             my %subnames = map { $_ => 1 } qw (translate maketext gettext l loc x __);
15              
16             #===================================
17             sub extract {
18             #===================================
19 43     43 1 291 my $self = shift;
20 43         78 my $text = shift;
21              
22 43         327 my $doc = PPI::Document->new( \$text, index_locations => 1 );
23              
24 43         93521 foreach my $statement ( @{ $doc->find('PPI::Statement') } ) {
  43         215  
25 89         28653 my @children = $statement->schildren;
26              
27 89         1621 while ( my $child = shift @children ) {
28             next
29             unless @children
30 140 100 66     1798 && ( $child->isa('PPI::Token::Word')
      66        
31             && $subnames{ $child->content }
32             || $child->isa('PPI::Token::Magic')
33             && $child->content eq '_' );
34              
35 45         351 my $list = shift @children;
36             next
37 45 50 33     139 unless $list->isa('PPI::Structure::List')
38             && $list->schildren;
39              
40 45         1107 $self->_check_arg_list($list);
41             }
42             }
43             }
44              
45             #===================================
46             sub _check_arg_list {
47             #===================================
48 45     45   80 my $self = shift;
49 45         57 my $list = shift;
50 45         130 my @args = ( $list->schildren )[0]->schildren;
51              
52 45         636 my $final_string = '';
53 45         61 my ( $line, $mode );
54              
55 45         204 while ( my $string_el = shift @args ) {
56             return
57 49 50 66     326 unless $string_el->isa('PPI::Token::Quote')
58             || $string_el->isa('PPI::Token::HereDoc');
59 49   66     293 $line ||= $string_el->location->[0];
60 49         15413 my $string;
61 49 100       271 if ( $string_el->isa('PPI::Token::HereDoc') ) {
62 15         54 $string = join( '', $string_el->heredoc );
63 15 100       125 $mode
64             = $string_el->{_mode} eq 'interpolate'
65             ? 'double'
66             : 'literal';
67             }
68             else {
69 34         192 $string = $string_el->string;
70 34 100 100     735 $mode
    100          
71             = $string_el->isa('PPI::Token::Quote::Literal') ? 'literal'
72             : ( $string_el->isa('PPI::Token::Quote::Double')
73             || $string_el->isa('PPI::Token::Quote::Interpolate') )
74             ? 'double'
75             : 'single';
76             }
77              
78 49 100       168 if ( $mode eq 'double' ) {
    100          
79             return
80 32 50       134 if !!( $string =~ /(?
81 32         3067 $string = eval qq("$string");
82             }
83             elsif ( $mode eq 'single' ) {
84 11         32 $string =~ s/\\'/'/g;
85             }
86              
87             # $string =~ s/(?
88 49         146 $string =~ s/\\\\/\\/g;
89              
90             # unless $mode eq 'literal';
91              
92 49         103 $final_string .= $string;
93              
94 49         81 my $next_op = shift @args;
95             last
96 49 100 66     285 unless $next_op
      100        
97             && $next_op->isa('PPI::Token::Operator')
98             && $next_op->content eq '.';
99             }
100 45 100       197 return unless $final_string;
101              
102 43         107 my $vars = join( '', map { $_->content } @args );
  8         23  
103 43         267 $self->add_entry( $final_string, $line, $vars );
104             }
105              
106              
107             1;
108              
109             __END__