[agent/codex:gpt-5.4-mini] Read ~/spec/code/core/go/i18n/RFC.md fully. Find ONE feature... #115
2 changed files with 86 additions and 7 deletions
31
grammar.go
31
grammar.go
|
|
@ -190,7 +190,7 @@ func Upper(s string) string {
|
|||
}
|
||||
|
||||
func getVerbForm(lang, verb, form string) string {
|
||||
data := GetGrammarData(lang)
|
||||
data := grammarDataForLang(lang)
|
||||
if data == nil || data.Verbs == nil {
|
||||
return ""
|
||||
}
|
||||
|
|
@ -207,7 +207,7 @@ func getVerbForm(lang, verb, form string) string {
|
|||
}
|
||||
|
||||
func getWord(lang, word string) string {
|
||||
data := GetGrammarData(lang)
|
||||
data := grammarDataForLang(lang)
|
||||
if data == nil || data.Words == nil {
|
||||
return ""
|
||||
}
|
||||
|
|
@ -215,7 +215,7 @@ func getWord(lang, word string) string {
|
|||
}
|
||||
|
||||
func getPunct(lang, rule, defaultVal string) string {
|
||||
data := GetGrammarData(lang)
|
||||
data := grammarDataForLang(lang)
|
||||
if data == nil {
|
||||
return defaultVal
|
||||
}
|
||||
|
|
@ -233,7 +233,7 @@ func getPunct(lang, rule, defaultVal string) string {
|
|||
}
|
||||
|
||||
func getNounForm(lang, noun, form string) string {
|
||||
data := GetGrammarData(lang)
|
||||
data := grammarDataForLang(lang)
|
||||
if data == nil || data.Nouns == nil {
|
||||
return ""
|
||||
}
|
||||
|
|
@ -477,7 +477,7 @@ func Article(word string) string {
|
|||
|
||||
func articleForCurrentLanguage(lowerWord, originalWord string) (string, bool) {
|
||||
lang := currentLangForGrammar()
|
||||
data := GetGrammarData(lang)
|
||||
data := grammarDataForLang(lang)
|
||||
if data == nil {
|
||||
return "", false
|
||||
}
|
||||
|
|
@ -768,7 +768,7 @@ func DefiniteArticle(word string) string {
|
|||
return article
|
||||
}
|
||||
lang := currentLangForGrammar()
|
||||
data := GetGrammarData(lang)
|
||||
data := grammarDataForLang(lang)
|
||||
if data != nil && data.Articles.Definite != "" {
|
||||
return data.Articles.Definite
|
||||
}
|
||||
|
|
@ -794,7 +794,7 @@ func DefinitePhrase(word string) string {
|
|||
|
||||
func definiteArticleForCurrentLanguage(lowerWord, originalWord string) (string, bool) {
|
||||
lang := currentLangForGrammar()
|
||||
data := GetGrammarData(lang)
|
||||
data := grammarDataForLang(lang)
|
||||
if data == nil {
|
||||
return "", false
|
||||
}
|
||||
|
|
@ -807,6 +807,23 @@ func definiteArticleForCurrentLanguage(lowerWord, originalWord string) (string,
|
|||
return "", false
|
||||
}
|
||||
|
||||
func grammarDataForLang(lang string) *GrammarData {
|
||||
if data := GetGrammarData(lang); data != nil {
|
||||
return data
|
||||
}
|
||||
if base := baseLanguageTag(lang); base != "" {
|
||||
return GetGrammarData(base)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func baseLanguageTag(lang string) string {
|
||||
if idx := indexAny(lang, "-_"); idx > 0 {
|
||||
return lang[:idx]
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func definiteArticleFromGrammarForms(data *GrammarData, lowerWord, originalWord, lang string) (string, bool) {
|
||||
if data == nil || data.Articles.Definite == "" {
|
||||
return "", false
|
||||
|
|
|
|||
|
|
@ -7,6 +7,16 @@ import (
|
|||
"time"
|
||||
)
|
||||
|
||||
type regionFallbackLoader struct{}
|
||||
|
||||
func (regionFallbackLoader) Languages() []string {
|
||||
return []string{"en-GB"}
|
||||
}
|
||||
|
||||
func (regionFallbackLoader) Load(lang string) (map[string]Message, *GrammarData, error) {
|
||||
return map[string]Message{}, nil, nil
|
||||
}
|
||||
|
||||
func TestPastTense(t *testing.T) {
|
||||
// Ensure grammar data is loaded from embedded JSON
|
||||
svc, err := New()
|
||||
|
|
@ -933,6 +943,58 @@ func TestFrenchGrammarData(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestGrammarFallbackToBaseLanguageTag(t *testing.T) {
|
||||
prevDefault := Default()
|
||||
prevGrammar := GetGrammarData("en")
|
||||
t.Cleanup(func() {
|
||||
SetGrammarData("en", prevGrammar)
|
||||
SetDefault(prevDefault)
|
||||
})
|
||||
|
||||
SetGrammarData("en", &GrammarData{
|
||||
Verbs: map[string]VerbForms{
|
||||
"delete": {Past: "deleted", Gerund: "deleting"},
|
||||
},
|
||||
Nouns: map[string]NounForms{
|
||||
"file": {One: "file", Other: "files"},
|
||||
},
|
||||
Articles: ArticleForms{
|
||||
IndefiniteDefault: "a",
|
||||
IndefiniteVowel: "an",
|
||||
Definite: "the",
|
||||
},
|
||||
Punct: PunctuationRules{
|
||||
LabelSuffix: ":",
|
||||
ProgressSuffix: "...",
|
||||
},
|
||||
Words: map[string]string{
|
||||
"status": "Status",
|
||||
},
|
||||
})
|
||||
|
||||
svc, err := NewWithLoader(regionFallbackLoader{})
|
||||
if err != nil {
|
||||
t.Fatalf("NewWithLoader() failed: %v", err)
|
||||
}
|
||||
SetDefault(svc)
|
||||
if err := svc.SetLanguage("en-GB"); err != nil {
|
||||
t.Fatalf("SetLanguage(en-GB) failed: %v", err)
|
||||
}
|
||||
|
||||
if got := PastTense("delete"); got != "deleted" {
|
||||
t.Fatalf("PastTense(delete) = %q, want %q", got, "deleted")
|
||||
}
|
||||
if got := Pluralize("file", 2); got != "files" {
|
||||
t.Fatalf("Pluralize(file, 2) = %q, want %q", got, "files")
|
||||
}
|
||||
if got := Article("apple"); got != "an" {
|
||||
t.Fatalf("Article(apple) = %q, want %q", got, "an")
|
||||
}
|
||||
if got := Label("status"); got != "Status:" {
|
||||
t.Fatalf("Label(status) = %q, want %q", got, "Status:")
|
||||
}
|
||||
}
|
||||
|
||||
func TestTemplateFuncs(t *testing.T) {
|
||||
funcs := TemplateFuncs()
|
||||
expected := []string{
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue