Class: XRay::CSS::Parser

Inherits:
BaseParser show all
Defined in:
lib/css/parser.rb

Direct Known Subclasses

VisitableParser

Constant Summary collapse

TERM =
%q([^;{}'"])
TERM2 =
%q([^;{}'",])
QUOT_EXPR =
"'[^']*'"
DQUOT_EXPR =
'"[^"]*"'
R_IDENT =
/-?[_a-z][_a-z0-9-]*/
R_ANY =
%r"((?:#{TERM})|(?:#{QUOT_EXPR})|(?:#{DQUOT_EXPR}))+"
R_SELECTOR =
%r"((?:#{TERM2})|(?:#{QUOT_EXPR})|(?:#{DQUOT_EXPR}))+"
R_PROPERTY =
/[*_+\\]?-?[_a-z\\][\\_a-z0-9-]*/

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods inherited from BaseParser

#batch, #check, #eos?, #raw_scan, #reset, #scan, #skip, #skip_empty, #to_s

Constructor Details

#initialize(css, logger) ⇒ Parser

Returns a new instance of Parser.



20
21
22
23
# File 'lib/css/parser.rb', line 20

def initialize(css, logger)
  super
  @comments = []
end

Instance Attribute Details

#commentsObject (readonly)

Returns the value of attribute comments.



18
19
20
# File 'lib/css/parser.rb', line 18

def comments
  @comments
end

Instance Method Details

#parse_commentObject



140
141
142
143
144
145
# File 'lib/css/parser.rb', line 140

def parse_comment
  log 'pare comment'
  comment =  raw_scan /\/\*[^*]*\*+([^\/*][^*]*\*+)*\//
  log "  #{comment}" 
  comment
end

#parse_declarationObject



115
116
117
118
119
120
121
122
123
# File 'lib/css/parser.rb', line 115

def parse_declaration
  log '   parse declaration'
  
  property = parse_property
  skip /:/
  value = parse_value
  
  Declaration.new(property, value)
end

#parse_declarationsObject



102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/css/parser.rb', line 102

def parse_declarations
  first = true
  batch(:parse_declaration) do
    if check /\}/
      false
    else 
      skip(first ? /[;\s]*/ : /[;\s]+/)
      first = false
      !check /\}/
    end
  end
end

#parse_directiveObject



51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/css/parser.rb', line 51

def parse_directive
  log 'parse directive'

  skip /@/
  keyword = scan R_IDENT 
  skip_empty
  
  expr = check(/\{/) || check(/;/) ? nil : 
      scan(R_ANY)

  block = nil
  if check /\{/
    skip /\{/
    block = parse_stylesheet true
    skip /\}/
  end

  unless block
    skip /;/ 
  end

  log "  keyword: #{keyword} #{keyword.position}"
  log("  expression: #{expr} #{expr.position}") if expr
  log("  block:\n#{block}\n#{block.position}") if block
  Directive.new keyword, expr, block
end

#parse_propertyObject



125
126
127
128
129
130
# File 'lib/css/parser.rb', line 125

def parse_property
  log '    parse property'
  property = scan R_PROPERTY 
  log "     #{property} #{property.position}"
  property
end

#parse_rulesetObject



78
79
80
81
82
83
84
85
86
87
# File 'lib/css/parser.rb', line 78

def parse_ruleset
  log 'parse ruleset'

  selector = check(/\{/) ? nil : parse_selector
  skip /\{/
  declarations = do_parse_declarations
  skip /\}/
  
  RuleSet.new selector, declarations
end

#parse_selectorObject



89
90
91
92
93
# File 'lib/css/parser.rb', line 89

def parse_selector
  log ' parse selector'
  simple_selectors = batch(:parse_simple_selector, /\{/, /,/)
  Selector.new simple_selectors
end

#parse_simple_selectorObject



95
96
97
98
99
100
# File 'lib/css/parser.rb', line 95

def parse_simple_selector
  log '  parse simple selector'
  selector = scan R_SELECTOR 
  log "   #{selector} #{selector.position}"
  selector
end

#parse_statementObject

ruleset or directive



41
42
43
44
45
46
47
48
49
# File 'lib/css/parser.rb', line 41

def parse_statement
  log 'parse statement'

  if check /@/
    parse_directive
  else
    parse_ruleset
  end
end

#parse_stylesheet(inner = false) ⇒ Object Also known as: parse



25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/css/parser.rb', line 25

def parse_stylesheet(inner = false)
  log 'parse stylesheet'
  
  do_parse_comment

  stats = batch(:parse_statement) do 
    skip_empty
    !(inner ? check(/\}/) : eos?)
  end
  
  StyleSheet.new stats
end

#parse_valueObject



132
133
134
135
136
137
138
# File 'lib/css/parser.rb', line 132

def parse_value
  log '    parse value'

  value = scan R_ANY 
  log "     #{value} #{value.position}"
  value 
end