File Coverage

blib/lib/PPIx/EditorTools/Lexer.pm
Criterion Covered Total %
statement 54 57 94.7
branch 25 34 73.5
condition 4 6 66.6
subroutine 9 9 100.0
pod 0 2 0.0
total 92 108 85.1


line stmt bran cond sub pod time code
1             package PPIx::EditorTools::Lexer;
2             our $AUTHORITY = 'cpan:YANICK';
3             # ABSTRACT: Simple Lexer used for syntax highlighting
4             $PPIx::EditorTools::Lexer::VERSION = '0.20';
5 2     2   161750 use 5.008;
  2         20  
6 2     2   9 use strict;
  2         4  
  2         34  
7 2     2   7 use warnings;
  2         3  
  2         49  
8 2     2   8 use Carp;
  2         4  
  2         98  
9              
10 2     2   10 use base 'PPIx::EditorTools';
  2         5  
  2         430  
11 2     2   15 use Class::XSAccessor accessors => {};
  2         5  
  2         13  
12              
13 2     2   250 use PPI;
  2         3  
  2         932  
14              
15              
16             sub lexer {
17 8     8 0 17541 my ( $self, %args ) = @_;
18 8         19 my $markup = delete $args{highlighter};
19              
20 8         31 $self->process_doc(%args);
21              
22 8         18 my $ppi = $self->ppi;
23              
24 8 50       18 return [] unless defined $ppi;
25 8         23 $ppi->index_locations;
26              
27 8         2424 my @tokens = $ppi->tokens;
28              
29 8         266 foreach my $t (@tokens) {
30              
31 91         261 my ( $row, $rowchar ) = @{ $t->location };
  91         155  
32              
33 91         847 my $css = class_to_css($t);
34              
35 91         166 my $len = $t->length;
36              
37 91         264 $markup->( $css, $row, $rowchar, $len );
38             }
39             }
40              
41              
42             sub class_to_css {
43 91     91 0 106 my $Token = shift;
44              
45 91 100       224 if ( $Token->isa('PPI::Token::Word') ) {
46              
47             # There are some words we can be very confident are
48             # being used as keywords
49 37 50 66     60 unless ( $Token->snext_sibling and $Token->snext_sibling->content eq '=>' ) {
50 37 100       1319 if ( $Token->content =~ /^(?:sub|return)$/ ) {
    100          
51 3         17 return 'keyword';
52             } elsif ( $Token->content =~ /^(?:undef|shift|defined|bless)$/ ) {
53 4         32 return 'core';
54             }
55             }
56              
57 30 50 66     219 if ( $Token->previous_sibling and $Token->previous_sibling->content eq '->' ) {
58 0 0       0 if ( $Token->content =~ /^(?:new)$/ ) {
59 0         0 return 'core';
60             }
61             }
62              
63 30 100       887 if ( $Token->parent->isa('PPI::Statement::Include') ) {
    100          
    100          
    100          
    50          
64 8 100       35 if ( $Token->content =~ /^(?:use|no)$/ ) {
65 5         29 return 'keyword';
66             }
67 3 100       17 if ( $Token->content eq $Token->parent->pragma ) {
68 2         68 return 'pragma';
69             }
70             } elsif ( $Token->parent->isa('PPI::Statement::Variable') ) {
71 4 50       30 if ( $Token->content =~ /^(?:my|local|our)$/ ) {
72 4         24 return 'keyword';
73             }
74             } elsif ( $Token->parent->isa('PPI::Statement::Compound') ) {
75 8 50       74 if ( $Token->content =~ /^(?:if|else|elsif|unless|for|foreach|while|my)$/ ) {
76 8         43 return 'keyword';
77             }
78             } elsif ( $Token->parent->isa('PPI::Statement::Package') ) {
79 1 50       15 if ( $Token->content eq 'package' ) {
80 1         5 return 'keyword';
81             }
82             } elsif ( $Token->parent->isa('PPI::Statement::Scheduled') ) {
83 0         0 return 'keyword';
84             }
85             }
86              
87             # Normal coloring
88 64         238 my $css = ref $Token;
89 64         197 $css =~ s/^.+:://;
90 64         113 $css;
91             }
92              
93              
94             1;
95              
96             =pod
97              
98             =encoding UTF-8
99              
100             =head1 NAME
101              
102             PPIx::EditorTools::Lexer - Simple Lexer used for syntax highlighting
103              
104             =head1 VERSION
105              
106             version 0.20
107              
108             =head1 SYNOPSIS
109              
110             PPIx::EditorTools::Lexer->new->lexer(
111             code => "package TestPackage;\nsub x { 1;\n",
112             highlighter => sub {
113             my ( $css, $row, $rowchar, $len ) = @_;
114             ...
115             },
116             );
117              
118             =head1 DESCRIPTION
119              
120             Go over the various interesting elements of a give piece
121             of code or an already process PPI tree.
122             For each token call the user supplied 'highlighter' function with
123             the follow values:
124              
125             $css - The keyword that can be used for colouring.
126             $row - The row number where the token starts
127             $rowchar - The character within that row where the token starts
128             $len - The length of the token
129              
130             =head1 METHODS
131              
132             =over 4
133              
134             =item new()
135              
136             Constructor. Generally shouldn't be called with any arguments.
137              
138             =item find( ppi => PPI::Document $ppi, highlighter => sub {...} )
139              
140             =item find( code => Str $code, highlighter => sub ...{} )
141              
142             Accepts either a C<PPI::Document> to process or a string containing
143             the code (which will be converted into a C<PPI::Document>) to process.
144             Return a reference to an array.
145              
146             =back
147              
148             =head1 SEE ALSO
149              
150             This class inherits from C<PPIx::EditorTools>.
151             Also see L<App::EditorTools>, L<Padre>, and L<PPI>.
152              
153             =head1 AUTHORS
154              
155             =over 4
156              
157             =item *
158              
159             Steffen Mueller C<smueller@cpan.org>
160              
161             =item *
162              
163             Mark Grimes C<mgrimes@cpan.org>
164              
165             =item *
166              
167             Ahmad M. Zawawi <ahmad.zawawi@gmail.com>
168              
169             =item *
170              
171             Gabor Szabo <gabor@szabgab.com>
172              
173             =item *
174              
175             Yanick Champoux <yanick@cpan.org>
176              
177             =back
178              
179             =head1 COPYRIGHT AND LICENSE
180              
181             This software is copyright (c) 2017, 2014, 2012 by The Padre development team as listed in Padre.pm..
182              
183             This is free software; you can redistribute it and/or modify it under
184             the same terms as the Perl 5 programming language system itself.
185              
186             =cut
187              
188             __END__
189              
190              
191             # Copyright 2008-2011 The Padre development team as listed in Padre.pm.
192             # LICENSE
193             # This program is free software; you can redistribute it and/or
194             # modify it under the same terms as Perl 5 itself.
195