Exemple #1
0
        //
        // Combinators combine elements together, in a Selector.
        //
        // Because our parser isn't white-space sensitive, special care
        // has to be taken, when parsing the descendant combinator, ` `,
        // as it's an empty space. We have to check the previous character
        // in the input, to see if it's a ` ` character. More info on how
        // we deal with this in *combinator.js*.
        //
        public Combinator Combinator(Parser parser)
        {
            var index = parser.Tokenizer.Location.Index;

            Node match;

            if (match = parser.Tokenizer.Match(@"[+>~]") || parser.Tokenizer.Match(@"&\s?") || parser.Tokenizer.Match(@"::"))
            {
                return(NodeProvider.Combinator(match.ToString(), index));
            }

            return(NodeProvider.Combinator(char.IsWhiteSpace(parser.Tokenizer.GetPreviousCharIgnoringComments()) ? " " : null, index));
        }
Exemple #2
0
        //
        // Mixins
        //

        //
        // A Mixin call, with an optional argument list
        //
        //     #mixins > .square(#fff);
        //     .rounded(4px, black);
        //     .button;
        //
        // The `while` loop is there because mixins can be
        // namespaced, but we only support the child and descendant
        // selector for now.
        //
        public MixinCall MixinCall(Parser parser)
        {
            var elements = new NodeList <Element>();
            var index    = parser.Tokenizer.Location.Index;

            RegexMatchResult e;
            Combinator       c = null;

            PushComments();

            for (var i = parser.Tokenizer.Location.Index; e = parser.Tokenizer.Match(@"[#.][a-zA-Z0-9_-]+"); i = parser.Tokenizer.Location.Index)
            {
                elements.Add(NodeProvider.Element(c, e.Value, i));

                i = parser.Tokenizer.Location.Index;
                var match = parser.Tokenizer.Match('>');
                c = match != null?NodeProvider.Combinator(match.Value, i) : null;
            }

            var args = new List <NamedArgument>();

            if (parser.Tokenizer.Match('('))
            {
                Expression arg;
                while (arg = Expression(parser))
                {
                    var    value = arg;
                    string name  = null;

                    if (arg.Value.Count == 1 && arg.Value[0] is Variable)
                    {
                        if (parser.Tokenizer.Match(':'))
                        {
                            if (value = Expression(parser))
                            {
                                name = (arg.Value[0] as Variable).Name;
                            }
                            else
                            {
                                throw new ParsingException("Expected value", parser.Tokenizer.Location.Index);
                            }
                        }
                    }

                    args.Add(new NamedArgument {
                        Name = name, Value = value
                    });

                    if (!parser.Tokenizer.Match(','))
                    {
                        break;
                    }
                }
                if (!parser.Tokenizer.Match(')'))
                {
                    throw new ParsingException("Expected ')'", parser.Tokenizer.Location.Index);
                }
            }

            if (elements.Count > 0)
            {
                // if elements then we've picked up chars so don't need to worry about remembering
                var postComments = GatherAndPullComments(parser);

                if (End(parser))
                {
                    var mixinCall = NodeProvider.MixinCall(elements, args, index);
                    mixinCall.PostComments = postComments;
                    PopComments();
                    return(mixinCall);
                }
            }

            PopComments();
            return(null);
        }