What's wrong
ToTitleCase (CaseConverter/CaseConverter.cs, around line 204) runs SplitOnCaseChange directly on the input. Unlike ToPascalCase and ToMacroCase, it doesn't first replace non-alphanumerics. SplitOnCaseChange treats letter → non-letter as a word boundary (around line 121), so it inserts a space before every punctuation mark. TextInfo.ToTitleCase then sees the punctuation as the start of a new word and capitalises the letter after it.
The README describes ToTitleCase as "Each Word Capitalized", and ordinary prose is its natural input. The existing tests use only space-separated letters, so this isn't caught.
Reproduced
[TestMethod] public void TitleComma() => Assert.AreEqual("Hello, World", "hello, world".ToTitleCase());
[TestMethod] public void TitleApostrophe() => Assert.AreEqual("Don't Stop", "don't stop".ToTitleCase());
[TestMethod] public void TitleUnderscore() => Assert.AreEqual("Foo Bar", "foo_bar".ToTitleCase());
| Input |
Expected |
Actual |
hello, world |
Hello, World |
Hello , World |
don't stop |
Don't Stop |
Don 'T Stop |
foo_bar |
Foo Bar |
Foo _Bar |
Titles such as "Rock 'N' Roll", "What's New?", or "Part 1: Setup" all come out mangled.
Suggested fix
In the ToTitleCase path, split only on case transitions (lower → upper, acronym → word) and on letter ↔ digit, not on letter → punctuation. One way is a parameter or a separate helper on SplitOnCaseChange. If _ and - should act as word separators in title case, map them to spaces explicitly. Keep ToPascalCase working: it calls ToTitleCase after ReplaceNonAlphaNumericWithSpace, so it shouldn't be affected. Its tests should keep passing.
Acceptance: the three tests above pass, and the existing TitleCase and PascalCase tests are unchanged.
What's wrong
ToTitleCase(CaseConverter/CaseConverter.cs, around line 204) runsSplitOnCaseChangedirectly on the input. UnlikeToPascalCaseandToMacroCase, it doesn't first replace non-alphanumerics.SplitOnCaseChangetreats letter → non-letter as a word boundary (around line 121), so it inserts a space before every punctuation mark.TextInfo.ToTitleCasethen sees the punctuation as the start of a new word and capitalises the letter after it.The README describes
ToTitleCaseas "Each Word Capitalized", and ordinary prose is its natural input. The existing tests use only space-separated letters, so this isn't caught.Reproduced
hello, worldHello, WorldHello , Worlddon't stopDon't StopDon 'T Stopfoo_barFoo BarFoo _BarTitles such as "Rock 'N' Roll", "What's New?", or "Part 1: Setup" all come out mangled.
Suggested fix
In the
ToTitleCasepath, split only on case transitions (lower → upper, acronym → word) and on letter ↔ digit, not on letter → punctuation. One way is a parameter or a separate helper onSplitOnCaseChange. If_and-should act as word separators in title case, map them to spaces explicitly. KeepToPascalCaseworking: it callsToTitleCaseafterReplaceNonAlphaNumericWithSpace, so it shouldn't be affected. Its tests should keep passing.Acceptance: the three tests above pass, and the existing TitleCase and PascalCase tests are unchanged.