Exemplo n.º 1
0
        private void ParseDecoratorArgumentRunOff(PreTokenEnumerator enumerator, ref FlatTokenParserState state, ref StringBuilder tokenContent)
        {
            var next = enumerator.Next();

            tokenContent.Append(next);

            if (string.IsNullOrWhiteSpace(next))
            {
                return;
            }

            switch (next)
            {
            case ",":
                state = FlatTokenParserState.InDecoratorArgument;
                break;

            case ")":
                state = FlatTokenParserState.InDecorator;
                break;

            default:
                throw new TokenizerException($"Unexpected character: '{next}'");
            }
        }
Exemplo n.º 2
0
        private void ParseDecoratorArgument(PreTokenEnumerator enumerator, ref FlatTokenParserState state, ref PreTokenDecorator decorator, ref string argument, ref StringBuilder tokenContent)
        {
            var next = enumerator.Next();

            tokenContent.Append(next);

            if (string.IsNullOrWhiteSpace(argument) &&
                string.IsNullOrWhiteSpace(next))
            {
                return;
            }

            switch (next)
            {
            case ")":
                decorator.Args.Add(argument.Trim());
                argument = string.Empty;
                state    = FlatTokenParserState.InDecorator;
                break;

            case "'":
                if (string.IsNullOrWhiteSpace(argument))
                {
                    argument = string.Empty;
                    state    = FlatTokenParserState.InDecoratorArgumentSingleQuotes;
                }
                else
                {
                    argument += next;
                }
                break;

            case @"""":
                if (string.IsNullOrWhiteSpace(argument))
                {
                    argument = string.Empty;
                    state    = FlatTokenParserState.InDecoratorArgumentDoubleQuotes;
                }
                else
                {
                    argument += next;
                }
                break;

            case ",":
                decorator.Args.Add(argument.Trim());
                argument = string.Empty;
                state    = FlatTokenParserState.InDecoratorArgument;
                break;

            default:
                argument += next;
                break;
            }
        }
Exemplo n.º 3
0
        private void ParseFrontMatterComment(RawTokenEnumerator enumerator, ref FlatTokenParserState state)
        {
            var next = enumerator.Next();

            switch (next)
            {
            case "\n":
                state = FlatTokenParserState.InFrontMatter;
                break;
            }
        }
Exemplo n.º 4
0
        private void ParseStart(RawTokenEnumerator enumerator, ref FlatTokenParserState state)
        {
            var peek = enumerator.Peek(4);

            if (peek == "---\n")
            {
                state = FlatTokenParserState.InFrontMatter;
                enumerator.Next(4);
                return;
            }

            peek = enumerator.Peek(5);

            if (peek == "---\r\n")
            {
                state = FlatTokenParserState.InFrontMatter;
                enumerator.Next(4); // Next() will trim /r/n
                return;
            }

            state = FlatTokenParserState.InPreamble;
        }
Exemplo n.º 5
0
        private void ParseFrontMatterOptionValue(RawTemplate template, RawTokenEnumerator enumerator, ref StringBuilder frontMatterName, ref StringBuilder frontMatterValue, ref FlatTokenParserState state)
        {
            var next = enumerator.Next();

            switch (next)
            {
            case "\n":
                var rawName = frontMatterName.ToString().Trim();
                var name    = frontMatterName.ToString().Trim().ToLowerInvariant();
                var value   = frontMatterValue.ToString().Trim().ToLowerInvariant();

                if (bool.TryParse(value, out var asBool))
                {
                    switch (name)
                    {
                    case "throwexceptiononmissingproperty":
                        template.Options.ThrowExceptionOnMissingProperty = asBool;
                        break;

                    case "trimleadingwhitespace":
                        template.Options.TrimLeadingWhitespaceInTokenPreamble = asBool;
                        break;

                    case "trimtrailingwhitespace":
                        template.Options.TrimTrailingWhiteSpace = asBool;
                        break;

                    case "outoforder":
                        template.Options.OutOfOrderTokens = asBool;
                        break;

                    case "casesensitive":
                        if (asBool)
                        {
                            template.Options.TokenStringComparison = StringComparison.InvariantCulture;
                        }
                        else
                        {
                            template.Options.TokenStringComparison = StringComparison.InvariantCultureIgnoreCase;
                        }
                        break;

                    default:
                        throw new ParsingException($"Unknown front matter option: {rawName}", enumerator);
                    }
                }
                else
                {
                    throw new ParsingException($"Unable to convert front matter option to boolean: {rawName}", enumerator);
                }

                frontMatterName.Clear();
                frontMatterValue.Clear();
                state = FlatTokenParserState.InFrontMatter;
                break;

            default:
                frontMatterValue.Append(next);
                break;
            }
        }
Exemplo n.º 6
0
        private void ParseFrontMatterOption(RawTokenEnumerator enumerator, ref StringBuilder frontMatterName, ref FlatTokenParserState state)
        {
            var next = enumerator.Next();

            switch (next)
            {
            case ":":
                state = FlatTokenParserState.InFrontMatterOptionValue;
                break;

            default:
                frontMatterName.Append(next);
                break;
            }
        }
Exemplo n.º 7
0
        private void ParseFrontMatter(RawTokenEnumerator enumerator, ref StringBuilder frontMatterName, ref FlatTokenParserState state)
        {
            var peek = enumerator.Peek(4);

            if (peek == "---\n")
            {
                state = FlatTokenParserState.InPreamble;
                enumerator.Next(4);
                return;
            }

            peek = enumerator.Peek(5);

            if (peek == "---\r\n")
            {
                state = FlatTokenParserState.InPreamble;
                enumerator.Next(4); // Next() will trim \r\n
                return;
            }

            var next = enumerator.Next();

            switch (next)
            {
            case "#":
                state = FlatTokenParserState.InFrontMatterComment;
                break;

            case "\n":
                break;

            default:
                state = FlatTokenParserState.InFrontMatterOption;
                frontMatterName.Append(next);
                break;
            }
        }
Exemplo n.º 8
0
        private void ParseFrontMatterOptionValue(PreTemplate template, PreTokenEnumerator enumerator, ref StringBuilder frontMatterName, ref StringBuilder frontMatterValue, ref FlatTokenParserState state)
        {
            var next = enumerator.Next();

            switch (next)
            {
            case "\n":
                var rawName = frontMatterName.ToString().Trim();
                var name    = frontMatterName.ToString().Trim().ToLowerInvariant();
                var value   = frontMatterValue.ToString().Trim().ToLowerInvariant();

                switch (name)
                {
                case "trimleadingwhitespace":
                    var trimLeadingWhitespaceInTokenPreamble = ConvertFrontMatterOptionToBool(value, rawName, enumerator);
                    template.Options.TrimLeadingWhitespaceInTokenPreamble = trimLeadingWhitespaceInTokenPreamble;
                    break;

                case "trimtrailingwhitespace":
                    var trimTrailingWhiteSpace = ConvertFrontMatterOptionToBool(value, rawName, enumerator);
                    template.Options.TrimTrailingWhiteSpace = trimTrailingWhiteSpace;
                    break;

                case "trimpreamblebeforenewline":
                    var trimPreambleBeforeNewLine = ConvertFrontMatterOptionToBool(value, rawName, enumerator);
                    template.Options.TrimPreambleBeforeNewLine = trimPreambleBeforeNewLine;
                    break;

                case "outoforder":
                    var outOfOrderTokens = ConvertFrontMatterOptionToBool(value, rawName, enumerator);
                    template.Options.OutOfOrderTokens = outOfOrderTokens;
                    break;

                case "terminateonnewline":
                    var terminateOnNewline = ConvertFrontMatterOptionToBool(value, rawName, enumerator);
                    template.Options.TerminateOnNewline = terminateOnNewline;
                    break;

                case "ignoremissingproperties":
                    var ignoreMissingProperties = ConvertFrontMatterOptionToBool(value, rawName, enumerator);
                    template.Options.IgnoreMissingProperties = ignoreMissingProperties;
                    break;

                case "name":
                    template.Name = frontMatterValue.ToString().Trim();
                    break;

                case "hint":
                    template.Hints.Add(new Hint
                    {
                        Text     = frontMatterValue.ToString().Trim(),
                        Optional = false
                    });
                    break;

                case "hint?":
                    template.Hints.Add(new Hint
                    {
                        Text     = frontMatterValue.ToString().Trim(),
                        Optional = true
                    });
                    break;

                case "casesensitive":
                    var caseSensitive = ConvertFrontMatterOptionToBool(value, rawName, enumerator);
                    if (caseSensitive)
                    {
                        template.Options.TokenStringComparison = StringComparison.InvariantCulture;
                    }
                    else
                    {
                        template.Options.TokenStringComparison = StringComparison.InvariantCultureIgnoreCase;
                    }
                    break;

                case "tag":
                    template.Tags.Add(frontMatterValue.ToString().Trim());
                    break;

                default:
                    throw new ParsingException($"Unknown front matter option: {rawName}", enumerator);
                }

                frontMatterName.Clear();
                frontMatterValue.Clear();
                state = FlatTokenParserState.InFrontMatter;
                break;

            default:
                frontMatterValue.Append(next);
                break;
            }
        }
Exemplo n.º 9
0
        private void ParseDecorator(RawTemplate template, ref RawToken token, RawTokenEnumerator enumerator, ref FlatTokenParserState state, ref RawTokenDecorator decorator)
        {
            var next = enumerator.Next();

            if (string.IsNullOrWhiteSpace(next))
            {
                return;
            }

            switch (next)
            {
            case "}":
                token.Decorators.Add(decorator);
                template.Tokens.Add(token);
                token     = new RawToken();
                decorator = new RawTokenDecorator();
                state     = FlatTokenParserState.InPreamble;
                break;

            case ",":
                token.Decorators.Add(decorator);
                decorator = new RawTokenDecorator();
                break;

            case "(":
                state = FlatTokenParserState.InDecoratorArgument;
                break;

            default:
                decorator.AppendName(next);
                break;
            }
        }
Exemplo n.º 10
0
        private void ParseDecorator(PreTemplate template, ref PreToken token, PreTokenEnumerator enumerator, ref FlatTokenParserState state, ref PreTokenDecorator decorator, ref bool inFrontMatterToken, ref StringBuilder tokenContent, TokenizerOptions options)
        {
            var next = enumerator.Next();

            tokenContent.Append(next);

            if (string.IsNullOrWhiteSpace(next))
            {
                if (inFrontMatterToken == false)
                {
                    return;
                }
                if (next != "\n")
                {
                    return;
                }
            }

            switch (next)
            {
            case "}" when inFrontMatterToken == false:
            case "\n" when inFrontMatterToken:
                token.IsFrontMatterToken = inFrontMatterToken;
                AppendDecorator(enumerator, token, decorator);
                AppendToken(template, token, ref tokenContent, options);
                token     = new PreToken();
                decorator = new PreTokenDecorator();
                if (inFrontMatterToken)
                {
                    inFrontMatterToken = false;
                    state = FlatTokenParserState.InFrontMatter;
                }
                else
                {
                    state = FlatTokenParserState.InPreamble;
                }
                break;

            case ",":
                AppendDecorator(enumerator, token, decorator);
                decorator = new PreTokenDecorator();
                break;

            case "(":
                state = FlatTokenParserState.InDecoratorArgument;
                break;

            case "}" when inFrontMatterToken:
            case "\n" when inFrontMatterToken == false:
                throw  new ParsingException($"'{decorator.Name}' unexpected character: {next}", enumerator);

            case "!":
                if (string.IsNullOrWhiteSpace(decorator.Name))
                {
                    decorator.IsNotDecorator = true;
                }
                else
                {
                    throw  new ParsingException($"'{decorator.Name}' unexpected character: {next}", enumerator);
                }
                break;

            default:
                decorator.AppendName(next);
                break;
            }
        }
Exemplo n.º 11
0
        private void ParseTokenValueRunOff(PreTokenEnumerator enumerator, ref PreTemplate template, ref PreToken token, ref FlatTokenParserState state, ref bool inFrontMatterToken, ref StringBuilder tokenContent, TokenizerOptions options)
        {
            var next = enumerator.Next();

            tokenContent.Append(next);

            if (string.IsNullOrWhiteSpace(next))
            {
                if (inFrontMatterToken == false)
                {
                    return;
                }
                if (next != "\n")
                {
                    return;
                }
            }

            switch (next)
            {
            case ":":
                state = FlatTokenParserState.InDecorator;
                break;

            case "}" when inFrontMatterToken == false:
            case "\n" when inFrontMatterToken:
                token.IsFrontMatterToken = inFrontMatterToken;
                AppendToken(template, token, ref tokenContent, options);
                token = new PreToken();
                if (inFrontMatterToken)
                {
                    inFrontMatterToken = false;
                    state = FlatTokenParserState.InFrontMatter;
                }
                else
                {
                    state = FlatTokenParserState.InPreamble;
                }
                break;

            default:
                throw new TokenizerException($"Unexpected character: '{next}'");
            }
        }
Exemplo n.º 12
0
        private void ParseTokenValueInDoubleQuotes(PreTokenEnumerator enumerator, ref PreToken token, ref FlatTokenParserState state, ref StringBuilder tokenContent)
        {
            var next = enumerator.Next();

            switch (next)
            {
            case @"""":
                state = FlatTokenParserState.InTokenValueRunOff;
                break;

            default:
                token.AppendValue(next);
                break;
            }

            tokenContent.Append(next);
        }
Exemplo n.º 13
0
        private void ParseTokenValue(PreTemplate template, ref PreToken token, PreTokenEnumerator enumerator, ref FlatTokenParserState state, ref bool inFrontMatterToken, ref StringBuilder tokenContent, TokenizerOptions options)
        {
            var next = enumerator.Next();
            var peek = enumerator.Peek();

            tokenContent.Append(next);

            switch (next)
            {
            case "{":
                throw new ParsingException($"Unexpected character '{{' in token '{token.Name}'", enumerator);

            case "}" when inFrontMatterToken == false:
            case "\n" when inFrontMatterToken:
                token.IsFrontMatterToken = inFrontMatterToken;
                AppendToken(template, token, ref tokenContent, options);
                token = new PreToken();
                if (inFrontMatterToken)
                {
                    inFrontMatterToken = false;
                    state = FlatTokenParserState.InFrontMatter;
                }
                else
                {
                    state = FlatTokenParserState.InPreamble;
                }
                break;

            case ":":
                state = FlatTokenParserState.InDecorator;
                break;

            case "'":
                state = FlatTokenParserState.InTokenValueSingleQuotes;
                break;

            case "\"":
                state = FlatTokenParserState.InTokenValueDoubleQuotes;
                break;

            case " ":
                switch (peek)
                {
                case " ":
                case "}" when inFrontMatterToken == false:
                case "\n" when inFrontMatterToken:
                case ":":
                    break;

                default:
                    if (token.HasValue)
                    {
                        throw new ParsingException($"Invalid character '{peek}' in token '{token.Name}'", enumerator);
                    }
                    break;
                }

                break;

            case "}" when inFrontMatterToken:
            case "\n" when inFrontMatterToken == false:
                throw  new ParsingException($"'{token.Name}' unexpected character: {next}", enumerator);

            default:
                token.AppendValue(next);
                break;
            }
        }
Exemplo n.º 14
0
        private void ParseTokenName(PreTemplate template, ref PreToken token, PreTokenEnumerator enumerator, ref FlatTokenParserState state, ref bool inFrontMatterToken, ref StringBuilder tokenContent, TokenizerOptions options)
        {
            var next = enumerator.Next();
            var peek = enumerator.Peek();

            tokenContent.Append(next);

            switch (next)
            {
            case "{":
                throw new ParsingException($"Unexpected character '{{' in token '{token.Name}'", enumerator);

            case "}":
                if (inFrontMatterToken)
                {
                    throw new ParsingException($"Invalid character '{next}' in token '{token.Name}'", enumerator);
                }
                else
                {
                    AppendToken(template, token, ref tokenContent, options);
                    token = new PreToken();
                    state = FlatTokenParserState.InPreamble;
                }
                break;

            case "$":
                token.TerminateOnNewline = true;
                switch (peek)
                {
                case " ":
                case "?":
                case "*":
                case "}":
                case ":":
                case "!":
                    break;

                default:
                    throw new ParsingException($"Invalid character '{peek}' in token '{token.Name}'", enumerator);
                }
                break;

            case "?":
                token.Optional = true;
                switch (peek)
                {
                case " ":
                case "$":
                case "*":
                case "}":
                case ":":
                case "!":
                    break;

                default:
                    throw new ParsingException($"Invalid character '{peek}' in token '{token.Name}'", enumerator);
                }

                if (token.Required)
                {
                    throw new ParsingException($"Required token {token.Name} can't be Optional", enumerator);
                }

                break;

            case "*":
                token.Repeating = true;
                token.Optional  = true;
                switch (peek)
                {
                case " ":
                case "$":
                case "?":
                case "}":
                case ":":
                case "!":
                    break;

                default:
                    throw new ParsingException($"Invalid character '{peek}' in token '{token.Name}'", enumerator);
                }
                break;

            case "!":
                token.Required = true;
                switch (peek)
                {
                case " ":
                case "*":
                case "$":
                case "?":
                case "}":
                case ":":
                    break;

                default:
                    throw new ParsingException($"Invalid character '{peek}' in token '{token.Name}'", enumerator);
                }

                if (token.Optional)
                {
                    throw new ParsingException($"Optional token {token.Name} can't be Required", enumerator);
                }

                break;

            case ":":
                state = FlatTokenParserState.InDecorator;
                break;

            case "=":
                state = FlatTokenParserState.InTokenValue;
                break;

            case " ":
                switch (peek)
                {
                case " ":
                case "*":
                case "$":
                case "?":
                case "}":
                case ":":
                case "!":
                case "=":
                    break;

                case "\n" when inFrontMatterToken:
                    break;

                default:
                    if (string.IsNullOrWhiteSpace(token.Name) == false)
                    {
                        throw new ParsingException($"Invalid character '{peek}' in token '{token.Name}'", enumerator);
                    }
                    break;
                }

                break;

            case "\n":
                if (inFrontMatterToken)
                {
                    token.IsFrontMatterToken = true;
                    AppendToken(template, token, ref tokenContent, options);
                    token = new PreToken();
                    inFrontMatterToken = false;
                    state = FlatTokenParserState.InFrontMatter;
                }
                else
                {
                    throw new ParsingException($"Invalid character '{next}' in token '{token.Name}'", enumerator);
                }
                break;

            default:
                if (ValidTokenNameCharacters.Contains(next))
                {
                    token.AppendName(next);
                }
                else
                {
                    throw new ParsingException($"Invalid character '{next}' in token '{token.Name}'", enumerator);
                }
                break;
            }
        }
Exemplo n.º 15
0
        private void ParsePreamble(ref PreToken token, PreTokenEnumerator enumerator, ref FlatTokenParserState state, ref StringBuilder tokenContent)
        {
            var next = enumerator.Next();

            switch (next)
            {
            case "{":
                if (enumerator.Peek() == "{")
                {
                    token.AppendPreamble("{");
                    enumerator.Next();
                }
                else
                {
                    token.Location = enumerator.Location.Clone();
                    tokenContent.Append("{");

                    state = FlatTokenParserState.InTokenName;
                }
                break;

            case "}":
                if (enumerator.Peek() == "}")
                {
                    token.AppendPreamble("}");
                    enumerator.Next();
                    break;
                }
                throw new ParsingException($"Unescaped character '}}' in template.", enumerator);


            default:
                token.AppendPreamble(next);
                break;
            }
        }
Exemplo n.º 16
0
        private void ParsePreamble(ref RawToken token, RawTokenEnumerator enumerator, ref FlatTokenParserState state)
        {
            var next = enumerator.Next();

            switch (next)
            {
            case "{":
                state = FlatTokenParserState.InTokenName;
                break;

            default:
                if (token.Preamble == null)
                {
                    token.Preamble = string.Empty;
                }
                token.Preamble += next;
                break;
            }
        }
Exemplo n.º 17
0
        private void ParseTokenName(RawTemplate template, ref RawToken token, RawTokenEnumerator enumerator, ref FlatTokenParserState state)
        {
            var next = enumerator.Next();
            var peek = enumerator.Peek();

            switch (next)
            {
            case "{":
                throw new ParsingException($"Unexpected character '{{' in token '{token.Name}'", enumerator);

            case "}":
                template.Tokens.Add(token);
                token = new RawToken();
                state = FlatTokenParserState.InPreamble;
                break;

            case "$":
                token.TerminateOnNewline = true;
                switch (peek)
                {
                case "?":
                case "*":
                case "}":
                case ":":
                    break;

                default:
                    throw new ParsingException($"Invalid character '{peek}' in token '{token.Name}'", enumerator);
                }
                break;

            case "?":
                token.Optional = true;
                switch (peek)
                {
                case "$":
                case "*":
                case "}":
                case ":":
                    break;

                default:
                    throw new ParsingException($"Invalid character '{peek}' in token '{token.Name}'", enumerator);
                }
                break;

            case "*":
                token.Repeating = true;
                token.Optional  = true;
                switch (peek)
                {
                case "$":
                case "?":
                case "}":
                case ":":
                    break;

                default:
                    throw new ParsingException($"Invalid character '{peek}' in token '{token.Name}'", enumerator);
                }
                break;

            case ":":
                state = FlatTokenParserState.InDecorator;
                break;

            default:
                if (token.Name == null)
                {
                    token.Name = string.Empty;
                }
                if (ValidTokenNameCharacters.Contains(next))
                {
                    token.Name += next;
                }
                else
                {
                    throw new ParsingException($"Invalid character '{next}' in token '{token.Name}'", enumerator);
                }
                break;
            }
        }
Exemplo n.º 18
0
        private void ParseDecoratorArgumentInSingleQuotes(PreTokenEnumerator enumerator, ref FlatTokenParserState state, ref PreTokenDecorator decorator, ref string argument, ref StringBuilder tokenContent)
        {
            var next = enumerator.Next();

            switch (next)
            {
            case "'":
                decorator.Args.Add(argument);
                argument = string.Empty;
                state    = FlatTokenParserState.InDecoratorArgumentRunOff;
                break;

            default:
                argument += next;
                break;
            }

            tokenContent.Append(next);
        }
Exemplo n.º 19
0
        private void ParseDecoratorArgumentInDoubleQuotes(RawTokenEnumerator enumerator, ref FlatTokenParserState state, ref RawTokenDecorator decorator, ref string argument)
        {
            var next = enumerator.Next();

            switch (next)
            {
            case @"""":
                decorator.Args.Add(argument);
                argument = string.Empty;
                state    = FlatTokenParserState.InDecoratorArgumentRunOff;
                break;

            default:
                argument += next;
                break;
            }
        }
Exemplo n.º 20
0
        private void ParseFrontMatterOption(PreTokenEnumerator enumerator, ref StringBuilder frontMatterName, ref FlatTokenParserState state, ref bool inFrontMatterToken, ref PreToken token)
        {
            var next = enumerator.Next();

            switch (next)
            {
            case ":":
                if (frontMatterName.ToString().Trim().ToLowerInvariant() == "set")
                {
                    inFrontMatterToken = true;
                    frontMatterName.Clear();
                    token.Location = enumerator.Location.Clone();
                    state          = FlatTokenParserState.InTokenName;
                }
                else
                {
                    state = FlatTokenParserState.InFrontMatterOptionValue;
                }

                break;

            default:
                frontMatterName.Append(next);
                break;
            }
        }