Beispiel #1
0
 /// <summary>
 /// selectors :  ws selector (s ',' ws selector)* ws ;
 /// </summary>
 /// <param name="node"></param>
 /// <param name="action"></param>
 /// <returns></returns>
 private IEnumerable<ElementBlock> Selectors(PegNode node, Func<IEnumerable<ElementBlock>, IEnumerable<ElementBlock>> action)
 {
     foreach(var selector in node.AsEnumerable(x => x.id_.ToEnLess() == EnLess.selector))
     {
         var selectors = Selector(selector);
         foreach(var s in action(selectors)) yield return s;
     }
 }
Beispiel #2
0
 /// <summary>
 /// primary: (import / declaration / ruleset / comment)* ;
 /// </summary>
 /// <param name="node"></param>
 /// <param name="elementBlock"></param>
 private ElementBlock Primary(PegNode node, ElementBlock elementBlock)
 {
     foreach (var nextPrimary in node.AsEnumerable())
     {
         switch (nextPrimary.id_.ToEnLess())
         {
             case EnLess.import:
                 Import(nextPrimary.child_, elementBlock);
                 //element.Children.AddRange(import);
                 break;
             case EnLess.insert:
                 Insert(nextPrimary.child_, elementBlock);
                 //element.Children.AddRange(import);
                 break;
             case EnLess.standard_ruleset:
                 RuleSet(nextPrimary, elementBlock);
                 break;
             case EnLess.mixin_ruleset:
                 Mixin(nextPrimary,elementBlock);
                 break;
             case EnLess.declaration:
                 Declaration(nextPrimary.child_, elementBlock);
                 break;
         }
     }
     return elementBlock;
 }
Beispiel #3
0
        /// <summary>
        /// selector : (s select element s)+ arguments? ;
        /// </summary>
        /// <param name="node"></param>
        /// <returns></returns>
        private IEnumerable<ElementBlock> Selector(PegNode node)
        {
            var enumerator = node.AsEnumerable().GetEnumerator();
            while(enumerator.MoveNext())
            {
                ElementBlock block;

                var selector = enumerator.Current.GetAsString(Src).Trim();
                enumerator.MoveNext();
                var name = enumerator.Current.GetAsString(Src);

                var next = enumerator.Current.next_;
                var isMixinWithArgs = next != null && next.ToEnLess() == EnLess.arguments;

                if (isMixinWithArgs)
                    block = new PureMixinBlock(name, selector);
                else
                    block = new ElementBlock(name, selector);

                if (isMixinWithArgs)
                {
                    var arguments = GetMixinArguments(next, block);
                    enumerator.MoveNext();

                    foreach (var argument in arguments)
                        block.Add(argument);
                }

                yield return block;
            }
        }
Beispiel #4
0
        private IEnumerable<Variable> GetMixinArguments(PegNode arguments, ElementBlock block)
        {
            var enumerator = arguments.AsEnumerable().GetEnumerator();
            var variables = new List<Variable>();
            var position = 0;

            while (enumerator.MoveNext())
            {
                var node = enumerator.Current;

                string name;
                IEnumerable<INode> value;
                if (node.child_.ToEnLess() == EnLess.variable) // expect "@variable: expression"
                {
                    name = node.child_.GetAsString(Src);
                    value = Expressions(node.child_.next_, block);
                }
                else  // expect "expresion"
                {
                    // HACK: to make Arguments return as expected.
                    var tmpNode = new PegNode(null, (int) EnLess.arguments);
                    tmpNode.child_ = new PegNode(tmpNode, (int)EnLess.argument);
                    tmpNode.child_.child_ = node.child_;

                    name = position.ToString();
                    value = Arguments(tmpNode, block).ToList();
                }

                variables.Add(new Variable(name, value));

                if(node.next_ == null || node.next_.ToEnLess() != EnLess.argument)
                    break;

                position++;
            }

            return variables;
        }
Beispiel #5
0
        /// <summary>
        /// TODO: Added quick fix for multipule mixins, but need to add mixins with variables which will changes things a bit
        /// </summary>
        /// <param name="node"></param>
        /// <param name="elementBlock"></param>
        //        private void OldMixin(PegNode node, Element element)
        //        {
        //            var root = element.GetRoot();
        //            foreach (var el in Selectors(node.child_, els => els))
        //                root = root.Descend(el.Selector, el);
        //            if (root.Children != null) element.Children.AddRange(root.Children);
        //        }
        private void Mixin(PegNode node, ElementBlock elementBlock)
        {
            var root = elementBlock.GetRoot();
            var rules = new List<INode>();
            foreach (var mixins in node.AsEnumerable())
            {
                var selectors = Selectors(mixins, els => els).ToList();
                if (selectors.Count() > 1)
                {
                    foreach (var el in selectors)
                        root = root.Descend(el.Selector, el);
                    if (root.Children != null)
                        rules.AddRange(root.Children);
                }
                else
                {
                    var el = selectors.First();
                    foreach (var mixinElement in root.Nearests(el.Name))
                    {
                        if (mixinElement.Children == null)
                            continue;

                        var children = GetMixinChildren(elementBlock, el.Variables, mixinElement.Children);

                        rules.AddRange(children);

                        el.Parent = elementBlock;
                    }
                }

            }

            elementBlock.Children.AddRange(rules);
        }
Beispiel #6
0
 /// <summary>
 /// fonts : font (s ',' s font)+  ;
 /// </summary>
 /// <param name="node"></param>
 /// <returns></returns>
 private INode Fonts(PegNode node)
 {
     var fonts = from childNode in node.AsEnumerable()
                 select (childNode.child_ ?? childNode).GetAsString(Src);
     return new FontFamily(fonts.ToArray());
 }
Beispiel #7
0
 /// <summary>
 /// cursor (s ',' s cursor)+  ;
 /// </summary>
 /// <param name="node"></param>
 /// <returns></returns>
 private INode Cursors(PegNode node)
 {
     var set = from childNode in node.AsEnumerable()
                 select (childNode.child_ ?? childNode).GetAsString(Src);
     return new CursorSet(set.ToArray());
 }
Beispiel #8
0
 /// <summary>
 /// arguments : '(' s argument s (',' s argument s)* ')';
 /// argument : color / number unit / string / [a-zA-Z]+ '=' dimension / function / expressions / [-a-zA-Z0-9_%$/.&=:;#+?]+ / keyword (S keyword)*;
 /// </summary>
 /// <param name="node"></param>
 /// <param name="element"></param>
 /// <returns></returns>
 private IEnumerable<INode> Arguments(PegNode node, ElementBlock element)
 {
     foreach (var argument in node.AsEnumerable())
     {
         if (argument.child_ == null)
             yield return new Anonymous(argument.GetAsString(Src));
         else
         {
             switch (argument.child_.id_.ToEnLess())
             {
                 case EnLess.color:
                     yield return Color(argument.child_);
                     break;
                 case EnLess.number:
                     yield return Number(argument.child_);
                     break;
                 case EnLess.function:
                     yield return Function(argument.child_, element);
                     break;
                 case EnLess.expressions:
                     yield return Expression(argument.child_, element);
                     break;
                 case EnLess.@string:
                     yield return new String(argument.GetAsString(Src));
                     break;
                 case EnLess.keyword:
                     yield return new Keyword(argument.GetAsString(Src));
                     break;
                 default:
                     yield return new Anonymous(argument.GetAsString(Src));
                     break;
             }
         }
     }
 }
Beispiel #9
0
 /// <summary>
 /// selector : (s select element s)+ arguments? ;
 /// </summary>
 /// <param name="node"></param>
 /// <returns></returns>
 private IEnumerable<Element> Selector(PegNode node)
 {
     var enumerator = node.AsEnumerable().GetEnumerator();
     while(enumerator.MoveNext())
     {
         var selector = enumerator.Current.GetAsString(Src).Trim();
         enumerator.MoveNext();
         var name = enumerator.Current.GetAsString(Src);
         yield return new Element(name, selector);
     }
 }
Beispiel #10
0
 /// <summary>
 /// arguments : '(' s argument s (',' s argument s)* ')';
 /// </summary>
 /// <param name="node"></param>
 /// <returns></returns>
 private IEnumerable<INode> Arguments(PegNode node)
 {
     foreach (var argument in node.AsEnumerable().Skip(1))
     {
         if (argument.child_ == null)
             yield return new Anonymous(argument.GetAsString(Src));
         else
         {
             switch (argument.child_.id_.ToEnLess())
             {
                 case EnLess.color:
                     yield return Color(argument);
                     break;
                 case EnLess.number:
                     yield return Number(argument);
                     break;
                 case EnLess.@string:
                     yield return new String(argument.GetAsString(Src));
                     break;
                 case EnLess.keyword:
                     yield return new Keyword(argument.GetAsString(Src));
                     break;
                 default:
                     yield return new Anonymous(argument.GetAsString(Src));
                     break;
             }
         }
     }
 }