decred.org/dcrdex@v1.0.5/client/intl/intl.go (about) 1 // This code is available on the terms of the project LICENSE.md file, 2 // also available online at https://blueoakcouncil.org/license/1.0.0. 3 4 package intl 5 6 const defaultLanguage = "en-US" 7 8 // Trasnlation is a versioned localized string. Notes added to the english 9 // translation will be presented to human translators. 10 type Translation struct { 11 Version int 12 T string 13 Notes string // english only 14 } 15 16 var translations = map[string] /* lang */ map[string] /* caller ID */ map[string] /* translation ID */ *Translation{} 17 18 // Registrar is used for registering translations for a specific language and 19 // caller context. 20 type Registrar struct { 21 callerID string 22 lang string 23 m map[string]*Translation 24 } 25 26 // NewRegistrar constructs a Registrar. 27 func NewRegistrar(callerID string, lang string, preAlloc int) *Registrar { 28 callers, found := translations[lang] 29 if !found { 30 callers = make(map[string]map[string]*Translation) 31 translations[lang] = callers 32 } 33 m := make(map[string]*Translation, preAlloc) 34 callers[callerID] = m 35 return &Registrar{ 36 callerID: callerID, 37 lang: lang, 38 m: m, 39 } 40 } 41 42 // Register registers a translation. 43 func (r *Registrar) Register(translationID string, t *Translation) { 44 r.m[translationID] = t 45 } 46 47 // TranslationReport is a report of missing and extraneous translations. 48 type TranslationReport struct { 49 Missing map[string] /* caller ID */ map[string]*Translation // English translation 50 Extras []string /* caller ID */ 51 } 52 53 // Report generates a TranslationReport for each registered language. 54 func Report() map[string] /* lang */ *TranslationReport { 55 reports := make(map[string]*TranslationReport) 56 57 for lang := range translations { 58 if lang == defaultLanguage { 59 continue 60 } 61 reports[lang] = &TranslationReport{ 62 Missing: make(map[string]map[string]*Translation), 63 } 64 } 65 enUS := translations[defaultLanguage] 66 for callerID, enTranslations := range enUS { 67 for lang, callers := range translations { 68 if lang == defaultLanguage { 69 continue 70 } 71 r := reports[lang] 72 ts := callers[callerID] 73 if ts == nil { 74 ts = make(map[string]*Translation) 75 } 76 missing := r.Missing[callerID] 77 if missing == nil { 78 missing = make(map[string]*Translation) 79 r.Missing[callerID] = missing 80 } 81 for translationID, enTranslation := range enTranslations { 82 t := ts[translationID] 83 if t == nil || t.Version < enTranslation.Version { 84 missing[translationID] = enTranslation 85 } 86 } 87 } 88 } 89 90 for lang, callers := range translations { 91 if lang == defaultLanguage { 92 continue 93 } 94 r := reports[lang] 95 for callerID, ts := range callers { 96 enTranslations := enUS[callerID] 97 for translationID := range ts { 98 if enTranslations[translationID] == nil { 99 r.Extras = append(r.Extras, callerID+" -> "+translationID) 100 } 101 } 102 } 103 } 104 105 return reports 106 }