From 54490260417cfff29195d388bd2928d7cf7c82e1 Mon Sep 17 00:00:00 2001 From: Virgil Date: Thu, 2 Apr 2026 05:10:36 +0000 Subject: [PATCH] Fix unicode capitalization in plural forms --- grammar.go | 31 +++++++++++++++++++------------ grammar_test.go | 27 +++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 12 deletions(-) diff --git a/grammar.go b/grammar.go index cd91bec..fe85c22 100644 --- a/grammar.go +++ b/grammar.go @@ -371,10 +371,7 @@ func Pluralize(noun string, count int) string { } lower := core.Lower(noun) if form := getNounForm(currentLangForGrammar(), lower, "one"); form != "" { - if unicode.IsUpper(rune(noun[0])) && len(form) > 0 { - return core.Upper(string(form[0])) + form[1:] - } - return form + return preserveInitialCapitalization(noun, form) } return noun } @@ -389,16 +386,10 @@ func PluralForm(noun string) string { } lower := core.Lower(noun) if form := getNounForm(currentLangForGrammar(), lower, "other"); form != "" { - if unicode.IsUpper(rune(noun[0])) && len(form) > 0 { - return core.Upper(string(form[0])) + form[1:] - } - return form + return preserveInitialCapitalization(noun, form) } if plural, ok := irregularNouns[lower]; ok { - if unicode.IsUpper(rune(noun[0])) { - return core.Upper(string(plural[0])) + plural[1:] - } - return plural + return preserveInitialCapitalization(noun, plural) } return applyRegularPlural(noun) } @@ -675,6 +666,22 @@ func isInitialism(word string) bool { return hasLetter } +func preserveInitialCapitalization(original, form string) string { + if original == "" || form == "" { + return form + } + originalRunes := []rune(original) + formRunes := []rune(form) + if len(originalRunes) == 0 || len(formRunes) == 0 { + return form + } + if !unicode.IsUpper(originalRunes[0]) { + return form + } + formRunes[0] = unicode.ToUpper(formRunes[0]) + return string(formRunes) +} + func initialismUsesVowelSound(word string) bool { if word == "" { return false diff --git a/grammar_test.go b/grammar_test.go index 50af1f3..99e9a3e 100644 --- a/grammar_test.go +++ b/grammar_test.go @@ -263,6 +263,33 @@ func TestPluralize_UsesLocaleSingularOverride(t *testing.T) { } } +func TestPluralize_PreservesUnicodeCapitalization(t *testing.T) { + prev := Default() + t.Cleanup(func() { + SetDefault(prev) + }) + + svc, err := New() + if err != nil { + t.Fatalf("New() failed: %v", err) + } + SetDefault(svc) + + if err := SetLanguage("fr"); err != nil { + t.Fatalf("SetLanguage(fr) failed: %v", err) + } + + if got, want := Pluralize("Élément", 1), "Élément"; got != want { + t.Fatalf("Pluralize(%q, 1) = %q, want %q", "Élément", got, want) + } + if got, want := Pluralize("Élément", 2), "Éléments"; got != want { + t.Fatalf("Pluralize(%q, 2) = %q, want %q", "Élément", got, want) + } + if got, want := PluralForm("Élément"), "Éléments"; got != want { + t.Fatalf("PluralForm(%q) = %q, want %q", "Élément", got, want) + } +} + func TestPluralForm(t *testing.T) { svc, err := New() if err != nil { -- 2.45.3