File Coverage

blib/lib/Syntax/Highlight/CSS.pm
Criterion Covered Total %
statement 64 66 96.9
branch 14 18 77.7
condition n/a
subroutine 9 9 100.0
pod 2 2 100.0
total 89 95 93.6


line stmt bran cond sub pod time code
1             package Syntax::Highlight::CSS;
2              
3 2     2   51337 use warnings;
  2         4  
  2         62  
4 2     2   10 use strict;
  2         4  
  2         2688  
5              
6             our $VERSION = '0.0102';
7              
8             # # #
9             # # #
10             # # #
11             #
12             #
13             #
14             # WARNING!!!! The code presented below is NOT suitable for persons
15             # with heart deseases and mental disorders,
16             #
17             # LOOK AT IT AT YOUR OWN RISK!!!!
18             #
19             #
20             #
21             # # #
22             # # #
23             # # #
24              
25             sub new {
26 2     2 1 1566 my $class = shift;
27 2         6 my %args = @_;
28             $args{ +lc } = delete $args{$_}
29 2         10 for keys %args;
30              
31 2         7 my $self = bless {}, $class;
32              
33 2 50       14 $self->_pre( defined $args{pre} ? $args{pre} : 1 );
34 2 100       9 $self->_line_numbers( defined $args{nnn} ? $args{nnn} : 0 );
35            
36 2         7 return $self;
37             }
38              
39             sub parse {
40 2     2 1 487 my ( $self, $input ) = @_;
41              
42 2 50       10 $input = ''
43             unless defined $input;
44              
45 2         7 my $text = $self->_parse_css( $input );
46              
47 2 100       7 if ( $self->_line_numbers ) {
48 1         5 $text = $self->_add_line_numbers( $text );
49             }
50              
51 2 50       7 if ( $self->_pre ) {
52 2         30 $text = '
' . $text . '
';
53             }
54              
55 2         7 return $text;
56             }
57              
58             sub _add_line_numbers {
59 1     1   2 my ( $self, $text ) = @_;
60 1         3 my $line = 0;
61 1         4 $text =~ s|^|
62 7         97 ''
63             . sprintf('%3d', $line++)
64             . ' '
65             |gem;
66              
67 1         5 return $text;
68             }
69              
70             sub _parse_css {
71 2     2   4 my $self = shift;
72              
73 2         4 $_ = shift; # input CSS
74              
75             # yes YES, blah blah is really retarded.. but oh well
76 2         3 my @quoted;
77 2         6 s/(" .+? (?
78 0         0 push @quoted, $1;
79 0         0 'HIGHLIGHT<>PARSER<>QUOTED<>' . $#quoted . '>'
80             /gsex;
81              
82 2         3 my @comments;
83 2         23 s{(/\* .+? \*/)}{
84 2         7 push @comments, $1;
85 2         10 'HIGHLIGHT<>PARSER<>COMMENT<>' . $#comments . '>'
86             }gsex;
87              
88 2         3 my @rulesets;
89 2         21 s/(?<={)([^{}]+)(?=})/
90 4         12 push @rulesets, $1;
91 4         36 'HIGHLIGHT<>PARSER<>RULESET<>' . $#rulesets . '>';
92             /gex;
93              
94             # parse selectors
95 2         19 s# (?:\A | (?<=[{};]) )
96             (\s*)
97             ( [^;{}]+? )
98             (\s*)
99             (?=[{;])#
100 10         25 $1
101             . $self->_parse_sel($2)
102             . $3
103             #gex;
104            
105             # properties/values;
106 2         8 for my $ruleset ( @rulesets ) {
107 4         70 $ruleset =~ s#(?: \A | (?<=[;]) )
108             (\s*) ([a-zA-Z-]+) (\s*) : (\s*) (.+?) (\s*)
109             (?=[;}]|\z)#$1$2$3:$4$5$6#gsx;
110             }
111              
112 2         20 s#HIGHLIGHT<>PARSER<>RULESET<>(\d+)>#$rulesets[$1]#g;
113              
114 2         6 s#
115             (HIGHLIGHT<>PARSER<>COMMENT<>\d+>)
116             (\s*)#$1$2#xg;
117              
118 2         11 s{()((?:(?!).)+)}{
119 4         10 my ($one, $two) = ($1, $2);
120 4 50       28 $two =~ /(.+?)(\s*HIGHLIGHT<>PARSER<>COMMENT<>\d>\s*)(.+)/
121             ? qq|$one$1$2$3|
122             : "$one$two";
123             }ges;
124              
125 2         15 s#HIGHLIGHT<>PARSER<>COMMENT<>(\d+)>#$comments[$1]#g;
126              
127 2         4 s#HIGHLIGHT<>PARSER<>QUOTED<>(\d+)>#$quoted[$1]#g;
128              
129 2         7 return $_;
130             }
131              
132             sub _parse_sel {
133 10     10   23 my $self = shift;
134 10         19 $_ = shift; # selector
135              
136 10 100       85 unless ( s#
137             ( \@(?:media|charset|import) )
138             (\s+)
139             ([^;{]+?)
140             (\s*)
141             \z#$1$2$3$4#gix
142             ) {
143 4         14 s{(:{1,2} \s*)(\S+)}{$1$2}gx;
144 4         27 s#(\s*)(.+)(\s*)#$1$2$3#sg;
145             }
146              
147 10         186 return $_;
148             }
149              
150             sub _pre {
151 4     4   5 my $self = shift;
152 4 100       13 if ( @_ ) {
153 2         9 $self->{PRE} = shift;
154             }
155 4         10 return $self->{PRE};
156             }
157              
158             sub _line_numbers {
159 4     4   6 my $self = shift;
160 4 100       9 if ( @_ ) {
161 2         5 $self->{LINE_NUMBERS} = shift;
162             }
163 4         13 return $self->{LINE_NUMBERS};
164             }
165              
166             1;
167             __END__