예제 #1
0
        protected override IJadeCompileResult CompileFromAst(JRootNode ast)
        {
            var result = new HtmlCompileResult();
            //Compile the KJade AST to a HTML AST
            var htmlAst = GetHtmlNode(ast);

            //Emit on first level nodes because the root is not a real node
            foreach (var firstLevelNode in htmlAst.Children)
            {
                EmitHtml(firstLevelNode, result.Value);
            }
            return(result);
        }
예제 #2
0
 protected abstract IJadeCompileResult CompileFromAst(JRootNode ast);
예제 #3
0
        public JRootNode ParseTokens(List <JadeToken> tokens)
        {
            var originalCode = string.Concat(tokens.Select(t => t.TextRepresentation + new string(' ', t.IndentationLevel) + '\n'));
            var rootNode     = new JRootNode();
            //Parse the input tokens and build an AST.
            var nestingLevel = new Stack <int>();

            nestingLevel.Push(-1); //-1, signifying an unreachable nesting level. All nodes are children of this root.
            var lastNodeOnLevel = new Stack <JNode>();

            lastNodeOnLevel.Push(rootNode);
            foreach (var jToken in tokens)
            {
                var newNode = CreateNodeFromJadeToken(jToken);

                if (newNode.Attributes.Count == 0 && newNode.Element == null && newNode.Classes.Count == 0 && newNode.Id == null && newNode.Value == null)
                {
                    //Unfortunately, this node is useless!
                    continue;
                }

                var currentNestingLevel = nestingLevel.Peek();
                if (jToken.IndentationLevel > currentNestingLevel + 1)
                {
                    //The indentation level jumped illegally
                    var errorPosition = CalculateCodePosition(tokens, jToken);
                    throw new KJadeParserException("Unexpected indentation: the indentation may not change by more than one value at a time!", errorPosition);
                }

                if (jToken.IndentationLevel > currentNestingLevel)
                {
                    //We're nesting deeper
                    lastNodeOnLevel.Peek().Children.Add(newNode);
                    nestingLevel.Push(currentNestingLevel + 1);
                    lastNodeOnLevel.Push(newNode);
                }
                else if (jToken.IndentationLevel == currentNestingLevel)
                {
                    //We're on the same level
                    lastNodeOnLevel.Pop(); //Pop the previous node added, because it's on the same level
                    lastNodeOnLevel.Peek().Children.Add(newNode);
                    lastNodeOnLevel.Push(newNode);
                }
                else if (jToken.IndentationLevel < currentNestingLevel)
                {
                    //We're going back toward the root
                    while (nestingLevel.Peek() > jToken.IndentationLevel)
                    {
                        //Pop off parent layers
                        nestingLevel.Pop();
                        lastNodeOnLevel.Pop();
                    }
                    //We've popped our way down
                    //Indent level has been decreased
                    //Pop the same-level last node on the level
                    lastNodeOnLevel.Pop();
                    lastNodeOnLevel.Peek().Children.Add(newNode);
                    lastNodeOnLevel.Push(newNode);
                }
            }
            nestingLevel.Pop(); //We've reached the end!

            //Prune the tree

            return(rootNode);
        }