Skip to content

Commit

Permalink
Properly handle singular vs plural defaults for untranslated strings. F…
Browse files Browse the repository at this point in the history
…ixes #9
  • Loading branch information
leonelquinteros committed Sep 1, 2017
1 parent 756045a commit 4b94e83
Show file tree
Hide file tree
Showing 5 changed files with 142 additions and 33 deletions.
39 changes: 27 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -156,17 +156,20 @@ This is a normal Go compiler behavior.
For quick/simple translations you can use the package level functions directly.

```go
import "github.com/leonelquinteros/gotext"
import (
"fmt"
"github.com/leonelquinteros/gotext"
)

func main() {
// Configure package
gotext.Configure("/path/to/locales/root/dir", "en_UK", "domain-name")

// Translate text from default domain
println(gotext.Get("My text on 'domain-name' domain"))
fmt.Println(gotext.Get("My text on 'domain-name' domain"))

// Translate text from a different domain without reconfigure
println(gotext.GetD("domain2", "Another text on a different domain"))
fmt.Println(gotext.GetD("domain2", "Another text on a different domain"))
}

```
Expand All @@ -177,7 +180,10 @@ All translation strings support dynamic variables to be inserted without transla
Use the fmt.Printf syntax (from Go's "fmt" package) to specify how to print the non-translated variable inside the translation string.

```go
import "github.com/leonelquinteros/gotext"
import (
"fmt"
"github.com/leonelquinteros/gotext"
)

func main() {
// Configure package
Expand All @@ -187,7 +193,7 @@ func main() {
name := "John"

// Translate text with variables
println(gotext.Get("Hi, my name is %s", name))
fmt.Println(gotext.Get("Hi, my name is %s", name))
}

```
Expand All @@ -199,7 +205,10 @@ When having multiple languages/domains/libraries at the same time, you can creat
so you can handle each settings on their own.

```go
import "github.com/leonelquinteros/gotext"
import (
"fmt"
"github.com/leonelquinteros/gotext"
)

func main() {
// Create Locale with library path and language code
Expand All @@ -209,13 +218,13 @@ func main() {
l.AddDomain("default")

// Translate text from default domain
println(l.Get("Translate this"))
fmt.Println(l.Get("Translate this"))

// Load different domain
l.AddDomain("translations")

// Translate text from domain
println(l.GetD("translations", "Translate this"))
fmt.Println(l.GetD("translations", "Translate this"))
}
```

Expand All @@ -233,7 +242,10 @@ For when you need to work with PO files and strings,
you can directly use the Po object to parse it and access the translations in there in the same way.

```go
import "github.com/leonelquinteros/gotext"
import (
"fmt"
"github.com/leonelquinteros/gotext"
)

func main() {
// Set PO content
Expand All @@ -252,7 +264,7 @@ msgstr "This one sets the var: %s"
po := new(Po)
po.Parse(str)

println(po.Get("Translate this"))
fmt.Println(po.Get("Translate this"))
}
```

Expand All @@ -266,7 +278,10 @@ as defined in (https://www.gnu.org/savannah-checkouts/gnu/gettext/manual/html_no
Plural formulas are parsed and evaluated using [Kinako](https://github.com/mattn/kinako)

```go
import "github.com/leonelquinteros/gotext"
import (
"fmt"
"github.com/leonelquinteros/gotext"
)

func main() {
// Set PO content
Expand All @@ -293,7 +308,7 @@ msgstr[1] "This one is the plural: %s"
po := new(Po)
po.Parse(str)

println(po.GetN("One with var: %s", "Several with vars: %s", 54, v))
fmt.Println(po.GetN("One with var: %s", "Several with vars: %s", 54, v))
// "This one is the plural: Variable"
}
```
Expand Down
9 changes: 6 additions & 3 deletions gotext.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,20 @@ Package gotext implements GNU gettext utilities.
For quick/simple translations you can use the package level functions directly.
import "github.com/leonelquinteros/gotext"
import (
"fmt"
"github.com/leonelquinteros/gotext"
)
func main() {
// Configure package
gotext.Configure("/path/to/locales/root/dir", "en_UK", "domain-name")
// Translate text from default domain
println(gotext.Get("My text on 'domain-name' domain"))
fmt.Println(gotext.Get("My text on 'domain-name' domain"))
// Translate text from a different domain without reconfigure
println(gotext.GetD("domain2", "Another text on a different domain"))
fmt.Println(gotext.GetD("domain2", "Another text on a different domain"))
}
*/
Expand Down
100 changes: 90 additions & 10 deletions gotext_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,11 @@ msgstr "Some random translation in a context"
msgid "More"
msgstr "More translation"
msgid "Untranslated"
msgid_plural "Several untranslated"
msgstr[0] ""
msgstr[1] ""
`

// Create Locales directory on default location
Expand Down Expand Up @@ -141,6 +146,79 @@ msgstr "More translation"
}
}

func TestUntranslated(t *testing.T) {
// Set PO content
str := `
# msgid ""
# msgstr ""
# Initial comment
# Headers below
"Language: en\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
msgid "Untranslated"
msgid_plural "Several untranslated"
msgstr[0] ""
msgstr[1] ""
`

// Create Locales directory on default location
dirname := path.Clean("/tmp" + string(os.PathSeparator) + "en_US")
err := os.MkdirAll(dirname, os.ModePerm)
if err != nil {
t.Fatalf("Can't create test directory: %s", err.Error())
}

// Write PO content to default domain file
filename := path.Clean(dirname + string(os.PathSeparator) + "default.po")

f, err := os.Create(filename)
if err != nil {
t.Fatalf("Can't create test file: %s", err.Error())
}
defer f.Close()

_, err = f.WriteString(str)
if err != nil {
t.Fatalf("Can't write to test file: %s", err.Error())
}

// Set package configuration
Configure("/tmp", "en_US", "default")

// Test untranslated
tr := Get("Untranslated")
if tr != "Untranslated" {
t.Errorf("Expected 'Untranslated' but got '%s'", tr)
}
tr = GetN("Untranslated", "Several untranslated", 1)
if tr != "Untranslated" {
t.Errorf("Expected 'Untranslated' but got '%s'", tr)
}

tr = GetN("Untranslated", "Several untranslated", 2)
if tr != "Several untranslated" {
t.Errorf("Expected 'Several untranslated' but got '%s'", tr)
}

tr = GetD("default", "Untranslated")
if tr != "Untranslated" {
t.Errorf("Expected 'Untranslated' but got '%s'", tr)
}
tr = GetND("default", "Untranslated", "Several untranslated", 1)
if tr != "Untranslated" {
t.Errorf("Expected 'Untranslated' but got '%s'", tr)
}

tr = GetND("default", "Untranslated", "Several untranslated", 2)
if tr != "Several untranslated" {
t.Errorf("Expected 'Several untranslated' but got '%s'", tr)
}
}

func TestPackageRace(t *testing.T) {
// Set PO content
str := `# Some comment
Expand Down Expand Up @@ -184,16 +262,18 @@ msgstr[2] "And this is the second plural form: %s"
c1 := make(chan bool)
c2 := make(chan bool)

// Test translations
go func(done chan bool) {
Get("My text")
done <- true
}(c1)
for i := 0; i < 100; i++ {
// Test translations
go func(done chan bool) {
Get("My text")
done <- true
}(c1)

go func(done chan bool) {
Get("My text")
done <- true
}(c2)
go func(done chan bool) {
Get("My text")
done <- true
}(c2)

Get("My text")
Get("My text")
}
}
9 changes: 6 additions & 3 deletions locale.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@ multiple languages at the same time by working with this object.
Example:
import "github.com/leonelquinteros/gotext"
import (
"fmt"
"github.com/leonelquinteros/gotext"
)
func main() {
// Create Locale with library path and language code
Expand All @@ -24,13 +27,13 @@ Example:
l.AddDomain("default")
// Translate text from default domain
println(l.Get("Translate this"))
fmt.Println(l.Get("Translate this"))
// Load different domain ('/path/to/i18n/dir/en_US/LC_MESSAGES/extras.po')
l.AddDomain("extras")
// Translate text from domain
println(l.GetD("extras", "Translate this"))
fmt.Println(l.GetD("extras", "Translate this"))
}
*/
Expand Down
18 changes: 13 additions & 5 deletions po.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,13 @@ package gotext
import (
"bufio"
"fmt"
"github.com/mattn/kinako/vm"
"io/ioutil"
"net/textproto"
"os"
"strconv"
"strings"
"sync"

"github.com/mattn/kinako/vm"
)

type translation struct {
Expand Down Expand Up @@ -46,7 +45,12 @@ func (t *translation) getN(n int) string {
}
}

// Return unstranlated plural by default
// Return unstranlated singular if corresponding
if n == 0 {
return t.id
}

// Return untranslated plural by default
return t.pluralID
}

Expand All @@ -57,7 +61,10 @@ And it's safe for concurrent use by multiple goroutines by using the sync packag
Example:
import "github.com/leonelquinteros/gotext"
import (
"fmt"
"github.com/leonelquinteros/gotext"
)
func main() {
// Create po object
Expand All @@ -67,7 +74,7 @@ Example:
po.ParseFile("/path/to/po/file/translations.po")
// Get translation
println(po.Get("Translate this"))
fmt.Println(po.Get("Translate this"))
}
*/
Expand Down Expand Up @@ -439,6 +446,7 @@ func (po *Po) GetN(str, plural string, n int, vars ...interface{}) string {
if n == 1 {
return fmt.Sprintf(str, vars...)
}

return fmt.Sprintf(plural, vars...)
}

Expand Down

0 comments on commit 4b94e83

Please sign in to comment.