diff --git a/CHANGES.md b/CHANGES.md
index b7cb18d5..363388b1 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -309,6 +309,7 @@ SmartFormat is not a fully-fledged HTML parser. If this is required, use [AngleS
a) Get the culture from the `FormattingInfo.FormatterOptions`.
b) Get the culture from the `IFormatProvider` argument (which may be a `CultureInfo`) to `SmartFormatter.Format(IFormatProvider, string, object?[])`
c) The `CultureInfo.CurrentUICulture`
+ d) `CultureInfo.InvariantCulture` maps to `CultureInfo.GetCultureInfo("en")` ([#243](https://github.com/axuno/SmartFormat/pull/243))
### 20. Refactored `TimeFormatter` ([#220](https://github.com/axuno/SmartFormat/pull/220), [#221](https://github.com/axuno/SmartFormat/pull/221), [#234](https://github.com/axuno/SmartFormat/pull/234))
@@ -502,9 +503,24 @@ var formatter = new SmartFormatter()
```
### 24. Miscellaneous
- * Since [#228](https://github.com/axuno/SmartFormat/pull/228) there are no more `Cysharp.Text` classes used in the `SmartFormat` namespace
- * Created class `ZStringBuilder` as a wrapper around `Utf16ValueStringBuilder`.
- * Replaced occurrences of `Utf16ValueStringBuilder` with `ZStringBuilder`.
+
+a) Cyhsarp.Text
+
+Since [#228](https://github.com/axuno/SmartFormat/pull/228) there are no more `Cysharp.Text` classes used in the `SmartFormat` namespace
+ * Created class `ZStringBuilder` as a wrapper around `Utf16ValueStringBuilder`.
+ * Replaced occurrences of `Utf16ValueStringBuilder` with `ZStringBuilder`.
+
+b) Split character for options and formats
+
+Since [#243](https://github.com/axuno/SmartFormat/pull/243) the character to split options and formats can be changed. This allows having the default split character `|` as part of the output string.
+Affects `ChooseFormatter`, `ConditionalFormatter`, `IsMatchFormatter`, `ListFormatter`, `PluralLocalizationFormatter`, `SubStringFormatter`. Example:
+```Csharp
+var smart = Smart.CreateDefaultSmartFormat();
+// Change SplitChar from | to TAB, so we can use | for the output string
+smart.GetFormatterExtension()!.SplitChar = '\t';
+_ = smart.Format({0:cond:|No|\t|Yes|}", 1);
+// Result: "|Yes|"
+```
v2.7.2
===
diff --git a/src/SmartFormat.Tests/Extensions/ChooseFormatterTests.cs b/src/SmartFormat.Tests/Extensions/ChooseFormatterTests.cs
index dfa1e7bd..0ab04d16 100644
--- a/src/SmartFormat.Tests/Extensions/ChooseFormatterTests.cs
+++ b/src/SmartFormat.Tests/Extensions/ChooseFormatterTests.cs
@@ -2,6 +2,7 @@
using NUnit.Framework;
using SmartFormat.Core.Formatting;
using SmartFormat.Core.Settings;
+using SmartFormat.Extensions;
using SmartFormat.Tests.TestUtils;
namespace SmartFormat.Tests.Extensions
@@ -33,6 +34,16 @@ public void Choose_should_work_with_numbers_strings_and_booleans(string format,
Assert.AreEqual(expectedResult, smart.Format(format, arg0));
}
+ [Test]
+ public void Choose_With_Changed_SplitChar()
+ {
+ var smart = Smart.CreateDefaultSmartFormat();
+ // Set SplitChar from | to TAB, so we can use | for the output string
+ smart.GetFormatterExtension()!.SplitChar = '\t';
+ var result = smart.Format("{0:choose(1\t2\t3):|one|\t|two|\t|three|}", 2);
+ Assert.That(result, Is.EqualTo("|two|"));
+ }
+
[TestCase("{0:choose(true|True):one|two|default}", true, "two")]
[TestCase("{0:choose(true|TRUE):one|two|default}", true, "default")]
[TestCase("{0:choose(string|String):one|two|default}", "String", "two")]
@@ -123,4 +134,4 @@ public void May_Contain_Nested_Choose_Formats(int? nullableInt, int valueIfNull,
Assert.That(result, Is.EqualTo(expected));
}
}
-}
\ No newline at end of file
+}
diff --git a/src/SmartFormat.Tests/Extensions/ConditionalFormatterTests.cs b/src/SmartFormat.Tests/Extensions/ConditionalFormatterTests.cs
index ccc9211f..36926019 100644
--- a/src/SmartFormat.Tests/Extensions/ConditionalFormatterTests.cs
+++ b/src/SmartFormat.Tests/Extensions/ConditionalFormatterTests.cs
@@ -1,6 +1,7 @@
using System;
using NUnit.Framework;
using SmartFormat.Core.Formatting;
+using SmartFormat.Extensions;
using SmartFormat.Tests.TestUtils;
using SmartFormat.Utilities;
@@ -38,6 +39,17 @@ public void Test_Bool(string format, string expected)
smart.Test(format, args, expected);
}
+ [TestCase("{0:cond:|Yes|\t|No|}", 0, "|Yes|")]
+ [TestCase("{0:cond:|Yes|\t|No|}", 1, "|No|")]
+ public void Test_With_Changed_SplitChar(string format, int arg, string expected)
+ {
+ var smart = Smart.CreateDefaultSmartFormat();
+ // Set SplitChar from | to TAB, so we can use | for the output string
+ smart.GetFormatterExtension()!.SplitChar = '\t';
+ var result = smart.Format(format, arg);
+ Assert.That(result, Is.EqualTo(expected));
+ }
+
[Test]
public void Explicit_Formatter_With_Not_Enough_Parameters_Should_Throw()
{
diff --git a/src/SmartFormat.Tests/Extensions/IsMatchFormatterTests.cs b/src/SmartFormat.Tests/Extensions/IsMatchFormatterTests.cs
index 4498833e..6d2407a9 100644
--- a/src/SmartFormat.Tests/Extensions/IsMatchFormatterTests.cs
+++ b/src/SmartFormat.Tests/Extensions/IsMatchFormatterTests.cs
@@ -44,8 +44,19 @@ public void Less_Than_2_Format_Options_Should_Throw()
// less than 2 format options should throw exception
Assert.Throws(() =>
_formatter.Format("{theKey:ismatch(^.+123.+$):Dummy content}", _variable));
- Assert.DoesNotThrow(() =>
- _formatter.Format("{theKey:ismatch(^.+123.+$):Dummy content|2nd option}", _variable));
+ }
+
+ // The "{}" in the format will (as always) output the matching variable
+ [TestCase("{theKey:ismatch(^.+123.+$):|Has match for '{}'|\t|No match|}", "|Has match for 'Some123Content'|")]
+ [TestCase("{theKey:ismatch(^.+999.+$):|Has match for '{}'|\t|No match|}", "|No match|")]
+ public void Test_With_Changed_SplitChar(string format, string expected)
+ {
+ var variable = new Dictionary { {"theKey", "Some123Content"}};
+ var smart = Smart.CreateDefaultSmartFormat();
+ // Set SplitChar from | to TAB, so we can use | for the output string
+ smart.GetFormatterExtension()!.SplitChar = '\t';
+ var result = smart.Format(format, variable);
+ Assert.That(result, Is.EqualTo(expected));
}
[Test]
diff --git a/src/SmartFormat.Tests/Extensions/ListFormatterTests.cs b/src/SmartFormat.Tests/Extensions/ListFormatterTests.cs
index 8d07eecd..b830a431 100644
--- a/src/SmartFormat.Tests/Extensions/ListFormatterTests.cs
+++ b/src/SmartFormat.Tests/Extensions/ListFormatterTests.cs
@@ -38,6 +38,17 @@ public void Simple_List()
Assert.AreEqual("one, two, and three", result);
}
+ [Test]
+ public void Simple_List_Changed_SplitChar()
+ {
+ var smart = Smart.CreateDefaultSmartFormat();
+ // Set SplitChar from | to TAB, so we can use | for the output string
+ smart.GetFormatterExtension()!.SplitChar = '\t';
+ var items = new[] { "one", "two", "three" };
+ var result = smart.Format("{0:list:{}\t|\t|}", new object[] { items }); // important: not only "items" as the parameter
+ Assert.AreEqual("one|two|three", result);
+ }
+
[Test]
public void Empty_List()
{
diff --git a/src/SmartFormat.Tests/Extensions/PluralLocalizationFormatterTests.cs b/src/SmartFormat.Tests/Extensions/PluralLocalizationFormatterTests.cs
index 69d2597e..7a6e187c 100644
--- a/src/SmartFormat.Tests/Extensions/PluralLocalizationFormatterTests.cs
+++ b/src/SmartFormat.Tests/Extensions/PluralLocalizationFormatterTests.cs
@@ -278,5 +278,23 @@ public void Nested_PlaceHolders_Pluralization(int numOfPeople, string format, bo
Assert.That(result, numOfPeople == 1 ? Is.EqualTo("There is a person.") : Is.EqualTo("There are 2 people."));
}
+
+ [TestCase(1, "There {People.Count:plural:|is a person|.\t|are {} people|.}", "There |is a person|.")]
+ [TestCase(2, "There {People.Count:plural:|is a person|.\t|are {} people|.}", "There |are 2 people|.")]
+ public void Pluralization_With_Changed_SplitChar(int numOfPeople, string format, string expected)
+ {
+ var data = numOfPeople == 1
+ ? new {People = new List