Added basic i18n
This commit is contained in:
3
cmd/compilei18n/go.mod
Normal file
3
cmd/compilei18n/go.mod
Normal file
@@ -0,0 +1,3 @@
|
||||
module chatgpt.com/c/tools/compliei18n
|
||||
|
||||
go 1.25.0
|
||||
121
cmd/compilei18n/main.go
Normal file
121
cmd/compilei18n/main.go
Normal file
@@ -0,0 +1,121 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"go/ast"
|
||||
"go/parser"
|
||||
"go/token"
|
||||
"os"
|
||||
"sort"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func main() {
|
||||
const goFile = "i18n/messages.go"
|
||||
const outFile = "resources/src/messages.json"
|
||||
|
||||
keys, err := extractStringConsts(goFile)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
existing := map[string]string{}
|
||||
if data, err := os.ReadFile(outFile); err == nil {
|
||||
if len(bytes.TrimSpace(data)) > 0 {
|
||||
if err := json.Unmarshal(data, &existing); err != nil {
|
||||
panic(fmt.Errorf("parse %s: %w", outFile, err))
|
||||
}
|
||||
}
|
||||
} else if !os.IsNotExist(err) {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
merged := map[string]string{}
|
||||
for _, key := range keys {
|
||||
if val, ok := existing[key]; ok {
|
||||
merged[key] = val
|
||||
} else {
|
||||
merged[key] = "TODO: " + key
|
||||
}
|
||||
}
|
||||
|
||||
// Detect stale keys.
|
||||
for key := range existing {
|
||||
found := false
|
||||
for _, k := range keys {
|
||||
if k == key {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
fmt.Fprintf(os.Stderr, "stale key in %s: %s\n", outFile, key)
|
||||
}
|
||||
}
|
||||
|
||||
// Write stable sorted JSON.
|
||||
sorted := make([]string, 0, len(merged))
|
||||
for k := range merged {
|
||||
sorted = append(sorted, k)
|
||||
}
|
||||
sort.Strings(sorted)
|
||||
|
||||
buf := &bytes.Buffer{}
|
||||
buf.WriteString("{\n")
|
||||
for i, k := range sorted {
|
||||
kj, _ := json.Marshal(k)
|
||||
vj, _ := json.Marshal(merged[k])
|
||||
comma := ","
|
||||
if i == len(sorted)-1 {
|
||||
comma = ""
|
||||
}
|
||||
fmt.Fprintf(buf, " %s: %s%s\n", kj, vj, comma)
|
||||
}
|
||||
buf.WriteString("}\n")
|
||||
|
||||
if err := os.WriteFile(outFile, buf.Bytes(), 0644); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func extractStringConsts(path string) ([]string, error) {
|
||||
fset := token.NewFileSet()
|
||||
file, err := parser.ParseFile(fset, path, nil, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var keys []string
|
||||
|
||||
for _, decl := range file.Decls {
|
||||
gen, ok := decl.(*ast.GenDecl)
|
||||
if !ok || gen.Tok != token.CONST {
|
||||
continue
|
||||
}
|
||||
|
||||
for _, spec := range gen.Specs {
|
||||
vs, ok := spec.(*ast.ValueSpec)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
for _, value := range vs.Values {
|
||||
lit, ok := value.(*ast.BasicLit)
|
||||
if !ok || lit.Kind != token.STRING {
|
||||
continue
|
||||
}
|
||||
|
||||
s, err := strconv.Unquote(lit.Value)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
keys = append(keys, s)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sort.Strings(keys)
|
||||
return keys, nil
|
||||
}
|
||||
Reference in New Issue
Block a user