Skip to content

Commit

Permalink
Add ellipsis to Truncate & TruncateWords (#60)
Browse files Browse the repository at this point in the history
  • Loading branch information
hishamco authored and sebastienros committed Jan 29, 2018
1 parent 563c845 commit 945da4f
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 53 deletions.
6 changes: 6 additions & 0 deletions Fluid.Benchmarks/Fluid.Benchmarks.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@
<TargetFramework>netcoreapp2.0</TargetFramework>
</PropertyGroup>

<ItemGroup>
<Compile Remove="BenchmarkDotNet.Artifacts\**" />
<EmbeddedResource Remove="BenchmarkDotNet.Artifacts\**" />
<None Remove="BenchmarkDotNet.Artifacts\**" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="BenchmarkDotNet" Version="0.10.9" />
<PackageReference Include="DotLiquid" Version="2.0.174" />
Expand Down
75 changes: 46 additions & 29 deletions Fluid.Tests/StringFiltersTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -194,56 +194,73 @@ public void Split()
Assert.Equal(new StringValue("c"), result.Enumerate().ElementAt(2));
}

[Fact]
public void Truncate()
[Theory]
[InlineData("The cat came back the very next day", 13, "The cat ca...")]
[InlineData("Hello", 3, "...")]
[InlineData("Hello", 10, "Hello...")]
[InlineData("Hello", 0, "...")]
[InlineData(null, 5, "")]
public void Truncate(string input, int size, string output)
{
var input = new StringValue("Hello World");

var arguments = new FilterArguments().Add(new NumberValue(5)).Add(new StringValue("..."));
var source = new StringValue(input);
var arguments = new FilterArguments().Add(new NumberValue(size));
var context = new TemplateContext();
var result = StringFilters.Truncate(source, arguments, context);

var result = StringFilters.Truncate(input, arguments, context);

Assert.Equal("Hello...", result.ToStringValue());
Assert.Equal(output, result.ToStringValue());
}

[Fact]
public void TruncateShortString()
[Theory]
[InlineData("ABCDEFGHIJKLMNOPQRSTUVWXYZ", 18, ", and so on", "ABCDEFG, and so on")]
[InlineData("I'm a little teapot, short and stout.", 15, "", "I'm a little te")]
[InlineData("ABCDEFGHIJKLMNOPQRSTUVWXYZ", 5, ", and so on", ", and so on")]
[InlineData("ABCD EFGH IJKLM NOPQRS TUVWXYZ", 3, "", "ABC")]
[InlineData("ABCD EFGH IJKLM NOPQRS TUVWXYZ", 0, "", "")]
public void TruncateWithCustomEllipsis(string input, int size, string ellipsis, string output)
{
var input = new StringValue("Hello");

var arguments = new FilterArguments().Add(new NumberValue(5)).Add(new StringValue("..."));
var source = new StringValue(input);
var arguments = new FilterArguments()
.Add(new NumberValue(size))
.Add(new StringValue(ellipsis));
var context = new TemplateContext();
var result = StringFilters.Truncate(source, arguments, context);

var result = StringFilters.Truncate(input, arguments, context);

Assert.Equal("Hello", result.ToStringValue());
Assert.Equal(output, result.ToStringValue());
}

[Fact]
public void TruncateNullString()
[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)
{
var input = new StringValue(null);

var arguments = new FilterArguments().Add(new NumberValue(5)).Add(new StringValue("..."));
var source = new StringValue(input);
var arguments = new FilterArguments()
.Add(new NumberValue(size));
var context = new TemplateContext();

var result = StringFilters.Truncate(input, arguments, context);
var result = StringFilters.TruncateWords(source, arguments, context);

Assert.Null(result.ToStringValue());
Assert.Equal(output, result.ToStringValue());
}

[Fact]
public void TruncateWords()
[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, "", "")]
public void TruncateWordsWithCustomEllipsis(string input, int size, string ellispsis, string output)
{
var input = new StringValue("This is a nice story with a bad end.");
var source = new StringValue(input);
var arguments = new FilterArguments()
.Add(new NumberValue(size))
.Add(new StringValue(ellispsis));

var arguments = new FilterArguments().Add(new NumberValue(5)).Add(new StringValue("..."));
var context = new TemplateContext();

var result = StringFilters.TruncateWords(input, arguments, context);
var result = StringFilters.TruncateWords(source, arguments, context);

Assert.Equal("This is a nice story...", result.ToStringValue());
Assert.Equal(output, result.ToStringValue());
}

[Fact]
Expand Down
59 changes: 35 additions & 24 deletions Fluid/Filters/StringFilters.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Fluid.Values;

namespace Fluid.Filters
{
public static class StringFilters
{
private static readonly StringValue Ellipsis = new StringValue("...");

public static FilterCollection WithStringFilters(this FilterCollection filters)
{
filters.AddFilter("append", Append);
Expand Down Expand Up @@ -145,48 +146,58 @@ public static FluidValue Strip(FluidValue input, FilterArguments arguments, Temp

public static FluidValue Truncate(FluidValue input, FilterArguments arguments, TemplateContext context)
{
string text = input.ToStringValue();
int length = Convert.ToInt32(arguments.At(0).ToNumberValue());
var text = input.ToStringValue();
var size = Math.Max(0, Convert.ToInt32(arguments.At(0).ToNumberValue()));
var ellipsis = arguments.At(1).Or(Ellipsis).ToStringValue();

if (text == null || text.Length <= length)
if (text == null)
{
return input;
return NilValue.Empty;
}
else
else if (ellipsis.Length >= size)
{
var source = text.Substring(0, length);

if (arguments.Count > 1)
{
source += arguments.At(1).ToStringValue();
}
return new StringValue(ellipsis);
}
else if (text.Length > size - ellipsis.Length)
{
var source = text.Substring(0, size - ellipsis.Length) + ellipsis;

return new StringValue(source);
}
else
{
return new StringValue(text + ellipsis);
}
}
public static FluidValue TruncateWords(FluidValue input, FilterArguments arguments, TemplateContext context)
{
var source = input.ToStringValue();
var n = Convert.ToInt32(arguments.At(0).ToNumberValue());
var size = Math.Max(0, Convert.ToInt32(arguments.At(0).ToNumberValue()));
var ellipsis = arguments.At(1).Or(Ellipsis).ToStringValue();

var words = 0;
for (int 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 == n)
if (size > 0)
{
for (var i = 0; i < source.Length;)
{
source = source.Substring(0, i);
break;
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;
}
}
}

if (arguments.Count > 1)
else
{
source += arguments.At(1).ToStringValue();
source = "";
}

source += ellipsis;

return new StringValue(source);
}
Expand Down

0 comments on commit 945da4f

Please sign in to comment.