:ab: GNU gettext for Go (Imported By Kubernetes)


gettext-go: GNU gettext for Go (Imported By Kubernetes)

Install

  1. go get github.com/chai2010/gettext-go
  2. go run hello.go

The godoc.org or go.dev has more information.

Examples

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: 你好, 世界!
}
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; PO file: 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

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

// 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:

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:

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 [email protected].

Thanks!

Owner
chai2010
《Go语言高级编程》《Go语法树入门》《WebAssembly标准入门》作者
chai2010
Comments
  • po文件中的词条如果没有msgctxt, 无法被找到。

    po文件中的词条如果没有msgctxt, 无法被找到。

    在代码中:

    gettext.Gettext("Hello world!").
    

    po文件中:

    #: main.go:19
    msgid "Hello world!"
    msgstr "你好世界!"
    

    这种情况将无法得到翻译字符串。

    看了代码,在解析mo文件并将翻译保存到dict中时,使用了msgctxt+'\004'+msgid做为key。 在有msgctxt的情况下工作很正常,如PGettext("msgctxt", "msgid")。 在无msgctxt的情况下,Gettext("msgid")无法得到翻译字符串。在dict中实际的key是msgid的内容。而Gettext函数到dict中查找翻译字符串时,以所在函数名做为msgctxt,最后形成<func name>+'\004'+msgid做为key来查找,结果无法找到翻译字符串。

    如果Gettext()函数能生成正确的key,问题就能解决,修改方法如下:

    diff --git a/gettext/gettext.go b/gettext/gettext.go
    index ca14065..2171c74 100644
    --- a/gettext/gettext.go
    +++ b/gettext/gettext.go
    @@ -80,7 +80,7 @@ func Textdomain(domain string) string {
     //     msg := gettext.Gettext("Hello") // msgctxt is "some/package/name.Foo"
     // }
     func Gettext(msgid string) string {
    -   return PGettext(callerName(2), msgid)
    +   return PGettext("", msgid)
     }
    
     // Getdata attempt to translate a resource file into the user's native language,
    
  • I add a logger to save the keywords not translated to a file: messages.log

    I add a logger to save the keywords not translated to a file: messages.log

    This is useful for developers. New func SaveLog() can be call in main, such as 'defer gettext.SaveLog()'. It will save keywords not translated to 'messages.log' at the path you run it.

  • Fix import in hello.go

    Fix import in hello.go

    It is improperly importing github.com/chai2010/gettext-go/ instead of github.com/chai2010/gettext-go/gettext

    Before the fix: $ go build hello.go hello.go:12:2: no buildable Go source files in /storage/gopath/src/github.com/chai2010/gettext-go

    After the fix: $ go build hello.go $ ./hello 你好, 世界!

    This is also causing https://github.com/golang/dep/issues/170 since dep doesn't like importing the parent dir (not sure what's wrong with it though)

  • Need multiple languages support for multiple threads

    Need multiple languages support for multiple threads

    One scenario is for serving web requests with different languages. It seems domainManager is not exported and only defaultDomainManager can be used. It would be nice to export domainManager or have some way to allow different clients/threads to have different domainManger with its own locale.

  • Test failure

    Test failure

    The test suite fails for me on both Go 1.5.3 and 1.6.0:

    $ go test
    --- FAIL: TestCallerName (0.00s)
            caller_test.go:39: expect = github.com/chai2010/gettext-go/gettext.init, got = github.com/chai2010/gettext-go/gettext.init.1
    FAIL
    exit status 1
    FAIL    github.com/chai2010/gettext-go/gettext  0.226s
    
  • xgettext-go会提取出多余的反引号

    xgettext-go会提取出多余的反引号

    xgettext-go 通过 go install github.com/chai2010/gettext-go/cmd/xgettext-go@latest 安装,环境 go 1.18.1 Windows 10

    最小重现案例

    package terminal
    
    import "github.com/chai2010/gettext-go"
    
    func f() {
    	println(gettext.Gettext(`Hello world`))
    }
    

    output.pot 内容

    #: github.com/nnnewb/qn/internal/terminal/t.go:6
    #, go-format
    msgid "`Hello world`"
    msgstr ""
    

    问题怀疑是在 cmd/xgettext-go/pkg.go 这里,没考虑到反引号包裹的字符串的情况。

  • msgplural index parsing logic is wrong

    msgplural index parsing logic is wrong

    https://github.com/chai2010/gettext-go/blob/master/po/message.go#L134

    In the case where msgstr contains square brackets, the parsed index value would always be 0.

    Example:

    msgctxt "NAME OF BUTTON MERCHANTS CAN CLICK TO DOWNLOAD ALL THEIR PRODUCTS AS AN CSV "
    "FILE. INCLUDED IS THE NAME OF THE WAREHOUSE AND THE NUMBER OF ROWS THAT WILL "
    "BE IN THE FILE."
    msgid "Download CSV [{%2=warehouse name}] ({%1=number of products} row)"
    msgid_plural "Download CSV [{%2=warehouse name}] ({%1=number of products} rows)"
    msgstr	[0] "Baix[1]ar CSV [{%2=warehouse name}] ({%1=number of products} linha)"
    msgstr		[1] "Baix[2]ar CSV [{%2=warehouse name}] ({%1=number of products} linhas)"
    

    The expected length of Message.MsgStrPlural should be 2 but the actual result is 1 because the message contains square brackets.

  • Is DGettext working properly?

    Is DGettext working properly?

    I have this file structure image

    And this in my dialogue.po file

    msgid "Choose the day of the week ;)"
    msgstr "Оберіть день тижня ;)"
    

    When I am calling the foo.DGettext("dialogue", "Choose the day of the week ;)") english version is returned. The normal translations are working properly, but when I try to load from other domain it just returns me what I typed in.

  • v1.0计划

    v1.0计划

    • 目前的API还是从 google code 网址时代继承来的, 需要重新设计简化API和包路径
    • gettext是上个世纪的产物, 全局只有一个选择, 改进支持多局部多语言共存
    • 目前的context有缺陷, 内部闭包的路径解析不够稳定, 需要重新设计
    • 命令行工具, 可以自动从代码提取要翻译的文字, 同时对有问题的用法提供告警(比如传入的是变量字符串)
    • v0.1到v1.0的API变化, 尽量保证gofmt命令行替换可以完成升级
    • domain绑定到对象, 不同的pkg可以选择不同的domain, context是domain内部的区别, caller不再自动填充
    • 自动生成多国文本(调用翻译服务的API/插件模式)
    • 增加map类型的翻译文件, 可以作为po文件替代
    • 支持单个po/mo文件,和map类型,对于一个具体的翻译 FileSystem.LoadMessagesMap(domain, lang string) (map[string][]string, error)/map[domain][lang][msgid][]string/gettext/mapfs.NewXXX()/jsonString/map[string]interface{}/LoadJsonFile(domain, lang) ([]byte, error)
    • json: LoadMessagesFile("hello", "zh_CN", "json"), Json(s) FileSystem
    • 支持walk/playground等格式的json翻译
    • 其它

    https://pkg.go.dev/github.com/chai2010/gettext-go

Go (Golang) GNU gettext utilities package

Gotext GNU gettext utilities for Go. Features Implements GNU gettext support in native Go. Complete support for PO files including: Support for multil

Dec 18, 2022
:ab: GNU gettext for Go (Imported By Kubernetes)

Go语言QQ群: 102319854, 1055927514 凹语言(凹读音“Wa”)(The Wa Programming Language): https://github.com/wa-lang/wa gettext-go: GNU gettext for Go (Imported By Ku

Nov 12, 2022
Go (Golang) GNU gettext utilities package

Gotext GNU gettext utilities for Go. Features Implements GNU gettext support in native Go. Complete support for PO files including: Support for multil

Dec 18, 2022
Proof of concept project with MQTT and PLC4X imported as Go modules

portal-connect PoC for a edge MQTT client written in Go Basic project setup with PLC4X and Eclipse Paho How to run Install latest Go version https://g

Jan 19, 2022
Program to convert plain text to CSV file which can imported into Anki.

Program to convert plain text to CSV file which can imported into Anki. The motivation of this program is to save time by automatically coverting Question and Answer into CSV file which can be imported directly into Anki.

May 22, 2022
Concurrent task runner, developer's routine tasks automation toolkit. Simple modern alternative to GNU Make 🧰
Concurrent task runner, developer's routine tasks automation toolkit. Simple modern alternative to GNU Make 🧰

taskctl - concurrent task runner, developer's routine tasks automation toolkit Simple modern alternative to GNU Make. taskctl is concurrent task runne

Dec 14, 2022
Drop-in replacement for Go's flag package, implementing POSIX/GNU-style --flags.

Description pflag is a drop-in replacement for Go's flag package, implementing POSIX/GNU-style --flags. pflag is compatible with the GNU extensions to

Dec 30, 2022
Dependency-free replacement for GNU parallel, perfect fit for usage in an initramfs.

coshell v0.2.5 A no-frills dependency-free replacement for GNU parallel, perfect for initramfs usage. Licensed under GNU/GPL v2. How it works An sh -c

Dec 19, 2022
Drop-in replacement for Go's flag package, implementing POSIX/GNU-style --flags.

Description pflag is a drop-in replacement for Go's flag package, implementing POSIX/GNU-style --flags. pflag is compatible with the GNU extensions to

Nov 25, 2022
Go file operations library chasing GNU APIs.
Go file operations library chasing GNU APIs.

flop flop aims to make copying files easier in Go, and is modeled after GNU cp. Most administrators and engineers interact with GNU utilities every da

Nov 10, 2022
GNU Aspell spell checking library bindings for Go (golang)

Aspell library bindings for Go GNU Aspell is a spell checking tool written in C/C++. This package provides simplified Aspell bindings for Go. It uses

Nov 14, 2022
GNU GSL Statistics library (v1.15, GPLv3) implemented in Go

Statistics Pure Go implementation of the GSL Statistics library. For the API overview see Godoc. Why create this repository when there is also "github

Nov 23, 2021
A GNU/Linux monitoring and profiling tool focused on single processes.
A GNU/Linux monitoring and profiling tool focused on single processes.

Uroboros is a GNU/Linux monitoring tool focused on single processes. While utilities like top, ps and htop provide great overall details, they often l

Dec 26, 2022
Interactive package manager and resource monitor designed for the GNU/Linux.
Interactive package manager and resource monitor designed for the GNU/Linux.

pkgtop is an interactive package manager & resource monitor tool designed for the GNU/Linux. Package management (install/upgrade/remove etc.) can be a

Dec 28, 2022
Readline is a pure go(golang) implementation for GNU-Readline kind library
Readline is a pure go(golang) implementation for GNU-Readline kind library

A powerful readline library in Linux macOS Windows Solaris Guide Demo Shortcut Repos using readline Feedback If you have any questions, please submit

Jan 8, 2023
GNU coreutils remade in Go for RosetteOS

Rosebush GNU and POSIX coreutils remade in Go for RosetteOS Build To compile the Rosebush, simply make -B This will compile all the utils one by one.

Oct 4, 2021
IBus Engine for GoVarnam. An easy way to type Indian languages on GNU/Linux systems.

IBus Engine For GoVarnam An easy way to type Indian languages on GNU/Linux systems. goibus - golang implementation of libibus Thanks to sarim and haun

Feb 10, 2022
GNU-stow replacement to manage my dotfiles

Basically a replacement to GNU Stow for my use cases: TODO package for Homebrew add --dotfiles true|false flag add --script filename.sh flag that prin

Nov 27, 2022
GDScript Syntax Highlighting in GNU Nano

nano-gdscript GDScript Syntax Highlighting in GNU Nano. Updated regularly every minor updates. Contributions are welcomed Installation This is 100% fr

Dec 20, 2022
Go-aspell - GNU Aspell spell checking library bindings for golang

Aspell library bindings for Go GNU Aspell is a spell checking tool written in C/

Nov 14, 2022