예제 #1
0
        public Value Font(Parser parser)
        {
            var  value      = new NodeList();
            var  expression = new NodeList();
            Node e;

            var index = parser.Tokenizer.Location.Index;

            while (e = Shorthand(parser) || Entity(parser))
            {
                expression.Add(e);
            }
            value.Add(NodeProvider.Expression(expression, index));

            if (parser.Tokenizer.Match(','))
            {
                while (e = Expression(parser))
                {
                    value.Add(e);
                    if (!parser.Tokenizer.Match(','))
                    {
                        break;
                    }
                }
            }
            return(NodeProvider.Value(value, Important(parser), index));
        }
예제 #2
0
        //
        // Expressions either represent mathematical operations,
        // or white-space delimited Entities.
        //
        //     1px solid black
        //     @var * 2
        //
        public Expression Expression(Parser parser)
        {
            Node e;
            var  entities = new NodeList();

            var index = parser.Tokenizer.Location.Index;

            while (e = Addition(parser) || Entity(parser))
            {
                e.PostComments = PullComments();
                entities.Add(e);
            }

            if (entities.Count > 0)
            {
                return(NodeProvider.Expression(entities, index));
            }

            return(null);
        }
예제 #3
0
        public Expression MediaFeature(Parser parser)
        {
            NodeList features   = new NodeList();
            var      outerIndex = parser.Tokenizer.Location.Index;

            while (true)
            {
                GatherComments(parser);

                var keyword = Keyword(parser);
                if (keyword)
                {
                    keyword.PreComments  = PullComments();
                    keyword.PostComments = GatherAndPullComments(parser);
                    features.Add(keyword);
                }
                else if (parser.Tokenizer.Match('('))
                {
                    GatherComments(parser);

                    var memo     = Remember(parser);
                    var index    = parser.Tokenizer.Location.Index;
                    var property = Property(parser);

                    var preComments = GatherAndPullComments(parser);

                    // in order to support (color) and have rule/*comment*/: we need to keep :
                    // out of property
                    if (!string.IsNullOrEmpty(property) && !parser.Tokenizer.Match(':'))
                    {
                        Recall(parser, memo);
                        property = null;
                    }

                    GatherComments(parser);

                    memo = Remember(parser);

                    var entity = Entity(parser);

                    if (!entity || !parser.Tokenizer.Match(')'))
                    {
                        Recall(parser, memo);

                        // match "3/2" for instance
                        var unrecognised = parser.Tokenizer.Match(@"[^\){]+");
                        if (unrecognised)
                        {
                            entity = NodeProvider.TextNode(unrecognised.Value, parser.Tokenizer.Location.Index);
                        }

                        if (!unrecognised || !parser.Tokenizer.Match(')'))
                        {
                            throw new ParsingException("missing closing bracket for media feature", index);
                        }
                    }

                    if (!entity)
                    {
                        return(null);
                    }

                    entity.PreComments  = PullComments();
                    entity.PostComments = GatherAndPullComments(parser);

                    if (!string.IsNullOrEmpty(property))
                    {
                        var rule = NodeProvider.Rule(property, entity, index);
                        rule.IsSemiColonRequired = false;
                        features.Add(NodeProvider.Paren(rule, index));
                    }
                    else
                    {
                        features.Add(NodeProvider.Paren(entity, index));
                    }
                }
                else
                {
                    break;
                }
            }

            if (features.Count == 0)
            {
                return(null);
            }

            return(NodeProvider.Expression(features, outerIndex));
        }