class Crass::Parser

def consume_declaration(input = @tokens)

5.4.5. http://dev.w3.org/csswg/css-syntax-3/#consume-a-declaration

Consumes a declaration and returns it, or `nil` on parse error.
def consume_declaration(input = @tokens)
  declaration = {}
  value       = []
  declaration[:tokens] = input.collect do
    declaration[:name] = input.consume[:value]
    next_token = input.peek
    while next_token && next_token[:node] == :whitespace
      input.consume
      next_token = input.peek
    end
    unless next_token && next_token[:node] == :colon
      # Parse error.
      #
      # Note: The spec explicitly says to return nothing here, but Simon
      # Sapin's CSS parsing tests expect an error node.
      return create_node(:error, :value => 'invalid')
    end
    input.consume
    until input.peek.nil?
      value << consume_component_value(input)
    end
  end
  # Look for !important.
  important_tokens = value.reject {|token|
    node = token[:node]
    node == :whitespace || node == :comment || node == :semicolon
  }.last(2)
  if important_tokens.size == 2 &&
      important_tokens[0][:node] == :delim &&
      important_tokens[0][:value] == '!' &&
      important_tokens[1][:node] == :ident &&
      important_tokens[1][:value].downcase == 'important'
    declaration[:important] = true
    excl_index = value.index(important_tokens[0])
    # Technically the spec doesn't require us to trim trailing tokens after
    # the !important, but Simon Sapin's CSS parsing tests expect it and
    # tinycss2 does it, so we'll go along with the cool kids.
    value.slice!(excl_index, value.size - excl_index)
  else
    declaration[:important] = false
  end
  declaration[:value] = value
  create_node(:declaration, declaration)
end