Skip to content

Commit

Permalink
Fix handling of artificial languages
Browse files Browse the repository at this point in the history
This works around what seems to be an upstream by implementing a simplified tag matcher for artificual languages.

Fixes nicksnyder#252
  • Loading branch information
bep committed Apr 24, 2021
1 parent b3c1841 commit 453cc22
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 6 deletions.
2 changes: 0 additions & 2 deletions v2/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,3 @@ require (
golang.org/x/text v0.3.3
gopkg.in/yaml.v2 v2.3.0
)

replace golang.org/x/text => /Users/bep/dev/go/dump/text
52 changes: 50 additions & 2 deletions v2/i18n/bundle.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,57 @@ type Bundle struct {
matcher language.Matcher
}

// The matcher in x/text/language does not handle artificial languages,
// see https://github.com/golang/go/issues/45749
// This is a simplified matcher thatdelegates to the x/text/language matcher for
// the harder cases.
type matcher struct {
tags []language.Tag
defaultMatcher language.Matcher
}

func newMatcher(tags []language.Tag) language.Matcher {
var hasArt bool
for _, tag := range tags {
base, _ := tag.Base()
hasArt = base == artTagBase
if hasArt {
break
}
}

if !hasArt {
return language.NewMatcher(tags)
}

return matcher{
tags: tags,
defaultMatcher: language.NewMatcher(tags),
}
}

func (m matcher) Match(t ...language.Tag) (language.Tag, int, language.Confidence) {
if len(t) == 1 {
candidate := t[0]
base, _ := candidate.Base()
if base == artTagBase {
for i, tag := range m.tags {
if tag == candidate {
return candidate, i, language.Exact
}
}
}
}

return m.defaultMatcher.Match(t...)
}

// artTag is the language tag used for artificial languages
// https://en.wikipedia.org/wiki/Codes_for_constructed_languages
var artTag = language.MustParse("art")
var (
artTag = language.MustParse("art")
artTagBase, _ = artTag.Base()
)

// NewBundle returns a bundle with a default language and a default set of plural rules.
func NewBundle(defaultLanguage language.Tag) *Bundle {
Expand Down Expand Up @@ -126,7 +174,7 @@ func (b *Bundle) addTag(tag language.Tag) {
}
}
b.tags = append(b.tags, tag)
b.matcher = language.NewMatcher(b.tags)
b.matcher = newMatcher(b.tags)
}

// LanguageTags returns the list of language tags
Expand Down
2 changes: 1 addition & 1 deletion v2/i18n/bundle_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ hello = "`+expected+`"
func TestPseudoLanguages(t *testing.T) {
bundle := NewBundle(language.English)
bundle.RegisterUnmarshalFunc("toml", toml.Unmarshal)
expected := "a3"
expected := "a2"
bundle.MustParseMessageFileBytes([]byte(`
hello = "a1"
`), "art-x-a1.toml")
Expand Down
1 change: 0 additions & 1 deletion v2/i18n/localizer.go
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,6 @@ func (l *Localizer) LocalizeWithTag(lc *LocalizeConfig) (string, language.Tag, e

func (l *Localizer) getMessageTemplate(id string, defaultMessage *Message) (language.Tag, *MessageTemplate, error) {
_, i, _ := l.bundle.matcher.Match(l.tags...)
fmt.Println("I", l.tags, l.bundle.tags, i)
tag := l.bundle.tags[i]
mt := l.bundle.getMessageTemplate(tag, id)
if mt != nil {
Expand Down

0 comments on commit 453cc22

Please sign in to comment.