示例#1
0
        public override async Task <Completion> WriteToAsync(TextWriter writer, TextEncoder encoder, TemplateContext context)
        {
            TextStatement statement = new TextStatement("Hej!");

            await statement.WriteToAsync(writer, encoder, context);

            return(Completion.Normal);
        }
示例#2
0
        private Statement ParseStatement()
        {
            switch (Current.TokenType)
            {
            case TokenType.EOF:
                return(null);

            case TokenType.Print:
                return(ParsePrintStatement());

            case TokenType.Set:
                return(ParseSetStatement());

            case TokenType.If:
                return(ParseIfStatement());

            case TokenType.Foreach:
                return(ParseForeachStatement());

            case TokenType.For:
                return(ParseForStatement());

            case TokenType.Template:
                return(ParseTemplateStatement());

            case TokenType.OpenTag:
                return(ParseCallTemplateStatement());

            case TokenType.Text:
                TextStatement text = new TextStatement(Current.Data, Current.Line, Current.Column);
                Consume();
                return(text);

            default:
                throw new ParserException("Invalid token: " + Current.TokenType.ToString(), Current.Line, Current.Column);
            }
        }
示例#3
0
        public bool TryParse(string template, out IList <Statement> result, out IEnumerable <string> errors)
        {
            errors = Array.Empty <string>();
            var    segment = new StringSegment(template);
            Parser parser  = null;

            _context = new ParserContext();
            result   = _context.CurrentBlock.Statements;

            try
            {
                bool trimBefore = false;
                bool trimAfter  = false;

                int       previous = 0, index = 0;
                Statement s;

                while (true)
                {
                    previous = index;

                    if (!MatchTag(segment, index, out var start, out var end))
                    {
                        index = segment.Length;

                        if (index != previous)
                        {
                            // Consume last Text statement
                            ConsumeTextStatement(segment, previous, index, trimAfter, false);
                        }

                        break;
                    }
                    else
                    {
                        trimBefore = segment.Buffer[start + 2] == '-';

                        // Only create a parser if there are tags in the template
                        if (parser == null)
                        {
                            parser = new Parser(_languageData);
                        }

                        if (start != previous)
                        {
                            // Consume current Text statement
                            ConsumeTextStatement(segment, previous, start, trimAfter, trimBefore);
                        }

                        trimAfter = segment.Buffer[end - 2] == '-';

                        var tag = segment.Substring(start, end - start + 1);

                        if (trimAfter || trimBefore)
                        {
                            // Remove the dashes for the parser

                            StringBuilder sb = new StringBuilder(tag);

                            if (trimBefore)
                            {
                                sb[2] = ' ';
                            }

                            if (trimAfter)
                            {
                                sb[end - start - 2] = ' ';
                            }

                            tag = sb.ToString();
                        }

                        var tree = parser.Parse(tag);

                        if (tree.HasErrors())
                        {
                            int line = 1, col = 1;
                            foreach (var ch in segment.Buffer.Take(start))
                            {
                                switch (ch)
                                {
                                case '\n':
                                    line++;
                                    col = 1;
                                    break;

                                case '\r':
                                    // Ignore
                                    break;

                                default:
                                    col++;
                                    break;
                                }
                            }
                            errors = tree
                                     .ParserMessages
                                     .Select(x => $"{x.Message} at line:{line + x.Location.Line}, col:{col + x.Location.Column}")
                                     .ToArray();

                            return(false);
                        }

                        switch (tree.Root.Term.Name)
                        {
                        case "output":
                            s = BuildOutputStatement(tree.Root);
                            break;

                        case "tag":
                            s = BuildTagStatement(tree.Root);
                            break;

                        default:
                            s = null;
                            break;
                        }

                        index = end + 1;

                        // Entered a comment block?
                        if (_isComment)
                        {
                            s     = new CommentStatement(ConsumeTag(segment, end + 1, "endcomment", out end));
                            index = end;
                        }

                        // Entered a raw block?
                        if (_isRaw)
                        {
                            s     = new TextStatement(ConsumeTag(segment, end + 1, "endraw", out end));
                            index = end;
                        }

                        if (s != null)
                        {
                            _context.CurrentBlock.AddStatement(s);
                        }
                    }
                }