csspool-st 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.autotest +16 -0
- data/.gemtest +0 -0
- data/CHANGELOG.rdoc +87 -0
- data/Manifest.txt +62 -0
- data/README.rdoc +65 -0
- data/Rakefile +50 -0
- data/lib/csspool/collection.rb +50 -0
- data/lib/csspool/css/charset.rb +13 -0
- data/lib/csspool/css/declaration.rb +19 -0
- data/lib/csspool/css/document.rb +34 -0
- data/lib/csspool/css/document_handler.rb +51 -0
- data/lib/csspool/css/import_rule.rb +27 -0
- data/lib/csspool/css/media.rb +13 -0
- data/lib/csspool/css/parser.rb +1298 -0
- data/lib/csspool/css/parser.y +398 -0
- data/lib/csspool/css/rule_set.rb +17 -0
- data/lib/csspool/css/tokenizer.rb +231 -0
- data/lib/csspool/css/tokenizer.rex +97 -0
- data/lib/csspool/css.rb +8 -0
- data/lib/csspool/node.rb +41 -0
- data/lib/csspool/sac/document.rb +35 -0
- data/lib/csspool/sac/parser.rb +16 -0
- data/lib/csspool/sac.rb +2 -0
- data/lib/csspool/selector.rb +36 -0
- data/lib/csspool/selectors/additional.rb +6 -0
- data/lib/csspool/selectors/attribute.rb +21 -0
- data/lib/csspool/selectors/class.rb +11 -0
- data/lib/csspool/selectors/id.rb +11 -0
- data/lib/csspool/selectors/pseudo_class.rb +13 -0
- data/lib/csspool/selectors/simple.rb +22 -0
- data/lib/csspool/selectors/type.rb +6 -0
- data/lib/csspool/selectors/universal.rb +6 -0
- data/lib/csspool/selectors.rb +9 -0
- data/lib/csspool/terms/function.rb +17 -0
- data/lib/csspool/terms/hash.rb +6 -0
- data/lib/csspool/terms/ident.rb +15 -0
- data/lib/csspool/terms/number.rb +14 -0
- data/lib/csspool/terms/rgb.rb +20 -0
- data/lib/csspool/terms/string.rb +6 -0
- data/lib/csspool/terms/uri.rb +6 -0
- data/lib/csspool/terms.rb +7 -0
- data/lib/csspool/visitors/children.rb +50 -0
- data/lib/csspool/visitors/comparable.rb +84 -0
- data/lib/csspool/visitors/iterator.rb +80 -0
- data/lib/csspool/visitors/to_css.rb +248 -0
- data/lib/csspool/visitors/visitor.rb +17 -0
- data/lib/csspool/visitors.rb +5 -0
- data/lib/csspool.rb +21 -0
- data/test/css/test_document.rb +13 -0
- data/test/css/test_import_rule.rb +42 -0
- data/test/css/test_parser.rb +462 -0
- data/test/css/test_tokenizer.rb +320 -0
- data/test/helper.rb +65 -0
- data/test/sac/test_parser.rb +123 -0
- data/test/sac/test_properties.rb +43 -0
- data/test/sac/test_terms.rb +228 -0
- data/test/test_collection.rb +81 -0
- data/test/test_parser.rb +91 -0
- data/test/test_selector.rb +51 -0
- data/test/visitors/test_children.rb +20 -0
- data/test/visitors/test_comparable.rb +102 -0
- data/test/visitors/test_each.rb +19 -0
- data/test/visitors/test_to_css.rb +309 -0
- metadata +214 -0
@@ -0,0 +1,398 @@
|
|
1
|
+
class CSSPool::CSS::Parser
|
2
|
+
|
3
|
+
token CHARSET_SYM IMPORT_SYM STRING SEMI IDENT S COMMA LBRACE RBRACE STAR HASH
|
4
|
+
token LSQUARE RSQUARE EQUAL INCLUDES DASHMATCH RPAREN FUNCTION GREATER PLUS
|
5
|
+
token SLASH NUMBER MINUS LENGTH PERCENTAGE EMS EXS ANGLE TIME FREQ URI
|
6
|
+
token IMPORTANT_SYM MEDIA_SYM LPAREN
|
7
|
+
|
8
|
+
rule
|
9
|
+
document
|
10
|
+
: { @handler.start_document }
|
11
|
+
stylesheet
|
12
|
+
{ @handler.end_document }
|
13
|
+
;
|
14
|
+
stylesheet
|
15
|
+
: charset stylesheet
|
16
|
+
| import stylesheet
|
17
|
+
| charset
|
18
|
+
| import
|
19
|
+
| body
|
20
|
+
;
|
21
|
+
charset
|
22
|
+
: CHARSET_SYM STRING SEMI { @handler.charset interpret_string(val[1]), {} }
|
23
|
+
;
|
24
|
+
import
|
25
|
+
: IMPORT_SYM import_location medium SEMI {
|
26
|
+
@handler.import_style val[2], val[1]
|
27
|
+
}
|
28
|
+
| IMPORT_SYM import_location SEMI {
|
29
|
+
@handler.import_style [], val[1]
|
30
|
+
}
|
31
|
+
;
|
32
|
+
import_location
|
33
|
+
: import_location S
|
34
|
+
| STRING { result = Terms::String.new interpret_string val.first }
|
35
|
+
| URI { result = Terms::URI.new interpret_uri val.first }
|
36
|
+
;
|
37
|
+
medium
|
38
|
+
: medium COMMA media_query {
|
39
|
+
result = val.first + [val.last]
|
40
|
+
}
|
41
|
+
| media_query {
|
42
|
+
result = [val.first]
|
43
|
+
}
|
44
|
+
;
|
45
|
+
media_query
|
46
|
+
: IDENT S IDENT media_expression {
|
47
|
+
result = [Terms::Ident.new(interpret_identifier val[0]), Terms::Ident.new(interpret_identifier val[2])] + val.last
|
48
|
+
}
|
49
|
+
| IDENT S IDENT {
|
50
|
+
result = [Terms::Ident.new(interpret_identifier val[0]), Terms::Ident.new(interpret_identifier val.last)]
|
51
|
+
}
|
52
|
+
| IDENT media_expression {
|
53
|
+
result = [Terms::Ident.new(interpret_identifier val.first)] + val.last
|
54
|
+
}
|
55
|
+
| IDENT {
|
56
|
+
result = [Terms::Ident.new(interpret_identifier val.first)]
|
57
|
+
}
|
58
|
+
| expression media_expression {
|
59
|
+
result = [val.first] + val.last
|
60
|
+
}
|
61
|
+
| expression {
|
62
|
+
result = [val.first]
|
63
|
+
}
|
64
|
+
;
|
65
|
+
media_expression
|
66
|
+
: S IDENT expression media_expression {
|
67
|
+
result = [Terms::Ident.new(interpret_identifier val[1]), val[2]] + val.last
|
68
|
+
}
|
69
|
+
| S IDENT expression {
|
70
|
+
result = [Terms::Ident.new(interpret_identifier val[1]), val.last]
|
71
|
+
}
|
72
|
+
;
|
73
|
+
expression_internal
|
74
|
+
: property ':' expr
|
75
|
+
{ result = Selectors::MediaExpression.new val.first, val[2] }
|
76
|
+
| property ':' S expr
|
77
|
+
{ result = Selectors::MediaExpression.new val.first, val[3] }
|
78
|
+
| property S ':' expr
|
79
|
+
{ result = Selectors::MediaExpression.new val.first, val[3] }
|
80
|
+
| property S ':' S expr
|
81
|
+
{ result = Selectors::MediaExpression.new val.first, val[4] }
|
82
|
+
;
|
83
|
+
expression
|
84
|
+
: LPAREN expression_internal RPAREN {
|
85
|
+
result = val[1]
|
86
|
+
}
|
87
|
+
;
|
88
|
+
body
|
89
|
+
: ruleset body
|
90
|
+
| media body
|
91
|
+
| ruleset
|
92
|
+
| media
|
93
|
+
;
|
94
|
+
media
|
95
|
+
: start_media body RBRACE { @handler.end_media val.first }
|
96
|
+
;
|
97
|
+
start_media
|
98
|
+
: MEDIA_SYM medium LBRACE {
|
99
|
+
@handler.start_media val[1]
|
100
|
+
}
|
101
|
+
| MEDIA_SYM LBRACE { result = [] }
|
102
|
+
;
|
103
|
+
ruleset
|
104
|
+
: start_selector declarations RBRACE {
|
105
|
+
@handler.end_selector val.first
|
106
|
+
}
|
107
|
+
| start_selector RBRACE {
|
108
|
+
@handler.end_selector val.first
|
109
|
+
}
|
110
|
+
;
|
111
|
+
start_selector
|
112
|
+
: S start_selector { result = val.last }
|
113
|
+
| selectors LBRACE {
|
114
|
+
@handler.start_selector val.first
|
115
|
+
}
|
116
|
+
;
|
117
|
+
selectors
|
118
|
+
: selector COMMA selectors
|
119
|
+
{
|
120
|
+
# FIXME: should always garantee array
|
121
|
+
sel = Selector.new(val.first, {})
|
122
|
+
result = [sel, val[2]].flatten
|
123
|
+
}
|
124
|
+
| selector
|
125
|
+
{
|
126
|
+
result = [Selector.new(val.first, {})]
|
127
|
+
}
|
128
|
+
;
|
129
|
+
selector
|
130
|
+
: simple_selector combinator selector
|
131
|
+
{
|
132
|
+
val = val.flatten
|
133
|
+
val[2].combinator = val.delete_at 1
|
134
|
+
result = val
|
135
|
+
}
|
136
|
+
| simple_selector
|
137
|
+
;
|
138
|
+
combinator
|
139
|
+
: S { result = :s }
|
140
|
+
| GREATER { result = :> }
|
141
|
+
| PLUS { result = :+ }
|
142
|
+
;
|
143
|
+
simple_selector
|
144
|
+
: element_name hcap {
|
145
|
+
selector = val.first
|
146
|
+
selector.additional_selectors = val.last
|
147
|
+
result = [selector]
|
148
|
+
}
|
149
|
+
| element_name { result = val }
|
150
|
+
| hcap
|
151
|
+
{
|
152
|
+
ss = Selectors::Simple.new nil, nil
|
153
|
+
ss.additional_selectors = val.flatten
|
154
|
+
result = [ss]
|
155
|
+
}
|
156
|
+
;
|
157
|
+
element_name
|
158
|
+
: IDENT { result = Selectors::Type.new interpret_identifier val.first }
|
159
|
+
| STAR { result = Selectors::Universal.new val.first }
|
160
|
+
;
|
161
|
+
hcap
|
162
|
+
: hash { result = val }
|
163
|
+
| class { result = val }
|
164
|
+
| attrib { result = val }
|
165
|
+
| pseudo { result = val }
|
166
|
+
| hash hcap { result = val.flatten }
|
167
|
+
| class hcap { result = val.flatten }
|
168
|
+
| attrib hcap { result = val.flatten }
|
169
|
+
| pseudo hcap { result = val.flatten }
|
170
|
+
;
|
171
|
+
hash
|
172
|
+
: HASH {
|
173
|
+
result = Selectors::Id.new interpret_identifier val.first.sub(/^#/, '')
|
174
|
+
}
|
175
|
+
class
|
176
|
+
: '.' IDENT {
|
177
|
+
result = Selectors::Class.new interpret_identifier val.last
|
178
|
+
}
|
179
|
+
;
|
180
|
+
attrib
|
181
|
+
: LSQUARE IDENT EQUAL IDENT RSQUARE {
|
182
|
+
result = Selectors::Attribute.new(
|
183
|
+
interpret_identifier(val[1]),
|
184
|
+
interpret_identifier(val[3]),
|
185
|
+
Selectors::Attribute::EQUALS
|
186
|
+
)
|
187
|
+
}
|
188
|
+
| LSQUARE IDENT EQUAL STRING RSQUARE {
|
189
|
+
result = Selectors::Attribute.new(
|
190
|
+
interpret_identifier(val[1]),
|
191
|
+
interpret_string(val[3]),
|
192
|
+
Selectors::Attribute::EQUALS
|
193
|
+
)
|
194
|
+
}
|
195
|
+
| LSQUARE IDENT INCLUDES STRING RSQUARE {
|
196
|
+
result = Selectors::Attribute.new(
|
197
|
+
interpret_identifier(val[1]),
|
198
|
+
interpret_string(val[3]),
|
199
|
+
Selectors::Attribute::INCLUDES
|
200
|
+
)
|
201
|
+
}
|
202
|
+
| LSQUARE IDENT INCLUDES IDENT RSQUARE {
|
203
|
+
result = Selectors::Attribute.new(
|
204
|
+
interpret_identifier(val[1]),
|
205
|
+
interpret_identifier(val[3]),
|
206
|
+
Selectors::Attribute::INCLUDES
|
207
|
+
)
|
208
|
+
}
|
209
|
+
| LSQUARE IDENT DASHMATCH IDENT RSQUARE {
|
210
|
+
result = Selectors::Attribute.new(
|
211
|
+
interpret_identifier(val[1]),
|
212
|
+
interpret_identifier(val[3]),
|
213
|
+
Selectors::Attribute::DASHMATCH
|
214
|
+
)
|
215
|
+
}
|
216
|
+
| LSQUARE IDENT DASHMATCH STRING RSQUARE {
|
217
|
+
result = Selectors::Attribute.new(
|
218
|
+
interpret_identifier(val[1]),
|
219
|
+
interpret_string(val[3]),
|
220
|
+
Selectors::Attribute::DASHMATCH
|
221
|
+
)
|
222
|
+
}
|
223
|
+
| LSQUARE IDENT RSQUARE {
|
224
|
+
result = Selectors::Attribute.new(
|
225
|
+
interpret_identifier(val[1]),
|
226
|
+
nil,
|
227
|
+
Selectors::Attribute::SET
|
228
|
+
)
|
229
|
+
}
|
230
|
+
;
|
231
|
+
pseudo
|
232
|
+
: ':' IDENT {
|
233
|
+
result = Selectors::pseudo interpret_identifier(val[1])
|
234
|
+
}
|
235
|
+
| ':' ':' IDENT {
|
236
|
+
result = Selectors::PseudoElement.new(
|
237
|
+
interpret_identifier(val[2])
|
238
|
+
)
|
239
|
+
}
|
240
|
+
| ':' FUNCTION RPAREN {
|
241
|
+
result = Selectors::PseudoClass.new(
|
242
|
+
interpret_identifier(val[1].sub(/\($/, '')),
|
243
|
+
''
|
244
|
+
)
|
245
|
+
}
|
246
|
+
| ':' FUNCTION IDENT RPAREN {
|
247
|
+
result = Selectors::PseudoClass.new(
|
248
|
+
interpret_identifier(val[1].sub(/\($/, '')),
|
249
|
+
interpret_identifier(val[2])
|
250
|
+
)
|
251
|
+
}
|
252
|
+
;
|
253
|
+
declarations
|
254
|
+
: declaration SEMI declarations
|
255
|
+
| declaration SEMI
|
256
|
+
| declaration
|
257
|
+
;
|
258
|
+
declaration
|
259
|
+
: property ':' expr prio
|
260
|
+
{ @handler.property val.first, val[2], val[3] }
|
261
|
+
| property ':' S expr prio
|
262
|
+
{ @handler.property val.first, val[3], val[4] }
|
263
|
+
| property S ':' expr prio
|
264
|
+
{ @handler.property val.first, val[3], val[4] }
|
265
|
+
| property S ':' S expr prio
|
266
|
+
{ @handler.property val.first, val[4], val[5] }
|
267
|
+
;
|
268
|
+
prio
|
269
|
+
: IMPORTANT_SYM { result = true }
|
270
|
+
| { result = false }
|
271
|
+
;
|
272
|
+
property
|
273
|
+
: IDENT { result = interpret_identifier val[0] }
|
274
|
+
| STAR IDENT { result = interpret_identifier val.join }
|
275
|
+
;
|
276
|
+
operator
|
277
|
+
: COMMA
|
278
|
+
| SLASH
|
279
|
+
| EQUAL
|
280
|
+
;
|
281
|
+
expr
|
282
|
+
: term operator expr {
|
283
|
+
result = [val.first, val.last].flatten
|
284
|
+
val.last.first.operator = val[1]
|
285
|
+
}
|
286
|
+
| term expr { result = val.flatten }
|
287
|
+
| term { result = val }
|
288
|
+
;
|
289
|
+
term
|
290
|
+
: ident
|
291
|
+
| numeric
|
292
|
+
| string
|
293
|
+
| uri
|
294
|
+
| hexcolor
|
295
|
+
| function
|
296
|
+
;
|
297
|
+
function
|
298
|
+
: function S { result = val.first }
|
299
|
+
| FUNCTION expr RPAREN {
|
300
|
+
name = interpret_identifier val.first.sub(/\($/, '')
|
301
|
+
if name == 'rgb'
|
302
|
+
result = Terms::Rgb.new(*val[1])
|
303
|
+
else
|
304
|
+
result = Terms::Function.new name, val[1]
|
305
|
+
end
|
306
|
+
}
|
307
|
+
;
|
308
|
+
hexcolor
|
309
|
+
: hexcolor S { result = val.first }
|
310
|
+
| HASH { result = Terms::Hash.new val.first.sub(/^#/, '') }
|
311
|
+
;
|
312
|
+
uri
|
313
|
+
: uri S { result = val.first }
|
314
|
+
| URI { result = Terms::URI.new interpret_uri val.first }
|
315
|
+
string
|
316
|
+
: string S { result = val.first }
|
317
|
+
| STRING { result = Terms::String.new interpret_string val.first }
|
318
|
+
;
|
319
|
+
numeric
|
320
|
+
: unary_operator numeric {
|
321
|
+
result = val[1]
|
322
|
+
val[1].unary_operator = val.first
|
323
|
+
}
|
324
|
+
| NUMBER {
|
325
|
+
result = Terms::Number.new numeric val.first
|
326
|
+
}
|
327
|
+
| PERCENTAGE {
|
328
|
+
result = Terms::Number.new numeric(val.first), nil, '%'
|
329
|
+
}
|
330
|
+
| LENGTH {
|
331
|
+
unit = val.first.gsub(/[\s\d.]/, '')
|
332
|
+
result = Terms::Number.new numeric(val.first), nil, unit
|
333
|
+
}
|
334
|
+
| EMS {
|
335
|
+
result = Terms::Number.new numeric(val.first), nil, 'em'
|
336
|
+
}
|
337
|
+
| EXS {
|
338
|
+
result = Terms::Number.new numeric(val.first), nil, 'ex'
|
339
|
+
}
|
340
|
+
| ANGLE {
|
341
|
+
unit = val.first.gsub(/[\s\d.]/, '')
|
342
|
+
result = Terms::Number.new numeric(val.first), nil, unit
|
343
|
+
}
|
344
|
+
| TIME {
|
345
|
+
unit = val.first.gsub(/[\s\d.]/, '')
|
346
|
+
result = Terms::Number.new numeric(val.first), nil, unit
|
347
|
+
}
|
348
|
+
| FREQ {
|
349
|
+
unit = val.first.gsub(/[\s\d.]/, '')
|
350
|
+
result = Terms::Number.new numeric(val.first), nil, unit
|
351
|
+
}
|
352
|
+
;
|
353
|
+
unary_operator
|
354
|
+
: MINUS { result = :minus }
|
355
|
+
| PLUS { result = :plus }
|
356
|
+
;
|
357
|
+
ident
|
358
|
+
: ident S { result = val.first }
|
359
|
+
| IDENT { result = Terms::Ident.new interpret_identifier val.first }
|
360
|
+
;
|
361
|
+
|
362
|
+
---- inner
|
363
|
+
|
364
|
+
def numeric thing
|
365
|
+
thing = thing.gsub(/[^\d.]/, '')
|
366
|
+
Integer(thing) rescue Float(thing)
|
367
|
+
end
|
368
|
+
|
369
|
+
def interpret_identifier s
|
370
|
+
interpret_escapes s
|
371
|
+
end
|
372
|
+
|
373
|
+
def interpret_uri s
|
374
|
+
interpret_escapes s.match(/^url\((.*)\)$/mu)[1].strip.match(/^(['"]?)((?:\\.|.)*)\1$/mu)[2]
|
375
|
+
end
|
376
|
+
|
377
|
+
def interpret_string s
|
378
|
+
interpret_escapes s.match(/^(['"])((?:\\.|.)*)\1$/mu)[2]
|
379
|
+
end
|
380
|
+
|
381
|
+
def interpret_escapes s
|
382
|
+
token_exp = /\\([0-9a-fA-F]{1,6}(?:\r\n|\s)?)|\\(.)|(.)/mu
|
383
|
+
characters = s.scan(token_exp).map do |u_escape, i_escape, ident|
|
384
|
+
if u_escape
|
385
|
+
code = u_escape.chomp.to_i 16
|
386
|
+
code = 0xFFFD if code > 0x10FFFF
|
387
|
+
[code].pack('U')
|
388
|
+
elsif i_escape
|
389
|
+
if i_escape == "\n"
|
390
|
+
''
|
391
|
+
else
|
392
|
+
i_escape
|
393
|
+
end
|
394
|
+
else
|
395
|
+
ident
|
396
|
+
end
|
397
|
+
end.join ''
|
398
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module CSSPool
|
2
|
+
module CSS
|
3
|
+
class RuleSet < CSSPool::Node
|
4
|
+
attr_accessor :selectors
|
5
|
+
attr_accessor :declarations
|
6
|
+
attr_accessor :media
|
7
|
+
|
8
|
+
def initialize selectors, declarations = [], media = []
|
9
|
+
@selectors = selectors
|
10
|
+
@declarations = declarations
|
11
|
+
@media = media
|
12
|
+
|
13
|
+
selectors.each { |sel| sel.rule_set = self }
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,231 @@
|
|
1
|
+
#--
|
2
|
+
# DO NOT MODIFY!!!!
|
3
|
+
# This file is automatically generated by rex 1.0.5
|
4
|
+
# from lexical definition file "lib/csspool/css/tokenizer.rex".
|
5
|
+
#++
|
6
|
+
|
7
|
+
module CSSPool
|
8
|
+
module CSS
|
9
|
+
class Tokenizer < Parser
|
10
|
+
require 'strscan'
|
11
|
+
|
12
|
+
class ScanError < StandardError ; end
|
13
|
+
|
14
|
+
attr_reader :lineno
|
15
|
+
attr_reader :filename
|
16
|
+
attr_accessor :state
|
17
|
+
|
18
|
+
def scan_setup(str)
|
19
|
+
@ss = StringScanner.new(str)
|
20
|
+
@lineno = 1
|
21
|
+
@state = nil
|
22
|
+
end
|
23
|
+
|
24
|
+
def action
|
25
|
+
yield
|
26
|
+
end
|
27
|
+
|
28
|
+
def scan_str(str)
|
29
|
+
scan_setup(str)
|
30
|
+
do_parse
|
31
|
+
end
|
32
|
+
alias :scan :scan_str
|
33
|
+
|
34
|
+
def load_file( filename )
|
35
|
+
@filename = filename
|
36
|
+
open(filename, "r") do |f|
|
37
|
+
scan_setup(f.read)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def scan_file( filename )
|
42
|
+
load_file(filename)
|
43
|
+
do_parse
|
44
|
+
end
|
45
|
+
|
46
|
+
|
47
|
+
def next_token
|
48
|
+
return if @ss.eos?
|
49
|
+
|
50
|
+
# skips empty actions
|
51
|
+
until token = _next_token or @ss.eos?; end
|
52
|
+
token
|
53
|
+
end
|
54
|
+
|
55
|
+
def _next_token
|
56
|
+
text = @ss.peek(1)
|
57
|
+
@lineno += 1 if text == "\n"
|
58
|
+
token = case @state
|
59
|
+
when nil
|
60
|
+
case
|
61
|
+
when (text = @ss.scan(/url\([\s]*("([^\n\r\f\\"]|\\\n|\r\n|\r|\f|[^\0-\177]|\\[0-9A-Fa-f]{1,6}(\r\n|[\s])?|\\[^\n\r\f0-9A-Fa-f])*"|'([^\n\r\f\\']|\\\n|\r\n|\r|\f|[^\0-\177]|\\[0-9A-Fa-f]{1,6}(\r\n|[\s])?|\\[^\n\r\f0-9A-Fa-f])*')[\s]*\)/i))
|
62
|
+
action { [:URI, st(text)] }
|
63
|
+
|
64
|
+
when (text = @ss.scan(/url\([\s]*([!#\$%&*-~]|[^\0-\177]|\\[0-9A-Fa-f]{1,6}(\r\n|[\s])?|\\[^\n\r\f0-9A-Fa-f])*[\s]*\)/i))
|
65
|
+
action { [:URI, st(text)] }
|
66
|
+
|
67
|
+
when (text = @ss.scan(/U\+[0-9a-fA-F?]{1,6}(-[0-9a-fA-F]{1,6})?/i))
|
68
|
+
action {[:UNICODE_RANGE, st(text)] }
|
69
|
+
|
70
|
+
when (text = @ss.scan(/[\s]*\/\*(.|[\s]*)*?\*\/[\s]*/i))
|
71
|
+
action { next_token }
|
72
|
+
|
73
|
+
when (text = @ss.scan(/[-@]?([_A-Za-z]|[^\0-\177]|\\[0-9A-Fa-f]{1,6}(\r\n|[\s])?|\\[^\n\r\f0-9A-Fa-f])([_A-Za-z0-9-]|[^\0-\177]|\\[0-9A-Fa-f]{1,6}(\r\n|[\s])?|\\[^\n\r\f0-9A-Fa-f]|[.])*\(\s*/i))
|
74
|
+
action { [:FUNCTION, st(text)] }
|
75
|
+
|
76
|
+
when (text = @ss.scan(/[\s]*@import[\s]*/i))
|
77
|
+
action { [:IMPORT_SYM, st(text)] }
|
78
|
+
|
79
|
+
when (text = @ss.scan(/[\s]*@page[\s]*/i))
|
80
|
+
action { [:PAGE_SYM, st(text)] }
|
81
|
+
|
82
|
+
when (text = @ss.scan(/[\s]*@charset[\s]*/i))
|
83
|
+
action { [:CHARSET_SYM, st(text)] }
|
84
|
+
|
85
|
+
when (text = @ss.scan(/[\s]*@media[\s]*/i))
|
86
|
+
action { [:MEDIA_SYM, st(text)] }
|
87
|
+
|
88
|
+
when (text = @ss.scan(/[\s]*!([\s]*|[\s]*\/\*(.|[\s]*)*?\*\/[\s]*)important[\s]*/i))
|
89
|
+
action { [:IMPORTANT_SYM, st(text)] }
|
90
|
+
|
91
|
+
when (text = @ss.scan(/[-@]?([_A-Za-z]|[^\0-\177]|\\[0-9A-Fa-f]{1,6}(\r\n|[\s])?|\\[^\n\r\f0-9A-Fa-f])([_A-Za-z0-9-]|[^\0-\177]|\\[0-9A-Fa-f]{1,6}(\r\n|[\s])?|\\[^\n\r\f0-9A-Fa-f])*/i))
|
92
|
+
action { [:IDENT, st(text)] }
|
93
|
+
|
94
|
+
when (text = @ss.scan(/\#([_A-Za-z0-9-]|[^\0-\177]|\\[0-9A-Fa-f]{1,6}(\r\n|[\s])?|\\[^\n\r\f0-9A-Fa-f])+/i))
|
95
|
+
action { [:HASH, st(text)] }
|
96
|
+
|
97
|
+
when (text = @ss.scan(/[\s]*~=[\s]*/i))
|
98
|
+
action { [:INCLUDES, st(text)] }
|
99
|
+
|
100
|
+
when (text = @ss.scan(/[\s]*\|=[\s]*/i))
|
101
|
+
action { [:DASHMATCH, st(text)] }
|
102
|
+
|
103
|
+
when (text = @ss.scan(/[\s]*\^=[\s]*/i))
|
104
|
+
action { [:PREFIXMATCH, st(text)] }
|
105
|
+
|
106
|
+
when (text = @ss.scan(/[\s]*\$=[\s]*/i))
|
107
|
+
action { [:SUFFIXMATCH, st(text)] }
|
108
|
+
|
109
|
+
when (text = @ss.scan(/[\s]*\*=[\s]*/i))
|
110
|
+
action { [:SUBSTRINGMATCH, st(text)] }
|
111
|
+
|
112
|
+
when (text = @ss.scan(/[\s]*!=[\s]*/i))
|
113
|
+
action { [:NOT_EQUAL, st(text)] }
|
114
|
+
|
115
|
+
when (text = @ss.scan(/[\s]*=[\s]*/i))
|
116
|
+
action { [:EQUAL, st(text)] }
|
117
|
+
|
118
|
+
when (text = @ss.scan(/[\s]*\)/i))
|
119
|
+
action { [:RPAREN, st(text)] }
|
120
|
+
|
121
|
+
when (text = @ss.scan(/[\s]*\([\s]*/i))
|
122
|
+
action { [:LPAREN, st(text)] }
|
123
|
+
|
124
|
+
when (text = @ss.scan(/\[[\s]*/i))
|
125
|
+
action { [:LSQUARE, st(text)] }
|
126
|
+
|
127
|
+
when (text = @ss.scan(/[\s]*\]/i))
|
128
|
+
action { [:RSQUARE, st(text)] }
|
129
|
+
|
130
|
+
when (text = @ss.scan(/[\s]*\+[\s]*/i))
|
131
|
+
action { [:PLUS, st(text)] }
|
132
|
+
|
133
|
+
when (text = @ss.scan(/[\s]*\{[\s]*/i))
|
134
|
+
action { [:LBRACE, st(text)] }
|
135
|
+
|
136
|
+
when (text = @ss.scan(/[\s]*\}[\s]*/i))
|
137
|
+
action { [:RBRACE, st(text)] }
|
138
|
+
|
139
|
+
when (text = @ss.scan(/[\s]*>[\s]*/i))
|
140
|
+
action { [:GREATER, st(text)] }
|
141
|
+
|
142
|
+
when (text = @ss.scan(/[\s]*,[\s]*/i))
|
143
|
+
action { [:COMMA, st(',')] }
|
144
|
+
|
145
|
+
when (text = @ss.scan(/[\s]*;[\s]*/i))
|
146
|
+
action { [:SEMI, st(';')] }
|
147
|
+
|
148
|
+
when (text = @ss.scan(/\*/i))
|
149
|
+
action { [:STAR, st(text)] }
|
150
|
+
|
151
|
+
when (text = @ss.scan(/[\s]*~[\s]*/i))
|
152
|
+
action { [:TILDE, st(text)] }
|
153
|
+
|
154
|
+
when (text = @ss.scan(/\:not\([\s]*/i))
|
155
|
+
action { [:NOT, st(text)] }
|
156
|
+
|
157
|
+
when (text = @ss.scan(/[\s]*([0-9]*\.[0-9]+|[0-9]+)em[\s]*/i))
|
158
|
+
action { [:EMS, st(text)] }
|
159
|
+
|
160
|
+
when (text = @ss.scan(/[\s]*([0-9]*\.[0-9]+|[0-9]+)ex[\s]*/i))
|
161
|
+
action { [:EXS, st(text)] }
|
162
|
+
|
163
|
+
when (text = @ss.scan(/[\s]*([0-9]*\.[0-9]+|[0-9]+)(px|cm|mm|in|pt|pc)[\s]*/i))
|
164
|
+
action { [:LENGTH, st(text)] }
|
165
|
+
|
166
|
+
when (text = @ss.scan(/[\s]*([0-9]*\.[0-9]+|[0-9]+)(deg|rad|grad)[\s]*/i))
|
167
|
+
action { [:ANGLE, st(text)] }
|
168
|
+
|
169
|
+
when (text = @ss.scan(/[\s]*([0-9]*\.[0-9]+|[0-9]+)(ms|s)[\s]*/i))
|
170
|
+
action { [:TIME, st(text)] }
|
171
|
+
|
172
|
+
when (text = @ss.scan(/[\s]*([0-9]*\.[0-9]+|[0-9]+)[k]?hz[\s]*/i))
|
173
|
+
action { [:FREQ, st(text)] }
|
174
|
+
|
175
|
+
when (text = @ss.scan(/[\s]*([0-9]*\.[0-9]+|[0-9]+)%[\s]*/i))
|
176
|
+
action { [:PERCENTAGE, st(text)] }
|
177
|
+
|
178
|
+
when (text = @ss.scan(/[\s]*([0-9]*\.[0-9]+|[0-9]+)[\s]*/i))
|
179
|
+
action { [:NUMBER, st(text)] }
|
180
|
+
|
181
|
+
when (text = @ss.scan(/[\s]*\/\/[\s]*/i))
|
182
|
+
action { [:DOUBLESLASH, st(text)] }
|
183
|
+
|
184
|
+
when (text = @ss.scan(/[\s]*\/[\s]*/i))
|
185
|
+
action { [:SLASH, st('/')] }
|
186
|
+
|
187
|
+
when (text = @ss.scan(/<!--/i))
|
188
|
+
action { [:CDO, st(text)] }
|
189
|
+
|
190
|
+
when (text = @ss.scan(/-->/i))
|
191
|
+
action { [:CDC, st(text)] }
|
192
|
+
|
193
|
+
when (text = @ss.scan(/[\s]*\-(?![-@]?([_A-Za-z]|[^\0-\177]|\\[0-9A-Fa-f]{1,6}(\r\n|[\s])?|\\[^\n\r\f0-9A-Fa-f])([_A-Za-z0-9-]|[^\0-\177]|\\[0-9A-Fa-f]{1,6}(\r\n|[\s])?|\\[^\n\r\f0-9A-Fa-f])*)[\s]*/i))
|
194
|
+
action { [:MINUS, st(text)] }
|
195
|
+
|
196
|
+
when (text = @ss.scan(/[\s]*\+[\s]*/i))
|
197
|
+
action { [:PLUS, st(text)] }
|
198
|
+
|
199
|
+
when (text = @ss.scan(/[\s]+/i))
|
200
|
+
action { [:S, st(text)] }
|
201
|
+
|
202
|
+
when (text = @ss.scan(/("([^\n\r\f\\"]|\\\n|\r\n|\r|\f|[^\0-\177]|\\[0-9A-Fa-f]{1,6}(\r\n|[\s])?|\\[^\n\r\f0-9A-Fa-f])*"|'([^\n\r\f\\']|\\\n|\r\n|\r|\f|[^\0-\177]|\\[0-9A-Fa-f]{1,6}(\r\n|[\s])?|\\[^\n\r\f0-9A-Fa-f])*')/i))
|
203
|
+
action { [:STRING, st(text)] }
|
204
|
+
|
205
|
+
when (text = @ss.scan(/("([^\n\r\f\\"]|\\\n|\r\n|\r|\f|[^\0-\177]|\\[0-9A-Fa-f]{1,6}(\r\n|[\s])?|\\[^\n\r\f0-9A-Fa-f])*|'([^\n\r\f\\']|\\\n|\r\n|\r|\f|[^\0-\177]|\\[0-9A-Fa-f]{1,6}(\r\n|[\s])?|\\[^\n\r\f0-9A-Fa-f])*)/i))
|
206
|
+
action { [:INVALID, st(text)] }
|
207
|
+
|
208
|
+
when (text = @ss.scan(/./i))
|
209
|
+
action { [st(text), st(text)] }
|
210
|
+
|
211
|
+
else
|
212
|
+
text = @ss.string[@ss.pos .. -1]
|
213
|
+
raise ScanError, "can not match: '" + text + "'"
|
214
|
+
end # if
|
215
|
+
|
216
|
+
else
|
217
|
+
raise ScanError, "undefined state: '" + state.to_s + "'"
|
218
|
+
end # case state
|
219
|
+
token
|
220
|
+
end # def _next_token
|
221
|
+
|
222
|
+
def st o
|
223
|
+
@st ||= Hash.new { |h,k| h[k] = k }
|
224
|
+
@st[o]
|
225
|
+
end # class
|
226
|
+
|
227
|
+
end
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
# vim: syntax=lex
|