Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Revert "Add support for multiple languages" #84

Merged
merged 1 commit into from
Aug 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
232 changes: 74 additions & 158 deletions gotext.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,62 +24,54 @@ package gotext

import (
"encoding/gob"
"strings"
"sync"
)

// Global environment variables
type config struct {
sync.RWMutex

// Path to library directory where all locale directories and Translation files are.
library string

// Default domain to look at when no domain is specified. Used by package level functions.
domain string

// Language set.
languages []string
language string

// Path to library directory where all locale directories and Translation files are.
library string

// Storage for package level methods
locales []*Locale
storage *Locale
}

var globalConfig *config

func init() {
// Init default configuration
globalConfig = &config{
domain: "default",
languages: []string{"en_US"},
library: "/usr/local/share/locale",
locales: nil,
domain: "default",
language: "en_US",
library: "/usr/local/share/locale",
storage: nil,
}

// Register Translator types for gob encoding
gob.Register(TranslatorEncoding{})
}

// loadStorage creates a new Locale object at package level based on the Global variables settings
// for every language specified using Configure.
// loadStorage creates a new Locale object at package level based on the Global variables settings.
// It's called automatically when trying to use Get or GetD methods.
func loadStorage(force bool) {
globalConfig.Lock()

if globalConfig.locales == nil || force {
var locales []*Locale
for _, language := range globalConfig.languages {
locales = append(locales, NewLocale(globalConfig.library, language))
}
globalConfig.locales = locales
if globalConfig.storage == nil || force {
globalConfig.storage = NewLocale(globalConfig.library, globalConfig.language)
}

for _, locale := range globalConfig.locales {
if _, ok := locale.Domains[globalConfig.domain]; !ok || force {
locale.AddDomain(globalConfig.domain)
}
locale.SetDomain(globalConfig.domain)
if _, ok := globalConfig.storage.Domains[globalConfig.domain]; !ok || force {
globalConfig.storage.AddDomain(globalConfig.domain)
}
globalConfig.storage.SetDomain(globalConfig.domain)

globalConfig.Unlock()
}
Expand All @@ -88,9 +80,8 @@ func loadStorage(force bool) {
func GetDomain() string {
var dom string
globalConfig.RLock()
if globalConfig.locales != nil {
// All locales have the same domain
dom = globalConfig.locales[0].GetDomain()
if globalConfig.storage != nil {
dom = globalConfig.storage.GetDomain()
}
if dom == "" {
dom = globalConfig.domain
Expand All @@ -105,42 +96,28 @@ func GetDomain() string {
func SetDomain(dom string) {
globalConfig.Lock()
globalConfig.domain = dom
if globalConfig.locales != nil {
for _, locale := range globalConfig.locales {
locale.SetDomain(dom)
}
if globalConfig.storage != nil {
globalConfig.storage.SetDomain(dom)
}
globalConfig.Unlock()

loadStorage(true)
}

// GetLanguage returns the language gotext will translate into.
// If multiple languages have been supplied, the first one will be returned.
// GetLanguage is the language getter for the package configuration
func GetLanguage() string {
return GetLanguages()[0]
}

// GetLanguages returns all languages that have been supplied.
func GetLanguages() []string {
globalConfig.RLock()
defer globalConfig.RUnlock()
return globalConfig.languages
lang := globalConfig.language
globalConfig.RUnlock()

return lang
}

// SetLanguage sets the language code (or colon separated language codes) to be used at package level.
// SetLanguage sets the language code to be used at package level.
// It reloads the corresponding Translation file.
func SetLanguage(lang string) {
globalConfig.Lock()
var languages []string
for _, language := range strings.Split(lang, ":") {
language = SimplifiedLocale(language)
languages = append(languages, language)
if language == "C" {
break
}
}
globalConfig.languages = languages
globalConfig.language = SimplifiedLocale(lang)
globalConfig.Unlock()

loadStorage(true)
Expand All @@ -155,7 +132,7 @@ func GetLibrary() string {
return lib
}

// SetLibrary sets the root path for the locale directories and files to be used at package level.
// SetLibrary sets the root path for the loale directories and files to be used at package level.
// It reloads the corresponding Translation file.
func SetLibrary(lib string) {
globalConfig.Lock()
Expand Down Expand Up @@ -196,15 +173,7 @@ func SetStorage(storage *Locale) {
func Configure(lib, lang, dom string) {
globalConfig.Lock()
globalConfig.library = lib
var languages []string
for _, language := range strings.Split(lang, ":") {
language = SimplifiedLocale(language)
languages = append(languages, language)
if language == "C" {
break
}
}
globalConfig.languages = languages
globalConfig.language = SimplifiedLocale(lang)
globalConfig.domain = dom
globalConfig.Unlock()

Expand All @@ -229,20 +198,16 @@ func GetD(dom, str string, vars ...interface{}) string {
// Try to load default package Locale storage
loadStorage(false)

// Return Translation
globalConfig.RLock()
defer globalConfig.RUnlock()

var tr string
for i, locale := range globalConfig.locales {
if _, ok := locale.Domains[dom]; !ok {
locale.AddDomain(dom)
}
if !locale.IsTranslatedD(dom, str) && i < (len(globalConfig.locales)-1) {
continue
}
tr = locale.GetD(dom, str, vars...)
break
if _, ok := globalConfig.storage.Domains[dom]; !ok {
globalConfig.storage.AddDomain(dom)
}

tr := globalConfig.storage.GetD(dom, str, vars...)
globalConfig.RUnlock()

return tr
}

Expand All @@ -252,20 +217,16 @@ func GetND(dom, str, plural string, n int, vars ...interface{}) string {
// Try to load default package Locale storage
loadStorage(false)

// Return Translation
globalConfig.RLock()
defer globalConfig.RUnlock()

var tr string
for i, locale := range globalConfig.locales {
if _, ok := locale.Domains[dom]; !ok {
locale.AddDomain(dom)
}
if !locale.IsTranslatedND(dom, str, n) && i < (len(globalConfig.locales)-1) {
continue
}
tr = locale.GetND(dom, str, plural, n, vars...)
break
if _, ok := globalConfig.storage.Domains[dom]; !ok {
globalConfig.storage.AddDomain(dom)
}

tr := globalConfig.storage.GetND(dom, str, plural, n, vars...)
globalConfig.RUnlock()

return tr
}

Expand All @@ -287,17 +248,11 @@ func GetDC(dom, str, ctx string, vars ...interface{}) string {
// Try to load default package Locale storage
loadStorage(false)

// Return Translation
globalConfig.RLock()
defer globalConfig.RUnlock()
tr := globalConfig.storage.GetDC(dom, str, ctx, vars...)
globalConfig.RUnlock()

var tr string
for i, locale := range globalConfig.locales {
if !locale.IsTranslatedDC(dom, str, ctx) && i < (len(globalConfig.locales)-1) {
continue
}
tr = locale.GetDC(dom, str, ctx, vars...)
break
}
return tr
}

Expand All @@ -309,101 +264,62 @@ func GetNDC(dom, str, plural string, n int, ctx string, vars ...interface{}) str

// Return Translation
globalConfig.RLock()
defer globalConfig.RUnlock()
tr := globalConfig.storage.GetNDC(dom, str, plural, n, ctx, vars...)
globalConfig.RUnlock()

var tr string
for i, locale := range globalConfig.locales {
if !locale.IsTranslatedNDC(dom, str, n, ctx) && i < (len(globalConfig.locales)-1) {
continue
}
tr = locale.GetNDC(dom, str, plural, n, ctx, vars...)
break
}
return tr
}

// IsTranslated reports whether a string is translated in given languages.
// When the langs argument is omitted, the output of GetLanguages is used.
func IsTranslated(str string, langs ...string) bool {
return IsTranslatedND(GetDomain(), str, 0, langs...)
// IsTranslated reports whether a string is translated
func IsTranslated(str string) bool {
return IsTranslatedND(GetDomain(), str, 0)
}

// IsTranslatedN reports whether a plural string is translated in given languages.
// When the langs argument is omitted, the output of GetLanguages is used.
func IsTranslatedN(str string, n int, langs ...string) bool {
return IsTranslatedND(GetDomain(), str, n, langs...)
// IsTranslatedN reports whether a plural string is translated
func IsTranslatedN(str string, n int) bool {
return IsTranslatedND(GetDomain(), str, n)
}

// IsTranslatedD reports whether a domain string is translated in given languages.
// When the langs argument is omitted, the output of GetLanguages is used.
func IsTranslatedD(dom, str string, langs ...string) bool {
return IsTranslatedND(dom, str, 0, langs...)
// IsTranslatedD reports whether a domain string is translated
func IsTranslatedD(dom, str string) bool {
return IsTranslatedND(dom, str, 0)
}

// IsTranslatedND reports whether a plural domain string is translated in any of given languages.
// When the langs argument is omitted, the output of GetLanguages is used.
func IsTranslatedND(dom, str string, n int, langs ...string) bool {
if len(langs) == 0 {
langs = GetLanguages()
}

// IsTranslatedND reports whether a plural domain string is translated
func IsTranslatedND(dom, str string, n int) bool {
loadStorage(false)

globalConfig.RLock()
defer globalConfig.RUnlock()

for _, lang := range langs {
lang = SimplifiedLocale(lang)

for _, supportedLocale := range globalConfig.locales {
if lang != supportedLocale.GetActualLanguage(dom) {
continue
}
return supportedLocale.IsTranslatedND(dom, str, n)
}
if _, ok := globalConfig.storage.Domains[dom]; !ok {
globalConfig.storage.AddDomain(dom)
}
return false
}

// IsTranslatedC reports whether a context string is translated in given languages.
// When the langs argument is omitted, the output of GetLanguages is used.
func IsTranslatedC(str, ctx string, langs ...string) bool {
return IsTranslatedNDC(GetDomain(), str, 0, ctx, langs...)
return globalConfig.storage.IsTranslatedND(dom, str, n)
}

// IsTranslatedNC reports whether a plural context string is translated in given languages.
// When the langs argument is omitted, the output of GetLanguages is used.
func IsTranslatedNC(str string, n int, ctx string, langs ...string) bool {
return IsTranslatedNDC(GetDomain(), str, n, ctx, langs...)
// IsTranslatedC reports whether a context string is translated
func IsTranslatedC(str, ctx string) bool {
return IsTranslatedNDC(GetDomain(), str, 0, ctx)
}

// IsTranslatedDC reports whether a domain context string is translated in given languages.
// When the langs argument is omitted, the output of GetLanguages is used.
func IsTranslatedDC(dom, str, ctx string, langs ...string) bool {
return IsTranslatedNDC(dom, str, 0, ctx, langs...)
// IsTranslatedNC reports whether a plural context string is translated
func IsTranslatedNC(str string, n int, ctx string) bool {
return IsTranslatedNDC(GetDomain(), str, n, ctx)
}

// IsTranslatedNDC reports whether a plural domain context string is translated in any of given languages.
// When the langs argument is omitted, the output of GetLanguages is used.
func IsTranslatedNDC(dom, str string, n int, ctx string, langs ...string) bool {
if len(langs) == 0 {
langs = GetLanguages()
}
// IsTranslatedDC reports whether a domain context string is translated
func IsTranslatedDC(dom, str, ctx string) bool {
return IsTranslatedNDC(dom, str, 0, ctx)
}

// IsTranslatedNDC reports whether a plural domain context string is translated
func IsTranslatedNDC(dom, str string, n int, ctx string) bool {
loadStorage(false)

globalConfig.RLock()
defer globalConfig.RUnlock()

for _, lang := range langs {
lang = SimplifiedLocale(lang)

for _, locale := range globalConfig.locales {
if lang != locale.GetActualLanguage(dom) {
continue
}
return locale.IsTranslatedNDC(dom, str, n, ctx)
}
}
return false
return globalConfig.storage.IsTranslatedNDC(dom, str, n, ctx)
}