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;
|