Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
2b187d2
Add translatable interface
zeripath Jun 7, 2022
897f7aa
Add plural support using CLDR data
zeripath Jun 7, 2022
dc3d86f
Merge remote-tracking branch 'origin/main' into translation-improvements
zeripath Jun 27, 2022
6f1dde2
Merge remote-tracking branch 'origin' into translation-improvements
zeripath Jul 9, 2022
e30503e
reduce copying
zeripath Jul 9, 2022
4cca163
Merge remote-tracking branch 'origin' into translation-improvements
zeripath Jul 10, 2022
b26dcf0
use assign not :=
zeripath Jul 10, 2022
08cb842
update templates to use TrPlural
zeripath Jul 10, 2022
2fc923a
placate lint
zeripath Jul 10, 2022
cf0341f
placate lint 2
zeripath Jul 10, 2022
bf18312
Merge remote-tracking branch 'origin/main' into translation-improvements
zeripath Sep 1, 2022
09272c4
Use go templates instead.
zeripath Sep 1, 2022
928056d
placate lint
zeripath Sep 2, 2022
858b4cb
Merge remote-tracking branch 'origin/main' into translation-improvements
zeripath Sep 3, 2022
99f39aa
generate plural forms at time of locale reading
zeripath Sep 3, 2022
859d291
Merge branch 'main' into translation-improvements
zeripath Sep 3, 2022
492f0fc
Merge branch 'main' into translation-improvements
zeripath Sep 6, 2022
6f1dfb2
Merge branch 'main' into translation-improvements
zeripath Oct 5, 2022
18b8724
Merge branch 'main' into translation-improvements
zeripath Oct 7, 2022
eb28e9a
placate lint
zeripath Oct 8, 2022
62c37b3
Merge remote-tracking branch 'origin/main' into translation-improvements
zeripath Oct 8, 2022
4f023fa
also ensure generate creates a file that placates lint
zeripath Oct 8, 2022
f57e059
Merge branch 'main' into translation-improvements
zeripath Oct 10, 2022
9165c2d
Update options/locale/locale_en-US.ini
zeripath Oct 13, 2022
5ec920f
Merge remote-tracking branch 'origin/main' into translation-improvements
zeripath Oct 26, 2022
2e0e6a6
as per wxiaoguang
zeripath Oct 26, 2022
ed2e265
update docs
zeripath Oct 26, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
reduce copying
Signed-off-by: Andrew Thornton <[email protected]>
  • Loading branch information
zeripath committed Jul 9, 2022
commit e30503e83266df01e00c1b3b3aafea88561d8a0a
25 changes: 10 additions & 15 deletions modules/translation/i18n/i18n.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ type locale struct {
langName string

idxToMsgMap map[int]string // the map idx is generated by store's trKeyToIdxMap
pluralRules map[plurals.RuleType]*plurals.Rule

sourceFileName string
sourceFileInfo os.FileInfo
Expand All @@ -52,11 +51,10 @@ type LocaleStore struct {
trKeyToIdxMap map[string]int

defaultLang string
pluralRules plurals.Rules
}

func NewLocaleStore(isProd bool) *LocaleStore {
store := &LocaleStore{localeMap: make(map[string]*locale), trKeyToIdxMap: make(map[string]int), pluralRules: plurals.DefaultRules()}
store := &LocaleStore{localeMap: make(map[string]*locale), trKeyToIdxMap: make(map[string]int)}
if !isProd {
store.reloadMu = &sync.RWMutex{}
}
Expand Down Expand Up @@ -93,12 +91,6 @@ func (store *LocaleStore) AddLocaleByIni(langName, langDesc string, source inter
store.langNames = append(store.langNames, langName)
store.langDescs = append(store.langDescs, langDesc)

l.pluralRules = map[plurals.RuleType]*plurals.Rule{}
for typ, ruleMap := range store.pluralRules {
rule := ruleMap[l.langName]
l.pluralRules[typ] = rule
}

store.localeMap[l.langName] = l

return nil
Expand Down Expand Up @@ -328,22 +320,25 @@ func (l *locale) HasMessage(key string) bool {
}

func (l *locale) TrOrdinal(cnt interface{}, key string, args ...interface{}) string {
return l.TrPlurals(cnt, string(plurals.Ordinal), key, args...)
return l.trPlurals(cnt, plurals.DefaultRules.Ordinal(l.langName), key, args...)
}

func (l *locale) TrPlural(cnt interface{}, key string, args ...interface{}) string {
return l.TrPlurals(cnt, string(plurals.Cardinal), key, args...)
return l.trPlurals(cnt, plurals.DefaultRules.Rule(l.langName), key, args...)
}

func (l *locale) TrPlurals(cnt interface{}, ruleType, key string, args ...interface{}) string {
operands, err := plurals.NewOperands(cnt)
if err != nil {
return l.trPlurals(cnt, plurals.DefaultRules.RuleByType(plurals.RuleType(ruleType), l.langName), key, args...)
}

func (l *locale) trPlurals(cnt interface{}, rule *plurals.Rule, key string, args ...interface{}) string {
if rule == nil {
// if we fail to parse fall back to the standard
return l.Tr(key, args...)
}

rule := l.pluralRules[plurals.RuleType(ruleType)]
if rule == nil {
operands, err := plurals.NewOperands(cnt)
if err != nil {
// if we fail to parse fall back to the standard
return l.Tr(key, args...)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import (
"strings"
)

// As noted above relation is a lot simpler than the original full rules imply:
// As noted below relation is a lot simpler than the original full rules imply:
//
// relation = expr ('=' | '!=') range_list
// expr = operand ('%' value)?
Expand Down
9 changes: 5 additions & 4 deletions modules/translation/i18n/plurals/generate/main/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,11 +120,13 @@ var codeTemplate = template.Must(template.New("codeTemplate").Parse(`// This fil
package plurals

// DefaultRules returns a map of Rules generated from CLDR language data.
func DefaultRules() Rules {
rules := Rules{}
var DefaultRules *Rules

func init() {
DefaultRules := &Rules{}
{{range $p, $plurals := .Plurals}}
{{range .LocaleGroups}}
addPluralRules(rules, {{printf "%q" $plurals.Type}}, {{printf "%#v" .SplitLocales}}, &Rule{
addPluralRules(DefaultRules, {{printf "%q" $plurals.Type}}, {{printf "%#v" .SplitLocales}}, &Rule{
PluralForms: newPluralFormSet({{range $i, $e := .Rules}}{{if $i}}, {{end}}{{$e.CountTitle}}{{end}}),
PluralFormFunc: func(ops *Operands) Form { {{range .Rules}}{{if .GoCondition}}
// {{.Condition}}
Expand All @@ -135,7 +137,6 @@ func DefaultRules() Rules {
},
}){{end}}
{{end}}
return rules
}
`))

Expand Down
2 changes: 1 addition & 1 deletion modules/translation/i18n/plurals/rule_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ func runTests(t *testing.T, pluralRuleID, typ string, tests []pluralFormTest) {
if pluralRuleID == "root" {
return
}
pluralRules := DefaultRules()
pluralRules := DefaultRules
if rule := pluralRules.RuleByType(RuleType(typ), pluralRuleID); rule != nil {
for _, test := range tests {
ops, err := NewOperands(test.num)
Expand Down
59 changes: 50 additions & 9 deletions modules/translation/i18n/plurals/rules.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,31 @@ type Rule struct {
PluralFormFunc func(*Operands) Form
}

func addPluralRules(rules Rules, typ RuleType, ids []string, ps *Rule) {
func addPluralRules(rules *Rules, typ RuleType, ids []string, ps *Rule) {
for _, id := range ids {
if id == "root" {
continue
}
if rules[typ] == nil {
rules[typ] = map[string]*Rule{}
switch typ {
case Cardinal:
if rules.CardinalMap == nil {
rules.CardinalMap = map[string]*Rule{}
}
rules.CardinalMap[id] = ps
case Ordinal:
if rules.OrdinalMap == nil {
rules.OrdinalMap = map[string]*Rule{}
}
rules.OrdinalMap[id] = ps
default:
if rules.Others == nil {
rules.Others = map[RuleType]map[string]*Rule{}
}
if rules.Others[typ] == nil {
rules.Others[typ] = map[string]*Rule{}
}
rules.Others[typ][id] = ps
}
rules[typ][id] = ps
}
}

Expand All @@ -45,18 +61,37 @@ func newPluralFormSet(pluralForms ...Form) map[Form]struct{} {
return set
}

type Rules map[RuleType]map[string]*Rule
type Rules struct {
CardinalMap map[string]*Rule
OrdinalMap map[string]*Rule
Others map[RuleType]map[string]*Rule
}

// Rule returns the closest matching plural rule for the language tag
// or nil if no rule could be found.
func (r Rules) Rule(locale string) *Rule {
for {
if rule, ok := r["cardinal"][locale]; ok {
if rule, ok := r.CardinalMap[locale]; ok {
return rule
}
idx := strings.LastIndex(locale, "-")
if idx < 0 {
return r.CardinalMap["en"]
}
locale = locale[:idx]
}
}

// Rule returns the closest matching plural rule for the language tag
// or nil if no rule could be found.
func (r Rules) Ordinal(locale string) *Rule {
for {
if rule, ok := r.OrdinalMap[locale]; ok {
return rule
}
idx := strings.LastIndex(locale, "-")
if idx < 0 {
return r["cardinal"]["en"]
return r.OrdinalMap["en"]
}
locale = locale[:idx]
}
Expand All @@ -65,13 +100,19 @@ func (r Rules) Rule(locale string) *Rule {
// Rule returns the closest matching plural rule for the language tag
// or nil if no rule could be found.
func (r Rules) RuleByType(typ RuleType, locale string) *Rule {
switch typ {
case Cardinal:
return r.Rule(locale)
case Ordinal:
return r.Ordinal(locale)
}
for {
if rule, ok := r[typ][locale]; ok {
if rule, ok := r.Others[typ][locale]; ok {
return rule
}
idx := strings.LastIndex(locale, "-")
if idx < 0 {
return r[typ]["en"]
return r.Others[typ]["en"]
}
locale = locale[:idx]
}
Expand Down
Loading