Skip to content

Commit

Permalink
prettify language source file, wip #210
Browse files Browse the repository at this point in the history
  • Loading branch information
MJacred committed Jan 10, 2020
1 parent bcd4583 commit 9d10a57
Show file tree
Hide file tree
Showing 6 changed files with 80 additions and 17 deletions.
13 changes: 12 additions & 1 deletion v2/goi18n/extract_command.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,15 @@ If no files or paths are provided, it walks the current working directory.
Flags:
-pretty prettyLevel
In case you write the source language file yourself, but don't adhere strictly to the file format.
This command flag will prettify your source language localization.
Allowed values:
- [empty]
- lean
- full
Default: [empty]
-sourceLanguage tag
The language tag of the extracted messages (e.g. en, en-US, zh-Hant-CN).
Default: en
Expand All @@ -45,6 +54,7 @@ type extractCommand struct {
sourceLanguage languageTag
outdir string
format string
prettyLevel pretty
}

func (ec *extractCommand) name() string {
Expand All @@ -55,6 +65,7 @@ func (ec *extractCommand) parse(args []string) error {
flags := flag.NewFlagSet("extract", flag.ExitOnError)
flags.Usage = usageExtract

flags.Var(&ec.prettyLevel, "pretty", "")
flags.Var(&ec.sourceLanguage, "sourceLanguage", "en")
flags.StringVar(&ec.outdir, "outdir", ".", "")
flags.StringVar(&ec.format, "format", "toml", "")
Expand Down Expand Up @@ -108,7 +119,7 @@ func (ec *extractCommand) execute() error {
messageTemplates[m.ID] = mt
}
}
path, content, err := writeFile(ec.outdir, "active", ec.sourceLanguage.Tag(), ec.format, messageTemplates, true)
path, content, err := writeFile(ec.outdir, "active", ec.sourceLanguage.Tag(), ec.format, messageTemplates, ec.prettyLevel, true)
if err != nil {
return err
}
Expand Down
35 changes: 35 additions & 0 deletions v2/goi18n/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,3 +153,38 @@ func (lt languageTag) Tag() language.Tag {
}
return tag
}

const (
// Lean prints key-value-pairs in active language source file with table
Lean int8 = 1 << iota
// Full means the hash will be printed additionally to `Lean` to the active language source file as well
Full
)

type pretty struct{
Level int8
}

func (p pretty) String() string {
switch p.Level {
case Lean:
return "lean"
case Full:
return "full"
}
return "undefined"
}

func (p *pretty) Set(value string) error {
lean := pretty{Lean}
full := pretty{Full}

if value == lean.String() {
*p = lean
} else if value == full.String() {
*p = full
} else {
return fmt.Errorf("invalid value %q for pretty flag", value)
}
return nil
}
13 changes: 7 additions & 6 deletions v2/goi18n/marshal.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ import (
yaml "gopkg.in/yaml.v2"
)

func writeFile(outdir, label string, langTag language.Tag, format string, messageTemplates map[string]*i18n.MessageTemplate, sourceLanguage bool) (path string, content []byte, err error) {
v := marshalValue(messageTemplates, sourceLanguage)
func writeFile(outdir, label string, langTag language.Tag, format string, messageTemplates map[string]*i18n.MessageTemplate, prettyLevel pretty, sourceLanguage bool) (path string, content []byte, err error) {
v := marshalValue(messageTemplates, prettyLevel, sourceLanguage)
content, err = marshal(v, format)
if err != nil {
return "", nil, fmt.Errorf("failed to marshal %s strings to %s: %s", langTag, format, err)
Expand All @@ -23,18 +23,19 @@ func writeFile(outdir, label string, langTag language.Tag, format string, messag
return
}

func marshalValue(messageTemplates map[string]*i18n.MessageTemplate, sourceLanguage bool) interface{} {
func marshalValue(messageTemplates map[string]*i18n.MessageTemplate, prettyLevel pretty, sourceLanguage bool) interface{} {
v := make(map[string]interface{}, len(messageTemplates))
for id, template := range messageTemplates {
if other := template.PluralTemplates[plural.Other]; sourceLanguage && len(template.PluralTemplates) == 1 &&
other != nil && template.Description == "" && template.LeftDelim == "" && template.RightDelim == "" {
if other := template.PluralTemplates[plural.Other]; prettyLevel == (pretty{}) && sourceLanguage &&
len(template.PluralTemplates) == 1 && other != nil && template.Description == "" &&
template.LeftDelim == "" && template.RightDelim == "" {
v[id] = other.Src
} else {
m := map[string]string{}
if template.Description != "" {
m["description"] = template.Description
}
if !sourceLanguage {
if !sourceLanguage || (sourceLanguage && prettyLevel != (pretty{}) && prettyLevel.Level == Full) {
m["hash"] = template.Hash
}
for pluralForm, template := range template.PluralTemplates {
Expand Down
33 changes: 24 additions & 9 deletions v2/goi18n/merge_command.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,15 @@ appropriate name and pass it in to goi18n merge.
Flags:
-pretty prettyLevel
In case you write the source language file yourself, but don't adhere strictly to the file format.
This command flag will prettify your source language localization.
Allowed values:
- [empty]
- lean
- full
Default: [empty]
-sourceLanguage tag
Translate messages from this language (e.g. en, en-US, zh-Hant-CN)
Default: en
Expand All @@ -56,6 +65,7 @@ type mergeCommand struct {
sourceLanguage languageTag
outdir string
format string
prettyLevel pretty
}

func (mc *mergeCommand) name() string {
Expand All @@ -66,6 +76,7 @@ func (mc *mergeCommand) parse(args []string) error {
flags := flag.NewFlagSet("merge", flag.ExitOnError)
flags.Usage = usageMerge

flags.Var(&mc.prettyLevel, "pretty", "")
flags.Var(&mc.sourceLanguage, "sourceLanguage", "en")
flags.StringVar(&mc.outdir, "outdir", ".", "")
flags.StringVar(&mc.format, "format", "toml", "")
Expand All @@ -89,7 +100,8 @@ func (mc *mergeCommand) execute() error {
}
inFiles[path] = content
}
ops, err := merge(inFiles, mc.sourceLanguage.Tag(), mc.outdir, mc.format)

ops, err := merge(inFiles, mc.prettyLevel, mc.sourceLanguage.Tag(), mc.outdir, mc.format)
if err != nil {
return err
}
Expand All @@ -110,18 +122,19 @@ type fileSystemOp struct {
deleteFiles []string
}

func merge(messageFiles map[string][]byte, sourceLanguageTag language.Tag, outdir, outputFormat string) (*fileSystemOp, error) {
func merge(messageFiles map[string][]byte, prettyLevel pretty, sourceLanguageTag language.Tag, outdir, outputFormat string) (*fileSystemOp, error) {
unmerged := make(map[language.Tag][]map[string]*i18n.MessageTemplate)
sourceMessageTemplates := make(map[string]*i18n.MessageTemplate)
unmarshalFuncs := map[string]i18n.UnmarshalFunc{
"json": json.Unmarshal,
"toml": toml.Unmarshal,
"yaml": yaml.Unmarshal,
}
// Generate message templates from source and target files.
for path, content := range messageFiles {
mf, err := i18n.ParseMessageFileBytes(content, path, unmarshalFuncs)
if err != nil {
return nil, fmt.Errorf("failed to load message file %s: %s", path, err)
return nil, fmt.Errorf("failed to load message file %q: %s", path, err)
}
templates := map[string]*i18n.MessageTemplate{}
for _, m := range mf.Messages {
Expand All @@ -145,14 +158,16 @@ func merge(messageFiles map[string][]byte, sourceLanguageTag language.Tag, outdi
}

if len(sourceMessageTemplates) == 0 {
return nil, fmt.Errorf("no messages found for source locale %s", sourceLanguageTag)
return nil, fmt.Errorf("no messages found for source locale %q", sourceLanguageTag)
}

// Join the lists elements per language tag in `unmerged` by language into `all` and
// add already translated message templates.
pluralRules := plural.DefaultRules()
all := make(map[language.Tag]map[string]*i18n.MessageTemplate)
all[sourceLanguageTag] = sourceMessageTemplates
for _, srcTemplate := range sourceMessageTemplates {
for dstLangTag, messageTemplates := range unmerged {
for dstLangTag, dstMessageTemplatesList := range unmerged {
if dstLangTag == sourceLanguageTag {
continue
}
Expand All @@ -179,8 +194,8 @@ func merge(messageFiles map[string][]byte, sourceLanguageTag language.Tag, outdi
}

// Check all unmerged message templates for this message id.
for _, messageTemplates := range messageTemplates {
unmergedTemplate := messageTemplates[srcTemplate.ID]
for _, dstMessageTemplates := range dstMessageTemplatesList {
unmergedTemplate := dstMessageTemplates[srcTemplate.ID]
if unmergedTemplate == nil {
continue
}
Expand Down Expand Up @@ -232,15 +247,15 @@ func merge(messageFiles map[string][]byte, sourceLanguageTag language.Tag, outdi

writeFiles := make(map[string][]byte, len(translate)+len(active))
for langTag, messageTemplates := range translate {
path, content, err := writeFile(outdir, "translate", langTag, outputFormat, messageTemplates, false)
path, content, err := writeFile(outdir, "translate", langTag, outputFormat, messageTemplates, prettyLevel, false)
if err != nil {
return nil, err
}
writeFiles[path] = content
}
deleteFiles := []string{}
for langTag, messageTemplates := range active {
path, content, err := writeFile(outdir, "active", langTag, outputFormat, messageTemplates, langTag == sourceLanguageTag)
path, content, err := writeFile(outdir, "active", langTag, outputFormat, messageTemplates, prettyLevel, langTag == sourceLanguageTag)
if err != nil {
return nil, err
}
Expand Down
2 changes: 1 addition & 1 deletion v2/i18n/message.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ type Message struct {
// LeftDelim is the left Go template delimiter.
LeftDelim string

// RightDelim is the right Go template delimiter.``
// RightDelim is the right Go template delimiter.
RightDelim string

// Zero is the content of the message for the CLDR plural form "zero".
Expand Down
1 change: 1 addition & 0 deletions v2/i18n/parse.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ func addChildMessages(id string, data interface{}, messages []*Message) ([]*Mess
return messages, nil
}

// parsePath extracts and returns the language tag and file format used for unmarshalling from the given path.
func parsePath(path string) (langTag, format string) {
formatStartIdx := -1
for i := len(path) - 1; i >= 0; i-- {
Expand Down

0 comments on commit 9d10a57

Please sign in to comment.