Esempio n. 1
0
            public override bool Parse(ParseContext context, ref ParseResult <LavaTagResult> result)
            {
                var start = context.Scanner.Cursor.Position;

                if (_skipWhiteSpace)
                {
                    context.SkipWhiteSpace();
                }

                Parser <(LavaTagResult, string, TextSpan, LavaTagResult)> tagParser;

                if (_tagFormat == LavaTagFormatSpecifier.LavaShortcode)
                {
                    tagParser = LavaTagParsers.LavaShortcodeStart()
                                .And(Terms.Text(_tagName))
                                .And(AnyCharBefore(LavaTagParsers.LavaShortcodeEnd(), canBeEmpty: true))
                                .And(LavaTagParsers.LavaShortcodeEnd());
                }
                else
                {
                    tagParser = LavaTagParsers.LavaTagStart()
                                .And(Terms.Text(_tagName)).
                                And(AnyCharBefore(LavaFluidParser.LavaTokenEnd, canBeEmpty: true))
                                .And(LavaFluidParser.LavaTokenEnd);
                }

                var tagResult = new ParseResult <(LavaTagResult, string, TextSpan, LavaTagResult)>();

                var parseSucceeded = tagParser.Parse(context, ref tagResult);

                if (!parseSucceeded)
                {
                    context.Scanner.Cursor.ResetPosition(start);
                    return(false);
                }

                var lavaResult = new LavaTagResult(tagResult.Value.Item1.TagResult,
                                                   new TextSpan(context.Scanner.Buffer, start.Offset, context.Scanner.Cursor.Position.Offset - start.Offset),
                                                   _tagFormat);

                result.Set(start.Offset, context.Scanner.Cursor.Offset, lavaResult);

                return(true);
            }
Esempio n. 2
0
        /// <summary>
        /// Create a parser for the set of tags and shortcodes that have been defined.
        /// </summary>
        /// <param name="throwOnUnknownTag">If true, undefined tags return null rather than throwing an exception.</param>
        /// <returns></returns>
        /// <remarks>The option to ignore unknown tags can be used to ignore output tags that are not defined until the render process.</remarks>
        private Parser <Statement> CreateKnownTagsParser(bool throwOnUnknownTag)
        {
            var parser = OneOf(
                LavaTagParsers.LavaTagStart()
                .SkipAnd(Identifier.ElseError(ErrorMessages.IdentifierAfterTagStart)
                         .Switch((context, tagName) =>
            {
                if (RegisteredTags.TryGetValue(tagName, out var tag))
                {
                    return(tag);
                }
                else if (throwOnUnknownTag)
                {
                    throw new global::Fluid.ParseException($"Unknown tag '{tagName}' at {context.Scanner.Cursor.Position}");
                }

                return(null);
            })
                         ),
                LavaTagParsers.LavaShortcodeStart()
                .SkipAnd(Identifier.ElseError(ErrorMessages.IdentifierAfterTagStart)
                         .Switch((context, tagName) =>
            {
                var shortcodeTagName = tagName + "_";

                if (RegisteredTags.TryGetValue(shortcodeTagName, out var shortcode))
                {
                    return(shortcode);
                }

                throw new global::Fluid.ParseException($"Unknown shortcode '{tagName}' at {context.Scanner.Cursor.Position}");
            })
                         )
                );

            return(parser);
        }
Esempio n. 3
0
        private void CreateLavaDocumentParsers()
        {
            // Define the top-level parsers.
            var anyTags   = CreateKnownTagsParser(throwOnUnknownTag: false);
            var knownTags = CreateKnownTagsParser(throwOnUnknownTag: true);

            var outputElement = OutputStart.SkipAnd(FilterExpression.And(OutputEnd.ElseError(ErrorMessages.ExpectedOutputEnd))
                                                    .Then <Statement>(x => new OutputStatement(x.Item1)));

            var textElement = AnyCharBefore(OutputStart.Or(LavaTagParsers.LavaTagStart().AsFluidTagResultParser()).Or(LavaTagParsers.LavaShortcodeStart().AsFluidTagResultParser()))
                              .Then <Statement>((ctx, x) =>
            {
                // Keep track of each text span such that whitespace trimming can be applied
                var p = ( FluidParseContext )ctx;

                var result = new TextSpanStatement(x);

                p.PreviousTextSpanStatement = result;

                if (p.StripNextTextSpanStatement)
                {
                    result.StripLeft             = true;
                    p.StripNextTextSpanStatement = false;
                }

                result.PreviousIsTag    = p.PreviousIsTag;
                result.PreviousIsOutput = p.PreviousIsOutput;

                return(result);
            });

            // Define parsers for Lava block/inline comments.
            var blockCommentElement = Terms.Text("/-").SkipAnd(AnyCharBefore(Terms.Text("-/")));
            var lineCommentElement  = Terms.Text("/-").SkipAnd(AnyCharBefore(Terms.Char('\r').SkipAnd(Terms.Char('\n'))));

            var commentElement = blockCommentElement.Or(lineCommentElement);

            // Set the parser to be used for a block element.
            // This parser returns an empty result when an unknown tag is found.
            _anyTagsListParser = ZeroOrMany(outputElement.Or(anyTags).Or(textElement));

            // Set the parser to be used for the entire template.
            // This parser raises an exception when an unknown tag is found.
            _knownTagsListParser = ZeroOrMany(outputElement.Or(knownTags).Or(textElement));
        }