...

Source file src/github.com/chai2010/gettext-go/tr.go

Documentation: github.com/chai2010/gettext-go

     1  // Copyright 2013 ChaiShushan <chaishushan{AT}gmail.com>. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package gettext
     6  
     7  import (
     8  	"encoding/json"
     9  
    10  	"github.com/chai2010/gettext-go/mo"
    11  	"github.com/chai2010/gettext-go/plural"
    12  	"github.com/chai2010/gettext-go/po"
    13  )
    14  
    15  var nilTranslator = &translator{
    16  	MessageMap:    make(map[string]mo.Message),
    17  	PluralFormula: plural.Formula("??"),
    18  }
    19  
    20  type translator struct {
    21  	MessageMap    map[string]mo.Message
    22  	PluralFormula func(n int) int
    23  }
    24  
    25  func newMoTranslator(name string, data []byte) (*translator, error) {
    26  	var (
    27  		f   *mo.File
    28  		err error
    29  	)
    30  	if len(data) != 0 {
    31  		f, err = mo.Load(data)
    32  	} else {
    33  		f, err = mo.LoadFile(name)
    34  	}
    35  	if err != nil {
    36  		return nil, err
    37  	}
    38  	var tr = &translator{
    39  		MessageMap: make(map[string]mo.Message),
    40  	}
    41  	for _, v := range f.Messages {
    42  		tr.MessageMap[tr.makeMapKey(v.MsgContext, v.MsgId)] = v
    43  	}
    44  	if lang := f.MimeHeader.Language; lang != "" {
    45  		tr.PluralFormula = plural.Formula(lang)
    46  	} else {
    47  		tr.PluralFormula = plural.Formula("??")
    48  	}
    49  	return tr, nil
    50  }
    51  
    52  func newPoTranslator(name string, data []byte) (*translator, error) {
    53  	var (
    54  		f   *po.File
    55  		err error
    56  	)
    57  	if len(data) != 0 {
    58  		f, err = po.Load(data)
    59  	} else {
    60  		f, err = po.LoadFile(name)
    61  	}
    62  	if err != nil {
    63  		return nil, err
    64  	}
    65  	var tr = &translator{
    66  		MessageMap: make(map[string]mo.Message),
    67  	}
    68  	for _, v := range f.Messages {
    69  		tr.MessageMap[tr.makeMapKey(v.MsgContext, v.MsgId)] = mo.Message{
    70  			MsgContext:   v.MsgContext,
    71  			MsgId:        v.MsgId,
    72  			MsgIdPlural:  v.MsgIdPlural,
    73  			MsgStr:       v.MsgStr,
    74  			MsgStrPlural: v.MsgStrPlural,
    75  		}
    76  	}
    77  	if lang := f.MimeHeader.Language; lang != "" {
    78  		tr.PluralFormula = plural.Formula(lang)
    79  	} else {
    80  		tr.PluralFormula = plural.Formula("??")
    81  	}
    82  	return tr, nil
    83  }
    84  
    85  func newJsonTranslator(lang, name string, jsonData []byte) (*translator, error) {
    86  	var msgList []struct {
    87  		MsgContext  string   `json:"msgctxt"`      // msgctxt context
    88  		MsgId       string   `json:"msgid"`        // msgid untranslated-string
    89  		MsgIdPlural string   `json:"msgid_plural"` // msgid_plural untranslated-string-plural
    90  		MsgStr      []string `json:"msgstr"`       // msgstr translated-string
    91  	}
    92  	if err := json.Unmarshal(jsonData, &msgList); err != nil {
    93  		return nil, err
    94  	}
    95  
    96  	var tr = &translator{
    97  		MessageMap:    make(map[string]mo.Message),
    98  		PluralFormula: plural.Formula(lang),
    99  	}
   100  
   101  	for _, v := range msgList {
   102  		var v_MsgStr string
   103  		var v_MsgStrPlural = v.MsgStr
   104  
   105  		if len(v.MsgStr) != 0 {
   106  			v_MsgStr = v.MsgStr[0]
   107  		}
   108  
   109  		tr.MessageMap[tr.makeMapKey(v.MsgContext, v.MsgId)] = mo.Message{
   110  			MsgContext:   v.MsgContext,
   111  			MsgId:        v.MsgId,
   112  			MsgIdPlural:  v.MsgIdPlural,
   113  			MsgStr:       v_MsgStr,
   114  			MsgStrPlural: v_MsgStrPlural,
   115  		}
   116  	}
   117  	return tr, nil
   118  }
   119  
   120  func (p *translator) PGettext(msgctxt, msgid string) string {
   121  	return p.findMsgStr(msgctxt, msgid)
   122  }
   123  
   124  func (p *translator) PNGettext(msgctxt, msgid, msgidPlural string, n int) string {
   125  	n = p.PluralFormula(n)
   126  	if ss := p.findMsgStrPlural(msgctxt, msgid, msgidPlural); len(ss) != 0 {
   127  		if n >= len(ss) {
   128  			n = len(ss) - 1
   129  		}
   130  		if ss[n] != "" {
   131  			return ss[n]
   132  		}
   133  	}
   134  	if msgidPlural != "" && n > 0 {
   135  		return msgidPlural
   136  	}
   137  	return msgid
   138  }
   139  
   140  func (p *translator) findMsgStr(msgctxt, msgid string) string {
   141  	key := p.makeMapKey(msgctxt, msgid)
   142  	if v, ok := p.MessageMap[key]; ok {
   143  		if v.MsgStr != "" {
   144  			return v.MsgStr
   145  		}
   146  	}
   147  	return msgid
   148  }
   149  
   150  func (p *translator) findMsgStrPlural(msgctxt, msgid, msgidPlural string) []string {
   151  	key := p.makeMapKey(msgctxt, msgid)
   152  	if v, ok := p.MessageMap[key]; ok {
   153  		if len(v.MsgIdPlural) != 0 {
   154  			if len(v.MsgStrPlural) != 0 {
   155  				return v.MsgStrPlural
   156  			} else {
   157  				return nil
   158  			}
   159  		} else {
   160  			if len(v.MsgStr) != 0 {
   161  				return []string{v.MsgStr}
   162  			} else {
   163  				return nil
   164  			}
   165  		}
   166  	}
   167  	return nil
   168  }
   169  
   170  func (p *translator) makeMapKey(msgctxt, msgid string) string {
   171  	if msgctxt != "" {
   172  		return msgctxt + mo.EotSeparator + msgid
   173  	}
   174  	return msgid
   175  }
   176  

View as plain text