예제 #1
0
 /// <summary>
 /// keyword: [-a-zA-Z]+ !ns;
 /// </summary>
 /// <param name="node"></param>
 /// <returns></returns>
 private INode Keyword(LessPegNode node)
 {
     return new Keyword(node.GetAsString(Src));
 }
예제 #2
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(LessPegNode 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(LessPegNode node, ElementBlock elementBlock)
        {
            var root = elementBlock.GetRoot();
            var rules = new List<INode>();
            foreach (var mixins in node.Children())
            {
                var selectors = Selectors(mixins, els => els).ToList();
                if (selectors.Count() > 1)
                {
                    foreach (var el in selectors)
                        root = root.Descend(el.Selector, el);

                    var last = selectors.Last();

                    var children = GetMixinChildren(elementBlock, last, root);

                    if(children != null)
                        rules.AddRange(children);
                }
                else
                {
                    var el = selectors.First();
                    foreach (var mixinElement in root.Nearests(el.Name))
                    {
                        var children = GetMixinChildren(elementBlock, el, mixinElement);

                        if(children != null)
                            rules.AddRange(children);
                    }
                }

            }

            elementBlock.Children.AddRange(rules);
        }
예제 #3
0
        /// <summary>
        /// space_delimited_expressions: expression (WS expression)* important? ;
        /// </summary>
        /// <param name="node"></param>
        /// <param name="elementBlock"></param>
        /// <returns></returns>
        private IEnumerable<INode> SpaceDelimitedExpressions(LessPegNode node, ElementBlock elementBlock)
        {
            yield return Expression(node.Child, elementBlock);
            node = node.Next;

            //Tail
            while (node != null)
            {
                switch (node.Type())
                {
                    case EnLess.expression:
                        yield return Expression(node.Child, elementBlock);
                        break;
                    case EnLess.important:
                        yield return new Keyword("!important");
                        break;
                }
                node = node.Next;
            }
        }
예제 #4
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(LessPegNode node, ElementBlock element)
 {
     foreach (var argument in node.Children())
     {
         if (argument.Child == null)
             yield return new Anonymous(argument.GetAsString(Src));
         else
         {
             switch (argument.Child.Type())
             {
                 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;
             }
         }
     }
 }
예제 #5
0
        /// <summary>
        /// rgb:(rgb_node)(rgb_node)(rgb_node) / hex hex hex ;
        /// </summary>
        /// <param name="node"></param>
        /// <returns></returns>
        private INode RGB(LessPegNode node)
        {
            int r = 0, g = 0, b = 0;
            string tmp;

            var rgbNode = node.Child; //Fisrt node;
            if (rgbNode != null)
            {
                tmp = rgbNode.GetAsString(Src);
                r = int.Parse(tmp.Length==1 ? tmp+tmp : tmp, NumberStyles.HexNumber);
                rgbNode = rgbNode.Next;
                if (rgbNode != null)
                {
                    tmp = rgbNode.GetAsString(Src);
                    g = int.Parse(tmp.Length == 1 ? tmp + tmp : tmp, NumberStyles.HexNumber);
                    rgbNode = rgbNode.Next;
                    if (rgbNode != null)
                    {
                        tmp = rgbNode.GetAsString(Src);
                        b = int.Parse(tmp.Length == 1 ? tmp + tmp : tmp, NumberStyles.HexNumber);
                    }
                }
            }
            return new Color(r, g, b);
        }
예제 #6
0
        /// <summary>
        /// selector : (s select element s)+ arguments? ;
        /// </summary>
        /// <param name="node"></param>
        /// <returns></returns>
        private IEnumerable<ElementBlock> Selector(LessPegNode node)
        {
            var enumerator = node.Children().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.Type() == EnLess.arguments;

                if (isMixinWithArgs)
                {
                    var mixinBlock = new MixinBlock(name, selector);
                    block = mixinBlock;

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

                    foreach (var argument in arguments)
                        mixinBlock.Arguments.Add(argument);
                }
                else
                    block = new ElementBlock(name, selector);

                yield return block;
            }
        }
예제 #7
0
 /// <summary>
 /// expressions: operation_expressions / space_delimited_expressions / [-a-zA-Z0-9_%*/.&=:,#+? \[\]()]+ ;
 /// </summary>
 /// <param name="node"></param>
 /// <param name="elementBlock"></param>
 /// <returns></returns>
 private IEnumerable<INode> Expressions(LessPegNode node, ElementBlock elementBlock)
 {
     // Expression
     switch (node.Type())
     {
         case EnLess.operation_expressions:
             return OperationExpressions(node.Child, elementBlock).ToList();
         case EnLess.space_delimited_expressions:
             return SpaceDelimitedExpressions(node.Child, elementBlock).ToList();
         default:
             if (node.Child == null) //CatchAll
                 return new List<INode>
                            {
                                new Anonymous(node.GetAsString(Src))
                            };
             return Expressions(node.Child, elementBlock);
     }
 }
예제 #8
0
 private ElementBlock Primary(LessPegNode node)
 {
     var element = new ElementBlock("");
     return Primary(node, element);
 }
예제 #9
0
 /// <summary>
 /// entity :  function / fonts / accessor / keyword  / variable / literal  ;
 /// </summary>
 /// <param name="node"></param>
 /// <param name="elementBlock"></param>
 /// <returns></returns>
 private INode Entity(LessPegNode node, ElementBlock elementBlock)
 {
     switch (node.Type())
     {
         case EnLess.literal:
             return Entity(node.Child, elementBlock);
         case EnLess.number:
             return Number(node);
         case EnLess.color:
             return Color(node);
         case EnLess.variable:
             return Variable(node);
         case EnLess.accessor:
             return Accessor(node.Child, elementBlock);
         case EnLess.fonts:
             return Fonts(node);
         case EnLess.keyword:
             return Keyword(node);
         case EnLess.function:
             return Function(node, elementBlock);
         case EnLess.cursors:
             return Cursors(node);
         case EnLess.@string:
             return new String(node.GetAsString(Src));
         default:
             return new Anonymous(node.GetAsString(Src));
     }
 }
예제 #10
0
 /// <summary>
 /// expression: '(' s expressions s ')' / entity ;
 /// </summary>
 /// <param name="node"></param>
 /// <param name="elementBlock"></param>
 /// <returns></returns>
 private INode Expression(LessPegNode node, ElementBlock elementBlock)
 {
     switch (node.Type())
     {
         case EnLess.expressions:
             return new Expression(Expressions(node, elementBlock), elementBlock);
         case EnLess.entity:
             var entity  = Entity(node.Child, elementBlock);
             entity.Parent = elementBlock;
             return entity;
         default:
             throw new ParsingException("Expression should either be child expressions or an entity");
     }
 }
예제 #11
0
        /// <summary>
        /// declaration:  standard_declaration / catchall_declaration ;
        /// </summary>
        /// <param name="node"></param>
        /// <param name="elementBlock"></param>
        private void Declaration(LessPegNode node, ElementBlock elementBlock)
        {
            var name = node.GetAsString(Src).Replace(" ", "");
            var nextNode = node.Next;

            if(nextNode == null){
                // TODO: emit warning: empty declaration //
                return;
            }
            if (nextNode.Type() == EnLess.comment)
                nextNode = nextNode.Next;

            var values = Expressions(nextNode, elementBlock);
            var property = name.StartsWith("@") ? new Variable(name, values) : new Property(name, values);
            elementBlock.Add(property);
        }
예제 #12
0
 /// <summary>
 /// cursor (s ',' s cursor)+  ;
 /// </summary>
 /// <param name="node"></param>
 /// <returns></returns>
 private INode Cursors(LessPegNode node)
 {
     var set = from childNode in node.Children()
                 select (childNode.Child ?? childNode).GetAsString(Src);
     return new CursorSet(set.ToArray());
 }
예제 #13
0
 /// <summary>
 /// color: '#' rgb;
 /// </summary>
 /// <param name="node"></param>
 /// <returns></returns>
 private INode Color(LessPegNode node)
 {
     return RGB(node.Child);
 }
예제 #14
0
 /// <summary>
 /// number: '-'? [0-9]* '.' [0-9]+ / '-'? [0-9]+;
 /// </summary>
 /// <param name="node"></param>
 /// <returns></returns>
 private INode Number(LessPegNode node)
 {
     var val = float.Parse(node.GetAsString(Src), NumberFormatInfo.InvariantInfo);
     var unit = "";
     node = node.Next;
     if (node != null && node.Type() == EnLess.unit) unit = node.GetAsString(Src);
     return new Number(unit, val);
 }
예제 #15
0
 /// <summary>
 /// fonts : font (s ',' s font)+  ;
 /// </summary>
 /// <param name="node"></param>
 /// <returns></returns>
 private INode Fonts(LessPegNode node)
 {
     var fonts = from childNode in node.Children()
                 select (childNode.Child ?? childNode).GetAsString(Src);
     return new FontFamily(fonts.ToArray());
 }
예제 #16
0
        /// <summary>
        /// operation_expressions:  expression (operator expression)+;
        /// </summary>
        /// <param name="node"></param>
        /// <param name="elementBlock"></param>
        /// <returns></returns>
        private IEnumerable<INode> OperationExpressions(LessPegNode node, ElementBlock elementBlock)
        {
            yield return Expression(node.Child, elementBlock);
            node = node.Next;

            //Tail
            while (node != null)
            {
                switch (node.Type())
                {
                    case EnLess.@operator:
                        yield return new Operator(node.GetAsString(Src), elementBlock);
                        break;
                    case EnLess.expression:
                        yield return Expression(node.Child, elementBlock);
                        break;
                    case EnLess.comment:
                        node.ToString();
                        break;
                }
                node = node.Next;
            }
        }
예제 #17
0
 /// <summary>
 /// function: function_name arguments ;
 /// </summary>
 /// <param name="node"></param>
 /// <param name="element"></param>
 /// <returns></returns>
 private INode Function(LessPegNode node, ElementBlock element)
 {
     var funcName = node.Child.GetAsString(Src);
     var arguments = Arguments(node.Child.Next, element);
     return new Function(funcName, arguments.ToList());
 }
예제 #18
0
 /// <summary>
 /// primary: (import / declaration / ruleset / comment)* ;
 /// </summary>
 /// <param name="node"></param>
 /// <param name="elementBlock"></param>
 private ElementBlock Primary(LessPegNode node, ElementBlock elementBlock)
 {
     foreach (var nextPrimary in node.Children())
     {
         switch (nextPrimary.Type())
         {
             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;
 }
예제 #19
0
        private IEnumerable<Variable> GetMixinArguments(LessPegNode arguments, ElementBlock block)
        {
            var enumerator = arguments.Children().GetEnumerator();
            var variables = new List<Variable>();
            var position = 0;

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

                string name;
                IEnumerable<INode> value;
                if (node.Child.Type() == 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 LessPegNode(null, (int) EnLess.arguments, Root);
                    tmpNode.Child = new LessPegNode(tmpNode, (int)EnLess.argument, Root);
                    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.Type() != EnLess.argument)
                    break;

                position++;
            }

            return variables;
        }
예제 #20
0
 /// <summary>
 /// ruleset: selectors [{] ws prsimary ws [}] ws /  ws selectors ';' ws;
 /// </summary>
 /// <param name="node"></param>
 /// <param name="elementBlock"></param>
 private void RuleSet(LessPegNode node, ElementBlock elementBlock)
 {
     foreach (var el in Selectors(node.Child, els => StandardSelectors(elementBlock, els)))
         Primary(node.Child.Next, el);
 }
예제 #21
0
        /// <summary>
        /// import :  ws '@import'  S import_url medias? s ';' ;
        /// </summary>
        /// <param name="node"></param>
        private IEnumerable<INode> Import(LessPegNode node, ElementBlock elementBlock)
        {
            node = (node.Child ?? node);
            //
            //            var path = "";
            //            if(node.ToEnLess()==EnLess.expressions)
            //            {
            //                var values = Expressions(node, element);
            //                var fakeVariableName = new Variable(string.Format("@{0}", DateTime.Now.Ticks), values);
            //                element.Add(fakeVariableName);
            //                path = fakeVariableName.ToCss();
            //            }
            //            else
            //            {
            //                path = (node).GetAsString(Src)
            //                    .Replace("\"", "").Replace("'", "");
            //            }

            var path = (node).GetAsString(Src)
                .Replace("\"", "").Replace("'", "");

            if(HttpContext.Current!=null){
                path = HttpContext.Current.Server.MapPath(path);
            }

            if(File.Exists(path))
            {
                var engine = new ExtensibleEngineImpl(File.ReadAllText(path), elementBlock);
                return engine.LessDom.Children;
            }
            return new List<INode>();
        }
예제 #22
0
 /// <summary>
 /// selectors :  ws selector (s ',' ws selector)* ws ;
 /// </summary>
 /// <param name="node"></param>
 /// <param name="action"></param>
 /// <returns></returns>
 private IEnumerable<ElementBlock> Selectors(LessPegNode node, Func<IEnumerable<ElementBlock>, IEnumerable<ElementBlock>> action)
 {
     foreach(var selector in node.Children(x => x.Type() == EnLess.selector))
     {
         var selectors = Selector(selector);
         foreach(var s in action(selectors)) yield return s;
     }
 }
예제 #23
0
        private IEnumerable<INode> Insert(LessPegNode node, ElementBlock elementBlock)
        {
            node = (node.Child ?? node);
            var path = (node).GetAsString(Src)
                .Replace("\"", "").Replace("'", "");

            if (HttpContext.Current != null){
                path = HttpContext.Current.Server.MapPath(path);
            }

            if (File.Exists(path)){
                var text = File.ReadAllText(path);
                elementBlock.Add(new Insert(text));
            }
            return new List<INode>();
        }
예제 #24
0
 /// <summary>
 /// variable: '@' [-_a-zA-Z0-9]+; 
 /// </summary>
 /// <param name="node"></param>
 /// <returns></returns>
 private INode Variable(LessPegNode node)
 {
     return new Variable(node.GetAsString(Src));
 }
예제 #25
0
 /// <summary>
 /// accessor: accessor_name '[' accessor_key ']'; 
 /// </summary>
 /// <param name="node"></param>
 /// <param name="elementBlock"></param>
 /// <returns></returns>
 private INode Accessor(LessPegNode node, ElementBlock elementBlock)
 {
     var ident = node.GetAsString(Src);
     var key = node.Next.GetAsString(Src).Replace("'", "");
     var el = elementBlock.NearestAs<ElementBlock>(ident);
     if (el != null)
     {
         var prop = el.GetAs<Property>(key);
         if (prop != null) return prop.Value;
     }
     return new Anonymous("");
 }