func formatForLang(t language.Tag, index []byte) *Format { for ; ; t = t.Parent() { if x, ok := language.CompactIndex(t); ok { return &formats[index[x]] } } }
func (p *I18n) set(lng *language.Tag, code, message string) { lang := lng.String() if _, ok := p.Locales[lang]; !ok { p.Locales[lang] = make(map[string]string) } p.Locales[lang][code] = message }
// Translate one or more strings of text from a source language to a target // language. All inputs must be in the same language. // // The target parameter supplies the language to translate to. The supported // languages are listed at // https://cloud.google.com/translate/v2/translate-reference#supported_languages. // You can also call the SupportedLanguages method. // // The returned Translations appear in the same order as the inputs. func (c *Client) Translate(ctx context.Context, inputs []string, target language.Tag, opts *Options) ([]Translation, error) { call := c.raw.Translations.List(inputs, target.String()).Context(ctx) if opts != nil { if s := opts.Source; s != language.Und { call.Source(s.String()) } if f := opts.Format; f != "" { call.Format(string(f)) } if m := opts.Model; m != "" { call.Model(m) } } res, err := call.Do() if err != nil { return nil, err } var ts []Translation for _, t := range res.Translations { var source language.Tag if t.DetectedSourceLanguage != "" { source, err = language.Parse(t.DetectedSourceLanguage) if err != nil { return nil, err } } ts = append(ts, Translation{ Text: t.TranslatedText, Source: source, Model: t.Model, }) } return ts, nil }
// InfoFromTag returns a Info for the given language tag. func InfoFromTag(t language.Tag) Info { for { if index, ok := language.CompactIndex(t); ok { return InfoFromLangID(index, t.TypeForKey("nu")) } t = t.Parent() } }
//Get get locale func (p *DatabaseProvider) Get(lng *language.Tag, code string) string { var l Locale if err := p.Db.Where("lang = ? AND code = ?", lng.String(), code).First(&l).Error; err != nil { p.Logger.Error(err) } return l.Message }
//T translate by lang tag func (p *I18n) T(lng *language.Tag, code string, args ...interface{}) string { lang := lng.String() msg := p.Provider.Get(lng, code) if len(msg) == 0 { if items, ok := p.Locales[lang]; ok { msg = items[code] } } return fmt.Sprintf(msg, args...) }
// Tailoring returns a Tailoring for the given locale. One should // have completed all calls to Add before calling Tailoring. func (b *Builder) Tailoring(loc language.Tag) *Tailoring { t := &Tailoring{ id: loc.String(), builder: b, index: b.root.clone(), } t.index.id = t.id b.locale = append(b.locale, t) return t }
func ldmlBool(t language.Tag, old bool, key string) bool { switch t.TypeForKey(key) { case "true": return true case "false": return false default: return old } }
// FromTag reports the most likely currency for the given tag. It considers the // currency defined in the -u extension and infers the region if necessary. func FromTag(t language.Tag) (Unit, language.Confidence) { if cur := t.TypeForKey("cu"); len(cur) == 3 { c, _ := ParseISO(cur) return c, language.Exact } r, conf := t.Region() if cur, ok := FromRegion(r); ok { return cur, conf } return Unit{}, language.No }
// GetLanguages returns a list of languages as a key/value slice. Odd index/key = locale, // even index/value = Humanized readable string. The humanized strings contains the language // name in its language and language name in requested tag func GetLanguages(t language.Tag) []string { var ret = make([]string, len(tags)*2) n := getDict(t) i := 0 for _, t := range tags { b, _ := t.Base() r, _ := t.Region() ret[i] = GetLocale(b, r) ret[i+1] = fmt.Sprintf("%-20s (%s)", display.Self.Name(t), n.Languages().Name(t)) i = i + 2 } return ret }
// FromTag reports the most likely currency for the given tag. It considers the // currency defined in the -u extension and infers the region if necessary. func FromTag(t language.Tag) (Currency, language.Confidence) { if cur := t.TypeForKey("cu"); len(cur) == 3 { var buf [3]byte copy(buf[:], cur) tag.FixCase("XXX", buf[:]) if x := currency.Index(buf[:]); x > 0 { return Currency{uint16(x)}, language.Exact } } r, conf := t.Region() if cur, ok := FromRegion(r); ok { return cur, conf } return Currency{}, language.No }
//Set set locale func (p *DatabaseProvider) Set(lng *language.Tag, code, message string) { var l Locale var err error if p.Db.Where("lang = ? AND code = ?", lng.String(), code).First(&l).RecordNotFound() { l.Lang = lng.String() l.Code = code l.Message = message err = p.Db.Create(&l).Error } else { l.Message = message err = p.Db.Save(&l).Error } if err != nil { p.Logger.Error(err) } }
func (c *Catalog) get(tag language.Tag, key string) (msg string, ok bool) { c.mutex.Lock() defer c.mutex.Unlock() for ; ; tag = tag.Parent() { if msgs, ok := c.index[tag]; ok { if statement, ok := msgs[key]; ok { // TODO: use type switches when we implement selecting. msg := string(statement.(format.String)) return msg, true } } if tag == language.Und { break } } return "", false }
// SupportedLanguages returns a list of supported languages for translation. // The target parameter is the language to use to return localized, human // readable names of supported languages. func (c *Client) SupportedLanguages(ctx context.Context, target language.Tag) ([]Language, error) { call := c.raw.Languages.List().Context(ctx).Target(target.String()) res, err := call.Do() if err != nil { return nil, err } var ls []Language for _, l := range res.Languages { tag, err := language.Parse(l.Language) if err != nil { return nil, err } ls = append(ls, Language{ Name: l.Name, Tag: tag, }) } return ls, nil }
func (o *options) setFromTag(t language.Tag) { o.caseLevel = ldmlBool(t, o.caseLevel, "kc") o.backwards = ldmlBool(t, o.backwards, "kb") o.numeric = ldmlBool(t, o.numeric, "kn") // Extract settings from the BCP47 u extension. switch t.TypeForKey("ks") { // strength case "level1": o.ignore[colltab.Secondary] = true o.ignore[colltab.Tertiary] = true case "level2": o.ignore[colltab.Tertiary] = true case "level3", "": // The default. case "level4": o.ignore[colltab.Quaternary] = false case "identic": o.ignore[colltab.Quaternary] = false o.ignore[colltab.Identity] = false } switch t.TypeForKey("ka") { case "shifted": o.alternate = altShifted // The following two types are not official BCP47, but we support them to // give access to this otherwise hidden functionality. The name blanked is // derived from the LDML name blanked and posix reflects the main use of // the shift-trimmed option. case "blanked": o.alternate = altBlanked case "posix": o.alternate = altShiftTrimmed } // TODO: caseFirst ("kf"), reorder ("kr"), and maybe variableTop ("vt"). // Not used: // - normalization ("kk", not necessary for this implementation) // - hiraganaQuatenary ("kh", obsolete) }
// identifier creates an identifier from the given tag. func identifier(t language.Tag) string { return strings.Replace(t.String(), "-", "", -1) }
func (p *RedisProvider) key(lng *language.Tag, code string) string { return fmt.Sprintf("locale://%s/%s", lng.String(), code) }
//Del del locale func (p *DatabaseProvider) Del(lng *language.Tag, code string) { if err := p.Db.Where("lang = ? AND code = ?", lng.String(), code).Delete(Locale{}).Error; err != nil { p.Logger.Error(err) } }
// parent computes the structural parent. This means inheritance may change // script. So, unlike the CLDR parent, parent(zh-Hant) == zh. func parent(t language.Tag) language.Tag { if t.TypeForKey("va") != "" { t, _ = t.SetTypeForKey("va", "") return t } result := language.Und if b, s, r := t.Raw(); (r != language.Region{}) { result, _ = language.Raw.Compose(b, s, t.Extensions()) } else if (s != language.Script{}) { result, _ = language.Raw.Compose(b, t.Extensions()) } else if (b != language.Base{}) { result, _ = language.Raw.Compose(t.Extensions()) } return result }
// MatchLang finds the index of t in tags, using a matching algorithm used for // collation and search. tags[0] must be language.Und, the remaining tags should // be sorted alphabetically. // // Language matching for collation and search is different from the matching // defined by language.Matcher: the (inferred) base language must be an exact // match for the relevant fields. For example, "gsw" should not match "de". // Also the parent relation is different, as a parent may have a different // script. So usually the parent of zh-Hant is und, whereas for MatchLang it is // zh. func MatchLang(t language.Tag, tags []language.Tag) int { // Canonicalize the values, including collapsing macro languages. t, _ = language.All.Canonicalize(t) base, conf := t.Base() // Estimate the base language, but only use high-confidence values. if conf < language.High { // The root locale supports "search" and "standard". We assume that any // implementation will only use one of both. return 0 } // Maximize base and script and normalize the tag. if _, s, r := t.Raw(); (r != language.Region{}) { p, _ := language.Raw.Compose(base, s, r) // Taking the parent forces the script to be maximized. p = p.Parent() // Add back region and extensions. t, _ = language.Raw.Compose(p, r, t.Extensions()) } else { // Set the maximized base language. t, _ = language.Raw.Compose(base, s, t.Extensions()) } // Find start index of the language tag. start := 1 + sort.Search(len(tags)-1, func(i int) bool { b, _, _ := tags[i+1].Raw() return base.String() <= b.String() }) if start < len(tags) { if b, _, _ := tags[start].Raw(); b != base { return 0 } } // Besides the base language, script and region, only the collation type and // the custom variant defined in the 'u' extension are used to distinguish a // locale. // Strip all variants and extensions and add back the custom variant. tdef, _ := language.Raw.Compose(t.Raw()) tdef, _ = tdef.SetTypeForKey("va", t.TypeForKey("va")) // First search for a specialized collation type, if present. try := []language.Tag{tdef} if co := t.TypeForKey("co"); co != "" { tco, _ := tdef.SetTypeForKey("co", co) try = []language.Tag{tco, tdef} } for _, tx := range try { for ; tx != language.Und; tx = parent(tx) { for i, t := range tags[start:] { if b, _, _ := t.Raw(); b != base { break } if tx == t { return start + i } } } } return 0 }
//Keys list locale keys func (p *DatabaseProvider) Keys(lng *language.Tag) ([]string, error) { var keys []string err := p.Db.Model(&Locale{}).Where("lang = ?", lng.String()).Pluck("code", &keys).Error return keys, err }
// Gets the translation for the specified key in the language // represented by tag func (i18n JsonI18n) GetTranslation(key string, tag language.Tag) string { if val, ok := i18n.translations[tag.String()]; ok { return val[key] } return key }
func (i18n JsonI18n) addTranslationMap(languageMap TranslationMap, tag language.Tag) error { parent := tag.String() i18n.translations[parent] = languageMap return nil }