diff --git a/src/Humanizer.Tests/TransformersTests.cs b/src/Humanizer.Tests/TransformersTests.cs index a93992c33..6ffe4b159 100644 --- a/src/Humanizer.Tests/TransformersTests.cs +++ b/src/Humanizer.Tests/TransformersTests.cs @@ -34,4 +34,12 @@ public void TransformToSentenceCase(string input, string expectedOutput) => [InlineData("Title Case", "TITLE CASE")] public void TransformToUpperCase(string input, string expectedOutput) => Assert.Equal(expectedOutput, input.Transform(To.UpperCase)); + + [Theory] + [InlineData("a great article", "A Great Article")] + [InlineData("yet another conjunction", "Yet Another Conjunction")] + [InlineData("by this preposition", "By This Preposition")] + [InlineData("NASA and the future", "NASA and the Future")] + public void TransformToTitleCase_FirstWordExceptions(string input, string expectedOutput) => + Assert.Equal(expectedOutput, input.Transform(To.TitleCase)); } \ No newline at end of file diff --git a/src/Humanizer/Transformer/ToTitleCase.cs b/src/Humanizer/Transformer/ToTitleCase.cs index df506d9ea..477354600 100644 --- a/src/Humanizer/Transformer/ToTitleCase.cs +++ b/src/Humanizer/Transformer/ToTitleCase.cs @@ -10,7 +10,7 @@ public string Transform(string input) => #if NET7_0_OR_GREATER [GeneratedRegex(WordPattern)] private static partial Regex WordRegexGenerated(); - + private static Regex WordRegex() => WordRegexGenerated(); #else private static readonly Regex WordRegexDefinition = new(WordPattern, RegexOptions.Compiled); @@ -23,10 +23,19 @@ public string Transform(string input, CultureInfo culture) var matches = WordRegex().Matches(input); var builder = new StringBuilder(input); var textInfo = culture.TextInfo; + var isFirstWord = true; + foreach (Match word in matches) { var value = word.Value; - if (AllCapitals(value) || IsArticleOrConjunctionOrPreposition(value)) + var currentIsFirst = isFirstWord; + isFirstWord = false; + + if (AllCapitals(value)) + { + continue; + } + if (!currentIsFirst && IsArticleOrConjunctionOrPreposition(value)) { continue; }