tr.go 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  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. package gettext
  5. import (
  6. "github.com/chai2010/gettext-go/gettext/mo"
  7. "github.com/chai2010/gettext-go/gettext/plural"
  8. "github.com/chai2010/gettext-go/gettext/po"
  9. )
  10. var nilTranslator = &translator{
  11. MessageMap: make(map[string]mo.Message),
  12. PluralFormula: plural.Formula("??"),
  13. }
  14. type translator struct {
  15. MessageMap map[string]mo.Message
  16. PluralFormula func(n int) int
  17. }
  18. func newMoTranslator(name string, data []byte) (*translator, error) {
  19. var (
  20. f *mo.File
  21. err error
  22. )
  23. if len(data) != 0 {
  24. f, err = mo.LoadData(data)
  25. } else {
  26. f, err = mo.Load(name)
  27. }
  28. if err != nil {
  29. return nil, err
  30. }
  31. var tr = &translator{
  32. MessageMap: make(map[string]mo.Message),
  33. }
  34. for _, v := range f.Messages {
  35. tr.MessageMap[tr.makeMapKey(v.MsgContext, v.MsgId)] = v
  36. }
  37. if lang := f.MimeHeader.Language; lang != "" {
  38. tr.PluralFormula = plural.Formula(lang)
  39. } else {
  40. tr.PluralFormula = plural.Formula("??")
  41. }
  42. return tr, nil
  43. }
  44. func newPoTranslator(name string, data []byte) (*translator, error) {
  45. var (
  46. f *po.File
  47. err error
  48. )
  49. if len(data) != 0 {
  50. f, err = po.LoadData(data)
  51. } else {
  52. f, err = po.Load(name)
  53. }
  54. if err != nil {
  55. return nil, err
  56. }
  57. var tr = &translator{
  58. MessageMap: make(map[string]mo.Message),
  59. }
  60. for _, v := range f.Messages {
  61. tr.MessageMap[tr.makeMapKey(v.MsgContext, v.MsgId)] = mo.Message{
  62. MsgContext: v.MsgContext,
  63. MsgId: v.MsgId,
  64. MsgIdPlural: v.MsgIdPlural,
  65. MsgStr: v.MsgStr,
  66. MsgStrPlural: v.MsgStrPlural,
  67. }
  68. }
  69. if lang := f.MimeHeader.Language; lang != "" {
  70. tr.PluralFormula = plural.Formula(lang)
  71. } else {
  72. tr.PluralFormula = plural.Formula("??")
  73. }
  74. return tr, nil
  75. }
  76. func (p *translator) PGettext(msgctxt, msgid string) string {
  77. return p.PNGettext(msgctxt, msgid, "", 0)
  78. }
  79. func (p *translator) PNGettext(msgctxt, msgid, msgidPlural string, n int) string {
  80. n = p.PluralFormula(n)
  81. if ss := p.findMsgStrPlural(msgctxt, msgid, msgidPlural); len(ss) != 0 {
  82. if n >= len(ss) {
  83. n = len(ss) - 1
  84. }
  85. if ss[n] != "" {
  86. return ss[n]
  87. }
  88. }
  89. if msgidPlural != "" && n > 0 {
  90. return msgidPlural
  91. }
  92. return msgid
  93. }
  94. func (p *translator) findMsgStrPlural(msgctxt, msgid, msgidPlural string) []string {
  95. key := p.makeMapKey(msgctxt, msgid)
  96. if v, ok := p.MessageMap[key]; ok {
  97. if len(v.MsgIdPlural) != 0 {
  98. if len(v.MsgStrPlural) != 0 {
  99. return v.MsgStrPlural
  100. } else {
  101. return nil
  102. }
  103. } else {
  104. if len(v.MsgStr) != 0 {
  105. return []string{v.MsgStr}
  106. } else {
  107. return nil
  108. }
  109. }
  110. }
  111. return nil
  112. }
  113. func (p *translator) makeMapKey(msgctxt, msgid string) string {
  114. if msgctxt != "" {
  115. return msgctxt + mo.EotSeparator + msgid
  116. }
  117. return msgid
  118. }