message: allow translated substitutions (%m)

Change-Id: I23fa5fe7ca43d993a8559fd6a35ecb36f082aaf2
Reviewed-on: https://go-review.googlesource.com/84715
Run-TryBot: Marcel van Lohuizen <mpvl@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Nigel Tao <nigeltao@golang.org>
diff --git a/message/message.go b/message/message.go
index a3473bf..48d7663 100644
--- a/message/message.go
+++ b/message/message.go
@@ -156,6 +156,13 @@
 	}
 }
 
+type rawPrinter struct {
+	p *printer
+}
+
+func (p rawPrinter) Render(msg string)     { p.p.WriteString(msg) }
+func (p rawPrinter) Arg(i int) interface{} { return nil }
+
 // Arg implements catmsg.Renderer.
 func (p *printer) Arg(i int) interface{} { // TODO, also return "ok" bool
 	i--
diff --git a/message/message_test.go b/message/message_test.go
index 326f716..e84bd97 100644
--- a/message/message_test.go
+++ b/message/message_test.go
@@ -128,7 +128,7 @@
 			{"und", "hello %-42%%s ", joeAndMary, "hello %Joe %!(EXTRA string=Mary)"},
 		},
 	}, {
-		desc: "number formatting", // work around limitation of fmt
+		desc: "number formatting",
 		cat: []entry{
 			{"und", "files", "%d files left"},
 			{"und", "meters", "%.2f meters"},
@@ -141,6 +141,17 @@
 			{"de-CH", "files", args(1234), "1’234 Dateien übrig"},
 			{"de-CH-u-nu-mong", "files", args(1234), "᠑’᠒᠓᠔ Dateien übrig"},
 		},
+	}, {
+		desc: "substitute translation",
+		cat: []entry{
+			{"en", "google", "Google"},
+			{"en", "sub", "%s"},
+			{"en", "visit", "Lookup: %m."},
+		},
+		test: []test{
+			{"en", "visit", args("google"), "Lookup: Google."},
+			{"en", "visit", args("sub"), "Lookup: %s."},
+		},
 	}}
 
 	for _, tc := range testCases {
diff --git a/message/print.go b/message/print.go
index 777e172..da304cc 100644
--- a/message/print.go
+++ b/message/print.go
@@ -467,6 +467,11 @@
 		p.fmt.fmt_sx(v, udigits)
 	case 'q':
 		p.fmt.fmt_q(v)
+	case 'm':
+		ctx := p.cat.Context(p.tag, rawPrinter{p})
+		if ctx.Execute(v) == catalog.ErrNotFound {
+			p.WriteString(v)
+		}
 	default:
 		p.badVerb(verb)
 	}