mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-10-31 18:28:13 +00:00 
			
		
		
		
	Switch to v1.0.2 of github.com/chai2010/gettext-go
Signed-off-by: Davanum Srinivas <davanum@gmail.com>
This commit is contained in:
		
							
								
								
									
										4
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								go.mod
									
									
									
									
									
								
							| @@ -148,7 +148,7 @@ require ( | |||||||
| 	github.com/beorn7/perks v1.0.1 // indirect | 	github.com/beorn7/perks v1.0.1 // indirect | ||||||
| 	github.com/boltdb/bolt v1.3.1 // indirect | 	github.com/boltdb/bolt v1.3.1 // indirect | ||||||
| 	github.com/cespare/xxhash/v2 v2.1.2 // indirect | 	github.com/cespare/xxhash/v2 v2.1.2 // indirect | ||||||
| 	github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5 // indirect | 	github.com/chai2010/gettext-go v1.0.2 // indirect | ||||||
| 	github.com/checkpoint-restore/go-criu/v5 v5.3.0 // indirect | 	github.com/checkpoint-restore/go-criu/v5 v5.3.0 // indirect | ||||||
| 	github.com/cilium/ebpf v0.7.0 // indirect | 	github.com/cilium/ebpf v0.7.0 // indirect | ||||||
| 	github.com/containerd/cgroups v1.0.1 // indirect | 	github.com/containerd/cgroups v1.0.1 // indirect | ||||||
| @@ -306,7 +306,7 @@ replace ( | |||||||
| 	github.com/census-instrumentation/opencensus-proto => github.com/census-instrumentation/opencensus-proto v0.2.1 | 	github.com/census-instrumentation/opencensus-proto => github.com/census-instrumentation/opencensus-proto v0.2.1 | ||||||
| 	github.com/certifi/gocertifi => github.com/certifi/gocertifi v0.0.0-20200922220541-2c3bb06c6054 | 	github.com/certifi/gocertifi => github.com/certifi/gocertifi v0.0.0-20200922220541-2c3bb06c6054 | ||||||
| 	github.com/cespare/xxhash/v2 => github.com/cespare/xxhash/v2 v2.1.2 | 	github.com/cespare/xxhash/v2 => github.com/cespare/xxhash/v2 v2.1.2 | ||||||
| 	github.com/chai2010/gettext-go => github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5 | 	github.com/chai2010/gettext-go => github.com/chai2010/gettext-go v1.0.2 | ||||||
| 	github.com/checkpoint-restore/go-criu/v5 => github.com/checkpoint-restore/go-criu/v5 v5.3.0 | 	github.com/checkpoint-restore/go-criu/v5 => github.com/checkpoint-restore/go-criu/v5 v5.3.0 | ||||||
| 	github.com/chzyer/logex => github.com/chzyer/logex v1.1.10 | 	github.com/chzyer/logex => github.com/chzyer/logex v1.1.10 | ||||||
| 	github.com/chzyer/readline => github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e | 	github.com/chzyer/readline => github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e | ||||||
|   | |||||||
							
								
								
									
										4
									
								
								go.sum
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								go.sum
									
									
									
									
									
								
							| @@ -76,8 +76,8 @@ github.com/certifi/gocertifi v0.0.0-20200922220541-2c3bb06c6054 h1:uH66TXeswKn5P | |||||||
| github.com/certifi/gocertifi v0.0.0-20200922220541-2c3bb06c6054/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA= | github.com/certifi/gocertifi v0.0.0-20200922220541-2c3bb06c6054/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA= | ||||||
| github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= | github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= | ||||||
| github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= | github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= | ||||||
| github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5 h1:7aWHqerlJ41y6FOsEUvknqgXnGmJyJSbjhAWq5pO4F8= | github.com/chai2010/gettext-go v1.0.2 h1:1Lwwip6Q2QGsAdl/ZKPCwTe9fe0CjlUbqj5bFNSjIRk= | ||||||
| github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5/go.mod h1:/iP1qXHoty45bqomnu2LM+VVyAEdWN+vtSHGlQgyxbw= | github.com/chai2010/gettext-go v1.0.2/go.mod h1:y+wnP2cHYaVj19NZhYKAwEMH2CI1gNHeQQ+5AjwawxA= | ||||||
| github.com/checkpoint-restore/go-criu/v5 v5.3.0 h1:wpFFOoomK3389ue2lAb0Boag6XPht5QYpipxmSNL4d8= | github.com/checkpoint-restore/go-criu/v5 v5.3.0 h1:wpFFOoomK3389ue2lAb0Boag6XPht5QYpipxmSNL4d8= | ||||||
| github.com/checkpoint-restore/go-criu/v5 v5.3.0/go.mod h1:E/eQpaFtUKGOOSEBZgmKAcn+zUUwWxqcaKZlF54wK8E= | github.com/checkpoint-restore/go-criu/v5 v5.3.0/go.mod h1:E/eQpaFtUKGOOSEBZgmKAcn+zUUwWxqcaKZlF54wK8E= | ||||||
| github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= | github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= | ||||||
|   | |||||||
| @@ -6,7 +6,7 @@ go 1.18 | |||||||
|  |  | ||||||
| require ( | require ( | ||||||
| 	github.com/MakeNowJust/heredoc v1.0.0 | 	github.com/MakeNowJust/heredoc v1.0.0 | ||||||
| 	github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5 | 	github.com/chai2010/gettext-go v1.0.2 | ||||||
| 	github.com/davecgh/go-spew v1.1.1 | 	github.com/davecgh/go-spew v1.1.1 | ||||||
| 	github.com/daviddengcn/go-colortext v0.0.0-20160507010035-511bcaf42ccd | 	github.com/daviddengcn/go-colortext v0.0.0-20160507010035-511bcaf42ccd | ||||||
| 	github.com/docker/distribution v2.8.1+incompatible | 	github.com/docker/distribution v2.8.1+incompatible | ||||||
|   | |||||||
							
								
								
									
										4
									
								
								staging/src/k8s.io/kubectl/go.sum
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										4
									
								
								staging/src/k8s.io/kubectl/go.sum
									
									
									
										generated
									
									
									
								
							| @@ -58,8 +58,8 @@ github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:l | |||||||
| github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= | github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= | ||||||
| github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM= | github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM= | ||||||
| github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= | github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= | ||||||
| github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5 h1:7aWHqerlJ41y6FOsEUvknqgXnGmJyJSbjhAWq5pO4F8= | github.com/chai2010/gettext-go v1.0.2 h1:1Lwwip6Q2QGsAdl/ZKPCwTe9fe0CjlUbqj5bFNSjIRk= | ||||||
| github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5/go.mod h1:/iP1qXHoty45bqomnu2LM+VVyAEdWN+vtSHGlQgyxbw= | github.com/chai2010/gettext-go v1.0.2/go.mod h1:y+wnP2cHYaVj19NZhYKAwEMH2CI1gNHeQQ+5AjwawxA= | ||||||
| github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= | github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= | ||||||
| github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= | github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= | ||||||
| github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= | github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= | ||||||
|   | |||||||
| @@ -25,7 +25,7 @@ import ( | |||||||
| 	"os" | 	"os" | ||||||
| 	"strings" | 	"strings" | ||||||
|  |  | ||||||
| 	"github.com/chai2010/gettext-go/gettext" | 	gettext "github.com/chai2010/gettext-go" | ||||||
| 	"k8s.io/klog/v2" | 	"k8s.io/klog/v2" | ||||||
| ) | ) | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										5
									
								
								vendor/github.com/chai2010/gettext-go/.travis.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								vendor/github.com/chai2010/gettext-go/.travis.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,5 @@ | |||||||
|  | language: go | ||||||
|  |  | ||||||
|  | go: | ||||||
|  |   - "1.14" | ||||||
|  |   - tip | ||||||
							
								
								
									
										191
									
								
								vendor/github.com/chai2010/gettext-go/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										191
									
								
								vendor/github.com/chai2010/gettext-go/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,191 @@ | |||||||
|  | - *赞助 BTC: 1Cbd6oGAUUyBi7X7MaR4np4nTmQZXVgkCW* | ||||||
|  | - *赞助 ETH: 0x623A3C3a72186A6336C79b18Ac1eD36e1c71A8a6* | ||||||
|  | - *Go语言付费QQ群: 1055927514* | ||||||
|  |  | ||||||
|  | ---- | ||||||
|  |  | ||||||
|  | # gettext-go: GNU gettext for Go ([Imported By Kubernetes](https://pkg.go.dev/github.com/chai2010/gettext-go@v0.1.0/gettext?tab=importedby)) | ||||||
|  |  | ||||||
|  | - PkgDoc: [http://godoc.org/github.com/chai2010/gettext-go](http://godoc.org/github.com/chai2010/gettext-go) | ||||||
|  | - PkgDoc: [http://pkg.go.dev/github.com/chai2010/gettext-go](http://pkg.go.dev/github.com/chai2010/gettext-go) | ||||||
|  |  | ||||||
|  | ## Install | ||||||
|  |  | ||||||
|  | 1. `go get github.com/chai2010/gettext-go` | ||||||
|  | 2. `go run hello.go` | ||||||
|  |  | ||||||
|  | The godoc.org or go.dev has more information. | ||||||
|  |  | ||||||
|  | ## Examples | ||||||
|  |  | ||||||
|  | ```Go | ||||||
|  | package main | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"fmt" | ||||||
|  |  | ||||||
|  | 	"github.com/chai2010/gettext-go" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | func main() { | ||||||
|  | 	gettext := gettext.New("hello", "./examples/locale").SetLanguage("zh_CN") | ||||||
|  | 	fmt.Println(gettext.Gettext("Hello, world!")) | ||||||
|  |  | ||||||
|  | 	// Output: 你好, 世界! | ||||||
|  | } | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | ```Go | ||||||
|  | package main | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"fmt" | ||||||
|  |  | ||||||
|  | 	"github.com/chai2010/gettext-go" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | func main() { | ||||||
|  | 	gettext.SetLanguage("zh_CN") | ||||||
|  | 	gettext.BindLocale(gettext.New("hello", "locale")) | ||||||
|  |  | ||||||
|  | 	// gettext.BindLocale("hello", "locale")              // from locale dir | ||||||
|  | 	// gettext.BindLocale("hello", "locale.zip")          // from locale zip file | ||||||
|  | 	// gettext.BindLocale("hello", "locale.zip", zipData) // from embedded zip data | ||||||
|  |  | ||||||
|  | 	// translate source text | ||||||
|  | 	fmt.Println(gettext.Gettext("Hello, world!")) | ||||||
|  | 	// Output: 你好, 世界! | ||||||
|  |  | ||||||
|  | 	// if no msgctxt in PO file (only msgid and msgstr), | ||||||
|  | 	// specify context as "" by | ||||||
|  | 	fmt.Println(gettext.PGettext("", "Hello, world!")) | ||||||
|  | 	// Output: 你好, 世界! | ||||||
|  |  | ||||||
|  | 	// translate resource | ||||||
|  | 	fmt.Println(string(gettext.Getdata("poems.txt")))) | ||||||
|  | 	// Output: ... | ||||||
|  | } | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | Go file: [hello.go](https://github.com/chai2010/gettext-go/blob/master/examples/hello.go); PO file: [hello.po](https://github.com/chai2010/gettext-go/blob/master/examples/locale/default/LC_MESSAGES/hello.po); | ||||||
|  |  | ||||||
|  | ---- | ||||||
|  |  | ||||||
|  | ## API Changes (v0.1.0 vs v1.0.0) | ||||||
|  |  | ||||||
|  | ### Renamed package path | ||||||
|  |  | ||||||
|  | | v0.1.0 (old)                                    | v1.0.0 (new)                            | | ||||||
|  | | ----------------------------------------------- | --------------------------------------- | | ||||||
|  | | `github.com/chai2010/gettext-go/gettext`        | `github.com/chai2010/gettext-go`        | | ||||||
|  | | `github.com/chai2010/gettext-go/gettext/po`     | `github.com/chai2010/gettext-go/po`     | | ||||||
|  | | `github.com/chai2010/gettext-go/gettext/mo`     | `github.com/chai2010/gettext-go/mo`     | | ||||||
|  | | `github.com/chai2010/gettext-go/gettext/plural` | `github.com/chai2010/gettext-go/plural` | | ||||||
|  |  | ||||||
|  | ### Renamed functions | ||||||
|  |  | ||||||
|  | | v0.1.0 (old)                       | v1.0.0 (new)                | | ||||||
|  | | ---------------------------------- | --------------------------- | | ||||||
|  | | `gettext-go/gettext.*`             | `gettext-go.*`              | | ||||||
|  | | `gettext-go/gettext.DefaultLocal`  | `gettext-go.DefaultLanguage`| | ||||||
|  | | `gettext-go/gettext.BindTextdomain`| `gettext-go.BindLocale`     | | ||||||
|  | | `gettext-go/gettext.Textdomain`    | `gettext-go.SetDomain`      | | ||||||
|  | | `gettext-go/gettext.SetLocale`     | `gettext-go.SetLanguage`    | | ||||||
|  | | `gettext-go/gettext/po.Load`       | `gettext-go/po.LoadFile`    | | ||||||
|  | | `gettext-go/gettext/po.LoadData`   | `gettext-go/po.Load`        | | ||||||
|  | | `gettext-go/gettext/mo.Load`       | `gettext-go/mo.LoadFile`    | | ||||||
|  | | `gettext-go/gettext/mo.LoadData`   | `gettext-go/mo.Load`        | | ||||||
|  |  | ||||||
|  | ### Use empty string as the default context for `gettext.Gettext` | ||||||
|  |  | ||||||
|  | ```go | ||||||
|  | package main | ||||||
|  |  | ||||||
|  | // v0.1.0 | ||||||
|  | // if the **context** missing, use `callerName(2)` as the context: | ||||||
|  |  | ||||||
|  | // v1.0.0 | ||||||
|  | // if the **context** missing, use empty string as the context: | ||||||
|  |  | ||||||
|  | func main() { | ||||||
|  | 	gettext.Gettext("hello")           | ||||||
|  | 	// v0.1.0 => gettext.PGettext("main.main", "hello") | ||||||
|  | 	// v1.0.0 => gettext.PGettext("", "hello") | ||||||
|  |  | ||||||
|  | 	gettext.DGettext("domain", "hello") | ||||||
|  | 	// v0.1.0 => gettext.DPGettext("domain", "main.main", "hello") | ||||||
|  | 	// v1.0.0 => gettext.DPGettext("domain", "", "hello") | ||||||
|  |  | ||||||
|  | 	gettext.NGettext("domain", "hello", "hello2", n) | ||||||
|  | 	// v0.1.0 => gettext.PNGettext("domain", "main.main", "hello", "hello2", n) | ||||||
|  | 	// v1.0.0 => gettext.PNGettext("domain", "", "hello", "hello2", n) | ||||||
|  |  | ||||||
|  | 	gettext.DNGettext("domain", "hello", "hello2", n) | ||||||
|  | 	// v0.1.0 => gettext.DPNGettext("domain", "main.main", "hello", "hello2", n) | ||||||
|  | 	// v1.0.0 => gettext.DPNGettext("domain", "", "hello", "hello2", n) | ||||||
|  | } | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | ### `BindLocale` support `FileSystem` interface | ||||||
|  |  | ||||||
|  | ```go | ||||||
|  | // Use FileSystem: | ||||||
|  | //	BindLocale(New("poedit", "name", OS("path/to/dir"))) // bind "poedit" domain | ||||||
|  | //	BindLocale(New("poedit", "name", OS("path/to.zip"))) // bind "poedit" domain | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | ## New API in v1.0.0 | ||||||
|  |  | ||||||
|  | `Gettexter` interface: | ||||||
|  |  | ||||||
|  | ```go | ||||||
|  | type Gettexter interface { | ||||||
|  | 	FileSystem() FileSystem | ||||||
|  |  | ||||||
|  | 	GetDomain() string | ||||||
|  | 	SetDomain(domain string) Gettexter | ||||||
|  |  | ||||||
|  | 	GetLanguage() string | ||||||
|  | 	SetLanguage(lang string) Gettexter | ||||||
|  |  | ||||||
|  | 	Gettext(msgid string) string | ||||||
|  | 	PGettext(msgctxt, msgid string) string | ||||||
|  |  | ||||||
|  | 	NGettext(msgid, msgidPlural string, n int) string | ||||||
|  | 	PNGettext(msgctxt, msgid, msgidPlural string, n int) string | ||||||
|  |  | ||||||
|  | 	DGettext(domain, msgid string) string | ||||||
|  | 	DPGettext(domain, msgctxt, msgid string) string | ||||||
|  | 	DNGettext(domain, msgid, msgidPlural string, n int) string | ||||||
|  | 	DPNGettext(domain, msgctxt, msgid, msgidPlural string, n int) string | ||||||
|  |  | ||||||
|  | 	Getdata(name string) []byte | ||||||
|  | 	DGetdata(domain, name string) []byte | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func New(domain, path string, data ...interface{}) Gettexter | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | `FileSystem` interface: | ||||||
|  |  | ||||||
|  | ```go | ||||||
|  | type FileSystem interface { | ||||||
|  | 	LocaleList() []string | ||||||
|  | 	LoadMessagesFile(domain, lang, ext string) ([]byte, error) | ||||||
|  | 	LoadResourceFile(domain, lang, name string) ([]byte, error) | ||||||
|  | 	String() string | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func NewFS(name string, x interface{}) FileSystem | ||||||
|  | func OS(root string) FileSystem | ||||||
|  | func ZipFS(r *zip.Reader, name string) FileSystem | ||||||
|  | func NilFS(name string) FileSystem | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | ---- | ||||||
|  |  | ||||||
|  | ## BUGS | ||||||
|  |  | ||||||
|  | Please report bugs to <chaishushan@gmail.com>. | ||||||
|  |  | ||||||
|  | Thanks! | ||||||
| @@ -7,18 +7,17 @@ Package gettext implements a basic GNU's gettext library. | |||||||
| 
 | 
 | ||||||
| Example: | Example: | ||||||
| 	import ( | 	import ( | ||||||
| 		"github.com/chai2010/gettext-go/gettext" | 		"github.com/chai2010/gettext-go" | ||||||
| 	) | 	) | ||||||
| 
 | 
 | ||||||
| 	func main() { | 	func main() { | ||||||
| 		gettext.SetLocale("zh_CN") | 		gettext.SetLanguage("zh_CN") | ||||||
| 		gettext.Textdomain("hello") |  | ||||||
| 
 | 
 | ||||||
| 		// gettext.BindTextdomain("hello", "local", nil)         // from local dir | 		// gettext.BindLocale(gettext.New("hello", "locale"))              // from locale dir | ||||||
| 		// gettext.BindTextdomain("hello", "local.zip", nil)     // from local zip file | 		// gettext.BindLocale(gettext.New("hello", "locale.zip"))          // from locale zip file | ||||||
| 		// gettext.BindTextdomain("hello", "local.zip", zipData) // from embedded zip data | 		// gettext.BindLocale(gettext.New("hello", "locale.zip", zipData)) // from embedded zip data | ||||||
| 
 | 
 | ||||||
| 		gettext.BindTextdomain("hello", "local", nil) | 		gettext.BindLocale(gettext.New("hello", "locale")) | ||||||
| 
 | 
 | ||||||
| 		// translate source text | 		// translate source text | ||||||
| 		fmt.Println(gettext.Gettext("Hello, world!")) | 		fmt.Println(gettext.Gettext("Hello, world!")) | ||||||
| @@ -29,28 +28,30 @@ Example: | |||||||
| 		// Output: ... | 		// Output: ... | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| Translate directory struct("../examples/local.zip"): | Translate directory struct("./examples/locale.zip"): | ||||||
| 
 | 
 | ||||||
| 	Root: "path" or "file.zip/zipBaseName" | 	Root: "path" or "file.zip/zipBaseName" | ||||||
| 	 +-default                 # local: $(LC_MESSAGES) or $(LANG) or "default" | 	 +-default                 # locale: $(LC_MESSAGES) or $(LANG) or "default" | ||||||
| 	 |  +-LC_MESSAGES            # just for `gettext.Gettext` | 	 |  +-LC_MESSAGES            # just for `gettext.Gettext` | ||||||
| 	 |  |   +-hello.mo             # $(Root)/$(local)/LC_MESSAGES/$(domain).mo | 	 |  |   +-hello.mo             # $(Root)/$(lang)/LC_MESSAGES/$(domain).mo | ||||||
| 	 |  |   \-hello.po             # $(Root)/$(local)/LC_MESSAGES/$(domain).mo | 	 |  |   +-hello.po             # $(Root)/$(lang)/LC_MESSAGES/$(domain).po | ||||||
|  | 	 |  |   \-hello.json           # $(Root)/$(lang)/LC_MESSAGES/$(domain).json | ||||||
| 	 |  | | 	 |  | | ||||||
| 	 |  \-LC_RESOURCE            # just for `gettext.Getdata` | 	 |  \-LC_RESOURCE            # just for `gettext.Getdata` | ||||||
| 	 |      +-hello                # domain map a dir in resource translate | 	 |      +-hello                # domain map a dir in resource translate | ||||||
| 	 |         +-favicon.ico       # $(Root)/$(local)/LC_RESOURCE/$(domain)/$(filename) | 	 |         +-favicon.ico       # $(Root)/$(lang)/LC_RESOURCE/$(domain)/$(filename) | ||||||
| 	 |         \-poems.txt | 	 |         \-poems.txt | ||||||
| 	 | | 	 | | ||||||
| 	 \-zh_CN                   # simple chinese translate | 	 \-zh_CN                   # simple chinese translate | ||||||
| 	    +-LC_MESSAGES | 	    +-LC_MESSAGES | ||||||
| 	    |   +-hello.mo             # try "$(domain).mo" first | 	    |   +-hello.po             # try "$(domain).po" first | ||||||
| 	    |   \-hello.po             # try "$(domain).po" second | 	    |   +-hello.mo             # try "$(domain).mo" second | ||||||
|  | 	    |   \-hello.json           # try "$(domain).json" third | ||||||
| 	    | | 	    | | ||||||
| 	    \-LC_RESOURCE | 	    \-LC_RESOURCE | ||||||
| 	        +-hello | 	        +-hello | ||||||
| 	           +-favicon.ico       # try "$(local)/$(domain)/file" first | 	           +-favicon.ico       # $(lang)/$(domain)/favicon.ico | ||||||
| 	           \-poems.txt         # try "default/$(domain)/file" second | 	           \-poems.txt         # $(lang)/$(domain)/poems.txt | ||||||
| 
 | 
 | ||||||
| See: | See: | ||||||
| 	http://en.wikipedia.org/wiki/Gettext | 	http://en.wikipedia.org/wiki/Gettext | ||||||
							
								
								
									
										84
									
								
								vendor/github.com/chai2010/gettext-go/fs.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										84
									
								
								vendor/github.com/chai2010/gettext-go/fs.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,84 @@ | |||||||
|  | // Copyright 2013 ChaiShushan <chaishushan{AT}gmail.com>. All rights reserved. | ||||||
|  | // Use of this source code is governed by a BSD-style | ||||||
|  | // license that can be found in the LICENSE file. | ||||||
|  |  | ||||||
|  | package gettext | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"archive/zip" | ||||||
|  | 	"bytes" | ||||||
|  | 	"fmt" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | type FileSystem interface { | ||||||
|  | 	LocaleList() []string | ||||||
|  | 	LoadMessagesFile(domain, lang, ext string) ([]byte, error) | ||||||
|  | 	LoadResourceFile(domain, lang, name string) ([]byte, error) | ||||||
|  | 	String() string | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func NewFS(name string, x interface{}) FileSystem { | ||||||
|  | 	if x == nil { | ||||||
|  | 		if name != "" { | ||||||
|  | 			return OS(name) | ||||||
|  | 		} | ||||||
|  | 		return NilFS(name) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	switch x := x.(type) { | ||||||
|  | 	case []byte: | ||||||
|  | 		if len(x) == 0 { | ||||||
|  | 			return OS(name) | ||||||
|  | 		} | ||||||
|  | 		if r, err := zip.NewReader(bytes.NewReader(x), int64(len(x))); err == nil { | ||||||
|  | 			return ZipFS(r, name) | ||||||
|  | 		} | ||||||
|  | 		if fs, err := newJson(x, name); err == nil { | ||||||
|  | 			return fs | ||||||
|  | 		} | ||||||
|  | 	case string: | ||||||
|  | 		if len(x) == 0 { | ||||||
|  | 			return OS(name) | ||||||
|  | 		} | ||||||
|  | 		if r, err := zip.NewReader(bytes.NewReader([]byte(x)), int64(len(x))); err == nil { | ||||||
|  | 			return ZipFS(r, name) | ||||||
|  | 		} | ||||||
|  | 		if fs, err := newJson([]byte(x), name); err == nil { | ||||||
|  | 			return fs | ||||||
|  | 		} | ||||||
|  | 	case FileSystem: | ||||||
|  | 		return x | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return NilFS(name) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func OS(root string) FileSystem { | ||||||
|  | 	return newOsFS(root) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func ZipFS(r *zip.Reader, name string) FileSystem { | ||||||
|  | 	return newZipFS(r, name) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func NilFS(name string) FileSystem { | ||||||
|  | 	return &nilFS{name} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | type nilFS struct { | ||||||
|  | 	name string | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (p *nilFS) LocaleList() []string { | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (p *nilFS) LoadMessagesFile(domain, lang, ext string) ([]byte, error) { | ||||||
|  | 	return nil, fmt.Errorf("not found") | ||||||
|  | } | ||||||
|  | func (p *nilFS) LoadResourceFile(domain, lang, name string) ([]byte, error) { | ||||||
|  | 	return nil, fmt.Errorf("not found") | ||||||
|  | } | ||||||
|  | func (p *nilFS) String() string { | ||||||
|  | 	return "gettext.nilfs(" + p.name + ")" | ||||||
|  | } | ||||||
							
								
								
									
										66
									
								
								vendor/github.com/chai2010/gettext-go/fs_json.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								vendor/github.com/chai2010/gettext-go/fs_json.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,66 @@ | |||||||
|  | // Copyright 2020 ChaiShushan <chaishushan{AT}gmail.com>. All rights reserved. | ||||||
|  | // Use of this source code is governed by a BSD-style | ||||||
|  | // license that can be found in the LICENSE file. | ||||||
|  |  | ||||||
|  | package gettext | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"encoding/json" | ||||||
|  | 	"fmt" | ||||||
|  | 	"sort" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | type jsonFS struct { | ||||||
|  | 	name string | ||||||
|  | 	x    map[string]struct { | ||||||
|  | 		LC_MESSAGES map[string][]struct { | ||||||
|  | 			MsgContext  string   `json:"msgctxt"`      // msgctxt context | ||||||
|  | 			MsgId       string   `json:"msgid"`        // msgid untranslated-string | ||||||
|  | 			MsgIdPlural string   `json:"msgid_plural"` // msgid_plural untranslated-string-plural | ||||||
|  | 			MsgStr      []string `json:"msgstr"`       // msgstr translated-string | ||||||
|  | 		} | ||||||
|  | 		LC_RESOURCE map[string]map[string]string | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func isJsonData() bool { | ||||||
|  | 	return false | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func newJson(jsonData []byte, name string) (*jsonFS, error) { | ||||||
|  | 	p := &jsonFS{name: name} | ||||||
|  | 	if err := json.Unmarshal(jsonData, &p.x); err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return p, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (p *jsonFS) LocaleList() []string { | ||||||
|  | 	var ss []string | ||||||
|  | 	for lang := range p.x { | ||||||
|  | 		ss = append(ss, lang) | ||||||
|  | 	} | ||||||
|  | 	sort.Strings(ss) | ||||||
|  | 	return ss | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (p *jsonFS) LoadMessagesFile(domain, lang, ext string) ([]byte, error) { | ||||||
|  | 	if v, ok := p.x[lang]; ok { | ||||||
|  | 		if v, ok := v.LC_MESSAGES[domain+ext]; ok { | ||||||
|  | 			return json.Marshal(v) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return nil, fmt.Errorf("not found") | ||||||
|  | } | ||||||
|  | func (p *jsonFS) LoadResourceFile(domain, lang, name string) ([]byte, error) { | ||||||
|  | 	if v, ok := p.x[lang]; ok { | ||||||
|  | 		if v, ok := v.LC_RESOURCE[domain]; ok { | ||||||
|  | 			return []byte(v[name]), nil | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return nil, fmt.Errorf("not found") | ||||||
|  | } | ||||||
|  | func (p *jsonFS) String() string { | ||||||
|  | 	return "gettext.nilfs(" + p.name + ")" | ||||||
|  | } | ||||||
							
								
								
									
										91
									
								
								vendor/github.com/chai2010/gettext-go/fs_os.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										91
									
								
								vendor/github.com/chai2010/gettext-go/fs_os.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,91 @@ | |||||||
|  | // Copyright 2013 ChaiShushan <chaishushan{AT}gmail.com>. All rights reserved. | ||||||
|  | // Use of this source code is governed by a BSD-style | ||||||
|  | // license that can be found in the LICENSE file. | ||||||
|  |  | ||||||
|  | package gettext | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"archive/zip" | ||||||
|  | 	"bytes" | ||||||
|  | 	"fmt" | ||||||
|  | 	"io/ioutil" | ||||||
|  | 	"os" | ||||||
|  | 	"sort" | ||||||
|  | 	"strings" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | type osFS struct { | ||||||
|  | 	root string | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func newOsFS(root string) FileSystem { | ||||||
|  | 	// locale zip file | ||||||
|  | 	if fi, err := os.Stat(root); err == nil && !fi.IsDir() { | ||||||
|  | 		if strings.HasSuffix(strings.ToLower(root), ".zip") { | ||||||
|  | 			if x, err := ioutil.ReadFile(root); err == nil { | ||||||
|  | 				if r, err := zip.NewReader(bytes.NewReader(x), int64(len(x))); err == nil { | ||||||
|  | 					return ZipFS(r, root) | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		if strings.HasSuffix(strings.ToLower(root), ".json") { | ||||||
|  | 			if x, err := ioutil.ReadFile(root); err == nil { | ||||||
|  | 				if fs, err := newJson(x, root); err == nil { | ||||||
|  | 					return fs | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// locale dir | ||||||
|  | 	return &osFS{root: root} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (p *osFS) LocaleList() []string { | ||||||
|  | 	list, err := ioutil.ReadDir(p.root) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  | 	ssMap := make(map[string]bool) | ||||||
|  | 	for _, dir := range list { | ||||||
|  | 		if dir.IsDir() { | ||||||
|  | 			ssMap[dir.Name()] = true | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	var locales = make([]string, 0, len(ssMap)) | ||||||
|  | 	for s := range ssMap { | ||||||
|  | 		locales = append(locales, s) | ||||||
|  | 	} | ||||||
|  | 	sort.Strings(locales) | ||||||
|  | 	return locales | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (p *osFS) LoadMessagesFile(domain, locale, ext string) ([]byte, error) { | ||||||
|  | 	trName := p.makeMessagesFileName(domain, locale, ext) | ||||||
|  | 	rcData, err := ioutil.ReadFile(trName) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 	return rcData, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (p *osFS) LoadResourceFile(domain, locale, name string) ([]byte, error) { | ||||||
|  | 	rcName := p.makeResourceFileName(domain, locale, name) | ||||||
|  | 	rcData, err := ioutil.ReadFile(rcName) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 	return rcData, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (p *osFS) String() string { | ||||||
|  | 	return "gettext.localfs(" + p.root + ")" | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (p *osFS) makeMessagesFileName(domain, lang, ext string) string { | ||||||
|  | 	return fmt.Sprintf("%s/%s/LC_MESSAGES/%s%s", p.root, lang, domain, ext) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (p *osFS) makeResourceFileName(domain, lang, name string) string { | ||||||
|  | 	return fmt.Sprintf("%s/%s/LC_RESOURCE/%s/%s", p.root, lang, domain, name) | ||||||
|  | } | ||||||
							
								
								
									
										142
									
								
								vendor/github.com/chai2010/gettext-go/fs_zip.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										142
									
								
								vendor/github.com/chai2010/gettext-go/fs_zip.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,142 @@ | |||||||
|  | // Copyright 2013 ChaiShushan <chaishushan{AT}gmail.com>. All rights reserved. | ||||||
|  | // Use of this source code is governed by a BSD-style | ||||||
|  | // license that can be found in the LICENSE file. | ||||||
|  |  | ||||||
|  | package gettext | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"archive/zip" | ||||||
|  | 	"fmt" | ||||||
|  | 	"io/ioutil" | ||||||
|  | 	"sort" | ||||||
|  | 	"strings" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | type zipFS struct { | ||||||
|  | 	root string | ||||||
|  | 	name string | ||||||
|  | 	r    *zip.Reader | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func newZipFS(r *zip.Reader, name string) *zipFS { | ||||||
|  | 	fs := &zipFS{r: r, name: name} | ||||||
|  | 	fs.root = fs.zipRoot() | ||||||
|  | 	return fs | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (p *zipFS) zipName() string { | ||||||
|  | 	name := p.name | ||||||
|  | 	if x := strings.LastIndexAny(name, `\/`); x != -1 { | ||||||
|  | 		name = name[x+1:] | ||||||
|  | 	} | ||||||
|  | 	name = strings.TrimSuffix(name, ".zip") | ||||||
|  | 	return name | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (p *zipFS) zipRoot() string { | ||||||
|  | 	var somepath string | ||||||
|  | 	for _, f := range p.r.File { | ||||||
|  | 		if x := strings.Index(f.Name, "LC_MESSAGES"); x != -1 { | ||||||
|  | 			somepath = f.Name | ||||||
|  | 		} | ||||||
|  | 		if x := strings.Index(f.Name, "LC_RESOURCE"); x != -1 { | ||||||
|  | 			somepath = f.Name | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	if somepath == "" { | ||||||
|  | 		return p.zipName() | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	ss := strings.Split(somepath, "/") | ||||||
|  | 	for i, s := range ss { | ||||||
|  | 		// $(root)/$(lang)/LC_MESSAGES | ||||||
|  | 		// $(root)/$(lang)/LC_RESOURCE | ||||||
|  | 		if (s == "LC_MESSAGES" || s == "LC_RESOURCE") && i >= 2 { | ||||||
|  | 			return strings.Join(ss[:i-1], "/") | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return p.zipName() | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (p *zipFS) LocaleList() []string { | ||||||
|  | 	var locals []string | ||||||
|  | 	for s := range p.lsZip(p.r) { | ||||||
|  | 		locals = append(locals, s) | ||||||
|  | 	} | ||||||
|  | 	sort.Strings(locals) | ||||||
|  | 	return locals | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (p *zipFS) LoadMessagesFile(domain, lang, ext string) ([]byte, error) { | ||||||
|  | 	trName := p.makeMessagesFileName(domain, lang, ext) | ||||||
|  | 	for _, f := range p.r.File { | ||||||
|  | 		if f.Name != trName { | ||||||
|  | 			continue | ||||||
|  | 		} | ||||||
|  | 		rc, err := f.Open() | ||||||
|  | 		if err != nil { | ||||||
|  | 			return nil, err | ||||||
|  | 		} | ||||||
|  | 		rcData, err := ioutil.ReadAll(rc) | ||||||
|  | 		rc.Close() | ||||||
|  | 		return rcData, err | ||||||
|  | 	} | ||||||
|  | 	return nil, fmt.Errorf("not found") | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (p *zipFS) LoadResourceFile(domain, lang, name string) ([]byte, error) { | ||||||
|  | 	rcName := p.makeResourceFileName(domain, lang, name) | ||||||
|  | 	for _, f := range p.r.File { | ||||||
|  | 		if f.Name != rcName { | ||||||
|  | 			continue | ||||||
|  | 		} | ||||||
|  | 		rc, err := f.Open() | ||||||
|  | 		if err != nil { | ||||||
|  | 			return nil, err | ||||||
|  | 		} | ||||||
|  | 		rcData, err := ioutil.ReadAll(rc) | ||||||
|  | 		rc.Close() | ||||||
|  | 		return rcData, err | ||||||
|  | 	} | ||||||
|  | 	return nil, fmt.Errorf("not found") | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (p *zipFS) String() string { | ||||||
|  | 	return "gettext.zipfs(" + p.name + ")" | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (p *zipFS) makeMessagesFileName(domain, lang, ext string) string { | ||||||
|  | 	return fmt.Sprintf("%s/%s/LC_MESSAGES/%s%s", p.root, lang, domain, ext) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (p *zipFS) makeResourceFileName(domain, lang, name string) string { | ||||||
|  | 	return fmt.Sprintf("%s/%s/LC_RESOURCE/%s/%s", p.root, lang, domain, name) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (p *zipFS) lsZip(r *zip.Reader) map[string]bool { | ||||||
|  | 	ssMap := make(map[string]bool) | ||||||
|  | 	for _, f := range r.File { | ||||||
|  | 		if x := strings.Index(f.Name, "LC_MESSAGES"); x != -1 { | ||||||
|  | 			s := strings.TrimRight(f.Name[:x], `\/`) | ||||||
|  | 			if x = strings.LastIndexAny(s, `\/`); x != -1 { | ||||||
|  | 				s = s[x+1:] | ||||||
|  | 			} | ||||||
|  | 			if s != "" { | ||||||
|  | 				ssMap[s] = true | ||||||
|  | 			} | ||||||
|  | 			continue | ||||||
|  | 		} | ||||||
|  | 		if x := strings.Index(f.Name, "LC_RESOURCE"); x != -1 { | ||||||
|  | 			s := strings.TrimRight(f.Name[:x], `\/`) | ||||||
|  | 			if x = strings.LastIndexAny(s, `\/`); x != -1 { | ||||||
|  | 				s = s[x+1:] | ||||||
|  | 			} | ||||||
|  | 			if s != "" { | ||||||
|  | 				ssMap[s] = true | ||||||
|  | 			} | ||||||
|  | 			continue | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return ssMap | ||||||
|  | } | ||||||
| @@ -5,57 +5,91 @@ | |||||||
| package gettext | package gettext | ||||||
| 
 | 
 | ||||||
| var ( | var ( | ||||||
| 	defaultManager = newDomainManager() | 	DefaultLanguage string = getDefaultLanguage() // use $(LC_MESSAGES) or $(LANG) or "default" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| var ( | type Gettexter interface { | ||||||
| 	DefaultLocale = getDefaultLocale() // use $(LC_MESSAGES) or $(LANG) or "default" | 	FileSystem() FileSystem | ||||||
| ) |  | ||||||
| 
 | 
 | ||||||
| // SetLocale sets and queries the program's current locale. | 	GetDomain() string | ||||||
|  | 	SetDomain(domain string) Gettexter | ||||||
|  | 
 | ||||||
|  | 	GetLanguage() string | ||||||
|  | 	SetLanguage(lang string) Gettexter | ||||||
|  | 
 | ||||||
|  | 	Gettext(msgid string) string | ||||||
|  | 	PGettext(msgctxt, msgid string) string | ||||||
|  | 
 | ||||||
|  | 	NGettext(msgid, msgidPlural string, n int) string | ||||||
|  | 	PNGettext(msgctxt, msgid, msgidPlural string, n int) string | ||||||
|  | 
 | ||||||
|  | 	DGettext(domain, msgid string) string | ||||||
|  | 	DPGettext(domain, msgctxt, msgid string) string | ||||||
|  | 	DNGettext(domain, msgid, msgidPlural string, n int) string | ||||||
|  | 	DPNGettext(domain, msgctxt, msgid, msgidPlural string, n int) string | ||||||
|  | 
 | ||||||
|  | 	Getdata(name string) []byte | ||||||
|  | 	DGetdata(domain, name string) []byte | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // New create Interface use default language. | ||||||
|  | func New(domain, path string, data ...interface{}) Gettexter { | ||||||
|  | 	return newLocale(domain, path, data...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | var defaultGettexter struct { | ||||||
|  | 	lang   string | ||||||
|  | 	domain string | ||||||
|  | 	Gettexter | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func init() { | ||||||
|  | 	defaultGettexter.lang = getDefaultLanguage() | ||||||
|  | 	defaultGettexter.domain = "default" | ||||||
|  | 	defaultGettexter.Gettexter = newLocale("", "") | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // BindLocale sets and queries program's domains. | ||||||
| // | // | ||||||
| // If the locale is not empty string, set the new local. | // Examples: | ||||||
|  | //	BindLocale(New("poedit", "locale")) // bind "poedit" domain | ||||||
| // | // | ||||||
| // If the locale is empty string, don't change anything. | // Use zip file: | ||||||
|  | //	BindLocale(New("poedit", "locale.zip"))          // bind "poedit" domain | ||||||
|  | //	BindLocale(New("poedit", "locale.zip", zipData)) // bind "poedit" domain | ||||||
|  | // | ||||||
|  | // Use FileSystem: | ||||||
|  | //	BindLocale(New("poedit", "name", OS("path/to/dir"))) // bind "poedit" domain | ||||||
|  | //	BindLocale(New("poedit", "name", OS("path/to.zip"))) // bind "poedit" domain | ||||||
|  | // | ||||||
|  | func BindLocale(g Gettexter) { | ||||||
|  | 	if g != nil { | ||||||
|  | 		defaultGettexter.Gettexter = g | ||||||
|  | 		defaultGettexter.SetLanguage(defaultGettexter.lang) | ||||||
|  | 	} else { | ||||||
|  | 		defaultGettexter.Gettexter = newLocale("", "") | ||||||
|  | 		defaultGettexter.SetLanguage(defaultGettexter.lang) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // SetLanguage sets and queries the program's current lang. | ||||||
|  | // | ||||||
|  | // If the lang is not empty string, set the new locale. | ||||||
|  | // | ||||||
|  | // If the lang is empty string, don't change anything. | ||||||
| // | // | ||||||
| // Returns is the current locale. | // Returns is the current locale. | ||||||
| // | // | ||||||
| // Examples: | // Examples: | ||||||
| //	SetLocale("")      // get locale: return DefaultLocale | //	SetLanguage("")      // get locale: return DefaultLocale | ||||||
| //	SetLocale("zh_CN") // set locale: return zh_CN | //	SetLanguage("zh_CN") // set locale: return zh_CN | ||||||
| //	SetLocale("")      // get locale: return zh_CN | //	SetLanguage("")      // get locale: return zh_CN | ||||||
| func SetLocale(locale string) string { | func SetLanguage(lang string) string { | ||||||
| 	return defaultManager.SetLocale(locale) | 	defaultGettexter.SetLanguage(lang) | ||||||
|  | 	return defaultGettexter.GetLanguage() | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // BindTextdomain sets and queries program's domains. | // SetDomain sets and retrieves the current message domain. | ||||||
| // |  | ||||||
| // If the domain and path are all not empty string, bind the new domain. |  | ||||||
| // If the domain already exists, return error. |  | ||||||
| // |  | ||||||
| // If the domain is not empty string, but the path is the empty string, |  | ||||||
| // delete the domain. |  | ||||||
| // If the domain don't exists, return error. |  | ||||||
| // |  | ||||||
| // If the domain and the path are all empty string, don't change anything. |  | ||||||
| // |  | ||||||
| // Returns is the all bind domains. |  | ||||||
| // |  | ||||||
| // Examples: |  | ||||||
| //	BindTextdomain("poedit", "local", nil) // bind "poedit" domain |  | ||||||
| //	BindTextdomain("", "", nil)            // return all domains |  | ||||||
| //	BindTextdomain("poedit", "", nil)      // delete "poedit" domain |  | ||||||
| //	BindTextdomain("", "", nil)            // return all domains |  | ||||||
| // |  | ||||||
| // Use zip file: |  | ||||||
| //	BindTextdomain("poedit", "local.zip", nil)     // bind "poedit" domain |  | ||||||
| //	BindTextdomain("poedit", "local.zip", zipData) // bind "poedit" domain |  | ||||||
| // |  | ||||||
| func BindTextdomain(domain, path string, zipData []byte) (domains, paths []string) { |  | ||||||
| 	return defaultManager.Bind(domain, path, zipData) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Textdomain sets and retrieves the current message domain. |  | ||||||
| // | // | ||||||
| // If the domain is not empty string, set the new domains. | // If the domain is not empty string, set the new domains. | ||||||
| // | // | ||||||
| @@ -64,10 +98,11 @@ func BindTextdomain(domain, path string, zipData []byte) (domains, paths []strin | |||||||
| // Returns is the all used domains. | // Returns is the all used domains. | ||||||
| // | // | ||||||
| // Examples: | // Examples: | ||||||
| //	Textdomain("poedit") // set domain: poedit | //	SetDomain("poedit") // set domain: poedit | ||||||
| //	Textdomain("")       // get domain: return poedit | //	SetDomain("")       // get domain: return poedit | ||||||
| func Textdomain(domain string) string { | func SetDomain(domain string) string { | ||||||
| 	return defaultManager.SetDomain(domain) | 	defaultGettexter.SetDomain(domain) | ||||||
|  | 	return defaultGettexter.GetDomain() | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Gettext attempt to translate a text string into the user's native language, | // Gettext attempt to translate a text string into the user's native language, | ||||||
| @@ -77,10 +112,10 @@ func Textdomain(domain string) string { | |||||||
| // | // | ||||||
| // Examples: | // Examples: | ||||||
| //	func Foo() { | //	func Foo() { | ||||||
| //		msg := gettext.Gettext("Hello") // msgctxt is "some/package/name.Foo" | //		msg := gettext.Gettext("Hello") // msgctxt is "" | ||||||
| //	} | //	} | ||||||
| func Gettext(msgid string) string { | func Gettext(msgid string) string { | ||||||
| 	return PGettext(callerName(2), msgid) | 	return defaultGettexter.Gettext(msgid) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Getdata attempt to translate a resource file into the user's native language, | // Getdata attempt to translate a resource file into the user's native language, | ||||||
| @@ -89,11 +124,11 @@ func Gettext(msgid string) string { | |||||||
| // Examples: | // Examples: | ||||||
| //	func Foo() { | //	func Foo() { | ||||||
| //		Textdomain("hello") | //		Textdomain("hello") | ||||||
| //		BindTextdomain("hello", "local.zip", nilOrZipData) | //		BindLocale("hello", "locale.zip", nilOrZipData) | ||||||
| //		poems := gettext.Getdata("poems.txt") | //		poems := gettext.Getdata("poems.txt") | ||||||
| //	} | //	} | ||||||
| func Getdata(name string) []byte { | func Getdata(name string) []byte { | ||||||
| 	return defaultManager.Getdata(name) | 	return defaultGettexter.Getdata(name) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // NGettext attempt to translate a text string into the user's native language, | // NGettext attempt to translate a text string into the user's native language, | ||||||
| @@ -107,7 +142,7 @@ func Getdata(name string) []byte { | |||||||
| //		msg := gettext.NGettext("%d people", "%d peoples", 2) | //		msg := gettext.NGettext("%d people", "%d peoples", 2) | ||||||
| //	} | //	} | ||||||
| func NGettext(msgid, msgidPlural string, n int) string { | func NGettext(msgid, msgidPlural string, n int) string { | ||||||
| 	return PNGettext(callerName(2), msgid, msgidPlural, n) | 	return defaultGettexter.NGettext(msgid, msgidPlural, n) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // PGettext attempt to translate a text string into the user's native language, | // PGettext attempt to translate a text string into the user's native language, | ||||||
| @@ -118,7 +153,7 @@ func NGettext(msgid, msgidPlural string, n int) string { | |||||||
| //		msg := gettext.PGettext("gettext-go.example", "Hello") // msgctxt is "gettext-go.example" | //		msg := gettext.PGettext("gettext-go.example", "Hello") // msgctxt is "gettext-go.example" | ||||||
| //	} | //	} | ||||||
| func PGettext(msgctxt, msgid string) string { | func PGettext(msgctxt, msgid string) string { | ||||||
| 	return PNGettext(msgctxt, msgid, "", 0) | 	return defaultGettexter.PGettext(msgctxt, msgid) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // PNGettext attempt to translate a text string into the user's native language, | // PNGettext attempt to translate a text string into the user's native language, | ||||||
| @@ -130,7 +165,7 @@ func PGettext(msgctxt, msgid string) string { | |||||||
| //		msg := gettext.PNGettext("gettext-go.example", "%d people", "%d peoples", 2) | //		msg := gettext.PNGettext("gettext-go.example", "%d people", "%d peoples", 2) | ||||||
| //	} | //	} | ||||||
| func PNGettext(msgctxt, msgid, msgidPlural string, n int) string { | func PNGettext(msgctxt, msgid, msgidPlural string, n int) string { | ||||||
| 	return defaultManager.PNGettext(msgctxt, msgid, msgidPlural, n) | 	return defaultGettexter.PNGettext(msgctxt, msgid, msgidPlural, n) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // DGettext like Gettext(), but looking up the message in the specified domain. | // DGettext like Gettext(), but looking up the message in the specified domain. | ||||||
| @@ -140,7 +175,7 @@ func PNGettext(msgctxt, msgid, msgidPlural string, n int) string { | |||||||
| //		msg := gettext.DGettext("poedit", "Hello") | //		msg := gettext.DGettext("poedit", "Hello") | ||||||
| //	} | //	} | ||||||
| func DGettext(domain, msgid string) string { | func DGettext(domain, msgid string) string { | ||||||
| 	return DPGettext(domain, callerName(2), msgid) | 	return defaultGettexter.DGettext(domain, msgid) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // DNGettext like NGettext(), but looking up the message in the specified domain. | // DNGettext like NGettext(), but looking up the message in the specified domain. | ||||||
| @@ -150,7 +185,7 @@ func DGettext(domain, msgid string) string { | |||||||
| //		msg := gettext.PNGettext("poedit", "gettext-go.example", "%d people", "%d peoples", 2) | //		msg := gettext.PNGettext("poedit", "gettext-go.example", "%d people", "%d peoples", 2) | ||||||
| //	} | //	} | ||||||
| func DNGettext(domain, msgid, msgidPlural string, n int) string { | func DNGettext(domain, msgid, msgidPlural string, n int) string { | ||||||
| 	return DPNGettext(domain, callerName(2), msgid, msgidPlural, n) | 	return defaultGettexter.DNGettext(domain, msgid, msgidPlural, n) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // DPGettext like PGettext(), but looking up the message in the specified domain. | // DPGettext like PGettext(), but looking up the message in the specified domain. | ||||||
| @@ -160,7 +195,7 @@ func DNGettext(domain, msgid, msgidPlural string, n int) string { | |||||||
| //		msg := gettext.DPGettext("poedit", "gettext-go.example", "Hello") | //		msg := gettext.DPGettext("poedit", "gettext-go.example", "Hello") | ||||||
| //	} | //	} | ||||||
| func DPGettext(domain, msgctxt, msgid string) string { | func DPGettext(domain, msgctxt, msgid string) string { | ||||||
| 	return DPNGettext(domain, msgctxt, msgid, "", 0) | 	return defaultGettexter.DPGettext(domain, msgctxt, msgid) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // DPNGettext like PNGettext(), but looking up the message in the specified domain. | // DPNGettext like PNGettext(), but looking up the message in the specified domain. | ||||||
| @@ -170,7 +205,7 @@ func DPGettext(domain, msgctxt, msgid string) string { | |||||||
| //		msg := gettext.DPNGettext("poedit", "gettext-go.example", "%d people", "%d peoples", 2) | //		msg := gettext.DPNGettext("poedit", "gettext-go.example", "%d people", "%d peoples", 2) | ||||||
| //	} | //	} | ||||||
| func DPNGettext(domain, msgctxt, msgid, msgidPlural string, n int) string { | func DPNGettext(domain, msgctxt, msgid, msgidPlural string, n int) string { | ||||||
| 	return defaultManager.DPNGettext(domain, msgctxt, msgid, msgidPlural, n) | 	return defaultGettexter.DPNGettext(domain, msgctxt, msgid, msgidPlural, n) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // DGetdata like Getdata(), but looking up the resource in the specified domain. | // DGetdata like Getdata(), but looking up the resource in the specified domain. | ||||||
| @@ -180,5 +215,5 @@ func DPNGettext(domain, msgctxt, msgid, msgidPlural string, n int) string { | |||||||
| //		msg := gettext.DGetdata("hello", "poems.txt") | //		msg := gettext.DGetdata("hello", "poems.txt") | ||||||
| //	} | //	} | ||||||
| func DGetdata(domain, name string) []byte { | func DGetdata(domain, name string) []byte { | ||||||
| 	return defaultManager.DGetdata(domain, name) | 	return defaultGettexter.DGetdata(domain, name) | ||||||
| } | } | ||||||
							
								
								
									
										39
									
								
								vendor/github.com/chai2010/gettext-go/gettext/caller.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										39
									
								
								vendor/github.com/chai2010/gettext-go/gettext/caller.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,39 +0,0 @@ | |||||||
| // Copyright 2013 ChaiShushan <chaishushan{AT}gmail.com>. All rights reserved. |  | ||||||
| // Use of this source code is governed by a BSD-style |  | ||||||
| // license that can be found in the LICENSE file. |  | ||||||
|  |  | ||||||
| package gettext |  | ||||||
|  |  | ||||||
| import ( |  | ||||||
| 	"regexp" |  | ||||||
| 	"runtime" |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| var ( |  | ||||||
| 	reInit    = regexp.MustCompile(`init·\d+$`) // main.init·1 |  | ||||||
| 	reClosure = regexp.MustCompile(`func·\d+$`) // main.func·001 |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| // caller types: |  | ||||||
| // runtime.goexit |  | ||||||
| // runtime.main |  | ||||||
| // main.init |  | ||||||
| // main.main |  | ||||||
| // main.init·1 -> main.init |  | ||||||
| // main.func·001 -> main.func |  | ||||||
| // code.google.com/p/gettext-go/gettext.TestCallerName |  | ||||||
| // ... |  | ||||||
| func callerName(skip int) string { |  | ||||||
| 	pc, _, _, ok := runtime.Caller(skip) |  | ||||||
| 	if !ok { |  | ||||||
| 		return "" |  | ||||||
| 	} |  | ||||||
| 	name := runtime.FuncForPC(pc).Name() |  | ||||||
| 	if reInit.MatchString(name) { |  | ||||||
| 		return reInit.ReplaceAllString(name, "init") |  | ||||||
| 	} |  | ||||||
| 	if reClosure.MatchString(name) { |  | ||||||
| 		return reClosure.ReplaceAllString(name, "func") |  | ||||||
| 	} |  | ||||||
| 	return name |  | ||||||
| } |  | ||||||
							
								
								
									
										119
									
								
								vendor/github.com/chai2010/gettext-go/gettext/domain.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										119
									
								
								vendor/github.com/chai2010/gettext-go/gettext/domain.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,119 +0,0 @@ | |||||||
| // Copyright 2013 ChaiShushan <chaishushan{AT}gmail.com>. All rights reserved. |  | ||||||
| // Use of this source code is governed by a BSD-style |  | ||||||
| // license that can be found in the LICENSE file. |  | ||||||
|  |  | ||||||
| package gettext |  | ||||||
|  |  | ||||||
| import ( |  | ||||||
| 	"sync" |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| type domainManager struct { |  | ||||||
| 	mutex     sync.Mutex |  | ||||||
| 	locale    string |  | ||||||
| 	domain    string |  | ||||||
| 	domainMap map[string]*fileSystem |  | ||||||
| 	trTextMap map[string]*translator |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func newDomainManager() *domainManager { |  | ||||||
| 	return &domainManager{ |  | ||||||
| 		locale:    DefaultLocale, |  | ||||||
| 		domainMap: make(map[string]*fileSystem), |  | ||||||
| 		trTextMap: make(map[string]*translator), |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (p *domainManager) makeTrMapKey(domain, locale string) string { |  | ||||||
| 	return domain + "_$$$_" + locale |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (p *domainManager) Bind(domain, path string, data []byte) (domains, paths []string) { |  | ||||||
| 	p.mutex.Lock() |  | ||||||
| 	defer p.mutex.Unlock() |  | ||||||
|  |  | ||||||
| 	switch { |  | ||||||
| 	case domain != "" && path != "": // bind new domain |  | ||||||
| 		p.bindDomainTranslators(domain, path, data) |  | ||||||
| 	case domain != "" && path == "": // delete domain |  | ||||||
| 		p.deleteDomain(domain) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// return all bind domain |  | ||||||
| 	for k, fs := range p.domainMap { |  | ||||||
| 		domains = append(domains, k) |  | ||||||
| 		paths = append(paths, fs.FsName) |  | ||||||
| 	} |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (p *domainManager) SetLocale(locale string) string { |  | ||||||
| 	p.mutex.Lock() |  | ||||||
| 	defer p.mutex.Unlock() |  | ||||||
| 	if locale != "" { |  | ||||||
| 		p.locale = locale |  | ||||||
| 	} |  | ||||||
| 	return p.locale |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (p *domainManager) SetDomain(domain string) string { |  | ||||||
| 	p.mutex.Lock() |  | ||||||
| 	defer p.mutex.Unlock() |  | ||||||
| 	if domain != "" { |  | ||||||
| 		p.domain = domain |  | ||||||
| 	} |  | ||||||
| 	return p.domain |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (p *domainManager) Getdata(name string) []byte { |  | ||||||
| 	return p.getdata(p.domain, name) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (p *domainManager) DGetdata(domain, name string) []byte { |  | ||||||
| 	return p.getdata(domain, name) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (p *domainManager) PNGettext(msgctxt, msgid, msgidPlural string, n int) string { |  | ||||||
| 	p.mutex.Lock() |  | ||||||
| 	defer p.mutex.Unlock() |  | ||||||
| 	return p.gettext(p.domain, msgctxt, msgid, msgidPlural, n) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (p *domainManager) DPNGettext(domain, msgctxt, msgid, msgidPlural string, n int) string { |  | ||||||
| 	p.mutex.Lock() |  | ||||||
| 	defer p.mutex.Unlock() |  | ||||||
| 	return p.gettext(domain, msgctxt, msgid, msgidPlural, n) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (p *domainManager) gettext(domain, msgctxt, msgid, msgidPlural string, n int) string { |  | ||||||
| 	if p.locale == "" || p.domain == "" { |  | ||||||
| 		return msgid |  | ||||||
| 	} |  | ||||||
| 	if _, ok := p.domainMap[domain]; !ok { |  | ||||||
| 		return msgid |  | ||||||
| 	} |  | ||||||
| 	if f, ok := p.trTextMap[p.makeTrMapKey(domain, p.locale)]; ok { |  | ||||||
| 		return f.PNGettext(msgctxt, msgid, msgidPlural, n) |  | ||||||
| 	} |  | ||||||
| 	return msgid |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (p *domainManager) getdata(domain, name string) []byte { |  | ||||||
| 	if p.locale == "" || p.domain == "" { |  | ||||||
| 		return nil |  | ||||||
| 	} |  | ||||||
| 	if _, ok := p.domainMap[domain]; !ok { |  | ||||||
| 		return nil |  | ||||||
| 	} |  | ||||||
| 	if fs, ok := p.domainMap[domain]; ok { |  | ||||||
| 		if data, err := fs.LoadResourceFile(domain, p.locale, name); err == nil { |  | ||||||
| 			return data |  | ||||||
| 		} |  | ||||||
| 		if p.locale != "default" { |  | ||||||
| 			if data, err := fs.LoadResourceFile(domain, "default", name); err == nil { |  | ||||||
| 				return data |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
							
								
								
									
										50
									
								
								vendor/github.com/chai2010/gettext-go/gettext/domain_helper.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										50
									
								
								vendor/github.com/chai2010/gettext-go/gettext/domain_helper.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,50 +0,0 @@ | |||||||
| // Copyright 2013 ChaiShushan <chaishushan{AT}gmail.com>. All rights reserved. |  | ||||||
| // Use of this source code is governed by a BSD-style |  | ||||||
| // license that can be found in the LICENSE file. |  | ||||||
|  |  | ||||||
| package gettext |  | ||||||
|  |  | ||||||
| import ( |  | ||||||
| 	"fmt" |  | ||||||
| 	"strings" |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| func (p *domainManager) bindDomainTranslators(domain, path string, data []byte) { |  | ||||||
| 	if _, ok := p.domainMap[domain]; ok { |  | ||||||
| 		p.deleteDomain(domain) // delete old domain |  | ||||||
| 	} |  | ||||||
| 	fs := newFileSystem(path, data) |  | ||||||
| 	for locale, _ := range fs.LocaleMap { |  | ||||||
| 		trMapKey := p.makeTrMapKey(domain, locale) |  | ||||||
| 		if data, err := fs.LoadMessagesFile(domain, locale, ".mo"); err == nil { |  | ||||||
| 			p.trTextMap[trMapKey], _ = newMoTranslator( |  | ||||||
| 				fmt.Sprintf("%s_%s.mo", domain, locale), |  | ||||||
| 				data, |  | ||||||
| 			) |  | ||||||
| 			continue |  | ||||||
| 		} |  | ||||||
| 		if data, err := fs.LoadMessagesFile(domain, locale, ".po"); err == nil { |  | ||||||
| 			p.trTextMap[trMapKey], _ = newPoTranslator( |  | ||||||
| 				fmt.Sprintf("%s_%s.po", domain, locale), |  | ||||||
| 				data, |  | ||||||
| 			) |  | ||||||
| 			continue |  | ||||||
| 		} |  | ||||||
| 		p.trTextMap[p.makeTrMapKey(domain, locale)] = nilTranslator |  | ||||||
| 	} |  | ||||||
| 	p.domainMap[domain] = fs |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (p *domainManager) deleteDomain(domain string) { |  | ||||||
| 	if _, ok := p.domainMap[domain]; !ok { |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	// delete all mo files |  | ||||||
| 	trMapKeyPrefix := p.makeTrMapKey(domain, "") |  | ||||||
| 	for k, _ := range p.trTextMap { |  | ||||||
| 		if strings.HasPrefix(k, trMapKeyPrefix) { |  | ||||||
| 			delete(p.trTextMap, k) |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	delete(p.domainMap, domain) |  | ||||||
| } |  | ||||||
							
								
								
									
										187
									
								
								vendor/github.com/chai2010/gettext-go/gettext/fs.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										187
									
								
								vendor/github.com/chai2010/gettext-go/gettext/fs.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,187 +0,0 @@ | |||||||
| // Copyright 2013 ChaiShushan <chaishushan{AT}gmail.com>. All rights reserved. |  | ||||||
| // Use of this source code is governed by a BSD-style |  | ||||||
| // license that can be found in the LICENSE file. |  | ||||||
|  |  | ||||||
| package gettext |  | ||||||
|  |  | ||||||
| import ( |  | ||||||
| 	"archive/zip" |  | ||||||
| 	"bytes" |  | ||||||
| 	"fmt" |  | ||||||
| 	"io/ioutil" |  | ||||||
| 	"log" |  | ||||||
| 	"os" |  | ||||||
| 	"strings" |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| type fileSystem struct { |  | ||||||
| 	FsName    string |  | ||||||
| 	FsRoot    string |  | ||||||
| 	FsZipData []byte |  | ||||||
| 	LocaleMap map[string]bool |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func newFileSystem(path string, data []byte) *fileSystem { |  | ||||||
| 	fs := &fileSystem{ |  | ||||||
| 		FsName:    path, |  | ||||||
| 		FsZipData: data, |  | ||||||
| 	} |  | ||||||
| 	if err := fs.init(); err != nil { |  | ||||||
| 		log.Printf("gettext-go: invalid domain, err = %v", err) |  | ||||||
| 	} |  | ||||||
| 	return fs |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (p *fileSystem) init() error { |  | ||||||
| 	zipName := func(name string) string { |  | ||||||
| 		if x := strings.LastIndexAny(name, `\/`); x != -1 { |  | ||||||
| 			name = name[x+1:] |  | ||||||
| 		} |  | ||||||
| 		name = strings.TrimSuffix(name, ".zip") |  | ||||||
| 		return name |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// zip data |  | ||||||
| 	if len(p.FsZipData) != 0 { |  | ||||||
| 		p.FsRoot = zipName(p.FsName) |  | ||||||
| 		p.LocaleMap = p.lsZip(p.FsZipData) |  | ||||||
| 		return nil |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// local dir or zip file |  | ||||||
| 	fi, err := os.Stat(p.FsName) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// local dir |  | ||||||
| 	if fi.IsDir() { |  | ||||||
| 		p.FsRoot = p.FsName |  | ||||||
| 		p.LocaleMap = p.lsDir(p.FsName) |  | ||||||
| 		return nil |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// local zip file |  | ||||||
| 	p.FsZipData, err = ioutil.ReadFile(p.FsName) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
| 	p.FsRoot = zipName(p.FsName) |  | ||||||
| 	p.LocaleMap = p.lsZip(p.FsZipData) |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (p *fileSystem) LoadMessagesFile(domain, local, ext string) ([]byte, error) { |  | ||||||
| 	if len(p.FsZipData) == 0 { |  | ||||||
| 		trName := p.makeMessagesFileName(domain, local, ext) |  | ||||||
| 		rcData, err := ioutil.ReadFile(trName) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return nil, err |  | ||||||
| 		} |  | ||||||
| 		return rcData, nil |  | ||||||
| 	} else { |  | ||||||
| 		r, err := zip.NewReader(bytes.NewReader(p.FsZipData), int64(len(p.FsZipData))) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return nil, err |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		trName := p.makeMessagesFileName(domain, local, ext) |  | ||||||
| 		for _, f := range r.File { |  | ||||||
| 			if f.Name != trName { |  | ||||||
| 				continue |  | ||||||
| 			} |  | ||||||
| 			rc, err := f.Open() |  | ||||||
| 			if err != nil { |  | ||||||
| 				return nil, err |  | ||||||
| 			} |  | ||||||
| 			rcData, err := ioutil.ReadAll(rc) |  | ||||||
| 			rc.Close() |  | ||||||
| 			return rcData, err |  | ||||||
| 		} |  | ||||||
| 		return nil, fmt.Errorf("not found") |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (p *fileSystem) LoadResourceFile(domain, local, name string) ([]byte, error) { |  | ||||||
| 	if len(p.FsZipData) == 0 { |  | ||||||
| 		rcName := p.makeResourceFileName(domain, local, name) |  | ||||||
| 		rcData, err := ioutil.ReadFile(rcName) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return nil, err |  | ||||||
| 		} |  | ||||||
| 		return rcData, nil |  | ||||||
| 	} else { |  | ||||||
| 		r, err := zip.NewReader(bytes.NewReader(p.FsZipData), int64(len(p.FsZipData))) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return nil, err |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		rcName := p.makeResourceFileName(domain, local, name) |  | ||||||
| 		for _, f := range r.File { |  | ||||||
| 			if f.Name != rcName { |  | ||||||
| 				continue |  | ||||||
| 			} |  | ||||||
| 			rc, err := f.Open() |  | ||||||
| 			if err != nil { |  | ||||||
| 				return nil, err |  | ||||||
| 			} |  | ||||||
| 			rcData, err := ioutil.ReadAll(rc) |  | ||||||
| 			rc.Close() |  | ||||||
| 			return rcData, err |  | ||||||
| 		} |  | ||||||
| 		return nil, fmt.Errorf("not found") |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (p *fileSystem) makeMessagesFileName(domain, local, ext string) string { |  | ||||||
| 	return fmt.Sprintf("%s/%s/LC_MESSAGES/%s%s", p.FsRoot, local, domain, ext) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (p *fileSystem) makeResourceFileName(domain, local, name string) string { |  | ||||||
| 	return fmt.Sprintf("%s/%s/LC_RESOURCE/%s/%s", p.FsRoot, local, domain, name) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (p *fileSystem) lsZip(data []byte) map[string]bool { |  | ||||||
| 	r, err := zip.NewReader(bytes.NewReader(data), int64(len(data))) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil |  | ||||||
| 	} |  | ||||||
| 	ssMap := make(map[string]bool) |  | ||||||
| 	for _, f := range r.File { |  | ||||||
| 		if x := strings.Index(f.Name, "LC_MESSAGES"); x != -1 { |  | ||||||
| 			s := strings.TrimRight(f.Name[:x], `\/`) |  | ||||||
| 			if x = strings.LastIndexAny(s, `\/`); x != -1 { |  | ||||||
| 				s = s[x+1:] |  | ||||||
| 			} |  | ||||||
| 			if s != "" { |  | ||||||
| 				ssMap[s] = true |  | ||||||
| 			} |  | ||||||
| 			continue |  | ||||||
| 		} |  | ||||||
| 		if x := strings.Index(f.Name, "LC_RESOURCE"); x != -1 { |  | ||||||
| 			s := strings.TrimRight(f.Name[:x], `\/`) |  | ||||||
| 			if x = strings.LastIndexAny(s, `\/`); x != -1 { |  | ||||||
| 				s = s[x+1:] |  | ||||||
| 			} |  | ||||||
| 			if s != "" { |  | ||||||
| 				ssMap[s] = true |  | ||||||
| 			} |  | ||||||
| 			continue |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	return ssMap |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (p *fileSystem) lsDir(path string) map[string]bool { |  | ||||||
| 	list, err := ioutil.ReadDir(path) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil |  | ||||||
| 	} |  | ||||||
| 	ssMap := make(map[string]bool) |  | ||||||
| 	for _, dir := range list { |  | ||||||
| 		if dir.IsDir() { |  | ||||||
| 			ssMap[dir.Name()] = true |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	return ssMap |  | ||||||
| } |  | ||||||
							
								
								
									
										205
									
								
								vendor/github.com/chai2010/gettext-go/locale.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										205
									
								
								vendor/github.com/chai2010/gettext-go/locale.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,205 @@ | |||||||
|  | // Copyright 2020 ChaiShushan <chaishushan{AT}gmail.com>. All rights reserved. | ||||||
|  | // Use of this source code is governed by a BSD-style | ||||||
|  | // license that can be found in the LICENSE file. | ||||||
|  |  | ||||||
|  | package gettext | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"fmt" | ||||||
|  | 	"sync" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | type _Locale struct { | ||||||
|  | 	mutex     sync.Mutex | ||||||
|  | 	fs        FileSystem | ||||||
|  | 	lang      string | ||||||
|  | 	domain    string | ||||||
|  | 	trMap     map[string]*translator | ||||||
|  | 	trCurrent *translator | ||||||
|  | } | ||||||
|  |  | ||||||
|  | var _ Gettexter = (*_Locale)(nil) | ||||||
|  |  | ||||||
|  | func newLocale(domain, path string, data ...interface{}) *_Locale { | ||||||
|  | 	if domain == "" { | ||||||
|  | 		domain = "default" | ||||||
|  | 	} | ||||||
|  | 	p := &_Locale{ | ||||||
|  | 		lang:   DefaultLanguage, | ||||||
|  | 		domain: domain, | ||||||
|  | 	} | ||||||
|  | 	if len(data) > 0 { | ||||||
|  | 		p.fs = NewFS(path, data[0]) | ||||||
|  | 	} else { | ||||||
|  | 		p.fs = NewFS(path, nil) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	p.syncTrMap() | ||||||
|  | 	return p | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (p *_Locale) makeTrMapKey(domain, _Locale string) string { | ||||||
|  | 	return domain + "_$$$_" + _Locale | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (p *_Locale) FileSystem() FileSystem { | ||||||
|  | 	return p.fs | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (p *_Locale) GetLanguage() string { | ||||||
|  | 	p.mutex.Lock() | ||||||
|  | 	defer p.mutex.Unlock() | ||||||
|  |  | ||||||
|  | 	return p.lang | ||||||
|  | } | ||||||
|  | func (p *_Locale) SetLanguage(lang string) Gettexter { | ||||||
|  | 	p.mutex.Lock() | ||||||
|  | 	defer p.mutex.Unlock() | ||||||
|  |  | ||||||
|  | 	if lang == "" { | ||||||
|  | 		lang = DefaultLanguage | ||||||
|  | 	} | ||||||
|  | 	if lang == p.lang { | ||||||
|  | 		return p | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	p.lang = lang | ||||||
|  | 	p.syncTrMap() | ||||||
|  | 	return p | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (p *_Locale) GetDomain() string { | ||||||
|  | 	p.mutex.Lock() | ||||||
|  | 	defer p.mutex.Unlock() | ||||||
|  | 	return p.domain | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (p *_Locale) SetDomain(domain string) Gettexter { | ||||||
|  | 	p.mutex.Lock() | ||||||
|  | 	defer p.mutex.Unlock() | ||||||
|  |  | ||||||
|  | 	if domain == "" || domain == p.domain { | ||||||
|  | 		return p | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	p.domain = domain | ||||||
|  | 	p.syncTrMap() | ||||||
|  | 	return p | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (p *_Locale) syncTrMap() { | ||||||
|  | 	p.trMap = make(map[string]*translator) | ||||||
|  | 	trMapKey := p.makeTrMapKey(p.domain, p.lang) | ||||||
|  |  | ||||||
|  | 	if tr, ok := p.trMap[trMapKey]; ok { | ||||||
|  | 		p.trCurrent = tr | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// try load po file | ||||||
|  | 	if data, err := p.fs.LoadMessagesFile(p.domain, p.lang, ".po"); err == nil { | ||||||
|  | 		if tr, err := newPoTranslator(fmt.Sprintf("%s_%s.po", p.domain, p.lang), data); err == nil { | ||||||
|  | 			p.trMap[trMapKey] = tr | ||||||
|  | 			p.trCurrent = tr | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// try load mo file | ||||||
|  | 	if data, err := p.fs.LoadMessagesFile(p.domain, p.lang, ".mo"); err == nil { | ||||||
|  | 		if tr, err := newMoTranslator(fmt.Sprintf("%s_%s.mo", p.domain, p.lang), data); err == nil { | ||||||
|  | 			p.trMap[trMapKey] = tr | ||||||
|  | 			p.trCurrent = tr | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// try load json file | ||||||
|  | 	if data, err := p.fs.LoadMessagesFile(p.domain, p.lang, ".json"); err == nil { | ||||||
|  | 		if tr, err := newJsonTranslator(p.lang, fmt.Sprintf("%s_%s.json", p.domain, p.lang), data); err == nil { | ||||||
|  | 			p.trMap[trMapKey] = tr | ||||||
|  | 			p.trCurrent = tr | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// no po/mo file | ||||||
|  | 	p.trMap[trMapKey] = nilTranslator | ||||||
|  | 	p.trCurrent = nilTranslator | ||||||
|  | 	return | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (p *_Locale) Gettext(msgid string) string { | ||||||
|  | 	p.mutex.Lock() | ||||||
|  | 	defer p.mutex.Unlock() | ||||||
|  | 	return p.trCurrent.PGettext("", msgid) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (p *_Locale) PGettext(msgctxt, msgid string) string { | ||||||
|  | 	p.mutex.Lock() | ||||||
|  | 	defer p.mutex.Unlock() | ||||||
|  | 	return p.trCurrent.PGettext(msgctxt, msgid) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (p *_Locale) NGettext(msgid, msgidPlural string, n int) string { | ||||||
|  | 	p.mutex.Lock() | ||||||
|  | 	defer p.mutex.Unlock() | ||||||
|  | 	return p.trCurrent.PNGettext("", msgid, msgidPlural, n) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (p *_Locale) PNGettext(msgctxt, msgid, msgidPlural string, n int) string { | ||||||
|  | 	p.mutex.Lock() | ||||||
|  | 	defer p.mutex.Unlock() | ||||||
|  | 	return p.trCurrent.PNGettext(msgctxt, msgid, msgidPlural, n) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (p *_Locale) DGettext(domain, msgid string) string { | ||||||
|  | 	p.mutex.Lock() | ||||||
|  | 	defer p.mutex.Unlock() | ||||||
|  | 	return p.gettext(domain, "", msgid, "", 0) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (p *_Locale) DNGettext(domain, msgid, msgidPlural string, n int) string { | ||||||
|  | 	p.mutex.Lock() | ||||||
|  | 	defer p.mutex.Unlock() | ||||||
|  | 	return p.gettext(domain, "", msgid, msgidPlural, n) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (p *_Locale) DPGettext(domain, msgctxt, msgid string) string { | ||||||
|  | 	p.mutex.Lock() | ||||||
|  | 	defer p.mutex.Unlock() | ||||||
|  | 	return p.gettext(domain, msgctxt, msgid, "", 0) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (p *_Locale) DPNGettext(domain, msgctxt, msgid, msgidPlural string, n int) string { | ||||||
|  | 	p.mutex.Lock() | ||||||
|  | 	defer p.mutex.Unlock() | ||||||
|  | 	return p.gettext(domain, msgctxt, msgid, msgidPlural, n) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (p *_Locale) Getdata(name string) []byte { | ||||||
|  | 	return p.getdata(p.domain, name) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (p *_Locale) DGetdata(domain, name string) []byte { | ||||||
|  | 	return p.getdata(domain, name) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (p *_Locale) gettext(domain, msgctxt, msgid, msgidPlural string, n int) string { | ||||||
|  | 	if f, ok := p.trMap[p.makeTrMapKey(domain, p.lang)]; ok { | ||||||
|  | 		return f.PNGettext(msgctxt, msgid, msgidPlural, n) | ||||||
|  | 	} | ||||||
|  | 	return msgid | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (p *_Locale) getdata(domain, name string) []byte { | ||||||
|  | 	if data, err := p.fs.LoadResourceFile(domain, p.lang, name); err == nil { | ||||||
|  | 		return data | ||||||
|  | 	} | ||||||
|  | 	if p.lang != "default" { | ||||||
|  | 		if data, err := p.fs.LoadResourceFile(domain, "default", name); err == nil { | ||||||
|  | 			return data | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
| @@ -7,11 +7,11 @@ Package mo provides support for reading and writing GNU MO file. | |||||||
| 
 | 
 | ||||||
| Examples: | Examples: | ||||||
| 	import ( | 	import ( | ||||||
| 		"github.com/chai2010/gettext-go/gettext/mo" | 		"github.com/chai2010/gettext-go/mo" | ||||||
| 	) | 	) | ||||||
| 
 | 
 | ||||||
| 	func main() { | 	func main() { | ||||||
| 		moFile, err := mo.Load("test.mo") | 		moFile, err := mo.LoadFile("test.mo") | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			log.Fatal(err) | 			log.Fatal(err) | ||||||
| 		} | 		} | ||||||
| @@ -48,7 +48,9 @@ func encodeData(hdr *moHeader, f *File) []byte { | |||||||
| 		} | 		} | ||||||
| 		msgList = append(msgList, v) | 		msgList = append(msgList, v) | ||||||
| 	} | 	} | ||||||
| 	sort.Sort(byMessages(msgList)) | 	sort.Slice(msgList, func(i, j int) bool { | ||||||
|  | 		return msgList[i].less(&msgList[j]) | ||||||
|  | 	}) | ||||||
| 
 | 
 | ||||||
| 	var buf bytes.Buffer | 	var buf bytes.Buffer | ||||||
| 	var msgIdPosList = make([]moStrPos, len(msgList)) | 	var msgIdPosList = make([]moStrPos, len(msgList)) | ||||||
| @@ -101,24 +103,3 @@ func encodeMsgStr(v Message) string { | |||||||
| 	} | 	} | ||||||
| 	return v.MsgStr | 	return v.MsgStr | ||||||
| } | } | ||||||
| 
 |  | ||||||
| type byMessages []Message |  | ||||||
| 
 |  | ||||||
| func (d byMessages) Len() int { |  | ||||||
| 	return len(d) |  | ||||||
| } |  | ||||||
| func (d byMessages) Less(i, j int) bool { |  | ||||||
| 	if a, b := d[i].MsgContext, d[j].MsgContext; a != b { |  | ||||||
| 		return a < b |  | ||||||
| 	} |  | ||||||
| 	if a, b := d[i].MsgId, d[j].MsgId; a != b { |  | ||||||
| 		return a < b |  | ||||||
| 	} |  | ||||||
| 	if a, b := d[i].MsgIdPlural, d[j].MsgIdPlural; a != b { |  | ||||||
| 		return a < b |  | ||||||
| 	} |  | ||||||
| 	return false |  | ||||||
| } |  | ||||||
| func (d byMessages) Swap(i, j int) { |  | ||||||
| 	d[i], d[j] = d[j], d[i] |  | ||||||
| } |  | ||||||
| @@ -37,17 +37,21 @@ type File struct { | |||||||
| 	Messages     []Message | 	Messages     []Message | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | // Load loads mo file format data. | ||||||
|  | func Load(data []byte) (*File, error) { | ||||||
|  | 	return loadData(data) | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // Load loads a named mo file. | // Load loads a named mo file. | ||||||
| func Load(name string) (*File, error) { | func LoadFile(path string) (*File, error) { | ||||||
| 	data, err := ioutil.ReadFile(name) | 	data, err := ioutil.ReadFile(path) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
| 	return LoadData(data) | 	return loadData(data) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // LoadData loads mo file format data. | func loadData(data []byte) (*File, error) { | ||||||
| func LoadData(data []byte) (*File, error) { |  | ||||||
| 	r := bytes.NewReader(data) | 	r := bytes.NewReader(data) | ||||||
| 
 | 
 | ||||||
| 	var magicNumber uint32 | 	var magicNumber uint32 | ||||||
| @@ -37,3 +37,16 @@ func (p Message) String() string { | |||||||
| 	} | 	} | ||||||
| 	return buf.String() | 	return buf.String() | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | func (m_i *Message) less(m_j *Message) bool { | ||||||
|  | 	if a, b := m_i.MsgContext, m_j.MsgContext; a != b { | ||||||
|  | 		return a < b | ||||||
|  | 	} | ||||||
|  | 	if a, b := m_i.MsgId, m_j.MsgId; a != b { | ||||||
|  | 		return a < b | ||||||
|  | 	} | ||||||
|  | 	if a, b := m_i.MsgIdPlural, m_j.MsgIdPlural; a != b { | ||||||
|  | 		return a < b | ||||||
|  | 	} | ||||||
|  | 	return false | ||||||
|  | } | ||||||
| @@ -7,7 +7,7 @@ Package plural provides standard plural formulas. | |||||||
| 
 | 
 | ||||||
| Examples: | Examples: | ||||||
| 	import ( | 	import ( | ||||||
| 		"code.google.com/p/gettext-go/gettext/plural" | 		"github.com/chai2010/gettext-go/plural" | ||||||
| 	) | 	) | ||||||
| 
 | 
 | ||||||
| 	func main() { | 	func main() { | ||||||
| @@ -7,11 +7,11 @@ Package po provides support for reading and writing GNU PO file. | |||||||
| 
 | 
 | ||||||
| Examples: | Examples: | ||||||
| 	import ( | 	import ( | ||||||
| 		"github.com/chai2010/gettext-go/gettext/po" | 		"github.com/chai2010/gettext-go/po" | ||||||
| 	) | 	) | ||||||
| 
 | 
 | ||||||
| 	func main() { | 	func main() { | ||||||
| 		poFile, err := po.Load("test.po") | 		poFile, err := po.LoadFile("test.po") | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			log.Fatal(err) | 			log.Fatal(err) | ||||||
| 		} | 		} | ||||||
| @@ -20,17 +20,21 @@ type File struct { | |||||||
| 	Messages   []Message | 	Messages   []Message | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Load loads a named po file. | // Load loads po file format data. | ||||||
| func Load(name string) (*File, error) { | func Load(data []byte) (*File, error) { | ||||||
| 	data, err := ioutil.ReadFile(name) | 	return loadData(data) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // LoadFile loads a named po file. | ||||||
|  | func LoadFile(path string) (*File, error) { | ||||||
|  | 	data, err := ioutil.ReadFile(path) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
| 	return LoadData(data) | 	return loadData(data) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // LoadData loads po file format data. | func loadData(data []byte) (*File, error) { | ||||||
| func LoadData(data []byte) (*File, error) { |  | ||||||
| 	r := newLineReader(string(data)) | 	r := newLineReader(string(data)) | ||||||
| 	var file File | 	var file File | ||||||
| 	for { | 	for { | ||||||
| @@ -59,7 +63,9 @@ func (f *File) Data() []byte { | |||||||
| 	// sort the massge as ReferenceFile/ReferenceLine field | 	// sort the massge as ReferenceFile/ReferenceLine field | ||||||
| 	var messages []Message | 	var messages []Message | ||||||
| 	messages = append(messages, f.Messages...) | 	messages = append(messages, f.Messages...) | ||||||
| 	sort.Sort(byMessages(messages)) | 	sort.Slice(messages, func(i, j int) bool { | ||||||
|  | 		return messages[i].less(&messages[j]) | ||||||
|  | 	}) | ||||||
| 
 | 
 | ||||||
| 	var buf bytes.Buffer | 	var buf bytes.Buffer | ||||||
| 	fmt.Fprintf(&buf, "%s\n", f.MimeHeader.String()) | 	fmt.Fprintf(&buf, "%s\n", f.MimeHeader.String()) | ||||||
| @@ -26,29 +26,21 @@ type Message struct { | |||||||
| 	MsgStrPlural []string // msgstr[0] translated-string-case-0 | 	MsgStrPlural []string // msgstr[0] translated-string-case-0 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| type byMessages []Message | func (p *Message) less(q *Message) bool { | ||||||
| 
 | 	if p.Comment.less(&q.Comment) { | ||||||
| func (d byMessages) Len() int { |  | ||||||
| 	return len(d) |  | ||||||
| } |  | ||||||
| func (d byMessages) Less(i, j int) bool { |  | ||||||
| 	if d[i].Comment.less(&d[j].Comment) { |  | ||||||
| 		return true | 		return true | ||||||
| 	} | 	} | ||||||
| 	if a, b := d[i].MsgContext, d[j].MsgContext; a != b { | 	if a, b := p.MsgContext, q.MsgContext; a != b { | ||||||
| 		return a < b | 		return a < b | ||||||
| 	} | 	} | ||||||
| 	if a, b := d[i].MsgId, d[j].MsgId; a != b { | 	if a, b := p.MsgId, q.MsgId; a != b { | ||||||
| 		return a < b | 		return a < b | ||||||
| 	} | 	} | ||||||
| 	if a, b := d[i].MsgIdPlural, d[j].MsgIdPlural; a != b { | 	if a, b := p.MsgIdPlural, q.MsgIdPlural; a != b { | ||||||
| 		return a < b | 		return a < b | ||||||
| 	} | 	} | ||||||
| 	return false | 	return false | ||||||
| } | } | ||||||
| func (d byMessages) Swap(i, j int) { |  | ||||||
| 	d[i], d[j] = d[j], d[i] |  | ||||||
| } |  | ||||||
| 
 | 
 | ||||||
| func (p *Message) readPoEntry(r *lineReader) (err error) { | func (p *Message) readPoEntry(r *lineReader) (err error) { | ||||||
| 	*p = Message{} | 	*p = Message{} | ||||||
| @@ -175,15 +167,27 @@ func (p *Message) readString(r *lineReader) (msg string, err error) { | |||||||
| func (p Message) String() string { | func (p Message) String() string { | ||||||
| 	var buf bytes.Buffer | 	var buf bytes.Buffer | ||||||
| 	fmt.Fprintf(&buf, "%s", p.Comment.String()) | 	fmt.Fprintf(&buf, "%s", p.Comment.String()) | ||||||
|  | 	if p.MsgContext != "" { | ||||||
|  | 		fmt.Fprintf(&buf, "msgctxt %s", encodePoString(p.MsgContext)) | ||||||
|  | 	} | ||||||
| 	fmt.Fprintf(&buf, "msgid %s", encodePoString(p.MsgId)) | 	fmt.Fprintf(&buf, "msgid %s", encodePoString(p.MsgId)) | ||||||
| 	if p.MsgIdPlural != "" { | 	if p.MsgIdPlural != "" { | ||||||
| 		fmt.Fprintf(&buf, "msgid_plural %s", encodePoString(p.MsgIdPlural)) | 		fmt.Fprintf(&buf, "msgid_plural %s", encodePoString(p.MsgIdPlural)) | ||||||
| 	} | 	} | ||||||
| 	if p.MsgStr != "" { | 	if len(p.MsgStrPlural) == 0 { | ||||||
| 		fmt.Fprintf(&buf, "msgstr %s", encodePoString(p.MsgStr)) | 		if p.MsgStr != "" { | ||||||
| 	} | 			fmt.Fprintf(&buf, "msgstr %s", encodePoString(p.MsgStr)) | ||||||
| 	for i := 0; i < len(p.MsgStrPlural); i++ { | 		} else { | ||||||
| 		fmt.Fprintf(&buf, "msgstr[%d] %s", i, encodePoString(p.MsgStrPlural[i])) | 			fmt.Fprintf(&buf, "msgstr %s", `""`+"\n") | ||||||
|  | 		} | ||||||
|  | 	} else { | ||||||
|  | 		for i := 0; i < len(p.MsgStrPlural); i++ { | ||||||
|  | 			if p.MsgStrPlural[i] != "" { | ||||||
|  | 				fmt.Fprintf(&buf, "msgstr[%d] %s", i, encodePoString(p.MsgStrPlural[i])) | ||||||
|  | 			} else { | ||||||
|  | 				fmt.Fprintf(&buf, "msgstr[%d] %s", i, `""`+"\n") | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
| 	} | 	} | ||||||
| 	return buf.String() | 	return buf.String() | ||||||
| } | } | ||||||
| @@ -70,7 +70,11 @@ func encodePoString(text string) string { | |||||||
| 				buf.WriteRune(r) | 				buf.WriteRune(r) | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		buf.WriteString(`\n"` + "\n") | 		if i < len(lines)-1 { | ||||||
|  | 			buf.WriteString(`\n"` + "\n") | ||||||
|  | 		} else { | ||||||
|  | 			buf.WriteString(`"` + "\n") | ||||||
|  | 		} | ||||||
| 	} | 	} | ||||||
| 	return buf.String() | 	return buf.String() | ||||||
| } | } | ||||||
| @@ -5,9 +5,11 @@ | |||||||
| package gettext | package gettext | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	"github.com/chai2010/gettext-go/gettext/mo" | 	"encoding/json" | ||||||
| 	"github.com/chai2010/gettext-go/gettext/plural" | 
 | ||||||
| 	"github.com/chai2010/gettext-go/gettext/po" | 	"github.com/chai2010/gettext-go/mo" | ||||||
|  | 	"github.com/chai2010/gettext-go/plural" | ||||||
|  | 	"github.com/chai2010/gettext-go/po" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| var nilTranslator = &translator{ | var nilTranslator = &translator{ | ||||||
| @@ -26,9 +28,9 @@ func newMoTranslator(name string, data []byte) (*translator, error) { | |||||||
| 		err error | 		err error | ||||||
| 	) | 	) | ||||||
| 	if len(data) != 0 { | 	if len(data) != 0 { | ||||||
| 		f, err = mo.LoadData(data) | 		f, err = mo.Load(data) | ||||||
| 	} else { | 	} else { | ||||||
| 		f, err = mo.Load(name) | 		f, err = mo.LoadFile(name) | ||||||
| 	} | 	} | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| @@ -53,9 +55,9 @@ func newPoTranslator(name string, data []byte) (*translator, error) { | |||||||
| 		err error | 		err error | ||||||
| 	) | 	) | ||||||
| 	if len(data) != 0 { | 	if len(data) != 0 { | ||||||
| 		f, err = po.LoadData(data) | 		f, err = po.Load(data) | ||||||
| 	} else { | 	} else { | ||||||
| 		f, err = po.Load(name) | 		f, err = po.LoadFile(name) | ||||||
| 	} | 	} | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| @@ -80,8 +82,43 @@ func newPoTranslator(name string, data []byte) (*translator, error) { | |||||||
| 	return tr, nil | 	return tr, nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | func newJsonTranslator(lang, name string, jsonData []byte) (*translator, error) { | ||||||
|  | 	var msgList []struct { | ||||||
|  | 		MsgContext  string   `json:"msgctxt"`      // msgctxt context | ||||||
|  | 		MsgId       string   `json:"msgid"`        // msgid untranslated-string | ||||||
|  | 		MsgIdPlural string   `json:"msgid_plural"` // msgid_plural untranslated-string-plural | ||||||
|  | 		MsgStr      []string `json:"msgstr"`       // msgstr translated-string | ||||||
|  | 	} | ||||||
|  | 	if err := json.Unmarshal(jsonData, &msgList); err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	var tr = &translator{ | ||||||
|  | 		MessageMap:    make(map[string]mo.Message), | ||||||
|  | 		PluralFormula: plural.Formula(lang), | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	for _, v := range msgList { | ||||||
|  | 		var v_MsgStr string | ||||||
|  | 		var v_MsgStrPlural = v.MsgStr | ||||||
|  | 
 | ||||||
|  | 		if len(v.MsgStr) != 0 { | ||||||
|  | 			v_MsgStr = v.MsgStr[0] | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		tr.MessageMap[tr.makeMapKey(v.MsgContext, v.MsgId)] = mo.Message{ | ||||||
|  | 			MsgContext:   v.MsgContext, | ||||||
|  | 			MsgId:        v.MsgId, | ||||||
|  | 			MsgIdPlural:  v.MsgIdPlural, | ||||||
|  | 			MsgStr:       v_MsgStr, | ||||||
|  | 			MsgStrPlural: v_MsgStrPlural, | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return tr, nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
| func (p *translator) PGettext(msgctxt, msgid string) string { | func (p *translator) PGettext(msgctxt, msgid string) string { | ||||||
| 	return p.PNGettext(msgctxt, msgid, "", 0) | 	return p.findMsgStr(msgctxt, msgid) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (p *translator) PNGettext(msgctxt, msgid, msgidPlural string, n int) string { | func (p *translator) PNGettext(msgctxt, msgid, msgidPlural string, n int) string { | ||||||
| @@ -100,6 +137,16 @@ func (p *translator) PNGettext(msgctxt, msgid, msgidPlural string, n int) string | |||||||
| 	return msgid | 	return msgid | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | func (p *translator) findMsgStr(msgctxt, msgid string) string { | ||||||
|  | 	key := p.makeMapKey(msgctxt, msgid) | ||||||
|  | 	if v, ok := p.MessageMap[key]; ok { | ||||||
|  | 		if v.MsgStr != "" { | ||||||
|  | 			return v.MsgStr | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return msgid | ||||||
|  | } | ||||||
|  | 
 | ||||||
| func (p *translator) findMsgStrPlural(msgctxt, msgid, msgidPlural string) []string { | func (p *translator) findMsgStrPlural(msgctxt, msgid, msgidPlural string) []string { | ||||||
| 	key := p.makeMapKey(msgctxt, msgid) | 	key := p.makeMapKey(msgctxt, msgid) | ||||||
| 	if v, ok := p.MessageMap[key]; ok { | 	if v, ok := p.MessageMap[key]; ok { | ||||||
| @@ -9,17 +9,17 @@ import ( | |||||||
| 	"strings" | 	"strings" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| func getDefaultLocale() string { | func getDefaultLanguage() string { | ||||||
| 	if v := os.Getenv("LC_MESSAGES"); v != "" { | 	if v := os.Getenv("LC_MESSAGES"); v != "" { | ||||||
| 		return simplifiedLocale(v) | 		return simplifiedLanguage(v) | ||||||
| 	} | 	} | ||||||
| 	if v := os.Getenv("LANG"); v != "" { | 	if v := os.Getenv("LANG"); v != "" { | ||||||
| 		return simplifiedLocale(v) | 		return simplifiedLanguage(v) | ||||||
| 	} | 	} | ||||||
| 	return "default" | 	return "default" | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func simplifiedLocale(lang string) string { | func simplifiedLanguage(lang string) string { | ||||||
| 	// en_US/en_US.UTF-8/zh_CN/zh_TW/el_GR@euro/... | 	// en_US/en_US.UTF-8/zh_CN/zh_TW/el_GR@euro/... | ||||||
| 	if idx := strings.Index(lang, ":"); idx != -1 { | 	if idx := strings.Index(lang, ":"); idx != -1 { | ||||||
| 		lang = lang[:idx] | 		lang = lang[:idx] | ||||||
							
								
								
									
										14
									
								
								vendor/modules.txt
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										14
									
								
								vendor/modules.txt
									
									
									
									
										vendored
									
									
								
							| @@ -173,12 +173,12 @@ github.com/blang/semver/v4 | |||||||
| # github.com/cespare/xxhash/v2 v2.1.2 => github.com/cespare/xxhash/v2 v2.1.2 | # github.com/cespare/xxhash/v2 v2.1.2 => github.com/cespare/xxhash/v2 v2.1.2 | ||||||
| ## explicit; go 1.11 | ## explicit; go 1.11 | ||||||
| github.com/cespare/xxhash/v2 | github.com/cespare/xxhash/v2 | ||||||
| # github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5 => github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5 | # github.com/chai2010/gettext-go v1.0.2 => github.com/chai2010/gettext-go v1.0.2 | ||||||
| ## explicit | ## explicit; go 1.14 | ||||||
| github.com/chai2010/gettext-go/gettext | github.com/chai2010/gettext-go | ||||||
| github.com/chai2010/gettext-go/gettext/mo | github.com/chai2010/gettext-go/mo | ||||||
| github.com/chai2010/gettext-go/gettext/plural | github.com/chai2010/gettext-go/plural | ||||||
| github.com/chai2010/gettext-go/gettext/po | github.com/chai2010/gettext-go/po | ||||||
| # github.com/checkpoint-restore/go-criu/v5 v5.3.0 => github.com/checkpoint-restore/go-criu/v5 v5.3.0 | # github.com/checkpoint-restore/go-criu/v5 v5.3.0 => github.com/checkpoint-restore/go-criu/v5 v5.3.0 | ||||||
| ## explicit; go 1.13 | ## explicit; go 1.13 | ||||||
| github.com/checkpoint-restore/go-criu/v5 | github.com/checkpoint-restore/go-criu/v5 | ||||||
| @@ -2591,7 +2591,7 @@ sigs.k8s.io/yaml | |||||||
| # github.com/census-instrumentation/opencensus-proto => github.com/census-instrumentation/opencensus-proto v0.2.1 | # github.com/census-instrumentation/opencensus-proto => github.com/census-instrumentation/opencensus-proto v0.2.1 | ||||||
| # github.com/certifi/gocertifi => github.com/certifi/gocertifi v0.0.0-20200922220541-2c3bb06c6054 | # github.com/certifi/gocertifi => github.com/certifi/gocertifi v0.0.0-20200922220541-2c3bb06c6054 | ||||||
| # github.com/cespare/xxhash/v2 => github.com/cespare/xxhash/v2 v2.1.2 | # github.com/cespare/xxhash/v2 => github.com/cespare/xxhash/v2 v2.1.2 | ||||||
| # github.com/chai2010/gettext-go => github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5 | # github.com/chai2010/gettext-go => github.com/chai2010/gettext-go v1.0.2 | ||||||
| # github.com/checkpoint-restore/go-criu/v5 => github.com/checkpoint-restore/go-criu/v5 v5.3.0 | # github.com/checkpoint-restore/go-criu/v5 => github.com/checkpoint-restore/go-criu/v5 v5.3.0 | ||||||
| # github.com/chzyer/logex => github.com/chzyer/logex v1.1.10 | # github.com/chzyer/logex => github.com/chzyer/logex v1.1.10 | ||||||
| # github.com/chzyer/readline => github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e | # github.com/chzyer/readline => github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Davanum Srinivas
					Davanum Srinivas