diff --git a/release_notes.md b/release_notes.md index 4c5e1993b..56c670e5a 100644 --- a/release_notes.md +++ b/release_notes.md @@ -1,7 +1,9 @@ ###In Development + - [#285](https://github.com/Mehdik/Humanizer/pull/285): Localised ToQuantity and added FarsiQuantifier - [#277](https://github.com/MehdiK/Humanizer/pull/277): Added support for custom enum description attribute property names - [#276](https://github.com/Mehdik/Humanizer/pull/276): Added Farsi ToOrdinalWords + [Commits](https://github.com/MehdiK/Humanizer/compare/v1.26.1...master) ###v1.26.1 - 2014-05-20 diff --git a/src/Humanizer.Tests/ApiApprover/PublicApiApprovalTest.approve_public_api.approved.txt b/src/Humanizer.Tests/ApiApprover/PublicApiApprovalTest.approve_public_api.approved.txt index f1381d093..63ec25df9 100644 --- a/src/Humanizer.Tests/ApiApprover/PublicApiApprovalTest.approve_public_api.approved.txt +++ b/src/Humanizer.Tests/ApiApprover/PublicApiApprovalTest.approve_public_api.approved.txt @@ -79,6 +79,7 @@ public class Configurator public Humanizer.Configuration.LocaliserRegistry Formatters { get; } public Humanizer.Configuration.LocaliserRegistry NumberToWordsConverters { get; } public Humanizer.Configuration.LocaliserRegistry Ordinalizers { get; } + public Humanizer.Configuration.LocaliserRegistry Quantifiers { get; } } public class LocaliserRegistry`1 @@ -243,6 +244,11 @@ public interface IOrdinalizer string Convert(int number, string numberString, Humanizer.GrammaticalGender gender); } +public interface IQuantifier +{ + string ToQuantity(string input, int quantity, Humanizer.ShowQuantityAs showQuantityAs, string format, System.IFormatProvider formatProvider); +} + public class ResourceKeys { public ResourceKeys() { } diff --git a/src/Humanizer.Tests/Humanizer.Tests.csproj b/src/Humanizer.Tests/Humanizer.Tests.csproj index c206f8c2b..3aa19f3f0 100644 --- a/src/Humanizer.Tests/Humanizer.Tests.csproj +++ b/src/Humanizer.Tests/Humanizer.Tests.csproj @@ -73,6 +73,7 @@ + diff --git a/src/Humanizer.Tests/Localisation/fa/ToQuantityTests.cs b/src/Humanizer.Tests/Localisation/fa/ToQuantityTests.cs new file mode 100644 index 000000000..1b021c063 --- /dev/null +++ b/src/Humanizer.Tests/Localisation/fa/ToQuantityTests.cs @@ -0,0 +1,47 @@ +using Xunit; +using Xunit.Extensions; + +namespace Humanizer.Tests.Localisation.fa +{ + public class ToQuantityTests : AmbientCulture + { + public ToQuantityTests() + : base("fa") { } + + [Theory] + [InlineData("مرد", 0, "0 مرد")] + [InlineData("مرد", 1, "1 مرد")] + [InlineData("مرد", 5, "5 مرد")] + public void ToQuantity(string word, int quatity, string expected) + { + Assert.Equal(expected, word.ToQuantity(quatity)); + } + + [Theory] + [InlineData("مرد", 0, "مرد")] + [InlineData("مرد", 1, "مرد")] + [InlineData("مرد", 5, "مرد ها")] + public void ToQuantityWithNoQuantity(string word, int quatity, string expected) + { + Assert.Equal(expected, word.ToQuantity(quatity, ShowQuantityAs.None)); + } + + [Theory] + [InlineData("مرد", 0, "0 مرد")] + [InlineData("مرد", 1, "1 مرد")] + [InlineData("مرد", 5, "5 مرد")] + public void ToQuantityNumeric(string word, int quatity, string expected) + { + Assert.Equal(expected, word.ToQuantity(quatity, ShowQuantityAs.Numeric)); + } + + [Theory] + [InlineData("مرد", 2, "دو مرد")] + [InlineData("مرد", 1, "یک مرد")] + [InlineData("مرد", 1200, "یک هزار و دویست مرد")] + public void ToQuantityWords(string word, int quatity, string expected) + { + Assert.Equal(expected, word.ToQuantity(quatity, ShowQuantityAs.Words)); + } + } +} diff --git a/src/Humanizer/Configuration/Configurator.cs b/src/Humanizer/Configuration/Configurator.cs index af94e3c22..e79b4f57b 100644 --- a/src/Humanizer/Configuration/Configurator.cs +++ b/src/Humanizer/Configuration/Configurator.cs @@ -6,6 +6,7 @@ using Humanizer.Localisation.NumberToWords; using Humanizer.Localisation.Ordinalizers; using Humanizer.Localisation.CollectionFormatters; +using Humanizer.Localisation.Quantifiers; namespace Humanizer.Configuration { @@ -51,6 +52,16 @@ public static LocaliserRegistry Ordinalizers get { return _ordinalizers; } } + private static readonly LocaliserRegistry _quantifiers = new QuantifierRegistry(); + + /// + /// A registry of quantifiers used to localise ToQuantity method + /// + public static LocaliserRegistry Quantifiers + { + get { return _quantifiers; } + } + internal static ICollectionFormatter CollectionFormatter { get @@ -58,7 +69,7 @@ internal static ICollectionFormatter CollectionFormatter return CollectionFormatters.ResolveForUiCulture(); } } - + /// /// The formatter to be used /// @@ -92,6 +103,17 @@ internal static IOrdinalizer Ordinalizer } } + /// + /// The quantifier to be used + /// + internal static IQuantifier Quantifier + { + get + { + return Quantifiers.ResolveForUiCulture(); + } + } + private static IDateTimeHumanizeStrategy _dateTimeHumanizeStrategy = new DefaultDateTimeHumanizeStrategy(); /// /// The strategy to be used for DateTime.Humanize diff --git a/src/Humanizer/Configuration/QuantifierRegistry.cs b/src/Humanizer/Configuration/QuantifierRegistry.cs new file mode 100644 index 000000000..ca71e1539 --- /dev/null +++ b/src/Humanizer/Configuration/QuantifierRegistry.cs @@ -0,0 +1,17 @@ +using Humanizer.Localisation.Quantifiers; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Humanizer.Configuration +{ + internal class QuantifierRegistry : LocaliserRegistry + { + public QuantifierRegistry() + :base(new DefaultQuantifier()) + { + Register("fa"); + } + } +} diff --git a/src/Humanizer/Humanizer.csproj b/src/Humanizer/Humanizer.csproj index 9a584436d..b608b00db 100644 --- a/src/Humanizer/Humanizer.csproj +++ b/src/Humanizer/Humanizer.csproj @@ -51,6 +51,7 @@ + @@ -94,6 +95,9 @@ + + + diff --git a/src/Humanizer/Localisation/Quantifiers/DefaultQuantifier.cs b/src/Humanizer/Localisation/Quantifiers/DefaultQuantifier.cs new file mode 100644 index 000000000..37f88b120 --- /dev/null +++ b/src/Humanizer/Localisation/Quantifiers/DefaultQuantifier.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Humanizer.Localisation.Quantifiers +{ + internal class DefaultQuantifier : IQuantifier + { + public string ToQuantity(string input, int quantity, ShowQuantityAs showQuantityAs = ShowQuantityAs.Numeric, string format = null, IFormatProvider formatProvider = null) + { + var transformedInput = TransformInput(input, quantity, showQuantityAs); + + if (showQuantityAs == ShowQuantityAs.None) + return transformedInput; + + if (showQuantityAs == ShowQuantityAs.Numeric) + return string.Format(formatProvider, "{0} {1}", quantity.ToString(format, formatProvider), transformedInput); + + return string.Format("{0} {1}", quantity.ToWords(), transformedInput); + } + + protected virtual string TransformInput(string input, int quantity, ShowQuantityAs showQuantityAs) + { + return quantity == 1 + ? input.Singularize(Plurality.CouldBeEither) + : input.Pluralize(Plurality.CouldBeEither); + + } + } +} diff --git a/src/Humanizer/Localisation/Quantifiers/FarsiQuantifier.cs b/src/Humanizer/Localisation/Quantifiers/FarsiQuantifier.cs new file mode 100644 index 000000000..9450f1bbf --- /dev/null +++ b/src/Humanizer/Localisation/Quantifiers/FarsiQuantifier.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Humanizer.Localisation.Quantifiers +{ + internal class FarsiQuantifier : DefaultQuantifier + { + protected override string TransformInput(string input, int quantity, ShowQuantityAs showQuantityAs) + { + //TODO: Use singularize and pluralize for Farsi + string postFix = string.Empty; + + if (showQuantityAs == ShowQuantityAs.None && quantity > 1) + { + postFix = " ها"; + } + + return string.Format("{0}{1}", input, postFix); + } + } +} diff --git a/src/Humanizer/Localisation/Quantifiers/IQuantifier.cs b/src/Humanizer/Localisation/Quantifiers/IQuantifier.cs new file mode 100644 index 000000000..a2e71f538 --- /dev/null +++ b/src/Humanizer/Localisation/Quantifiers/IQuantifier.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Humanizer.Localisation.Quantifiers +{ + /// + /// The interface used to localise the ToQuantity method + /// + public interface IQuantifier + { + /// + /// Convert input to quantity + /// + /// + /// + /// + /// + /// + /// + string ToQuantity(string input, int quantity, ShowQuantityAs showQuantityAs, string format, IFormatProvider formatProvider); + } +} diff --git a/src/Humanizer/Localisation/ResourceKeys.DateHumanize.cs b/src/Humanizer/Localisation/ResourceKeys.DateHumanize.cs index ee91374f9..edb840ce1 100644 --- a/src/Humanizer/Localisation/ResourceKeys.DateHumanize.cs +++ b/src/Humanizer/Localisation/ResourceKeys.DateHumanize.cs @@ -1,4 +1,6 @@ -namespace Humanizer.Localisation +using Humanizer.Configuration; +using Humanizer.Localisation.Quantifiers; +namespace Humanizer.Localisation { public partial class ResourceKeys { @@ -37,7 +39,7 @@ public static string GetResourceKey(TimeUnit timeUnit, Tense timeUnitTense, int var singularity = count == 1 ? Single : Multiple; var tense = timeUnitTense == Tense.Future ? FromNow : Ago; - var unit = timeUnit.ToString().ToQuantity(count, ShowQuantityAs.None); + var unit = new DefaultQuantifier().ToQuantity(timeUnit.ToString(), count, ShowQuantityAs.None); return DateTimeFormat.FormatWith(singularity, unit, tense); } } diff --git a/src/Humanizer/ToQuantityExtensions.cs b/src/Humanizer/ToQuantityExtensions.cs index 12e844237..e02458a63 100644 --- a/src/Humanizer/ToQuantityExtensions.cs +++ b/src/Humanizer/ToQuantityExtensions.cs @@ -1,4 +1,5 @@ -using System; +using Humanizer.Configuration; +using System; namespace Humanizer { /// @@ -46,7 +47,7 @@ public static class ToQuantityExtensions /// public static string ToQuantity(this string input, int quantity, ShowQuantityAs showQuantityAs = ShowQuantityAs.Numeric) { - return input.ToQuantity(quantity, showQuantityAs, format: null, formatProvider: null); + return Configurator.Quantifier.ToQuantity(input, quantity, showQuantityAs, null, null); } /// @@ -64,22 +65,8 @@ public static string ToQuantity(this string input, int quantity, ShowQuantityAs /// public static string ToQuantity(this string input, int quantity, string format, IFormatProvider formatProvider = null) { - return input.ToQuantity(quantity, showQuantityAs: ShowQuantityAs.Numeric, format: format, formatProvider: formatProvider); + return Configurator.Quantifier.ToQuantity(input, quantity, ShowQuantityAs.Numeric, format, formatProvider); } - private static string ToQuantity(this string input, int quantity, ShowQuantityAs showQuantityAs = ShowQuantityAs.Numeric, string format = null, IFormatProvider formatProvider = null) - { - var transformedInput = quantity == 1 - ? input.Singularize(Plurality.CouldBeEither) - : input.Pluralize(Plurality.CouldBeEither); - - if (showQuantityAs == ShowQuantityAs.None) - return transformedInput; - - if (showQuantityAs == ShowQuantityAs.Numeric) - return string.Format(formatProvider, "{0} {1}", quantity.ToString(format, formatProvider), transformedInput); - - return string.Format("{0} {1}", quantity.ToWords(), transformedInput); - } } }