Fix multi-line and backquotes string pot generation

The extraction of gettext entry does not translate properly multiline nor
backquotes:
* Multilines are printed as is, instead of follow the gettext spec:
  https://www.gnu.org/software/gettext/manual/html_node/Normalizing.html
* Strings with backquotes as printed as “msgid `this is my string`”,
* Multilines strings with backquotes are formatted as multi-lines to, without
  closing quotes on each lines.

The loading is correct though, this only impact the generation file.
Those generated files are thus then invalid and can’t be compile to mo file.
This commit is contained in:
Didier Roche 2023-07-26 11:14:28 +02:00
parent 1f7d156c36
commit 7f9fe4dccc
No known key found for this signature in database
GPG key ID: 98B24A9CE4AC208E
3 changed files with 42 additions and 7 deletions

View file

@ -248,8 +248,9 @@ func (g *GoFile) parseGetter(def GetterDef, args []*ast.BasicLit, pos string) {
return
}
msgID, _ := strconv.Unquote(args[def.Id].Value)
trans := parser.Translation{
MsgId: args[def.Id].Value,
MsgId: msgID,
SourceLocations: []string{pos},
}
if def.Plural > 0 {
@ -258,7 +259,8 @@ func (g *GoFile) parseGetter(def GetterDef, args []*ast.BasicLit, pos string) {
log.Printf("ERR: Unsupported call at %s (Plural not a string)", pos)
return
}
trans.MsgIdPlural = args[def.Plural].Value
msgIDPlural, _ := strconv.Unquote(args[def.Plural].Value)
trans.MsgIdPlural = msgIDPlural
}
if def.Context > 0 {
// Context must be a string

View file

@ -37,13 +37,13 @@ func (t *Translation) Dump() string {
data = append(data, "msgctxt "+t.Context)
}
data = append(data, "msgid "+t.MsgId)
data = append(data, toMsgIDString("msgid", t.MsgId)...)
if t.MsgIdPlural == "" {
data = append(data, "msgstr \"\"")
} else {
data = append(data, toMsgIDString("msgid_plural", t.MsgIdPlural)...)
data = append(data,
"msgid_plural "+t.MsgIdPlural,
"msgstr[0] \"\"",
"msgstr[1] \"\"")
}
@ -51,6 +51,38 @@ func (t *Translation) Dump() string {
return strings.Join(data, "\n")
}
// toMsgIDString returns the spec implementation of multi line support of po files by aligning msgid on it.
func toMsgIDString(prefix, msgID string) []string {
elems := strings.Split(msgID, "\n")
// Main case: single line.
if len(elems) == 1 {
return []string{fmt.Sprintf(`%s "%s"`, prefix, msgID)}
}
// Only one line, but finishing with \n
if strings.Count(msgID, "\n") == 1 && strings.HasSuffix(msgID, "\n") {
return []string{fmt.Sprintf(`%s "%s\n"`, prefix, strings.TrimSuffix(msgID, "\n"))}
}
// Skip last element for multiline which is an empty
var shouldEndWithEOL bool
if elems[len(elems)-1] == "" {
elems = elems[:len(elems)-1]
shouldEndWithEOL = true
}
data := []string{fmt.Sprintf(`%s ""`, prefix)}
for i, v := range elems {
l := fmt.Sprintf(`"%s\n"`, v)
// Last element without EOL
if i == len(elems)-1 && !shouldEndWithEOL {
l = fmt.Sprintf(`"%s"`, v)
}
data = append(data, l)
}
return data
}
// TranslationMap contains a map of translations with the ID as key
type TranslationMap map[string]*Translation

View file

@ -17,7 +17,6 @@ import (
const gotextPkgPath = "github.com/leonelquinteros/gotext"
type GetterDef struct {
Id int
Plural int
@ -287,8 +286,9 @@ func (g *GoFile) parseGetter(def GetterDef, args []*ast.BasicLit, pos string) {
return
}
msgID, _ := strconv.Unquote(args[def.Id].Value)
trans := parser.Translation{
MsgId: args[def.Id].Value,
MsgId: msgID,
SourceLocations: []string{pos},
}
if def.Plural > 0 {
@ -297,7 +297,8 @@ func (g *GoFile) parseGetter(def GetterDef, args []*ast.BasicLit, pos string) {
log.Printf("ERR: Unsupported call at %s (Plural not a string)", pos)
return
}
trans.MsgIdPlural = args[def.Plural].Value
msgIDPlural, _ := strconv.Unquote(args[def.Plural].Value)
trans.MsgIdPlural = msgIDPlural
}
if def.Context > 0 {
// Context must be a string