Files
gotext/cli/xgotext/parser/domain.go
2020-02-22 22:37:17 +01:00

130 lines
3.2 KiB
Go

package parser
import (
"sort"
"strings"
)
// Translation for a text to translate
type Translation struct {
MsgId string
MsgIdPlural string
Context string
SourceLocations []string
}
// AddLocations to translation
func (t *Translation) AddLocations(locations []string) {
if t.SourceLocations == nil {
t.SourceLocations = locations
} else {
t.SourceLocations = append(t.SourceLocations, locations...)
}
}
// Dump translation as string
func (t *Translation) Dump() string {
data := make([]string, 0, len(t.SourceLocations)+5)
for _, location := range t.SourceLocations {
data = append(data, "#: "+location)
}
if t.Context != "" {
data = append(data, "msgctxt "+t.Context)
}
data = append(data, "msgid "+t.MsgId)
if t.MsgIdPlural == "" {
data = append(data, "msgstr \"\"")
} else {
data = append(data,
"msgid_plural "+t.MsgIdPlural,
"msgstr[0] \"\"",
"msgstr[1] \"\"")
}
return strings.Join(data, "\n")
}
// TranslationMap contains a map of translations with the ID as key
type TranslationMap map[string]*Translation
// Dump the translation map as string
func (m TranslationMap) Dump() string {
// sort by translation id for consistence output
keys := make([]string, 0, len(m))
for k := range m {
keys = append(keys, k)
}
sort.Strings(keys)
data := make([]string, 0, len(m))
for _, key := range keys {
data = append(data, (m)[key].Dump())
}
return strings.Join(data, "\n\n")
}
// Domain holds all translations of one domain
type Domain struct {
Translations TranslationMap
ContextTranslations map[string]TranslationMap
}
// AddTranslation to the domain
func (d *Domain) AddTranslation(translation *Translation) {
if d.Translations == nil {
d.Translations = make(TranslationMap)
d.ContextTranslations = make(map[string]TranslationMap)
}
if translation.Context == "" {
if t, ok := d.Translations[translation.MsgId]; ok {
t.AddLocations(translation.SourceLocations)
} else {
d.Translations[translation.MsgId] = translation
}
} else {
if _, ok := d.ContextTranslations[translation.Context]; !ok {
d.ContextTranslations[translation.Context] = make(TranslationMap)
}
if t, ok := d.ContextTranslations[translation.Context][translation.MsgId]; ok {
t.AddLocations(translation.SourceLocations)
} else {
d.ContextTranslations[translation.Context][translation.MsgId] = translation
}
}
}
// Dump the domain as string
func (d *Domain) Dump() string {
data := make([]string, 0, len(d.ContextTranslations)+1)
data = append(data, d.Translations.Dump())
// sort context translations by context for consistence output
keys := make([]string, 0, len(d.ContextTranslations))
for k := range d.ContextTranslations {
keys = append(keys, k)
}
sort.Strings(keys)
for _, key := range keys {
data = append(data, d.ContextTranslations[key].Dump())
}
return strings.Join(data, "\n\n")
}
// DomainMap contains multiple domains as map with name as key
type DomainMap map[string]*Domain
// AddTranslation to domain map
func (m *DomainMap) AddTranslation(domain string, translation *Translation) {
if _, ok := (*m)[domain]; !ok {
(*m)[domain] = new(Domain)
}
(*m)[domain].AddTranslation(translation)
}