diff --git a/grammar.go b/grammar.go index fdfa01b..fad5b7f 100644 --- a/grammar.go +++ b/grammar.go @@ -406,10 +406,17 @@ func Article(word string) string { if word == "" { return "" } - lower := core.Lower(core.Trim(word)) + trimmed := core.Trim(word) + lower := core.Lower(trimmed) if article, ok := articleForCurrentLanguage(lower, word); ok { return article } + if isInitialism(trimmed) { + if initialismUsesVowelSound(trimmed) { + return "an" + } + return "a" + } for key := range consonantSounds { if core.HasPrefix(lower, key) { return "a" @@ -487,10 +494,14 @@ func maybeElideArticle(article, word, lang string) string { } func usesVowelSoundArticle(word string) bool { - lower := core.Lower(core.Trim(word)) - if lower == "" { + trimmed := core.Trim(word) + if trimmed == "" { return false } + if isInitialism(trimmed) { + return initialismUsesVowelSound(trimmed) + } + lower := core.Lower(trimmed) for key := range consonantSounds { if core.HasPrefix(lower, key) { return false @@ -527,6 +538,35 @@ func isFrenchLanguage(lang string) bool { return lang == "fr" || core.HasPrefix(lang, "fr-") } +func isInitialism(word string) bool { + if len(word) < 2 { + return false + } + hasLetter := false + for _, r := range word { + if !unicode.IsLetter(r) { + return false + } + hasLetter = true + if unicode.IsLower(r) { + return false + } + } + return hasLetter +} + +func initialismUsesVowelSound(word string) bool { + if word == "" { + return false + } + switch unicode.ToUpper([]rune(word)[0]) { + case 'A', 'E', 'F', 'H', 'I', 'L', 'M', 'N', 'O', 'R', 'S', 'X': + return true + default: + return false + } +} + func isVowel(r rune) bool { switch unicode.ToLower(r) { case 'a', 'e', 'i', 'o', 'u': diff --git a/grammar_test.go b/grammar_test.go index e923379..14afdc2 100644 --- a/grammar_test.go +++ b/grammar_test.go @@ -270,6 +270,8 @@ func TestArticle(t *testing.T) { {"honest", "an"}, // Vowel sound {"university", "a"}, // Consonant sound {"one", "a"}, // Consonant sound + {"SSH", "an"}, // Initialism: "ess-ess-aitch" + {"URL", "a"}, // Initialism: "you-are-ell" {"", ""}, }