From 4a52c7709da5a8592d3734fc910a005ec638a576 Mon Sep 17 00:00:00 2001 From: Mattias Lundell Date: Mon, 29 May 2017 11:36:18 +0200 Subject: [PATCH 1/2] Add support for multi-line msgid --- gotext_test.go | 8 +++--- locale_test.go | 10 +++---- po.go | 76 ++++++++++++++++++++++++++++++++++---------------- po_test.go | 44 +++++++++++++++++++++-------- 4 files changed, 94 insertions(+), 44 deletions(-) diff --git a/gotext_test.go b/gotext_test.go index d9b786d..a642e23 100644 --- a/gotext_test.go +++ b/gotext_test.go @@ -32,8 +32,8 @@ func TestGettersSetters(t *testing.T) { func TestPackageFunctions(t *testing.T) { // Set PO content str := ` -msgid "" -msgstr "" +# msgid "" +# msgstr "" # Initial comment # Headers below "Language: en\n" @@ -79,7 +79,7 @@ msgstr "Some random translation in a context" msgid "More" msgstr "More translation" - ` + ` // Create Locales directory on default location dirname := path.Clean("/tmp" + string(os.PathSeparator) + "en_US") @@ -157,7 +157,7 @@ msgstr[0] "This one is the singular: %s" msgstr[1] "This one is the plural: %s" msgstr[2] "And this is the second plural form: %s" - ` + ` // Create Locales directory on default location dirname := path.Clean(library + string(os.PathSeparator) + "en_US") diff --git a/locale_test.go b/locale_test.go index 062b0bf..2c9eb0a 100644 --- a/locale_test.go +++ b/locale_test.go @@ -9,8 +9,8 @@ import ( func TestLocale(t *testing.T) { // Set PO content str := ` -msgid "" -msgstr "" +# msgid "" +# msgstr "" # Initial comment # Headers below "Language: en\n" @@ -56,7 +56,7 @@ msgstr "Some random translation in a context" msgid "More" msgstr "More translation" - ` + ` // Create Locales directory with simplified language code dirname := path.Join("/tmp", "en", "LC_MESSAGES") @@ -176,7 +176,7 @@ msgstr "Some random translation in a context" msgid "More" msgstr "More translation" - ` + ` // Create Locales directory with simplified language code dirname := path.Join("/tmp", "en", "LC_MESSAGES") @@ -259,7 +259,7 @@ msgstr[0] "This one is the singular: %s" msgstr[1] "This one is the plural: %s" msgstr[2] "And this is the second plural form: %s" - ` + ` // Create Locales directory with simplified language code dirname := path.Join("/tmp", "es") diff --git a/po.go b/po.go index 57a8184..79be141 100644 --- a/po.go +++ b/po.go @@ -52,18 +52,18 @@ And it's safe for concurrent use by multiple goroutines by using the sync packag Example: - import "github.com/leonelquinteros/gotext" + import "github.com/leonelquinteros/gotext" - func main() { - // Create po object - po := new(gotext.Po) + func main() { + // Create po object + po := new(gotext.Po) - // Parse .po file - po.ParseFile("/path/to/po/file/translations.po") + // Parse .po file + po.ParseFile("/path/to/po/file/translations.po") - // Get translation - println(po.Get("Translate this")) - } + // Get translation + println(po.Get("Translate this")) + } */ type Po struct { @@ -92,6 +92,16 @@ type Po struct { ctxBuffer string } +type parseState int + +const ( + head parseState = iota + msgCtxt + msgID + msgIDPlural + msgStr +) + // ParseFile tries to read the file by its provided path (f) and parse its content as a .po file. func (po *Po) ParseFile(f string) { // Check if file exists @@ -133,6 +143,7 @@ func (po *Po) Parse(str string) { po.trBuffer = newTranslation() po.ctxBuffer = "" + state := head for _, l := range lines { // Trim spaces l = strings.TrimSpace(l) @@ -145,30 +156,34 @@ func (po *Po) Parse(str string) { // Buffer context and continue if strings.HasPrefix(l, "msgctxt") { po.parseContext(l) + state = msgCtxt continue } // Buffer msgid and continue if strings.HasPrefix(l, "msgid") && !strings.HasPrefix(l, "msgid_plural") { po.parseID(l) + state = msgID continue } // Check for plural form if strings.HasPrefix(l, "msgid_plural") { po.parsePluralID(l) + state = msgIDPlural continue } // Save translation if strings.HasPrefix(l, "msgstr") { po.parseMessage(l) + state = msgStr continue } // Multi line strings and headers if strings.HasPrefix(l, "\"") && strings.HasSuffix(l, "\"") { - po.parseString(l) + state = po.parseString(l, state) continue } } @@ -259,23 +274,36 @@ func (po *Po) parseMessage(l string) { // parseString takes a well formatted string without prefix // and creates headers or attach multi-line strings when corresponding -func (po *Po) parseString(l string) { - // Check for multiline from previously set msgid - if po.trBuffer.id != "" { - // Append to last translation found +func (po *Po) parseString(l string, state parseState) parseState { + switch state { + case msgStr: + // Check for multiline from previously set msgid + if po.trBuffer.id != "" { + // Append to last translation found + uq, _ := strconv.Unquote(l) + po.trBuffer.trs[len(po.trBuffer.trs)-1] += uq + + } + case msgID: + // Multiline msgid - Append to current id uq, _ := strconv.Unquote(l) - po.trBuffer.trs[len(po.trBuffer.trs)-1] += uq - - return + po.trBuffer.id += uq + case msgIDPlural: + // Multiline msgid - Append to current id + uq, _ := strconv.Unquote(l) + po.trBuffer.pluralID += uq + case msgCtxt: + // Multiline context - Append to current context + ctxt, _ := strconv.Unquote(l) + po.ctxBuffer += ctxt + default: + // Otherwise is a header + h, _ := strconv.Unquote(strings.TrimSpace(l)) + po.RawHeaders += h + return head } - // Otherwise is a header - h, err := strconv.Unquote(strings.TrimSpace(l)) - if err != nil { - return - } - - po.RawHeaders += h + return state } // isValidLine checks for line prefixes to detect valid syntax. diff --git a/po_test.go b/po_test.go index 9f59a33..ae96861 100644 --- a/po_test.go +++ b/po_test.go @@ -9,8 +9,6 @@ import ( func TestPo(t *testing.T) { // Set PO content str := ` -msgid "" -msgstr "" # Initial comment # Headers below "Language: en\n" @@ -26,6 +24,19 @@ msgstr "Translated text" msgid "Another string" msgstr "" +# Multi-line msgid +msgid "multi" +"line" +"id" +msgstr "id with multiline content" + +# Multi-line msgid_plural +msgid "multi" +"line" +"plural" +"id" +msgstr "plural id with multiline content" + #Multi-line string msgid "Multi-line" msgstr "Multi " @@ -60,7 +71,7 @@ msgstr "Some random translation in a context" msgid "More" msgstr "More translation" - ` + ` // Write PO content to file filename := path.Clean(os.TempDir() + string(os.PathSeparator) + "default.po") @@ -97,6 +108,18 @@ msgstr "More translation" t.Errorf("Expected 'This one is the singular: Variable' but got '%s'", tr) } + // Test multi-line id + tr = po.Get("multilineid") + if tr != "id with multiline content" { + t.Errorf("Expected 'id with multiline content' but got '%s'", tr) + } + + // Test multi-line plural id + tr = po.Get("multilinepluralid") + if tr != "plural id with multiline content" { + t.Errorf("Expected 'plural id with multiline content' but got '%s'", tr) + } + // Test multi-line tr = po.Get("Multi-line") if tr != "Multi line" { @@ -150,13 +173,12 @@ msgstr "More translation" t.Errorf("Expected 'More translation' but got '%s'", tr) } + t.Log(po.contexts) } func TestPoHeaders(t *testing.T) { // Set PO content str := ` -msgid "" -msgstr "" # Initial comment # Headers below "Language: en\n" @@ -167,7 +189,7 @@ msgstr "" # Some comment msgid "Example" msgstr "Translated example" - ` + ` // Create po object po := new(Po) @@ -198,7 +220,7 @@ msgstr[0] "Singular form" msgstr[1] "Plural form 1" msgstr[2] "Plural form 2" msgstr[3] "Plural form 3" - ` + ` // Create po object po := new(Po) @@ -241,7 +263,7 @@ msgstr[0] "Singular form" msgstr[1] "Plural form 1" msgstr[2] "Plural form 2" msgstr[3] "Plural form 3" - ` + ` // Create po object po := new(Po) @@ -280,7 +302,7 @@ msgstr[0] "Singular form" msgstr[1] "Plural form 1" msgstr[2] "Plural form 2" msgstr[3] "Plural form 3" - ` + ` // Create po object po := new(Po) @@ -328,7 +350,7 @@ msgstr[0] "Singular form" msgstr[1] "Plural form 1" msgstr[2] "Plural form 2" msgstr[3] "Plural form 3" - ` + ` // Create po object po := new(Po) @@ -394,7 +416,7 @@ msgstr[0] "This one is the singular: %s" msgstr[1] "This one is the plural: %s" msgstr[2] "And this is the second plural form: %s" - ` + ` // Create Po object po := new(Po) From 1c611eff63e4f7daf8560f69fbd661997e555d43 Mon Sep 17 00:00:00 2001 From: Mattias Lundell Date: Mon, 29 May 2017 11:44:49 +0200 Subject: [PATCH 2/2] removed debug print --- po_test.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/po_test.go b/po_test.go index ae96861..17804b0 100644 --- a/po_test.go +++ b/po_test.go @@ -172,8 +172,6 @@ msgstr "More translation" if tr != "More translation" { t.Errorf("Expected 'More translation' but got '%s'", tr) } - - t.Log(po.contexts) } func TestPoHeaders(t *testing.T) {