Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions Fluid.Tests/ParserTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,45 @@ public void ShouldParseCommentWithBlocks()
Assert.Equal(" {%if true%} {%endif%} ", (statements.ElementAt(0) as CommentStatement).Text.ToString());
}

[Fact]
public void ShouldParseInlineComment()
{
var statements = Parse(@"{% # this is an inline comment %}");

Assert.Single(statements);
Assert.IsType<CommentStatement>(statements.ElementAt(0));
Assert.Equal(" this is an inline comment", (statements.ElementAt(0) as CommentStatement).Text.ToString());
}

[Fact]
public void ShouldParseEmptyInlineComment()
{
var statements = Parse(@"{% #%}");

Assert.Single(statements);
Assert.IsType<CommentStatement>(statements.ElementAt(0));
Assert.Equal("", (statements.ElementAt(0) as CommentStatement).Text.ToString());
}

[Fact]
public void ShouldParseInlineCommentWithoutLiquidTags()
{
var statements = Parse(@"{% # this is a simple comment %}");

Assert.Single(statements);
Assert.IsType<CommentStatement>(statements.ElementAt(0));
}

[Fact]
public void ShouldParseInlineCommentWithWhitespaceTrim()
{
var statements = Parse(@"{%- # this is a trimmed comment -%}");

Assert.Single(statements);
Assert.IsType<CommentStatement>(statements.ElementAt(0));
Assert.Equal(" this is a trimmed comment", (statements.ElementAt(0) as CommentStatement).Text.ToString());
}

[Fact]
public void ShouldParseIfTag()
{
Expand Down
58 changes: 58 additions & 0 deletions Fluid.Tests/TemplateTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1209,5 +1209,63 @@ public async Task ArraysShouldCompareElements()
var result = await template.RenderAsync(context);
Assert.Contains("true", result);
}

[Fact]
public async Task InlineCommentShouldNotRender()
{
var source = "Hello {% # this is a comment %} World";
await CheckAsync(source, "Hello World");
}

[Fact]
public async Task InlineCommentShouldNotRenderAnyContent()
{
var source = "{% # this is a comment with text %}Result";
await CheckAsync(source, "Result");
}

[Fact]
public async Task InlineCommentShouldWorkWithWhitespaceTrim()
{
var source = "Hello{%- # this is a comment -%}World";
await CheckAsync(source, "HelloWorld");
}

[Fact]
public async Task InlineCommentShouldWorkInTemplates()
{
var source = @"
{% # Start of template %}
{% assign name = 'John' %}
{% # Output the name %}
Hello {{ name }}!
{% # End of template %}
";

_parser.TryParse(source, out var template, out var error);
var context = new TemplateContext();
var result = await template.RenderAsync(context);
Assert.Contains("Hello John!", result);
Assert.DoesNotContain("Start of template", result);
Assert.DoesNotContain("Output the name", result);
Assert.DoesNotContain("End of template", result);
}

[Fact]
public async Task InlineCommentShouldWorkBetweenTags()
{
var source = @"
{% if true %}
{% # This is between if tags %}
Success
{% endif %}
";

_parser.TryParse(source, out var template, out var error);
var context = new TemplateContext();
var result = await template.RenderAsync(context);
Assert.Contains("Success", result);
Assert.DoesNotContain("This is between if tags", result);
}
}
}
18 changes: 16 additions & 2 deletions Fluid/FluidParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,13 @@ public FluidParser(FluidParserOptions parserOptions)
;
CommentTag.Name = "CommentTag";

var InlineCommentTag = AnyCharBefore(TagEnd, canBeEmpty: true)
.AndSkip(TagEnd)
.Then<Statement>(x => new CommentStatement(x))
.ElseError("Invalid inline comment tag")
;
InlineCommentTag.Name = "InlineCommentTag";

var CaptureTag = Identifier.ElseError(string.Format(ErrorMessages.IdentifierAfterTag, "capture"))
.AndSkip(TagEnd)
.And(AnyTagsList)
Expand Down Expand Up @@ -507,6 +514,7 @@ public FluidParser(FluidParserOptions parserOptions)
RegisteredTags["break"] = BreakTag;
RegisteredTags["continue"] = ContinueTag;
RegisteredTags["comment"] = CommentTag;
RegisteredTags["#"] = InlineCommentTag;
RegisteredTags["capture"] = CaptureTag;
RegisteredTags["cycle"] = CycleTag;
RegisteredTags["decrement"] = DecrementTag;
Expand Down Expand Up @@ -565,7 +573,10 @@ public FluidParser(FluidParserOptions parserOptions)
return ReadFromList(modifiers);
}

var AnyTags = TagStart.SkipAnd(Identifier.ElseError(ErrorMessages.IdentifierAfterTagStart).Switch((context, previous) =>
var AnyTags = TagStart.SkipAnd(OneOf(
Terms.Char('#').Then(x => "#"),
Identifier.ElseError(ErrorMessages.IdentifierAfterTagStart)
).Switch((context, previous) =>
{
// Because tags like 'else' are not listed, they won't count in TagsList, and will stop being processed
// as inner tags in blocks like {% if %} TagsList {% endif $}
Expand All @@ -582,7 +593,10 @@ public FluidParser(FluidParserOptions parserOptions)
}
}));

var KnownTags = TagStart.SkipAnd(Identifier.ElseError(ErrorMessages.IdentifierAfterTagStart).Switch((context, previous) =>
var KnownTags = TagStart.SkipAnd(OneOf(
Terms.Char('#').Then(x => "#"),
Identifier.ElseError(ErrorMessages.IdentifierAfterTagStart)
).Switch((context, previous) =>
{
// Because tags like 'else' are not listed, they won't count in TagsList, and will stop being processed
// as inner tags in blocks like {% if %} TagsList {% endif $}
Expand Down