diff --git a/lib/po.js b/lib/po.js index 82d13f1..0d7a82f 100644 --- a/lib/po.js +++ b/lib/po.js @@ -181,6 +181,12 @@ PO.Item.prototype.toString = function () { var lines = [], that = this; + // reverse what extract(string) method during PO.parse does + var _escape = function (string) { + string = string.replace(/\\/g, '\\\\'); + return string.replace(/"/g, '\\"'); + }; + var _process = function (keyword, text, i) { var lines = [], parts = text.split(/\n/), @@ -188,11 +194,11 @@ PO.Item.prototype.toString = function () { if (parts.length > 1) { lines.push(keyword + index + ' ""'); parts.forEach(function (part) { - lines.push('"' + part + '"'); + lines.push('"' + _escape(part) + '"'); }); } else { - lines.push(keyword + index + ' "' + text + '"'); + lines.push(keyword + index + ' "' + _escape(text) + '"'); } return lines; }; diff --git a/test/fixtures/c-strings.po b/test/fixtures/c-strings.po new file mode 100644 index 0000000..597951e --- /dev/null +++ b/test/fixtures/c-strings.po @@ -0,0 +1,19 @@ +# French translation of Link (6.x-2.9) +# Copyright (c) 2011 by the French translation team +msgid "" +msgstr "" +"Project-Id-Version: Link (6.x-2.9)\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2011-12-31 23:39+0000\n" +"PO-Revision-Date: 2013-12-17 14:59+0100\n" +"Last-Translator: Ruben Vermeersch \n" +"Language: fr\n" +"Language-Team: French\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" +"MIME-Version: 1.0\n" +"X-Generator: Poedit 1.6.2\n" + +msgid "The name field must not contain characters like \" or \\" +msgstr "" diff --git a/test/parse.js b/test/parse.js index e252b08..4547775 100644 --- a/test/parse.js +++ b/test/parse.js @@ -84,4 +84,21 @@ describe('Parse', function () { assert.equal(ambiguousItems[0].msgctxt, 'folder display'); assert.equal(ambiguousItems[1].msgctxt, 'folder action'); }); + + describe('C-Strings', function () { + it('should parse the c-strings.po file', function () { + var po = PO.parse(fs.readFileSync(__dirname + '/fixtures/c-strings.po', 'utf8')); + + assert.notEqual(po, null); + }); + + it('should extract strings containing " and \\ characters', function () { + var po = PO.parse(fs.readFileSync(__dirname + '/fixtures/c-strings.po', 'utf8')); + + var items = po.items.filter(function (item) { + return (/^The name field must not contain/).test(item.msgid); + }); + assert.equal(items[0].msgid, 'The name field must not contain characters like " or \\'); + }); + }); }); diff --git a/test/write.js b/test/write.js index a1ccd11..2f33f3d 100644 --- a/test/write.js +++ b/test/write.js @@ -52,6 +52,30 @@ describe('Write', function () { assertHasLine(str, '#. Extracted comment'); }); + describe('C-Strings', function () { + it('should escape "', function () { + var item = new PO.Item(); + + item.msgid = '" should be written escaped'; + assertHasLine(item.toString(), 'msgid "\\" should be written escaped"'); + }); + + it('shoudl escape \\', function () { + var item = new PO.Item(); + + item.msgid = '\\ should be written escaped'; + assertHasLine(item.toString(), 'msgid "\\\\ should be written escaped"'); + }); + + it('should write identical file after parsing a file', function () { + var input = fs.readFileSync(__dirname + '/fixtures/c-strings.po', 'utf8'); + var po = PO.parse(input); + var str = po.toString(); + + assert.equal(str, input); + }); + }); + describe('msgctxt', function () { it('should write context field to file', function () { var input = fs.readFileSync(__dirname + '/fixtures/big.po', 'utf8');