go-vise

Constrained Size Output Virtual Machine
Info | Log | Files | Refs | README | LICENSE

commit 3a212f6626650acab306e2f5568e75f4d2326be9
parent 6b7046bc9f01f950c196b014624ae22889cd25d6
Author: lash <dev@holbrook.no>
Date:   Thu,  2 Jan 2025 08:22:12 +0000

Add gettext resource

Diffstat:
Mdev/walk/main.go | 33++++++++++++++++++++++++---------
Mlang/lang.go | 16++++++++++++++++
Aresource/gettext.go | 55+++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aresource/gettext_test.go | 52++++++++++++++++++++++++++++++++++++++++++++++++++++
Atestdata/testlocale/eng/default.po | 9+++++++++
Atestdata/testlocale/nor/default.po | 9+++++++++
Atestdata/testlocale/path.go | 11+++++++++++
7 files changed, 176 insertions(+), 9 deletions(-)

diff --git a/dev/walk/main.go b/dev/walk/main.go @@ -19,6 +19,7 @@ import ( var ( logg = logging.NewVanilla() + poFilebase = "default" ) type translator struct { @@ -30,13 +31,13 @@ type translator struct { w map[string]io.WriteCloser } -func newTranslator(ctx context.Context, rs resource.Resource, outPath string) *translator { +func newTranslator(ctx context.Context, rs resource.Resource, outPath string, filebase string) *translator { return &translator{ ctx: ctx, rs: rs, d: outPath, w: make(map[string]io.WriteCloser), - fileBase: "visedata", + fileBase: filebase, } } @@ -44,9 +45,14 @@ func(tr *translator) applyLanguage(node *debug.Node) { } -func(tr *translator) fileNameFor(ln lang.Language) string { - fileName := tr.fileBase + "." + ln.Code + ".po" - return path.Join(tr.d, fileName) +func(tr *translator) ensureFileNameFor(ln lang.Language) (string, error) { + fileName := tr.fileBase + ".po" + p := path.Join(tr.d, ln.Code) + err := os.MkdirAll(p, 0700) + if err != nil { + return "", err + } + return path.Join(p, fileName), nil } func(tr *translator) Close() error { @@ -131,7 +137,10 @@ msgstr "" } func(tr *translator) AddLang(ln lang.Language) error { - filePath := tr.fileNameFor(ln) + filePath, err := tr.ensureFileNameFor(ln) + if err != nil { + return err + } w, err := os.OpenFile(filePath, os.O_WRONLY | os.O_CREATE, 0644) s := fmt.Sprintf(`msgid "" msgstr "" @@ -176,16 +185,22 @@ func main() { var langs langVar flag.StringVar(&dir, "d", ".", "resource dir to read from") - flag.StringVar(&outDir, "o", ".", "output directory") + flag.StringVar(&outDir, "o", "locale", "output directory") flag.StringVar(&root, "root", "root", "entry point symbol") flag.Var(&langs, "l", "process for language") flag.Parse() fmt.Fprintf(os.Stderr, "starting session at symbol '%s' using resource dir: %s\n", root, dir) + err := os.MkdirAll(outDir, 0700) + if err != nil { + fmt.Fprintf(os.Stderr, "output dir create error: %v", err) + os.Exit(1) + } + ctx := context.Background() rsStore := fsdb.NewFsDb() - err := rsStore.Connect(ctx, dir) + err = rsStore.Connect(ctx, dir) if err != nil { fmt.Fprintf(os.Stderr, "resource db connect error: %v", err) os.Exit(1) @@ -193,7 +208,7 @@ func main() { rs := resource.NewDbResource(rsStore) - tr := newTranslator(ctx, rs, outDir) + tr := newTranslator(ctx, rs, outDir, poFilebase) defer tr.Close() for _, ln := range(langs.Langs()) { logg.DebugCtxf(ctx, "lang", "lang", ln) diff --git a/lang/lang.go b/lang/lang.go @@ -1,6 +1,7 @@ package lang import ( + "context" "fmt" "github.com/barbashov/iso639-3" @@ -37,3 +38,18 @@ func LanguageFromCode(code string) (Language, error) { func(l Language) String() string { return fmt.Sprintf("%s (%s)", l.Code, l.Name) } + +// LanguageFromContext scans the given context for a valid language +// specification, and if found returns a corresponding language +// object. +func LanguageFromContext(ctx context.Context) (Language, bool) { + //var code string + var lang Language + var ok bool + if ctx.Value("Language") != nil { + lang = ctx.Value("Language").(Language) + ok = true + //code = lang.Code + } + return lang, ok +} diff --git a/resource/gettext.go b/resource/gettext.go @@ -0,0 +1,55 @@ +package resource + +import ( + "context" + + gotext "gopkg.in/leonelquinteros/gotext.v1" + + "git.defalsify.org/vise.git/lang" +) + +type PoResource struct { + path string + domain string + defaultLanguage lang.Language + tr map[string]*gotext.Locale +} + +func NewPoResource(defaultLanguage lang.Language, path string, domain string) *PoResource { + o := &PoResource { + path: path, + domain: domain, + defaultLanguage: defaultLanguage, + tr: make(map[string]*gotext.Locale), + } + return o.WithLanguage(defaultLanguage) +} + +func(p *PoResource) WithLanguage(ln lang.Language) *PoResource { + o := gotext.NewLocale(p.path, ln.Code) + o.AddDomain(p.domain) + p.tr[ln.Code] = o + return p +} + +func(p *PoResource) get(ctx context.Context, sym string) (string, error) { + s := sym + ln, ok := lang.LanguageFromContext(ctx) + if !ok { + ln = p.defaultLanguage + } + o, ok := p.tr[ln.Code] + if ok { + logg.TraceCtxf(ctx, "poresource get", "sym", sym, "ln", ln, "path", p.path, "o", o) + s = o.Get(sym) + } + return s, nil +} + +func(p *PoResource) GetMenu(ctx context.Context, sym string) (string, error) { + return p.get(ctx, sym) +} + +func(p *PoResource) GetTemplate(ctx context.Context, sym string) (string, error) { + return p.get(ctx, sym) +} diff --git a/resource/gettext_test.go b/resource/gettext_test.go @@ -0,0 +1,52 @@ +package resource + +import ( + "context" + "testing" + + "git.defalsify.org/vise.git/testdata/testlocale" + "git.defalsify.org/vise.git/lang" +) + +func TestPoGet(t *testing.T) { + ln, err := lang.LanguageFromCode("nor") + if err != nil { + t.Fatal(err) + } + rs := NewPoResource(ln, testlocale.LocaleDir, "default") + ctx := context.WithValue(context.Background(), "Language", ln) + + ln, err = lang.LanguageFromCode("eng") + if err != nil { + t.Fatal(err) + } + rs = rs.WithLanguage(ln) + + s, err := rs.GetMenu(ctx, "foo") + if err != nil { + t.Fatal(err) + } + + if s != "fu" { + t.Fatalf("expected 'fu', got '%s'", s) + } + + // eng now + ctx = context.WithValue(context.Background(), "Language", ln) + + s, err = rs.GetMenu(ctx, "foo") + if err != nil { + t.Fatal(err) + } + if s != "foo" { + t.Fatalf("expected 'foo', got '%s'", s) + } + + s, err = rs.GetMenu(ctx, "bar") + if err != nil { + t.Fatal(err) + } + if s != "baz" { + t.Fatalf("expected 'baz', got '%s'", s) + } +} diff --git a/testdata/testlocale/eng/default.po b/testdata/testlocale/eng/default.po @@ -0,0 +1,9 @@ +msgid "" +msgstr "" + "Content-Type: text/plain; charset=UTF-8\n" + "Language: eng\n" + +msgid "" + "bar" +msgstr "" + "baz" diff --git a/testdata/testlocale/nor/default.po b/testdata/testlocale/nor/default.po @@ -0,0 +1,9 @@ +msgid "" +msgstr "" + "Content-Type: text/plain; charset=UTF-8\n" + "Language: nor\n" + +msgid "" + "foo" +msgstr "" + "fu" diff --git a/testdata/testlocale/path.go b/testdata/testlocale/path.go @@ -0,0 +1,11 @@ +package testlocale + +import ( + "path" + + testdataloader "github.com/peteole/testdata-loader" +) + +var ( + LocaleDir = path.Join(testdataloader.GetBasePath(), "testdata", "testlocale") +)