Пример #1
0
        internal static IEnumerable<Token> GetTokens(string template, string open = "{{", string close = "}}")
        {
            var index = 0;

            while (index < template.Length)
            {
                var offset = index;
                var brace = ScanBrace(template, open, ref index);

                Token? text = null;

                if (offset != brace)
                {
                    text = new Token
                    {
                        Offset = offset,
                        Length = brace - offset,
                        Type = TagType.Text
                    };
                }

                var token = new Token();

                index = SkipWhitespace(template, index);

                if (index == template.Length)
                {
                    if (text != null)
                        yield return (Token)text;
                    yield break;
                }

                if (template[index] != '!')
                {
                    switch (template[index])
                    {
                        case '&':
                            token.Type = TagType.Escaped;
                            index = SkipWhitespace(template, index + 1);
                            break;
                        case '#':
                            token.Type = TagType.Loop;
                            index = SkipWhitespace(template, index + 1);
                            break;
                        case '/':
                            token.Type = TagType.End;
                            index = SkipWhitespace(template, index + 1);
                            break;
                        case '^':
                            token.Type = TagType.Inverted;
                            index = SkipWhitespace(template, index + 1);
                            break;
                        case '>':
                            token.Type = TagType.Partial;
                            index = SkipWhitespace(template, index + 1);
                            break;
                        default:
                            token.Type = TagType.Attribute;
                            break;
                    }

                    var start = index;
                    var end = ScanWord(template, start);

                    token.Offset = start;
                    token.Length = end - start;

                    ScanBrace(template, close, ref index);

                    if (token.Type == TagType.Loop || token.Type == TagType.Inverted || token.Type == TagType.End || token.Type == TagType.Partial)
                    {
                        Standalone(template, ref text, ref index);
                    }

                    if (text != null)
                        yield return (Token)text;
                    yield return token;
                }
                else
                {
                    ScanBrace(template, close, ref index);
                    Standalone(template, ref text, ref index);

                    if (text != null)
                        yield return (Token)text;
                }
            }
        }
Пример #2
0
        private static void Standalone(string template, ref Token? text, ref int index)
        {
            int end = index;

            while (end < template.Length)
            {
                if (template[end] == '\r')
                {
                    end++;
                    if (end < template.Length && template[end] == '\n')
                    {
                        end++;
                    }
                    break;
                }
                if (template[end] == '\n')
                {
                    end++;
                    break;
                }
                if (!char.IsWhiteSpace(template[end]))
                    return;
                end++;
            }

            if (text != null)
            {
                var tok = (Token)text;

                int start = tok.Offset + tok.Length - 1;

                while (start >= 0)
                {
                    if (template[start] == '\r' || template[start] == '\n')
                        break;
                    if (!char.IsWhiteSpace(template[start]))
                        return;
                    start--;
                }

                tok.Length = start < tok.Offset ? 0 : start - tok.Offset + 1;
                text = tok.Length > 0 ? (Token?)tok : null;
            }

            index = end;
        }