示例#1
0
 def wrapper(tokens, *args):
     results = []
     for part in split_on_comma(tokens):
         result = function(remove_whitespace(part), *args)
         if result is None:
             return None
         results.append(result)
     return results
示例#2
0
def preprocess_declarations(base_url, declarations):
    """
    Expand shorthand properties and filter unsupported properties and values.

    Log a warning for every ignored declaration.

    Return a iterable of ``(name, value, priority)`` tuples.

    """
    def validation_error(level, reason):
        getattr(LOGGER,
                level)('Ignored `%s: %s` at %i:%i, %s.', declaration.name,
                       declaration.value.as_css(), declaration.line,
                       declaration.column, reason)

    for declaration in declarations:
        name = declaration.name

        if name in PREFIXED and not name.startswith(PREFIX):
            validation_error(
                'warn', 'the property is experimental or non-standard, use ' +
                PREFIX + name)
            continue

        if name in NOT_PRINT_MEDIA:
            validation_error(
                'info', 'the property does not apply for the print media')
            continue

        if name.startswith(PREFIX):
            unprefixed_name = name[len(PREFIX):]
            if unprefixed_name in UNPREFIXED:
                validation_error(
                    'warn',
                    'the property was unprefixed, use ' + unprefixed_name)
                continue
            if unprefixed_name in PREFIXED:
                name = unprefixed_name

        expander_ = EXPANDERS.get(name, validate_non_shorthand)
        tokens = remove_whitespace(declaration.value)
        try:
            # Use list() to consume generators now and catch any error.
            result = list(expander_(base_url, name, tokens))
        except InvalidValues as exc:
            validation_error(
                'warn',
                exc.args[0] if exc.args and exc.args[0] else 'invalid value')
            continue

        priority = declaration.priority
        for long_name, value in result:
            yield long_name.replace('-', '_'), value, priority
示例#3
0
def preprocess_declarations(base_url, declarations):
    """
    Expand shorthand properties and filter unsupported properties and values.

    Log a warning for every ignored declaration.

    Return a iterable of ``(name, value, priority)`` tuples.

    """
    def validation_error(level, reason):
        getattr(LOGGER, level)('Ignored `%s: %s` at %i:%i, %s.',
            declaration.name, declaration.value.as_css(),
            declaration.line, declaration.column, reason)

    for declaration in declarations:
        name = declaration.name

        if name in PREFIXED and not name.startswith(PREFIX):
            validation_error('warn',
                'the property is experimental or non-standard, use '
                + PREFIX + name)
            continue

        if name in NOT_PRINT_MEDIA:
            validation_error('info',
                'the property does not apply for the print media')
            continue

        if name.startswith(PREFIX):
            unprefixed_name = name[len(PREFIX):]
            if unprefixed_name in UNPREFIXED:
                validation_error('warn',
                    'the property was unprefixed, use ' + unprefixed_name)
                continue
            if unprefixed_name in PREFIXED:
                name = unprefixed_name

        expander_ = EXPANDERS.get(name, validate_non_shorthand)
        tokens = remove_whitespace(declaration.value)
        try:
            # Use list() to consume generators now and catch any error.
            result = list(expander_(base_url, name, tokens))
        except InvalidValues as exc:
            validation_error('warn',
                exc.args[0] if exc.args and exc.args[0] else 'invalid value')
            continue

        priority = declaration.priority
        for long_name, value in result:
            yield long_name.replace('-', '_'), value, priority
示例#4
0
def preprocess_descriptors(base_url, descriptors):
    """Filter unsupported names and values for descriptors.

    Log a warning for every ignored descriptor.

    Return a iterable of ``(name, value)`` tuples.

    """
    for descriptor in descriptors:
        tokens = remove_whitespace(descriptor.value)
        try:
            # Use list() to consume generators now and catch any error.
            result = list(validate(base_url, descriptor.name, tokens))
        except InvalidValues as exc:
            LOGGER.warning(
                'Ignored `%s: %s` at %i:%i, %s.', descriptor.name,
                descriptor.value.as_css(), descriptor.line, descriptor.column,
                exc.args[0] if exc.args and exc.args[0] else 'invalid value')
            continue

        for long_name, value in result:
            yield long_name.replace('-', '_'), value
示例#5
0
    def parse_media(self, tokens, errors):
        """For CSS 2.1, parse a list of media types.

        Media Queries are expected to override this.

        :param tokens:
            A list of tokens
        :raises:
            :class:`~.parsing.ParseError` on invalid media types/queries
        :returns:
            For CSS 2.1, a list of media types as strings
        """
        if not tokens:
            return ['all']
        media_types = []
        for part in split_on_comma(remove_whitespace(tokens)):
            types = [token.type for token in part]
            if types == ['IDENT']:
                media_types.append(part[0].value)
            else:
                raise ParseError(tokens[0], 'expected a media type'
                    + ((', got ' + ', '.join(types)) if types else ''))
        return media_types
示例#6
0
文件: css21.py 项目: AEliu/calibre
    def parse_media(self, tokens, errors):
        """For CSS 2.1, parse a list of media types.

        Media Queries are expected to override this.

        :param tokens:
            A list of tokens
        :raises:
            :class:`~.parsing.ParseError` on invalid media types/queries
        :returns:
            For CSS 2.1, a list of media types as strings
        """
        if not tokens:
            return ['all']
        media_types = []
        for part in split_on_comma(remove_whitespace(tokens)):
            types = [token.type for token in part]
            if types == ['IDENT']:
                media_types.append(part[0].value)
            else:
                raise ParseError(tokens[0], 'expected a media type'
                    + ((', got ' + ', '.join(types)) if types else ''))
        return media_types
示例#7
0
def preprocess_descriptors(base_url, descriptors):
    """Filter unsupported names and values for descriptors.

    Log a warning for every ignored descriptor.

    Return a iterable of ``(name, value)`` tuples.

    """
    for descriptor in descriptors:
        tokens = remove_whitespace(descriptor.value)
        try:
            # Use list() to consume generators now and catch any error.
            result = list(validate(base_url, descriptor.name, tokens))
        except InvalidValues as exc:
            LOGGER.warning(
                'Ignored `%s: %s` at %i:%i, %s.',
                descriptor.name, descriptor.value.as_css(),
                descriptor.line, descriptor.column,
                exc.args[0] if exc.args and exc.args[0] else 'invalid value')
            continue

        for long_name, value in result:
            yield long_name.replace('-', '_'), value
示例#8
0
文件: media3.py 项目: tokot/calibre
    def parse_media(self, tokens, errors):
        if not tokens:
            return [MediaQuery('all')]
        queries = []

        for part in split_on_comma(remove_whitespace(tokens)):
            negated = False
            media_type = None
            expressions = []
            try:
                for i, tok in enumerate(part):
                    if i == 0 and tok.type == 'IDENT':
                        val = tok.value.lower()
                        if val == 'only':
                            continue  # ignore leading ONLY
                        if val == 'not':
                            negated = True
                            continue
                    if media_type is None and tok.type == 'IDENT':
                        media_type = tok.value
                        continue
                    elif media_type is None:
                        media_type = 'all'

                    if tok.type == 'IDENT' and tok.value.lower() == 'and':
                        continue
                    if not tok.is_container:
                        raise MalformedExpression(
                            tok,
                            'expected a media expression not a %s' % tok.type)
                    if tok.type != '(':
                        raise MalformedExpression(
                            tok,
                            'media expressions must be in parentheses not %s' %
                            tok.type)
                    content = remove_whitespace(tok.content)
                    if len(content) == 0:
                        raise MalformedExpression(
                            tok, 'media expressions cannot be empty')
                    if content[0].type != 'IDENT':
                        raise MalformedExpression(
                            content[0],
                            'expected a media feature not a %s' % tok.type)
                    media_feature, expr = content[0].value, None
                    if len(content) > 1:
                        if len(content) < 3:
                            raise MalformedExpression(
                                content[1],
                                'malformed media feature definition')
                        if content[1].type != ':':
                            raise MalformedExpression(content[1],
                                                      'expected a :')
                        expr = content[2:]
                        if len(expr) == 1:
                            expr = expr[0]
                        elif len(expr) == 3 and (
                                expr[0].type, expr[1].type, expr[1].value,
                                expr[2].type) == ('INTEGER', 'DELIM', '/',
                                                  'INTEGER'):
                            # This should really be moved into token_data, but
                            # since RATIO is not part of CSS 2.1 and does not
                            # occur anywhere else, we special case it here.
                            r = expr[0]
                            r.value = (expr[0].value, expr[2].value)
                            r.type = 'RATIO'
                            r._as_css = expr[0]._as_css + expr[
                                1]._as_css + expr[2]._as_css
                            expr = r
                        else:
                            raise MalformedExpression(
                                expr[0], 'malformed media feature definition')

                    expressions.append((media_feature, expr))
            except MalformedExpression as err:
                errors.extend(ParseError(err.tok, err.message))
                media_type, negated, expressions = 'all', True, ()
            queries.append(
                MediaQuery(media_type or 'all',
                           expressions=tuple(expressions),
                           negated=negated))

        return queries
示例#9
0
文件: media3.py 项目: AEliu/calibre
    def parse_media(self, tokens, errors):
        if not tokens:
            return [MediaQuery('all')]
        queries = []

        for part in split_on_comma(remove_whitespace(tokens)):
            negated = False
            media_type = None
            expressions = []
            try:
                for i, tok in enumerate(part):
                    if i == 0 and tok.type == 'IDENT':
                        val = tok.value.lower()
                        if val == 'only':
                            continue  # ignore leading ONLY
                        if val == 'not':
                            negated = True
                            continue
                    if media_type is None and tok.type == 'IDENT':
                        media_type = tok.value
                        continue
                    elif media_type is None:
                        media_type = 'all'

                    if tok.type == 'IDENT' and tok.value.lower() == 'and':
                        continue
                    if not tok.is_container:
                        raise MalformedExpression(tok, 'expected a media expression not a %s' % tok.type)
                    if tok.type != '(':
                        raise MalformedExpression(tok, 'media expressions must be in parentheses not %s' % tok.type)
                    content = remove_whitespace(tok.content)
                    if len(content) == 0:
                        raise MalformedExpression(tok, 'media expressions cannot be empty')
                    if content[0].type != 'IDENT':
                        raise MalformedExpression(content[0], 'expected a media feature not a %s' % tok.type)
                    media_feature, expr = content[0].value, None
                    if len(content) > 1:
                        if len(content) < 3:
                            raise MalformedExpression(content[1], 'malformed media feature definition')
                        if content[1].type != ':':
                            raise MalformedExpression(content[1], 'expected a :')
                        expr = content[2:]
                        if len(expr) == 1:
                            expr = expr[0]
                        elif len(expr) == 3 and (expr[0].type, expr[1].type, expr[1].value, expr[2].type) == (
                            'INTEGER', 'DELIM', '/', 'INTEGER'):
                            # This should really be moved into token_data, but
                            # since RATIO is not part of CSS 2.1 and does not
                            # occur anywhere else, we special case it here.
                            r = expr[0]
                            r.value = (expr[0].value, expr[2].value)
                            r.type = 'RATIO'
                            r._as_css = expr[0]._as_css + expr[1]._as_css + expr[2]._as_css
                            expr = r
                        else:
                            raise MalformedExpression(expr[0], 'malformed media feature definition')

                    expressions.append((media_feature, expr))
            except MalformedExpression as err:
                errors.extend(ParseError(err.tok, err.message))
                media_type, negated, expressions = 'all', True, ()
            queries.append(MediaQuery(media_type or 'all', expressions=tuple(expressions), negated=negated))

        return queries