cmd/gotext: extract messages in entire binary
Added examples.
Also improved Placeholder name extraction.
Change-Id: I3f271156a1cd364ed4ec71d3e1f8ab8c48568baf
Reviewed-on: https://go-review.googlesource.com/80236
Run-TryBot: Marcel van Lohuizen <mpvl@golang.org>
Reviewed-by: Nigel Tao <nigeltao@golang.org>
diff --git a/cmd/gotext/examples/main.go b/cmd/gotext/examples/extract/main.go
similarity index 100%
rename from cmd/gotext/examples/main.go
rename to cmd/gotext/examples/extract/main.go
diff --git a/cmd/gotext/examples/textdata/gotext_en.out.json b/cmd/gotext/examples/extract/textdata/gotext_en.out.json
similarity index 83%
rename from cmd/gotext/examples/textdata/gotext_en.out.json
rename to cmd/gotext/examples/extract/textdata/gotext_en.out.json
index 3dd943a..2b9124c 100755
--- a/cmd/gotext/examples/textdata/gotext_en.out.json
+++ b/cmd/gotext/examples/extract/textdata/gotext_en.out.json
@@ -6,7 +6,7 @@
"message": {
"msg": "Hello world!\n"
},
- "position": "golang.org/x/text/cmd/gotext/examples/main.go:27:10"
+ "position": "golang.org/x/text/cmd/gotext/examples/extract/main.go:27:10"
},
{
"key": [
@@ -25,7 +25,7 @@
"expr": "city"
}
],
- "position": "golang.org/x/text/cmd/gotext/examples/main.go:31:10"
+ "position": "golang.org/x/text/cmd/gotext/examples/extract/main.go:31:10"
},
{
"key": [
@@ -45,7 +45,7 @@
"comment": "Town"
}
],
- "position": "golang.org/x/text/cmd/gotext/examples/main.go:35:10"
+ "position": "golang.org/x/text/cmd/gotext/examples/extract/main.go:35:10"
},
{
"key": [
@@ -74,7 +74,7 @@
"comment": "Place the person is visiting."
}
],
- "position": "golang.org/x/text/cmd/gotext/examples/main.go:40:10"
+ "position": "golang.org/x/text/cmd/gotext/examples/extract/main.go:40:10"
},
{
"key": [
@@ -111,18 +111,18 @@
"expr": "pp.extra"
}
],
- "position": "golang.org/x/text/cmd/gotext/examples/main.go:55:10"
+ "position": "golang.org/x/text/cmd/gotext/examples/extract/main.go:55:10"
},
{
"key": [
"%d files remaining!"
],
"message": {
- "msg": "{2} files remaining!"
+ "msg": "{} files remaining!"
},
"placeholders": [
{
- "id": "2",
+ "id": "",
"string": "%[1]d",
"type": "int",
"underlyingType": "int",
@@ -130,7 +130,7 @@
"expr": "2"
}
],
- "position": "golang.org/x/text/cmd/gotext/examples/main.go:62:10"
+ "position": "golang.org/x/text/cmd/gotext/examples/extract/main.go:62:10"
},
{
"key": [
@@ -149,7 +149,7 @@
"expr": "n"
}
],
- "position": "golang.org/x/text/cmd/gotext/examples/main.go:67:10"
+ "position": "golang.org/x/text/cmd/gotext/examples/extract/main.go:67:10"
},
{
"key": [
@@ -162,13 +162,13 @@
{
"id": "ReferralCode",
"string": "%[1]d",
- "type": "golang.org/x/text/cmd/gotext/examples.referralCode",
+ "type": "golang.org/x/text/cmd/gotext/examples/extract.referralCode",
"underlyingType": "int",
"argNum": 1,
"expr": "c"
}
],
- "position": "golang.org/x/text/cmd/gotext/examples/main.go:73:10"
+ "position": "golang.org/x/text/cmd/gotext/examples/extract/main.go:73:10"
},
{
"key": [
@@ -189,7 +189,7 @@
"expr": "device"
}
],
- "position": "golang.org/x/text/cmd/gotext/examples/main.go:81:10"
+ "position": "golang.org/x/text/cmd/gotext/examples/extract/main.go:81:10"
},
{
"key": [
@@ -216,6 +216,6 @@
"expr": "miles"
}
],
- "position": "golang.org/x/text/cmd/gotext/examples/main.go:85:10"
+ "position": "golang.org/x/text/cmd/gotext/examples/extract/main.go:85:10"
}
]
\ No newline at end of file
diff --git a/cmd/gotext/examples/extract_http/main.go b/cmd/gotext/examples/extract_http/main.go
new file mode 100644
index 0000000..4f7484f
--- /dev/null
+++ b/cmd/gotext/examples/extract_http/main.go
@@ -0,0 +1,17 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+//go:generate gotext extract
+
+import (
+ "net/http"
+
+ "golang.org/x/text/cmd/gotext/examples/extract_http/pkg"
+)
+
+func main() {
+ http.Handle("/generize", http.HandlerFunc(pkg.Generize))
+}
diff --git a/cmd/gotext/examples/extract_http/pkg/pkg.go b/cmd/gotext/examples/extract_http/pkg/pkg.go
new file mode 100644
index 0000000..56bb474
--- /dev/null
+++ b/cmd/gotext/examples/extract_http/pkg/pkg.go
@@ -0,0 +1,27 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package pkg
+
+import (
+ "net/http"
+
+ "golang.org/x/text/language"
+ "golang.org/x/text/message"
+)
+
+var matcher = language.NewMatcher(message.DefaultCatalog.Languages())
+
+func Generize(w http.ResponseWriter, r *http.Request) {
+ lang, _ := r.Cookie("lang")
+ accept := r.Header.Get("Accept-Language")
+ fallback := "en"
+ tag, _ := language.MatchStrings(matcher, lang.String(), accept, fallback)
+ p := message.NewPrinter(tag)
+
+ p.Fprintf(w, "Hello %s!\n", r.Header.Get("From"))
+
+ p.Fprintf(w, "Do you like your browser (%s)?\n", r.Header.Get("User-Agent"))
+
+}
diff --git a/cmd/gotext/examples/extract_http/textdata/gotext_en.out.json b/cmd/gotext/examples/extract_http/textdata/gotext_en.out.json
new file mode 100755
index 0000000..e6b9968
--- /dev/null
+++ b/cmd/gotext/examples/extract_http/textdata/gotext_en.out.json
@@ -0,0 +1,40 @@
+[
+ {
+ "key": [
+ "Hello %s!\n"
+ ],
+ "message": {
+ "msg": "Hello {From}!\n"
+ },
+ "placeholders": [
+ {
+ "id": "From",
+ "string": "%[1]s",
+ "type": "string",
+ "underlyingType": "string",
+ "argNum": 1,
+ "expr": "r.Header.Get(\"From\")"
+ }
+ ],
+ "position": "golang.org/x/text/cmd/gotext/examples/extract_http/pkg/pkg.go:23:11"
+ },
+ {
+ "key": [
+ "Do you like your browser (%s)?\n"
+ ],
+ "message": {
+ "msg": "Do you like your browser ({User_Agent})?\n"
+ },
+ "placeholders": [
+ {
+ "id": "User_Agent",
+ "string": "%[1]s",
+ "type": "string",
+ "underlyingType": "string",
+ "argNum": 1,
+ "expr": "r.Header.Get(\"User-Agent\")"
+ }
+ ],
+ "position": "golang.org/x/text/cmd/gotext/examples/extract_http/pkg/pkg.go:25:11"
+ }
+]
\ No newline at end of file
diff --git a/cmd/gotext/extract.go b/cmd/gotext/extract.go
index 3b6120d..b7ca559 100644
--- a/cmd/gotext/extract.go
+++ b/cmd/gotext/extract.go
@@ -70,7 +70,7 @@
var messages []Message
- for _, info := range iprog.InitialPackages() {
+ for _, info := range iprog.AllPackages {
for _, f := range info.Files {
// Associate comments with nodes.
cmap := ast.NewCommentMap(iprog.Fset, f, f.Comments)
@@ -259,6 +259,7 @@
func getID(arg *argument) string {
s := getLastComponent(arg.Expr)
+ s = strip(s)
s = strings.Replace(s, " ", "", -1)
// For small variable names, use user-defined types for more info.
if len(s) <= 2 && arg.UnderlyingType != arg.Type {
@@ -267,6 +268,29 @@
return strings.Title(s)
}
+// strip is a dirty hack to convert function calls to placeholder IDs.
+func strip(s string) string {
+ s = strings.Map(func(r rune) rune {
+ if unicode.IsSpace(r) || r == '-' {
+ return '_'
+ }
+ if !unicode.In(r, unicode.Letter, unicode.Mark) {
+ return -1
+ }
+ return r
+ }, s)
+ // Strip "Get" from getter functions.
+ if strings.HasPrefix(s, "Get") || strings.HasPrefix(s, "get") {
+ if len(s) > len("get") {
+ r, _ := utf8.DecodeRuneInString(s)
+ if !unicode.In(r, unicode.Ll, unicode.M) { // not lower or mark
+ s = s[len("get"):]
+ }
+ }
+ }
+ return s
+}
+
type placeholders struct {
index map[string]string
slice []Placeholder
diff --git a/cmd/gotext/message.go b/cmd/gotext/message.go
index 567cf5d..eaa9005 100644
--- a/cmd/gotext/message.go
+++ b/cmd/gotext/message.go
@@ -106,7 +106,7 @@
// Select selects a Text based on the feature value associated with a feature of
// a certain argument.
type Select struct {
- Feature string `json:"feature"` // Name of variable or Feature type
+ Feature string `json:"feature"` // Name of Feature type (e.g plural)
Arg string `json:"arg"` // The placeholder ID
Cases map[string]Text `json:"cases"`
}