Esempio n. 1
0
    def read_at_rule(self, at_keyword_token, tokens):
        """Read an at-rule from a token stream.

        :param at_keyword_token:
            The ATKEYWORD token that starts this at-rule
            You may have read it already to distinguish the rule
            from a ruleset.
        :param tokens:
            An iterator of subsequent tokens. Will be consumed just enough
            for one at-rule.
        :return:
            An unparsed :class:`AtRule`.
        :raises:
            :class:`~.parsing.ParseError` if the head is invalid for the core
            grammar. The body is **not** validated. See :class:`AtRule`.

        """
        # CSS syntax is case-insensitive
        at_keyword = at_keyword_token.value.lower()
        head = []
        # For the ParseError in case `tokens` is empty:
        token = at_keyword_token
        for token in tokens:
            if token.type in '{;':
                break
            # Ignore white space just after the at-keyword.
            else:
                head.append(token)
        # On unexpected end of stylesheet, pretend that a ';' was there
        head = strip_whitespace(head)
        for head_token in head:
            validate_any(head_token, 'at-rule head')
        body = token.content if token.type == '{' else None
        return AtRule(at_keyword, head, body,
                      at_keyword_token.line, at_keyword_token.column)
Esempio n. 2
0
    def read_at_rule(self, at_keyword_token, tokens):
        """Read an at-rule from a token stream.

        :param at_keyword_token:
            The ATKEYWORD token that starts this at-rule
            You may have read it already to distinguish the rule
            from a ruleset.
        :param tokens:
            An iterator of subsequent tokens. Will be consumed just enough
            for one at-rule.
        :return:
            An unparsed :class:`AtRule`.
        :raises:
            :class:`~.parsing.ParseError` if the head is invalid for the core
            grammar. The body is **not** validated. See :class:`AtRule`.

        """
        # CSS syntax is case-insensitive
        at_keyword = at_keyword_token.value.lower()
        head = []
        # For the ParseError in case `tokens` is empty:
        token = at_keyword_token
        for token in tokens:
            if token.type in '{;':
                break
            # Ignore white space just after the at-keyword.
            else:
                head.append(token)
        # On unexpected end of stylesheet, pretend that a ';' was there
        head = strip_whitespace(head)
        for head_token in head:
            validate_any(head_token, 'at-rule head')
        body = token.content if token.type == '{' else None
        return AtRule(at_keyword, head, body,
                      at_keyword_token.line, at_keyword_token.column)
Esempio n. 3
0
    def parse_ruleset(self, first_token, tokens):
        """Parse a ruleset: a selector followed by declaration block.

        :param first_token:
            The first token of the ruleset (probably of the selector).
            You may have read it already to distinguish the rule
            from an at-rule.
        :param tokens:
            an iterator of subsequent tokens. Will be consumed just enough
            for one ruleset.
        :return:
            a tuple of a :class:`RuleSet` and an error list.
            The errors are recovered :class:`~.parsing.ParseError` in declarations.
            (Parsing continues from the next declaration on such errors.)
        :raises:
            :class:`~.parsing.ParseError` if the selector is invalid for the
            core grammar.
            Note a that a selector can be valid for the core grammar but
            not for CSS 2.1 or another level.

        """
        selector = []
        for token in chain([first_token], tokens):
            if token.type == '{':
                # Parse/validate once we’ve read the whole rule
                selector = strip_whitespace(selector)
                if not selector:
                    raise ParseError(first_token, 'empty selector')
                for selector_token in selector:
                    validate_any(selector_token, 'selector')
                declarations, errors = self.parse_declaration_list(
                    token.content)
                ruleset = RuleSet(selector, declarations,
                                  first_token.line, first_token.column)
                return ruleset, errors
            else:
                selector.append(token)
        raise ParseError(token, 'no declaration block found for ruleset')
Esempio n. 4
0
    def parse_ruleset(self, first_token, tokens):
        """Parse a ruleset: a selector followed by declaration block.

        :param first_token:
            The first token of the ruleset (probably of the selector).
            You may have read it already to distinguish the rule
            from an at-rule.
        :param tokens:
            an iterator of subsequent tokens. Will be consumed just enough
            for one ruleset.
        :return:
            a tuple of a :class:`RuleSet` and an error list.
            The errors are recovered :class:`~.parsing.ParseError` in declarations.
            (Parsing continues from the next declaration on such errors.)
        :raises:
            :class:`~.parsing.ParseError` if the selector is invalid for the
            core grammar.
            Note a that a selector can be valid for the core grammar but
            not for CSS 2.1 or another level.

        """
        selector = []
        for token in chain([first_token], tokens):
            if token.type == '{':
                # Parse/validate once we’ve read the whole rule
                selector = strip_whitespace(selector)
                if not selector:
                    raise ParseError(first_token, 'empty selector')
                for selector_token in selector:
                    validate_any(selector_token, 'selector')
                declarations, errors = self.parse_declaration_list(
                    token.content)
                ruleset = RuleSet(selector, declarations,
                                  first_token.line, first_token.column)
                return ruleset, errors
            else:
                selector.append(token)
        raise ParseError(token, 'no declaration block found for ruleset')