Skip to content

Commit

Permalink
Don't add ellipsis when size is greater than number of words (#507)
Browse files Browse the repository at this point in the history
Co-authored-by: Sébastien Ros <[email protected]>
  • Loading branch information
hishamco and sebastienros authored Sep 21, 2022
1 parent 6b73b58 commit 8c68d0d
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 27 deletions.
20 changes: 13 additions & 7 deletions Fluid.Tests/StringFiltersTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -297,15 +297,21 @@ public void TruncateWithCustomEllipsis(string input, int size, string ellipsis,
}

[Theory]
[InlineData("The cat came back the very next day", 4, "The cat came back...")]
[InlineData("The cat came back the very next day", 1, "The...")]
[InlineData("The cat came back the very next day", 0, "...")]
[InlineData("The cat came back", 10, "The cat came back...")]
public void TruncateWords(string input, int size, string output)
[InlineData("one two three", 4, "one two three")]
[InlineData("one two three", 2, "one two...")]
[InlineData("one two three", null, "one two three")]
[InlineData("Two small (13&#8221; x 5.5&#8221; x 10&#8221; high) baskets fit inside one large basket (13&#8221; x 16&#8221; x 10.5&#8221; high) with cover.", 15, "Two small (13&#8221; x 5.5&#8221; x 10&#8221; high) baskets fit inside one large basket (13&#8221;...")]
[InlineData("测试测试测试测试", 5, "测试测试测试测试")]
[InlineData("one two\tthree\nfour", 3, "one two three...")]
[InlineData("one two three four", 2, "one two...")]
[InlineData(" one two three four", 2, "one two...")]
[InlineData("one two three four", 0, "one...")]
public void TruncateWords(string input, object size, string output)
{
var options = new TemplateOptions();
var source = new StringValue(input);
var arguments = new FilterArguments()
.Add(NumberValue.Create(size));
.Add(FluidValue.Create(size, options));
var context = new TemplateContext();

var result = StringFilters.TruncateWords(source, arguments, context);
Expand All @@ -316,7 +322,7 @@ public void TruncateWords(string input, int size, string output)
[Theory]
[InlineData("The cat came back the very next day", 4, "--", "The cat came back--")]
[InlineData("The cat came back the very next day", 4, "", "The cat came back")]
[InlineData("The cat came back the very next day", 0, "", "")]
[InlineData("The cat came back the very next day", 0, "", "The")]
public void TruncateWordsWithCustomEllipsis(string input, int size, string ellispsis, string output)
{
var source = new StringValue(input);
Expand Down
42 changes: 22 additions & 20 deletions Fluid/Filters/StringFilters.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Fluid.Values;

Expand Down Expand Up @@ -274,34 +275,35 @@ public static ValueTask<FluidValue> Truncate(FluidValue input, FilterArguments a
public static ValueTask<FluidValue> TruncateWords(FluidValue input, FilterArguments arguments, TemplateContext context)
{
var source = input.ToStringValue();
var size = Math.Max(0, Convert.ToInt32(arguments.At(0).ToNumberValue()));

// Default value is 15
// c.f. https://github.com/Shopify/liquid/blob/81f44e36be5f2110c26b6532fd4ccd22edaf59f2/lib/liquid/standardfilters.rb#L233
var size = Convert.ToInt32(arguments.At(0).Or(NumberValue.Create(15)).ToNumberValue());

if (size <= 0)
{
size = 1;
}

var ellipsis = arguments.At(1).Or(Ellipsis).ToStringValue();

var words = 0;
var chunks = new List<string>();

if (size > 0)
var length = source.Length;
for (var i = 0; i < length && chunks.Count < size;)
{
for (var i = 0; i < source.Length;)
{
while (i < source.Length && char.IsWhiteSpace(source[i])) i++;
while (i < source.Length && !char.IsWhiteSpace(source[i])) i++;
words++;

if (words >= size)
{
source = source.Substring(0, i);
break;
}
}
while (i < length && char.IsWhiteSpace(source[i++])) ;
var start = i - 1;
while (i < length && !char.IsWhiteSpace(source[i++])) ;
chunks.Add(source.Substring(start, i - start - (i < length ? 1 : 0)));
}
else

if (chunks.Count >= size)
{
source = "";
chunks[chunks.Count - 1] += ellipsis;
}

source += ellipsis;

return new StringValue(source);
return new StringValue(string.Join(" ", chunks));
}

public static ValueTask<FluidValue> Upcase(FluidValue input, FilterArguments arguments, TemplateContext context)
Expand Down

0 comments on commit 8c68d0d

Please sign in to comment.