Class: CSS::Parser
Overview
Parser based on CSS Syntax Module Level 4 §5, with the nesting extensions described in CSS Nesting Module Level 1 / Syntax 4. drafts.csswg.org/css-syntax/
Constant Summary collapse
- EOF_TOKEN =
Shared sentinel returned past the end of the token stream. It has no position, which is why ParseError messages at EOF show no ‘line:col:` prefix.
Token.new(:eof).freeze
Class Method Summary collapse
- .parse_block_contents(input, **opts) ⇒ Object
- .parse_comma_separated_values(input, **opts) ⇒ Object
- .parse_component_value(input, **opts) ⇒ Object
- .parse_component_values(input, **opts) ⇒ Object
- .parse_declaration(input, **opts) ⇒ Object
- .parse_rule(input, **opts) ⇒ Object
- .parse_stylesheet(input, **opts) ⇒ Object
Instance Method Summary collapse
-
#initialize(tokens) ⇒ Parser
constructor
A new instance of Parser.
-
#parse_block_contents ⇒ Object
§5.4.4.
-
#parse_comma_separated_values ⇒ Object
§5.3.9.
-
#parse_component_value ⇒ Object
§5.3.7.
-
#parse_component_values ⇒ Object
§5.3.8.
-
#parse_declaration ⇒ Object
§5.3.5.
-
#parse_rule ⇒ Object
§5.3.4.
-
#parse_stylesheet ⇒ Object
§5.3.3.
Constructor Details
#initialize(tokens) ⇒ Parser
Returns a new instance of Parser.
30 31 32 33 |
# File 'lib/css/parser.rb', line 30 def initialize(tokens) @tokens = tokens @pos = 0 end |
Class Method Details
.parse_block_contents(input, **opts) ⇒ Object
17 |
# File 'lib/css/parser.rb', line 17 def parse_block_contents(input, **opts) = build(input, **opts).parse_block_contents |
.parse_comma_separated_values(input, **opts) ⇒ Object
20 |
# File 'lib/css/parser.rb', line 20 def parse_comma_separated_values(input, **opts) = build(input, **opts).parse_comma_separated_values |
.parse_component_value(input, **opts) ⇒ Object
18 |
# File 'lib/css/parser.rb', line 18 def parse_component_value(input, **opts) = build(input, **opts).parse_component_value |
.parse_component_values(input, **opts) ⇒ Object
19 |
# File 'lib/css/parser.rb', line 19 def parse_component_values(input, **opts) = build(input, **opts).parse_component_values |
.parse_declaration(input, **opts) ⇒ Object
16 |
# File 'lib/css/parser.rb', line 16 def parse_declaration(input, **opts) = build(input, **opts).parse_declaration |
.parse_rule(input, **opts) ⇒ Object
15 |
# File 'lib/css/parser.rb', line 15 def parse_rule(input, **opts) = build(input, **opts).parse_rule |
.parse_stylesheet(input, **opts) ⇒ Object
14 |
# File 'lib/css/parser.rb', line 14 def parse_stylesheet(input, **opts) = build(input, **opts).parse_stylesheet |
Instance Method Details
#parse_block_contents ⇒ Object
§5.4.4. Used for parsing the contents of a ‘style=“…”` attribute, `@page` blocks, and similar contexts where there is no enclosing `{}`.
76 77 78 |
# File 'lib/css/parser.rb', line 76 def parse_block_contents Block.new(items: collect_block_items(stop_at_close_brace: false)) end |
#parse_comma_separated_values ⇒ Object
§5.3.9. Empty input produces ‘[[]]`; a trailing comma produces a trailing empty group.
104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 |
# File 'lib/css/parser.rb', line 104 def parse_comma_separated_values groups = [] current = [] loop do case peek.type when :eof groups << current return groups when :comma consume groups << current current = [] else current << consume_component_value end end end |
#parse_component_value ⇒ Object
§5.3.7.
81 82 83 84 85 86 87 88 89 90 91 92 93 |
# File 'lib/css/parser.rb', line 81 def parse_component_value skip_whitespace parse_error!('expected a component value') if peek.type == :eof cv = consume_component_value skip_whitespace parse_error!("unexpected token after component value: #{peek.type}") unless peek.type == :eof cv end |
#parse_component_values ⇒ Object
§5.3.8.
96 97 98 99 100 |
# File 'lib/css/parser.rb', line 96 def parse_component_values values = [] values << consume_component_value until peek.type == :eof values end |
#parse_declaration ⇒ Object
§5.3.5. Per spec, trailing tokens after the declaration are ignored.
62 63 64 65 66 67 68 69 70 71 72 |
# File 'lib/css/parser.rb', line 62 def parse_declaration skip_whitespace parse_error!('expected a declaration') unless peek.type == :ident decl = try_consume_declaration parse_error!('invalid declaration') unless decl decl end |
#parse_rule ⇒ Object
§5.3.4.
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
# File 'lib/css/parser.rb', line 41 def parse_rule skip_whitespace parse_error!('expected a rule, got end of input') if peek.type == :eof rule = if peek.type == :at_keyword consume_at_rule(nested: false) else consume_qualified_rule(nested: false) end parse_error!('invalid rule') if rule.nil? skip_whitespace parse_error!("unexpected token after rule: #{peek.type}") unless peek.type == :eof rule end |
#parse_stylesheet ⇒ Object
§5.3.3.
36 37 38 |
# File 'lib/css/parser.rb', line 36 def parse_stylesheet Stylesheet.new(rules: consume_rule_list(top_level: true)) end |