I've actually implemented my suggestion as it didn't take long at all to do. Seems to work very nicely. It's limited as it stands, as it presumes that {{x|y}}
is with x as a decimal type and y as a number of decimal characters. I also used <###
and ###>
instead because $
is used in the regex replacement string (eg. $1 is the first matched group, etc). So using #
meant I didn't have to escape them.
Just incase anyone's interested, here's the code:
using System.Text.RegularExpressions;
public static class NustacheUtil
{
public static string PreProcess(string templateString)
{
return Regex.Replace(templateString, @"{{(.*?)\|(\d+)}}", @"<###{{$1}}|$2###>");
}
public static string PostProcess(string templateString)
{
var result = templateString;
for(;;)
{
var match = Regex.Match(result, @"<###([0-9.]+?)\|(\d+)###>");
if(!match.Success || match.Groups.Count != 3)
{
break;
}
decimal value;
if(decimal.TryParse(match.Groups[1].Value, out value))
{
var numDecimalPlaces = match.Groups[2].Value;
result = result.Remove(match.Index, match.Length);
result = result.Insert(match.Index, value.ToString("N" + numDecimalPlaces));
}
}
return result;
}
}
And a few tests:
using NUnit.Framework;
[TestFixture]
class NustacheUtilTests
{
[Test]
public void PreProcessTest_Single()
{
// Arrange
const string templateString = "Test number: {{MyNumber|3}}";
// Act
var result = NustacheUtil.PreProcess(templateString);
// Assert
Assert.That(result, Is.EqualTo("Test number: <###{{MyNumber}}|3###>"));
}
[Test]
public void PostProcessTest_Single()
{
// Arrange
const string templateString = "Test number: <###123.456789|3###>";
// Act
var result = NustacheUtil.PostProcess(templateString);
// Assert
Assert.That(result, Is.EqualTo("Test number: 123.457"));
}
[Test]
public void PreProcessTest_Multiple()
{
// Arrange
const string templateString = "Test number: {{MyNumber|3}}, and another: {{OtherNumber|2}}";
// Act
var result = NustacheUtil.PreProcess(templateString);
// Assert
Assert.That(result, Is.EqualTo("Test number: <###{{MyNumber}}|3###>, and another: <###{{OtherNumber}}|2###>"));
}
[Test]
public void PostProcessTest_Multiple()
{
// Arrange
const string templateString = "Test number: <###123.457|3###>, and another: <###947.74933|2###>";
// Act
var result = NustacheUtil.PostProcess(templateString);
// Assert
Assert.That(result, Is.EqualTo("Test number: 123.457, and another: 947.75"));
}
}
And usage with Nustache:
var templateString = NustacheUtil.PreProcess(templateString);
templateString = Render.StringToString(templateString, dataSource);
templateString = NustacheUtil.PostProcess(templateString);
It obviously hasn't yet been used in anger. I'll update the code here when I make changes, as I'm sure I will make improvements as I use it properly.