Move flatten and flattenWithGrammar functions to dedicated file. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
133 lines
3.7 KiB
Go
133 lines
3.7 KiB
Go
// Package i18n provides internationalization for the CLI.
|
|
package i18n
|
|
|
|
import "strings"
|
|
|
|
// flatten recursively flattens nested maps into dot-notation keys.
|
|
func flatten(prefix string, data map[string]any, out map[string]Message) {
|
|
flattenWithGrammar(prefix, data, out, nil)
|
|
}
|
|
|
|
// flattenWithGrammar recursively flattens nested maps and extracts grammar data.
|
|
func flattenWithGrammar(prefix string, data map[string]any, out map[string]Message, grammar *GrammarData) {
|
|
for key, value := range data {
|
|
fullKey := key
|
|
if prefix != "" {
|
|
fullKey = prefix + "." + key
|
|
}
|
|
|
|
switch v := value.(type) {
|
|
case string:
|
|
out[fullKey] = Message{Text: v}
|
|
|
|
case map[string]any:
|
|
// Check if this is a verb form object
|
|
// Grammar data lives under "gram.*" (a nod to Gram - grandmother)
|
|
if grammar != nil && isVerbFormObject(v) {
|
|
verbName := key
|
|
if strings.HasPrefix(fullKey, "gram.verb.") {
|
|
verbName = strings.TrimPrefix(fullKey, "gram.verb.")
|
|
}
|
|
forms := VerbForms{}
|
|
if base, ok := v["base"].(string); ok {
|
|
_ = base // base form stored but not used in VerbForms
|
|
}
|
|
if past, ok := v["past"].(string); ok {
|
|
forms.Past = past
|
|
}
|
|
if gerund, ok := v["gerund"].(string); ok {
|
|
forms.Gerund = gerund
|
|
}
|
|
grammar.Verbs[strings.ToLower(verbName)] = forms
|
|
continue
|
|
}
|
|
|
|
// Check if this is a noun form object
|
|
if grammar != nil && isNounFormObject(v) {
|
|
nounName := key
|
|
if strings.HasPrefix(fullKey, "gram.noun.") {
|
|
nounName = strings.TrimPrefix(fullKey, "gram.noun.")
|
|
}
|
|
forms := NounForms{}
|
|
if one, ok := v["one"].(string); ok {
|
|
forms.One = one
|
|
}
|
|
if other, ok := v["other"].(string); ok {
|
|
forms.Other = other
|
|
}
|
|
if gender, ok := v["gender"].(string); ok {
|
|
forms.Gender = gender
|
|
}
|
|
grammar.Nouns[strings.ToLower(nounName)] = forms
|
|
continue
|
|
}
|
|
|
|
// Check if this is an article object
|
|
if grammar != nil && fullKey == "gram.article" {
|
|
if indef, ok := v["indefinite"].(map[string]any); ok {
|
|
if def, ok := indef["default"].(string); ok {
|
|
grammar.Articles.IndefiniteDefault = def
|
|
}
|
|
if vowel, ok := indef["vowel"].(string); ok {
|
|
grammar.Articles.IndefiniteVowel = vowel
|
|
}
|
|
}
|
|
if def, ok := v["definite"].(string); ok {
|
|
grammar.Articles.Definite = def
|
|
}
|
|
continue
|
|
}
|
|
|
|
// Check if this is a punctuation rules object
|
|
if grammar != nil && fullKey == "gram.punct" {
|
|
if label, ok := v["label"].(string); ok {
|
|
grammar.Punct.LabelSuffix = label
|
|
}
|
|
if progress, ok := v["progress"].(string); ok {
|
|
grammar.Punct.ProgressSuffix = progress
|
|
}
|
|
continue
|
|
}
|
|
|
|
// Check if this is a base word in gram.word.*
|
|
if grammar != nil && strings.HasPrefix(fullKey, "gram.word.") {
|
|
wordKey := strings.TrimPrefix(fullKey, "gram.word.")
|
|
// v could be a string or a nested object
|
|
if str, ok := value.(string); ok {
|
|
if grammar.Words == nil {
|
|
grammar.Words = make(map[string]string)
|
|
}
|
|
grammar.Words[strings.ToLower(wordKey)] = str
|
|
}
|
|
continue
|
|
}
|
|
|
|
// Check if this is a plural object (has CLDR plural category keys)
|
|
if isPluralObject(v) {
|
|
msg := Message{}
|
|
if zero, ok := v["zero"].(string); ok {
|
|
msg.Zero = zero
|
|
}
|
|
if one, ok := v["one"].(string); ok {
|
|
msg.One = one
|
|
}
|
|
if two, ok := v["two"].(string); ok {
|
|
msg.Two = two
|
|
}
|
|
if few, ok := v["few"].(string); ok {
|
|
msg.Few = few
|
|
}
|
|
if many, ok := v["many"].(string); ok {
|
|
msg.Many = many
|
|
}
|
|
if other, ok := v["other"].(string); ok {
|
|
msg.Other = other
|
|
}
|
|
out[fullKey] = msg
|
|
} else {
|
|
// Recurse into nested object
|
|
flattenWithGrammar(fullKey, v, out, grammar)
|
|
}
|
|
}
|
|
}
|
|
}
|