File Coverage

blib/lib/OCBNET/CSS3/Regex/Base.pm
Criterion Covered Total %
statement 34 46 73.9
branch 16 42 38.1
condition n/a
subroutine 8 8 100.0
pod 0 5 0.0
total 58 101 57.4


line stmt bran cond sub pod time code
1             ###################################################################################################
2             # Copyright 2013/2014 by Marcel Greter
3             # This file is part of OCBNET-CSS3 (GPL3)
4             ####################################################################################################
5             package OCBNET::CSS3::Regex::Base;
6             ####################################################################################################
7             our $VERSION = '0.2.7';
8             ####################################################################################################
9            
10 12     12   24026 use strict;
  12         24  
  12         367  
11 12     12   54 use warnings;
  12         39  
  12         516  
12             our @EXPORT;
13             our @EXPORT_OK;
14            
15             ####################################################################################################
16            
17             # load exporter and inherit from it
18 12     12   61 use Exporter qw(); our @ISA = qw(Exporter);
  12         19  
  12         13092  
19            
20             # define our functions that will be exported
21             push @EXPORT, qw($re_apo $re_quot $re_identifier $re_string);
22             push @EXPORT_OK, qw($re_uri $re_import last_match last_index);
23             push @EXPORT_OK, qw($re_vendors $re_url unquot unwrapUrl wrapUrl);
24            
25             ####################################################################################################
26             # base regular expressions
27             ####################################################################################################
28            
29             # match text in apos or quotes
30             #**************************************************************************************************
31             our $re_apo = qr/(?:[^\'\\]+|\\.)*/s;
32             our $re_quot = qr/(?:[^\"\\]+|\\.)*/s;
33            
34             # match an identifier or name
35             #**************************************************************************************************
36             our $re_identifier = qr/\b[_a-zA-Z][_a-zA-Z0-9\-]*/s;
37            
38             # match a text (can be identifier or quoted string)
39             #**************************************************************************************************
40             our $re_string = qr/(?:$re_identifier|\"$re_quot\"|\'$re_apo\')/is;
41            
42             # regular expression to match a wrapped url
43             #**************************************************************************************************
44             our $re_url = qr/url\((?:\'$re_apo\'|\"$re_quot\"|[^\)]*)\)/s;
45            
46             # match vendors prefixes
47             #**************************************************************************************************
48             our $re_vendors = qr/(?:o|ms|moz|webkit)/is;
49            
50             ####################################################################################################
51            
52             # parse urls out of the css file
53             # only supports wrapped urls
54             our $re_uri = qr/url\(\s*(?:
55             \s*\"(?!data:)($re_quot)\" |
56             \s*\'(?!data:)($re_apo)\' |
57             (?![\"\'])\s*(?!data:)([^\)]*)
58             )\s*\)/xi;
59            
60             ####################################################################################################
61            
62             # parse urls out of the css file
63             # also supports not wrapped urls
64             our $re_import = qr/\@import\s*(?:
65             url\(\s*(?:
66             \s*\"(?!data:)($re_quot)\" |
67             \s*\'(?!data:)($re_apo)\' |
68             (?![\"\'])\s*(?!data:)([^\)]*)
69             )\) | (?:
70             \s*\"(?!data:)($re_quot)\" |
71             \s*\'(?!data:)($re_apo)\' |
72             (?![\"\'])\s*(?!data:)([^\s;]*)
73             ))
74             \s*;?/xi;
75            
76             ####################################################################################################
77             # regular expressions helpers
78             ####################################################################################################
79            
80             # return first defined match of last expression
81             # helper for expressions that match alternatives
82             sub last_match ()
83             {
84 3 100   3 0 38 if (defined $1) { $1 }
  1 100       6  
    50          
    0          
    0          
    0          
    0          
    0          
    0          
85 1         14 elsif (defined $2) { $2 }
86 1         7 elsif (defined $3) { $3 }
87 0         0 elsif (defined $4) { $4 }
88 0         0 elsif (defined $5) { $5 }
89 0         0 elsif (defined $6) { $6 }
90 0         0 elsif (defined $7) { $7 }
91 0         0 elsif (defined $8) { $8 }
92 0         0 elsif (defined $9) { $9 }
93             }
94            
95             # return index of first defined match of last expression
96             # can be used to differentiate between match alternatives
97             sub last_index ()
98             {
99 3 100   3 0 29 if (defined $1) { 1 }
  1 100       5  
    50          
    0          
    0          
    0          
    0          
    0          
    0          
100 1         7 elsif (defined $2) { 2 }
101 1         8 elsif (defined $3) { 3 }
102 0         0 elsif (defined $4) { 4 }
103 0         0 elsif (defined $5) { 5 }
104 0         0 elsif (defined $6) { 6 }
105 0         0 elsif (defined $7) { 7 }
106 0         0 elsif (defined $8) { 8 }
107 0         0 elsif (defined $9) { 9 }
108             }
109            
110             ####################################################################################################
111            
112             # a very plain and simply unquote function
113             # implement correctly once we actually find the specs
114             # although we could add some known escaping sequences
115             #**************************************************************************************************
116             sub unquot
117             {
118             # get the string
119 6     6 0 22 my $txt = $_[0];
120             # replace hexadecimal representation
121             # http://www.w3.org/International/questions/qa-escapes
122 6         25 $txt =~ s/\\([0-9A-F]{2,6})\s?/chr hex $1/eg;
  3         13  
123 6         15 $txt =~ s/\&\#x([0-9A-F]{2,6});\s?/chr hex $1/eg;
  1         5  
124 6         19 $txt =~ s/\&\#([0-9]{2,6});\s?/chr $1/eg;
  2         11  
125             # replace escape character
126 6         9 $txt =~ s/\\(.)/$1/g;
127             # return result
128 6         29 $txt;
129             }
130            
131             ####################################################################################################
132            
133             # unwrap an url
134             #**************************************************************************************************
135             sub unwrapUrl
136             {
137             # check for css url pattern (call again to unwrap quotes)
138 10 100   10 0 86 return unwrapUrl($1) if $_[0] =~ m/\A\s*url\(\s*(.*?)\s*\)\s*\z/m;
139             # unwrap quotes if there are any
140 4 100       33 return $1 if $_[0] =~ m/\A\"(.*?)\"\z/m;
141 2 100       18 return $1 if $_[0] =~ m/\A\'(.*?)\'\z/m;
142             # return same as given
143 1         5 return $_[0];
144             }
145            
146             # wrap an url
147             #**************************************************************************************************
148             sub wrapUrl
149             {
150             # get url from arguments
151 1     1 0 3 my $url = $_[0];
152             # change slashes
153 1         4 $url =~ s/\\/\//g;
154             # escape quotes
155 1         2 $url =~ s/\"/\\\"/g;
156             # return wrapped url
157 1         9 return 'url("' . $url . '")';
158             }
159            
160             ####################################################################################################
161             ####################################################################################################
162             1;