Skip to content

Commit

Permalink
Merge pull request #18 from stoivo/main
Browse files Browse the repository at this point in the history
Minor changes which I think makes crass nicer
  • Loading branch information
rgrove authored May 23, 2024
2 parents e04ce0c + 47e6110 commit b51a88e
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 41 deletions.
34 changes: 17 additions & 17 deletions lib/crass/parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ module Crass

# Parses a CSS string or list of tokens.
#
# 5. http://dev.w3.org/csswg/css-syntax/#parsing
# 5. https://www.w3.org/TR/2013/WD-css-syntax-3-20130919/#parsing
class Parser
BLOCK_END_TOKENS = {
:'{' => :'}',
Expand All @@ -21,7 +21,7 @@ class Parser
#
# See {Tokenizer#initialize} for _options_.
#
# 5.3.6. http://dev.w3.org/csswg/css-syntax/#parse-a-list-of-declarations
# 5.3.6. https://www.w3.org/TR/2013/WD-css-syntax-3-20130919/#parse-a-list-of-declarations
def self.parse_properties(input, options = {})
Parser.new(input, options).parse_properties
end
Expand All @@ -32,7 +32,7 @@ def self.parse_properties(input, options = {})
#
# See {Tokenizer#initialize} for _options_.
#
# 5.3.3. http://dev.w3.org/csswg/css-syntax/#parse-a-list-of-rules
# 5.3.3. https://www.w3.org/TR/2013/WD-css-syntax-3-20130919/#parse-a-list-of-rules
def self.parse_rules(input, options = {})
parser = Parser.new(input, options)
rules = parser.consume_rules
Expand All @@ -50,7 +50,7 @@ def self.parse_rules(input, options = {})
#
# See {Tokenizer#initialize} for _options_.
#
# 5.3.2. http://dev.w3.org/csswg/css-syntax/#parse-a-stylesheet
# 5.3.2. https://www.w3.org/TR/2013/WD-css-syntax-3-20130919/#parse-a-stylesheet
def self.parse_stylesheet(input, options = {})
parser = Parser.new(input, options)
rules = parser.consume_rules(:top_level => true)
Expand Down Expand Up @@ -133,7 +133,7 @@ def initialize(input, options = {})

# Consumes an at-rule and returns it.
#
# 5.4.2. http://dev.w3.org/csswg/css-syntax-3/#consume-at-rule
# 5.4.2. https://www.w3.org/TR/2013/WD-css-syntax-3-20130919/#consume-at-rule
def consume_at_rule(input = @tokens)
rule = {}

Expand Down Expand Up @@ -180,7 +180,7 @@ def consume_at_rule(input = @tokens)
# Consumes a component value and returns it, or `nil` if there are no more
# tokens.
#
# 5.4.6. http://dev.w3.org/csswg/css-syntax-3/#consume-a-component-value
# 5.4.6. https://www.w3.org/TR/2013/WD-css-syntax-3-20130919/#consume-a-component-value
def consume_component_value(input = @tokens)
return nil unless token = input.consume

Expand All @@ -205,7 +205,7 @@ def consume_component_value(input = @tokens)

# Consumes a declaration and returns it, or `nil` on parse error.
#
# 5.4.5. http://dev.w3.org/csswg/css-syntax-3/#consume-a-declaration
# 5.4.5. https://www.w3.org/TR/2013/WD-css-syntax-3-20130919/#consume-a-declaration
def consume_declaration(input = @tokens)
declaration = {}
value = []
Expand Down Expand Up @@ -272,7 +272,7 @@ def consume_declaration(input = @tokens)
# * **:strict** - Set to `true` to exclude non-standard `:comment`,
# `:semicolon`, and `:whitespace` nodes.
#
# 5.4.4. http://dev.w3.org/csswg/css-syntax/#consume-a-list-of-declarations
# 5.4.4. https://www.w3.org/TR/2013/WD-css-syntax-3-20130919/#consume-a-list-of-declarations
def consume_declarations(input = @tokens, options = {})
declarations = []

Expand Down Expand Up @@ -322,7 +322,7 @@ def consume_declarations(input = @tokens, options = {})

# Consumes a function and returns it.
#
# 5.4.8. http://dev.w3.org/csswg/css-syntax-3/#consume-a-function
# 5.4.8. https://www.w3.org/TR/2013/WD-css-syntax-3-20130919/#consume-a-function
def consume_function(input = @tokens)
function = {
:name => input.current[:value],
Expand Down Expand Up @@ -353,7 +353,7 @@ def consume_function(input = @tokens)
# Consumes a qualified rule and returns it, or `nil` if a parse error
# occurs.
#
# 5.4.3. http://dev.w3.org/csswg/css-syntax-3/#consume-a-qualified-rule
# 5.4.3. https://www.w3.org/TR/2013/WD-css-syntax-3-20130919/#consume-a-qualified-rule
def consume_qualified_rule(input = @tokens)
rule = {:prelude => []}

Expand Down Expand Up @@ -394,7 +394,7 @@ def consume_qualified_rule(input = @tokens)

# Consumes a list of rules and returns them.
#
# 5.4.1. http://dev.w3.org/csswg/css-syntax/#consume-a-list-of-rules
# 5.4.1. https://www.w3.org/TR/2013/WD-css-syntax-3-20130919/#consume-a-list-of-rules
def consume_rules(flags = {})
rules = []

Expand Down Expand Up @@ -430,7 +430,7 @@ def consume_rules(flags = {})
# Consumes and returns a simple block associated with the current input
# token.
#
# 5.4.7. http://dev.w3.org/csswg/css-syntax/#consume-a-simple-block
# 5.4.7. https://www.w3.org/TR/2013/WD-css-syntax-3-20130919/#consume-a-simple-block
def consume_simple_block(input = @tokens)
start_token = input.current[:node]
end_token = BLOCK_END_TOKENS[start_token]
Expand Down Expand Up @@ -479,7 +479,7 @@ def create_style_rule(rule)

# Parses a single component value and returns it.
#
# 5.3.7. http://dev.w3.org/csswg/css-syntax-3/#parse-a-component-value
# 5.3.7. https://www.w3.org/TR/2013/WD-css-syntax-3-20130919/#parse-a-component-value
def parse_component_value(input = @tokens)
input = TokenScanner.new(input) unless input.is_a?(TokenScanner)

Expand All @@ -506,7 +506,7 @@ def parse_component_value(input = @tokens)

# Parses a list of component values and returns an array of parsed tokens.
#
# 5.3.8. http://dev.w3.org/csswg/css-syntax/#parse-a-list-of-component-values
# 5.3.8. https://www.w3.org/TR/2013/WD-css-syntax-3-20130919/#parse-a-list-of-component-values
def parse_component_values(input = @tokens)
input = TokenScanner.new(input) unless input.is_a?(TokenScanner)
tokens = []
Expand All @@ -520,7 +520,7 @@ def parse_component_values(input = @tokens)

# Parses a single declaration and returns it.
#
# 5.3.5. http://dev.w3.org/csswg/css-syntax/#parse-a-declaration
# 5.3.5. https://www.w3.org/TR/2013/WD-css-syntax-3-20130919/#parse-a-declaration
def parse_declaration(input = @tokens)
input = TokenScanner.new(input) unless input.is_a?(TokenScanner)

Expand Down Expand Up @@ -548,7 +548,7 @@ def parse_declaration(input = @tokens)
#
# See {#consume_declarations} for _options_.
#
# 5.3.6. http://dev.w3.org/csswg/css-syntax/#parse-a-list-of-declarations
# 5.3.6. https://www.w3.org/TR/2013/WD-css-syntax-3-20130919/#parse-a-list-of-declarations
def parse_declarations(input = @tokens, options = {})
input = TokenScanner.new(input) unless input.is_a?(TokenScanner)
consume_declarations(input, options)
Expand Down Expand Up @@ -582,7 +582,7 @@ def parse_properties(input = @tokens)

# Parses a single rule and returns it.
#
# 5.3.4. http://dev.w3.org/csswg/css-syntax-3/#parse-a-rule
# 5.3.4. https://www.w3.org/TR/2013/WD-css-syntax-3-20130919/#parse-a-rule
def parse_rule(input = @tokens)
input = TokenScanner.new(input) unless input.is_a?(TokenScanner)

Expand Down
34 changes: 17 additions & 17 deletions lib/crass/tokenizer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ module Crass

# Tokenizes a CSS string.
#
# 4. http://dev.w3.org/csswg/css-syntax/#tokenization
# 4. https://www.w3.org/TR/2013/WD-css-syntax-3-20130919/#tokenization
class Tokenizer
RE_COMMENT_CLOSE = /\*\//
RE_DIGIT = /[0-9]+/
Expand Down Expand Up @@ -66,7 +66,7 @@ def initialize(input, options = {})

# Consumes a token and returns the token that was consumed.
#
# 4.3.1. http://dev.w3.org/csswg/css-syntax/#consume-a-token
# 4.3.1. https://www.w3.org/TR/2013/WD-css-syntax-3-20130919/#consume-a-token
def consume
return nil if @s.eos?

Expand Down Expand Up @@ -271,7 +271,7 @@ def consume

# Consumes the remnants of a bad URL and returns the consumed text.
#
# 4.3.15. http://dev.w3.org/csswg/css-syntax/#consume-the-remnants-of-a-bad-url
# 4.3.15. https://www.w3.org/TR/2013/WD-css-syntax-3-20130919/#consume-the-remnants-of-a-bad-url
def consume_bad_url
text = String.new

Expand All @@ -297,7 +297,7 @@ def consume_bad_url

# Consumes comments and returns them, or `nil` if no comments were consumed.
#
# 4.3.2. http://dev.w3.org/csswg/css-syntax/#consume-comments
# 4.3.2. https://www.w3.org/TR/2013/WD-css-syntax-3-20130919/#consume-comments
def consume_comments
if @s.peek(2) == '/*'
@s.consume
Expand All @@ -322,7 +322,7 @@ def consume_comments
# next character in the input has already been verified not to be a newline
# or EOF.
#
# 4.3.8. http://dev.w3.org/csswg/css-syntax/#consume-an-escaped-code-point
# 4.3.8. https://www.w3.org/TR/2013/WD-css-syntax-3-20130919/#consume-an-escaped-code-point
def consume_escaped
return "\ufffd" if @s.eos?

Expand All @@ -346,7 +346,7 @@ def consume_escaped

# Consumes an ident-like token and returns it.
#
# 4.3.4. http://dev.w3.org/csswg/css-syntax/#consume-an-ident-like-token
# 4.3.4. https://www.w3.org/TR/2013/WD-css-syntax-3-20130919/#consume-an-ident-like-token
def consume_ident
value = consume_name

Expand All @@ -371,7 +371,7 @@ def consume_ident

# Consumes a name and returns it.
#
# 4.3.12. http://dev.w3.org/csswg/css-syntax/#consume-a-name
# 4.3.12. https://www.w3.org/TR/2013/WD-css-syntax-3-20130919/#consume-a-name
def consume_name
result = String.new

Expand Down Expand Up @@ -403,7 +403,7 @@ def consume_name
# original representation, its numeric value, and its type (either
# `:integer` or `:number`).
#
# 4.3.13. http://dev.w3.org/csswg/css-syntax/#consume-a-number
# 4.3.13. https://www.w3.org/TR/2013/WD-css-syntax-3-20130919/#consume-a-number
def consume_number
repr = String.new
type = :integer
Expand All @@ -426,7 +426,7 @@ def consume_number

# Consumes a numeric token and returns it.
#
# 4.3.3. http://dev.w3.org/csswg/css-syntax/#consume-a-numeric-token
# 4.3.3. https://www.w3.org/TR/2013/WD-css-syntax-3-20130919/#consume-a-numeric-token
def consume_numeric
number = consume_number
repr = number[0]
Expand Down Expand Up @@ -465,7 +465,7 @@ def consume_numeric
# Consumes a string token that ends at the given character, and returns the
# token.
#
# 4.3.5. http://dev.w3.org/csswg/css-syntax/#consume-a-string-token
# 4.3.5. https://www.w3.org/TR/2013/WD-css-syntax-3-20130919/#consume-a-string-token
def consume_string(ending = nil)
ending = @s.current if ending.nil?
value = String.new
Expand Down Expand Up @@ -506,7 +506,7 @@ def consume_string(ending = nil)
# Consumes a Unicode range token and returns it. Assumes the initial "u+" or
# "U+" has already been consumed.
#
# 4.3.7. http://dev.w3.org/csswg/css-syntax/#consume-a-unicode-range-token
# 4.3.7. https://www.w3.org/TR/2013/WD-css-syntax-3-20130919/#consume-a-unicode-range-token
def consume_unicode_range
value = @s.scan(RE_HEX) || String.new

Expand Down Expand Up @@ -538,7 +538,7 @@ def consume_unicode_range
# Consumes a URL token and returns it. Assumes the original "url(" has
# already been consumed.
#
# 4.3.6. http://dev.w3.org/csswg/css-syntax/#consume-a-url-token
# 4.3.6. https://www.w3.org/TR/2013/WD-css-syntax-3-20130919/#consume-a-url-token
def consume_url
value = String.new

Expand Down Expand Up @@ -586,7 +586,7 @@ def consume_url

# Converts a valid CSS number string into a number and returns the number.
#
# 4.3.14. http://dev.w3.org/csswg/css-syntax/#convert-a-string-to-a-number
# 4.3.14. https://www.w3.org/TR/2013/WD-css-syntax-3-20130919/#convert-a-string-to-a-number
def convert_string_to_number(str)
matches = RE_NUMBER_STR.match(str)

Expand Down Expand Up @@ -623,7 +623,7 @@ def create_token(type, properties = {})

# Preprocesses _input_ to prepare it for the tokenizer.
#
# 3.3. http://dev.w3.org/csswg/css-syntax/#input-preprocessing
# 3.3. https://www.w3.org/TR/2013/WD-css-syntax-3-20130919/#input-preprocessing
def preprocess(input)
input = input.to_s.encode('UTF-8',
:invalid => :replace,
Expand All @@ -638,7 +638,7 @@ def preprocess(input)
# identifier. If _text_ is `nil`, the current and next two characters in the
# input stream will be checked, but will not be consumed.
#
# 4.3.10. http://dev.w3.org/csswg/css-syntax/#would-start-an-identifier
# 4.3.10. https://www.w3.org/TR/2013/WD-css-syntax-3-20130919/#would-start-an-identifier
def start_identifier?(text = nil)
text = @s.current + @s.peek(2) if text.nil?

Expand All @@ -662,7 +662,7 @@ def start_identifier?(text = nil)
# If _text_ is `nil`, the current and next two characters in the input
# stream will be checked, but will not be consumed.
#
# 4.3.11. http://dev.w3.org/csswg/css-syntax/#starts-with-a-number
# 4.3.11. https://www.w3.org/TR/2013/WD-css-syntax-3-20130919/#starts-with-a-number
def start_number?(text = nil)
text = @s.current + @s.peek(2) if text.nil?

Expand Down Expand Up @@ -698,7 +698,7 @@ def tokenize
# valid escape sequence. If _text_ is `nil`, the current and next character
# in the input stream will be checked, but will not be consumed.
#
# 4.3.9. http://dev.w3.org/csswg/css-syntax/#starts-with-a-valid-escape
# 4.3.9. https://www.w3.org/TR/2013/WD-css-syntax-3-20130919/#starts-with-a-valid-escape
def valid_escape?(text = nil)
text = @s.current + @s.peek if text.nil?
!!(text[0] == '\\' && text[1] != "\n")
Expand Down
14 changes: 7 additions & 7 deletions test/test_css_parsing_tests.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ def load_css_tests(filename)
css = test[0]
expected = test[1]

it "should parse: #{css.gsub("\n", "\\n")}" do
it "should parse: #{css.gsub("\n", "\\n").inspect}" do
parser = Crass::Parser.new(css)
assert_equal(expected, translate_tokens(parser.parse_component_values))
end
Expand All @@ -40,7 +40,7 @@ def load_css_tests(filename)
css = test[0]
expected = test[1]

it "should parse: #{css.gsub("\n", "\\n")}" do
it "should parse: #{css.gsub("\n", "\\n").inspect}" do
parser = Crass::Parser.new(css)
assert_equal(expected, translate_tokens(parser.parse_declarations(parser.tokens, {:strict => true})))
end
Expand All @@ -57,7 +57,7 @@ def load_css_tests(filename)
css = test[0]
expected = test[1]

it "should parse: #{css.gsub("\n", "\\n")}" do
it "should parse: #{css.gsub("\n", "\\n").inspect}" do
parser = Crass::Parser.new(css)
assert_equal(expected, translate_tokens(parser.parse_component_value)[0])
end
Expand All @@ -74,7 +74,7 @@ def load_css_tests(filename)
css = test[0]
expected = test[1]

it "should parse: #{css.gsub("\n", "\\n")}" do
it "should parse: #{css.gsub("\n", "\\n").inspect}" do
parser = Crass::Parser.new(css)
assert_equal(expected, translate_tokens(parser.parse_declaration)[0])
end
Expand All @@ -91,7 +91,7 @@ def load_css_tests(filename)
css = test[0]
expected = test[1]

it "should parse: #{css.gsub("\n", "\\n")}" do
it "should parse: #{css.gsub("\n", "\\n").inspect}" do
parser = Crass::Parser.new(css)
assert_equal(expected, translate_tokens(parser.parse_rule)[0])
end
Expand All @@ -108,7 +108,7 @@ def load_css_tests(filename)
css = test[0]
expected = test[1]

it "should parse: #{css.gsub("\n", "\\n")}" do
it "should parse: #{css.gsub("\n", "\\n").inspect}" do
parser = Crass::Parser.new(css)
rules = parser.consume_rules

Expand All @@ -133,7 +133,7 @@ def load_css_tests(filename)
css = test[0]
expected = test[1]

it "should parse: #{css.gsub("\n", "\\n")}" do
it "should parse: #{css.gsub("\n", "\\n").inspect}" do
parser = Crass::Parser.new(css)
rules = parser.consume_rules(:top_level => true)

Expand Down

0 comments on commit b51a88e

Please sign in to comment.