gettext-parser
Advanced tools
Comparing version
# Changelog | ||
## v1.0.0 2015-01-21 | ||
* Bumped version to 1.0.0 to be compatible with semver | ||
* Changed tests from nodeunit to mocha | ||
* Unified code style in files and added jshint task to check it | ||
* Added Grunt support to check style and run tests on `npm test` | ||
## v0.2.0 2013-12-30 | ||
@@ -4,0 +11,0 @@ |
18
index.js
@@ -1,13 +0,13 @@ | ||
"use strict"; | ||
'use strict'; | ||
module.exports = { | ||
po: { | ||
parse: require("./lib/poparser"), | ||
compile: require("./lib/pocompiler") | ||
}, | ||
po: { | ||
parse: require('./lib/poparser'), | ||
compile: require('./lib/pocompiler') | ||
}, | ||
mo: { | ||
parse: require("./lib/moparser"), | ||
compile: require("./lib/mocompiler") | ||
} | ||
mo: { | ||
parse: require('./lib/moparser'), | ||
compile: require('./lib/mocompiler') | ||
} | ||
}; |
@@ -1,5 +0,5 @@ | ||
"use strict"; | ||
'use strict'; | ||
var encoding = require("encoding"), | ||
sharedFuncs = require("./shared"); | ||
var encoding = require('encoding'); | ||
var sharedFuncs = require('./shared'); | ||
@@ -13,3 +13,3 @@ /** | ||
*/ | ||
module.exports = function(table){ | ||
module.exports = function(table) { | ||
var compiler = new Compiler(table); | ||
@@ -25,3 +25,3 @@ return compiler.compile(); | ||
*/ | ||
function Compiler(table){ | ||
function Compiler(table) { | ||
this._table = table || {}; | ||
@@ -33,3 +33,3 @@ this._table.headers = this._table.headers || {}; | ||
this._writeFunc = "writeUInt32LE"; | ||
this._writeFunc = 'writeUInt32LE'; | ||
@@ -47,4 +47,4 @@ this._handleCharset(); | ||
*/ | ||
Compiler.prototype._handleCharset = function(){ | ||
var parts = (this._table.headers['content-type'] || "text/plain").split(";"), | ||
Compiler.prototype._handleCharset = function() { | ||
var parts = (this._table.headers['content-type'] || 'text/plain').split(';'), | ||
contentType = parts.shift(), | ||
@@ -54,12 +54,12 @@ charset = sharedFuncs.formatCharset(this._table.charset), | ||
params = parts.map(function(part){ | ||
var parts = part.split("="), | ||
params = parts.map(function(part) { | ||
var parts = part.split('='), | ||
key = parts.shift().trim(), | ||
value = parts.join("="); | ||
value = parts.join('='); | ||
if(key.toLowerCase() == "charset"){ | ||
if(!charset){ | ||
charset = sharedFuncs.formatCharset(value.trim() || "utf-8"); | ||
if (key.toLowerCase() === 'charset') { | ||
if (!charset) { | ||
charset = sharedFuncs.formatCharset(value.trim() || 'utf-8'); | ||
} | ||
return "charset=" + charset; | ||
return 'charset=' + charset; | ||
} | ||
@@ -70,9 +70,9 @@ | ||
if(!charset){ | ||
charset = this._table.charset || "utf-8"; | ||
params.push("charset=" + charset); | ||
if (!charset) { | ||
charset = this._table.charset || 'utf-8'; | ||
params.push('charset=' + charset); | ||
} | ||
this._table.charset = charset; | ||
this._table.headers['content-type'] = contentType + "; " + params.join("; "); | ||
this._table.headers['content-type'] = contentType + '; ' + params.join('; '); | ||
@@ -88,3 +88,3 @@ this._charset = charset; | ||
*/ | ||
Compiler.prototype._generateList = function(){ | ||
Compiler.prototype._generateList = function() { | ||
var list = []; | ||
@@ -97,11 +97,11 @@ | ||
Object.keys(this._table.translations).forEach((function(msgctxt){ | ||
if(typeof this._table.translations[msgctxt] != "object"){ | ||
Object.keys(this._table.translations).forEach((function(msgctxt) { | ||
if (typeof this._table.translations[msgctxt] !== 'object') { | ||
return; | ||
} | ||
Object.keys(this._table.translations[msgctxt]).forEach((function(msgid){ | ||
if(typeof this._table.translations[msgctxt][msgid] != "object"){ | ||
Object.keys(this._table.translations[msgctxt]).forEach((function(msgid) { | ||
if (typeof this._table.translations[msgctxt][msgid] !== 'object') { | ||
return; | ||
} | ||
if(msgctxt === "" && msgid === ""){ | ||
if (msgctxt === '' && msgid === '') { | ||
return; | ||
@@ -114,11 +114,11 @@ } | ||
if(msgctxt){ | ||
key = msgctxt + "\u0004" + key; | ||
if (msgctxt) { | ||
key = msgctxt + '\u0004' + key; | ||
} | ||
if(msgid_plural){ | ||
key += "\u0000" + msgid_plural; | ||
if (msgid_plural) { | ||
key += '\u0000' + msgid_plural; | ||
} | ||
value = [].concat(this._table.translations[msgctxt][msgid].msgstr || []).join("\u0000"); | ||
value = [].concat(this._table.translations[msgctxt][msgid].msgstr || []).join('\u0000'); | ||
@@ -141,6 +141,8 @@ list.push({ | ||
*/ | ||
Compiler.prototype._calculateSize = function(list){ | ||
var msgidLength = 0, msgstrLength = 0, totalLength = 0; | ||
Compiler.prototype._calculateSize = function(list) { | ||
var msgidLength = 0, | ||
msgstrLength = 0, | ||
totalLength = 0; | ||
list.forEach(function(translation){ | ||
list.forEach(function(translation) { | ||
msgidLength += translation.msgid.length + 1; // + extra 0x00 | ||
@@ -151,12 +153,12 @@ msgstrLength += translation.msgstr.length + 1; // + extra 0x00 | ||
totalLength = 4 + // magic number | ||
4 + // revision | ||
4 + // string count | ||
4 + // original string table offset | ||
4 + // translation string table offset | ||
4 + // hash table size | ||
4 + // hash table offset | ||
(4+4) * list.length + // original string table | ||
(4+4) * list.length + // translations string table | ||
msgidLength + // originals | ||
msgstrLength; // translations | ||
4 + // revision | ||
4 + // string count | ||
4 + // original string table offset | ||
4 + // translation string table offset | ||
4 + // hash table size | ||
4 + // hash table offset | ||
(4 + 4) * list.length + // original string table | ||
(4 + 4) * list.length + // translations string table | ||
msgidLength + // originals | ||
msgstrLength; // translations | ||
@@ -177,3 +179,3 @@ return { | ||
*/ | ||
Compiler.prototype._build = function(list, size){ | ||
Compiler.prototype._build = function(list, size) { | ||
var returnBuffer = new Buffer(size.total), | ||
@@ -196,3 +198,3 @@ curPosition = 0, | ||
// translation string table offset | ||
returnBuffer[this._writeFunc](28 + (4+4) * list.length, 16); | ||
returnBuffer[this._writeFunc](28 + (4 + 4) * list.length, 16); | ||
@@ -203,7 +205,7 @@ // hash table size | ||
// hash table offset | ||
returnBuffer[this._writeFunc](28 + (4+4) * list.length, 24); | ||
returnBuffer[this._writeFunc](28 + (4 + 4) * list.length, 24); | ||
// build originals table | ||
curPosition = 28 + 2 * (4 + 4) * list.length; | ||
for(i=0, len = list.length; i < len; i++){ | ||
for (i = 0, len = list.length; i < len; i++) { | ||
list[i].msgid.copy(returnBuffer, curPosition); | ||
@@ -213,10 +215,10 @@ returnBuffer[this._writeFunc](list[i].msgid.length, 28 + i * 8); | ||
returnBuffer[curPosition + list[i].msgid.length] = 0x00; | ||
curPosition += list[i].msgid.length+1; | ||
curPosition += list[i].msgid.length + 1; | ||
} | ||
// build translations table | ||
for(i=0, len = list.length; i<len; i++){ | ||
for (i = 0, len = list.length; i < len; i++) { | ||
list[i].msgstr.copy(returnBuffer, curPosition); | ||
returnBuffer[this._writeFunc](list[i].msgstr.length, 28 + (4 + 4) * list.length + i * 8); | ||
returnBuffer[this._writeFunc](curPosition, 28 + (4+4) * list.length + i * 8 + 4); | ||
returnBuffer[this._writeFunc](curPosition, 28 + (4 + 4) * list.length + i * 8 + 4); | ||
returnBuffer[curPosition + list[i].msgstr.length] = 0x00; | ||
@@ -234,3 +236,3 @@ curPosition += list[i].msgstr.length + 1; | ||
*/ | ||
Compiler.prototype.compile = function(){ | ||
Compiler.prototype.compile = function() { | ||
var list = this._generateList(), | ||
@@ -240,7 +242,7 @@ size = this._calculateSize(list); | ||
// sort by msgid | ||
list.sort(function(a, b){ | ||
if(a.msgid > b.msgid){ | ||
list.sort(function(a, b) { | ||
if (a.msgid > b.msgid) { | ||
return 1; | ||
} | ||
if(a.msgid < b.msgid){ | ||
if (a.msgid < b.msgid) { | ||
return -1; | ||
@@ -252,2 +254,2 @@ } | ||
return this._build(list, size); | ||
}; | ||
}; |
@@ -1,5 +0,5 @@ | ||
"use strict"; | ||
'use strict'; | ||
var encoding = require("encoding"), | ||
sharedFuncs = require("./shared"); | ||
var encoding = require('encoding'); | ||
var sharedFuncs = require('./shared'); | ||
@@ -13,3 +13,3 @@ /** | ||
*/ | ||
module.exports = function(buffer, defaultCharset){ | ||
module.exports = function(buffer, defaultCharset) { | ||
var parser = new Parser(buffer, defaultCharset); | ||
@@ -26,3 +26,3 @@ return parser.parse(); | ||
*/ | ||
function Parser(fileContents, defaultCharset){ | ||
function Parser(fileContents, defaultCharset) { | ||
@@ -34,3 +34,3 @@ this._fileContents = fileContents; | ||
*/ | ||
this._writeFunc = "writeUInt32LE"; | ||
this._writeFunc = 'writeUInt32LE'; | ||
@@ -40,5 +40,5 @@ /** | ||
*/ | ||
this._readFunc = "readUInt32LE"; | ||
this._readFunc = 'readUInt32LE'; | ||
this._charset = defaultCharset || "iso-8859-1"; | ||
this._charset = defaultCharset || 'iso-8859-1'; | ||
@@ -62,12 +62,12 @@ this._table = { | ||
*/ | ||
Parser.prototype._checkMagick = function(){ | ||
if(this._fileContents.readUInt32LE(0) == this.MAGIC){ | ||
this._readFunc = "readUInt32LE"; | ||
this._writeFunc = "writeUInt32LE"; | ||
Parser.prototype._checkMagick = function() { | ||
if (this._fileContents.readUInt32LE(0) === this.MAGIC) { | ||
this._readFunc = 'readUInt32LE'; | ||
this._writeFunc = 'writeUInt32LE'; | ||
return true; | ||
}else if(this._fileContents.readUInt32BE(0) == this.MAGIC){ | ||
this._readFunc = "readUInt32BE"; | ||
this._writeFunc = "writeUInt32BE"; | ||
} else if (this._fileContents.readUInt32BE(0) === this.MAGIC) { | ||
this._readFunc = 'readUInt32BE'; | ||
this._writeFunc = 'writeUInt32BE'; | ||
return true; | ||
}else{ | ||
} else { | ||
return false; | ||
@@ -81,3 +81,3 @@ } | ||
*/ | ||
Parser.prototype._loadTranslationTable = function(){ | ||
Parser.prototype._loadTranslationTable = function() { | ||
var offsetOriginals = this._offsetOriginals, | ||
@@ -88,3 +88,3 @@ offsetTranslations = this._offsetTranslations, | ||
for(var i = 0; i < this._total; i++){ | ||
for (var i = 0; i < this._total; i++) { | ||
// msgid string | ||
@@ -104,8 +104,8 @@ length = this._fileContents[this._readFunc](offsetOriginals); | ||
if(!i && !msgid.toString()){ | ||
if (!i && !msgid.toString()) { | ||
this._handleCharset(msgstr); | ||
} | ||
msgid = encoding.convert(msgid, "utf-8", this._charset).toString("utf-8"); | ||
msgstr = encoding.convert(msgstr, "utf-8", this._charset).toString("utf-8"); | ||
msgid = encoding.convert(msgid, 'utf-8', this._charset).toString('utf-8'); | ||
msgstr = encoding.convert(msgstr, 'utf-8', this._charset).toString('utf-8'); | ||
@@ -124,3 +124,3 @@ this._addString(msgid, msgstr); | ||
*/ | ||
Parser.prototype._handleCharset = function(headers){ | ||
Parser.prototype._handleCharset = function(headers) { | ||
@@ -130,7 +130,7 @@ var headersStr = headers.toString(), | ||
if((match = headersStr.match(/[; ]charset\s*=\s*([\w\-]+)/i))){ | ||
if ((match = headersStr.match(/[; ]charset\s*=\s*([\w\-]+)/i))) { | ||
this._charset = this._table.charset = sharedFuncs.formatCharset(match[1], this._charset); | ||
} | ||
headers = encoding.convert(headers, "utf-8", this._charset).toString("utf-8"); | ||
headers = encoding.convert(headers, 'utf-8', this._charset).toString('utf-8'); | ||
@@ -146,15 +146,16 @@ this._table.headers = sharedFuncs.parseHeader(headers); | ||
*/ | ||
Parser.prototype._addString = function(msgid, msgstr){ | ||
var translation = {}, parts, msgctxt, msgid_plural; | ||
Parser.prototype._addString = function(msgid, msgstr) { | ||
var translation = {}, | ||
parts, msgctxt, msgid_plural; | ||
msgid = msgid.split("\u0004"); | ||
if(msgid.length > 1){ | ||
msgid = msgid.split('\u0004'); | ||
if (msgid.length > 1) { | ||
msgctxt = msgid.shift(); | ||
translation.msgctxt = msgctxt; | ||
}else{ | ||
msgctxt = ""; | ||
} else { | ||
msgctxt = ''; | ||
} | ||
msgid = msgid.join("\u0004"); | ||
msgid = msgid.join('\u0004'); | ||
parts = msgid.split("\u0000"); | ||
parts = msgid.split('\u0000'); | ||
msgid = parts.shift(); | ||
@@ -164,10 +165,10 @@ | ||
if((msgid_plural = parts.join("\u0000"))){ | ||
if ((msgid_plural = parts.join('\u0000'))) { | ||
translation.msgid_plural = msgid_plural; | ||
} | ||
msgstr = msgstr.split("\u0000"); | ||
msgstr = msgstr.split('\u0000'); | ||
translation.msgstr = [].concat(msgstr || []); | ||
if(!this._table.translations[msgctxt]){ | ||
if (!this._table.translations[msgctxt]) { | ||
this._table.translations[msgctxt] = {}; | ||
@@ -184,4 +185,4 @@ } | ||
*/ | ||
Parser.prototype.parse = function(){ | ||
if(!this._checkMagick()){ | ||
Parser.prototype.parse = function() { | ||
if (!this._checkMagick()) { | ||
return false; | ||
@@ -214,2 +215,2 @@ } | ||
return this._table; | ||
}; | ||
}; |
@@ -1,5 +0,5 @@ | ||
"use strict"; | ||
'use strict'; | ||
var encoding = require("encoding"), | ||
sharedFuncs = require("./shared"); | ||
var encoding = require('encoding'); | ||
var sharedFuncs = require('./shared'); | ||
@@ -13,3 +13,3 @@ /** | ||
*/ | ||
module.exports = function(table){ | ||
module.exports = function(table) { | ||
var compiler = new Compiler(table); | ||
@@ -25,9 +25,7 @@ return compiler.compile(); | ||
*/ | ||
function Compiler(table){ | ||
function Compiler(table) { | ||
this._table = table || {}; | ||
this._table.headers = this._table.headers || {}; | ||
this._table.translations = this._table.translations || {}; | ||
this._translations = []; | ||
this._handleCharset(); | ||
@@ -38,3 +36,3 @@ } | ||
* Converts a comments object to a comment string. The comment object is | ||
* in the form of {translator:"", reference: "", extracted: "", flag: "", previous:""} | ||
* in the form of {translator:'', reference: '', extracted: '', flag: '', previous:''} | ||
* | ||
@@ -44,32 +42,26 @@ * @param {Object} comments A comments object | ||
*/ | ||
Compiler.prototype._drawComments = function(comments){ | ||
Compiler.prototype._drawComments = function(comments) { | ||
var lines = []; | ||
var types = [ | ||
{ | ||
key: "translator", | ||
prefix: "# " | ||
}, | ||
{ | ||
key: "reference", | ||
prefix: "#: " | ||
}, | ||
{ | ||
key: "extracted", | ||
prefix: "#. " | ||
}, | ||
{ | ||
key: "flag", | ||
prefix: "#, " | ||
}, | ||
{ | ||
key: "previous", | ||
prefix: "#| " | ||
} | ||
]; | ||
var types = [{ | ||
key: 'translator', | ||
prefix: '# ' | ||
}, { | ||
key: 'reference', | ||
prefix: '#: ' | ||
}, { | ||
key: 'extracted', | ||
prefix: '#. ' | ||
}, { | ||
key: 'flag', | ||
prefix: '#, ' | ||
}, { | ||
key: 'previous', | ||
prefix: '#| ' | ||
}]; | ||
types.forEach(function(type){ | ||
if(!comments[type.key]){ | ||
types.forEach(function(type) { | ||
if (!comments[type.key]) { | ||
return; | ||
} | ||
comments[type.key].split(/\r?\n|\r/).forEach(function(line){ | ||
comments[type.key].split(/\r?\n|\r/).forEach(function(line) { | ||
lines.push(type.prefix + line); | ||
@@ -79,3 +71,3 @@ }); | ||
return lines.join("\n"); | ||
return lines.join('\n'); | ||
}; | ||
@@ -90,3 +82,3 @@ | ||
*/ | ||
Compiler.prototype._drawBlock = function(block, override){ | ||
Compiler.prototype._drawBlock = function(block, override) { | ||
@@ -104,25 +96,25 @@ override = override || {}; | ||
// add comments | ||
if(comments && (comments = this._drawComments(comments))){ | ||
if (comments && (comments = this._drawComments(comments))) { | ||
response.push(comments); | ||
} | ||
if(msgctxt){ | ||
response.push(this._addPOString("msgctxt", msgctxt)); | ||
if (msgctxt) { | ||
response.push(this._addPOString('msgctxt', msgctxt)); | ||
} | ||
response.push(this._addPOString("msgid", msgid || "")); | ||
response.push(this._addPOString('msgid', msgid || '')); | ||
if(msgid_plural){ | ||
response.push(this._addPOString("msgid_plural", msgid_plural)); | ||
if (msgid_plural) { | ||
response.push(this._addPOString('msgid_plural', msgid_plural)); | ||
} | ||
if(msgstr.length <= 1){ | ||
response.push(this._addPOString("msgstr", msgstr[0] || "")); | ||
}else{ | ||
msgstr.forEach((function(msgstr, i){ | ||
response.push(this._addPOString("msgstr["+i+"]", msgstr || "")); | ||
if (msgstr.length <= 1) { | ||
response.push(this._addPOString('msgstr', msgstr[0] || '')); | ||
} else { | ||
msgstr.forEach((function(msgstr, i) { | ||
response.push(this._addPOString('msgstr[' + i + ']', msgstr || '')); | ||
}).bind(this)); | ||
} | ||
return response.join("\n"); | ||
return response.join('\n'); | ||
}; | ||
@@ -137,33 +129,33 @@ | ||
*/ | ||
Compiler.prototype._addPOString = function(key, value){ | ||
Compiler.prototype._addPOString = function(key, value) { | ||
var line; | ||
key = (key || "").toString(); | ||
key = (key || '').toString(); | ||
// escape newlines and quotes | ||
value = (value || "").toString(). | ||
replace(/\\/g, "\\\\"). | ||
replace(/\"/g, "\\\""). | ||
replace(/\t/g, "\\t"). | ||
replace(/\r/g, "\\r"). | ||
replace(/\n/g, "\\n"); | ||
value = (value || '').toString(). | ||
replace(/\\/g, '\\\\'). | ||
replace(/"/g, '\\"'). | ||
replace(/\t/g, '\\t'). | ||
replace(/\r/g, '\\r'). | ||
replace(/\n/g, '\\n'); | ||
var lines = sharedFuncs.foldLine(value); | ||
if(lines.length < 2){ | ||
return key + " \"" + (lines.shift() || "") + "\""; | ||
}else{ | ||
return key + " \"\"\n\"" + lines.join("\"\n\"") + "\""; | ||
if (lines.length < 2) { | ||
return key + ' "' + (lines.shift() || '') + '"'; | ||
} else { | ||
return key + ' ""\n"' + lines.join('"\n"') + '"'; | ||
} | ||
if(value.match(/\n/)){ | ||
value = value.replace(/\n/g, "\\n\n").replace(/\n$/, ""); | ||
line = ("\n"+value).split("\n").map(function(l){ | ||
if (value.match(/\n/)) { | ||
value = value.replace(/\n/g, '\\n\n').replace(/\n$/, ''); | ||
line = ('\n' + value).split('\n').map(function(l) { | ||
return '"' + l + '"'; | ||
}).join("\n"); | ||
}else{ | ||
}).join('\n'); | ||
} else { | ||
line = '"' + value + '"'; | ||
} | ||
return key + " " + line; | ||
return key + ' ' + line; | ||
}; | ||
@@ -174,18 +166,18 @@ | ||
*/ | ||
Compiler.prototype._handleCharset = function(){ | ||
var parts = (this._table.headers['content-type'] || "text/plain").split(";"), | ||
contentType = parts.shift(), | ||
charset = sharedFuncs.formatCharset(this._table.charset), | ||
params = []; | ||
Compiler.prototype._handleCharset = function() { | ||
var parts = (this._table.headers['content-type'] || 'text/plain').split(';'); | ||
var contentType = parts.shift(); | ||
var charset = sharedFuncs.formatCharset(this._table.charset); | ||
var params = []; | ||
params = parts.map(function(part){ | ||
var parts = part.split("="), | ||
params = parts.map(function(part) { | ||
var parts = part.split('='), | ||
key = parts.shift().trim(), | ||
value = parts.join("="); | ||
value = parts.join('='); | ||
if(key.toLowerCase() == "charset"){ | ||
if(!charset){ | ||
charset = sharedFuncs.formatCharset(value.trim() || "utf-8"); | ||
if (key.toLowerCase() === 'charset') { | ||
if (!charset) { | ||
charset = sharedFuncs.formatCharset(value.trim() || 'utf-8'); | ||
} | ||
return "charset=" + charset; | ||
return 'charset=' + charset; | ||
} | ||
@@ -196,9 +188,9 @@ | ||
if(!charset){ | ||
charset = this._table.charset || "utf-8"; | ||
params.push("charset=" + charset); | ||
if (!charset) { | ||
charset = this._table.charset || 'utf-8'; | ||
params.push('charset=' + charset); | ||
} | ||
this._table.charset = charset; | ||
this._table.headers['content-type'] = contentType + "; " + params.join("; "); | ||
this._table.headers['content-type'] = contentType + '; ' + params.join('; '); | ||
@@ -213,18 +205,20 @@ this._charset = charset; | ||
*/ | ||
Compiler.prototype.compile = function(){ | ||
Compiler.prototype.compile = function() { | ||
var response = [], | ||
headerBlock = this._table.translations[""] && this._table.translations[""][""] || {}; | ||
headerBlock = this._table.translations[''] && this._table.translations[''][''] || {}; | ||
response.push(this._drawBlock(headerBlock, {msgstr: sharedFuncs.generateHeader(this._table.headers)})); | ||
response.push(this._drawBlock(headerBlock, { | ||
msgstr: sharedFuncs.generateHeader(this._table.headers) | ||
})); | ||
Object.keys(this._table.translations).forEach((function(msgctxt){ | ||
if(typeof this._table.translations[msgctxt] != "object"){ | ||
Object.keys(this._table.translations).forEach((function(msgctxt) { | ||
if (typeof this._table.translations[msgctxt] !== 'object') { | ||
return; | ||
} | ||
Object.keys(this._table.translations[msgctxt]).forEach((function(msgid){ | ||
if(typeof this._table.translations[msgctxt][msgid] != "object"){ | ||
Object.keys(this._table.translations[msgctxt]).forEach((function(msgid) { | ||
if (typeof this._table.translations[msgctxt][msgid] !== 'object') { | ||
return; | ||
} | ||
if(msgctxt === "" && msgid === ""){ | ||
if (msgctxt === '' && msgid === '') { | ||
return; | ||
@@ -237,7 +231,7 @@ } | ||
if(this._charset == "utf-8" || this._charset == "ascii"){ | ||
return new Buffer(response.join("\n\n"), "utf-8"); | ||
}else{ | ||
return encoding.convert(response.join("\n\n"), this._charset); | ||
if (this._charset === 'utf-8' || this._charset === 'ascii') { | ||
return new Buffer(response.join('\n\n'), 'utf-8'); | ||
} else { | ||
return encoding.convert(response.join('\n\n'), this._charset); | ||
} | ||
}; | ||
}; |
@@ -1,5 +0,5 @@ | ||
"use strict"; | ||
'use strict'; | ||
var encoding = require("encoding"), | ||
sharedFuncs = require("./shared"); | ||
var encoding = require('encoding'); | ||
var sharedFuncs = require('./shared'); | ||
@@ -13,3 +13,3 @@ /** | ||
*/ | ||
module.exports = function(buffer, defaultCharset){ | ||
module.exports = function(buffer, defaultCharset) { | ||
var parser = new Parser(buffer, defaultCharset); | ||
@@ -27,10 +27,10 @@ return parser.parse(); | ||
*/ | ||
function Parser(fileContents, defaultCharset){ | ||
function Parser(fileContents, defaultCharset) { | ||
this._charset = defaultCharset || "iso-8859-1"; | ||
this._charset = defaultCharset || 'iso-8859-1'; | ||
if(typeof fileContents == "string"){ | ||
this._charset = "utf-8"; | ||
if (typeof fileContents === 'string') { | ||
this._charset = 'utf-8'; | ||
this._fileContents = fileContents; | ||
}else{ | ||
} else { | ||
this._handleCharset(fileContents); | ||
@@ -46,8 +46,9 @@ } | ||
*/ | ||
Parser.prototype._handleCharset = function(buf){ | ||
var str = (buf || "").toString(), | ||
pos, headers = "", match; | ||
Parser.prototype._handleCharset = function(buf) { | ||
var str = (buf || '').toString(), | ||
pos, headers = '', | ||
match; | ||
if((pos = str.search(/^\s*msgid/im))>=0){ | ||
if((pos = pos + str.substr(pos + 5).search(/^\s*(msgid|msgctxt)/im))){ | ||
if ((pos = str.search(/^\s*msgid/im)) >= 0) { | ||
if ((pos = pos + str.substr(pos + 5).search(/^\s*(msgid|msgctxt)/im))) { | ||
headers = str.substr(0, pos); | ||
@@ -57,10 +58,10 @@ } | ||
if((match = headers.match(/[; ]charset\s*=\s*([\w\-]+)(?:[\s;]|\\n)*"\s*$/mi))){ | ||
if ((match = headers.match(/[; ]charset\s*=\s*([\w\-]+)(?:[\s;]|\\n)*"\s*$/mi))) { | ||
this._charset = sharedFuncs.formatCharset(match[1], this._charset); | ||
} | ||
if(this._charset == "utf-8"){ | ||
if (this._charset === 'utf-8') { | ||
this._fileContents = str; | ||
}else{ | ||
this._fileContents = encoding.convert(buf, "utf-8", this._charset).toString("utf-8"); | ||
} else { | ||
this._fileContents = encoding.convert(buf, 'utf-8', this._charset).toString('utf-8'); | ||
} | ||
@@ -92,3 +93,3 @@ }; | ||
Parser.prototype.symbols = { | ||
quotes: /['"]/, | ||
quotes: /["']/, | ||
comments: /\#/, | ||
@@ -104,3 +105,3 @@ whitespace: /\s/, | ||
*/ | ||
Parser.prototype._lexer = function(){ | ||
Parser.prototype._lexer = function() { | ||
var chr, | ||
@@ -112,10 +113,10 @@ escaped = false, | ||
for(var i=0, len = this._fileContents.length; i<len; i++){ | ||
for (var i = 0, len = this._fileContents.length; i < len; i++) { | ||
chr = this._fileContents.charAt(i); | ||
switch(state){ | ||
switch (state) { | ||
case this.states.none: | ||
if(chr.match(this.symbols.quotes)){ | ||
if (chr.match(this.symbols.quotes)) { | ||
node = { | ||
type: this.types.string, | ||
value: "", | ||
value: '', | ||
quote: chr | ||
@@ -125,10 +126,10 @@ }; | ||
state = this.states.string; | ||
}else if(chr.match(this.symbols.comments)){ | ||
} else if (chr.match(this.symbols.comments)) { | ||
node = { | ||
type: this.types.comments, | ||
value: "" | ||
value: '' | ||
}; | ||
lex.push(node); | ||
state = this.states.comments; | ||
}else if(!chr.match(this.symbols.whitespace)){ | ||
} else if (!chr.match(this.symbols.whitespace)) { | ||
node = { | ||
@@ -143,5 +144,5 @@ type: this.types.key, | ||
case this.states.comments: | ||
if(chr == "\n"){ | ||
if (chr === '\n') { | ||
state = this.states.none; | ||
}else if(chr != "\r"){ | ||
} else if (chr !== '\r') { | ||
node.value += chr; | ||
@@ -151,7 +152,13 @@ } | ||
case this.states.string: | ||
if(escaped){ | ||
switch(chr){ | ||
case "t": node.value += "\t"; break; | ||
case "n": node.value += "\n"; break; | ||
case "r": node.value += "\r"; break; | ||
if (escaped) { | ||
switch (chr) { | ||
case 't': | ||
node.value += '\t'; | ||
break; | ||
case 'n': | ||
node.value += '\n'; | ||
break; | ||
case 'r': | ||
node.value += '\r'; | ||
break; | ||
default: | ||
@@ -161,9 +168,9 @@ node.value += chr; | ||
escaped = false; | ||
}else{ | ||
if(chr == node.quote){ | ||
} else { | ||
if (chr === node.quote) { | ||
state = this.states.none; | ||
}else if(chr == "\\"){ | ||
} else if (chr === '\\') { | ||
escaped = true; | ||
break; | ||
}else{ | ||
} else { | ||
node.value += chr; | ||
@@ -175,6 +182,6 @@ } | ||
case this.states.key: | ||
if(!chr.match(this.symbols.key)){ | ||
if (!chr.match(this.symbols.key)) { | ||
state = this.states.none; | ||
i--; | ||
}else{ | ||
} else { | ||
node.value += chr; | ||
@@ -195,11 +202,11 @@ } | ||
*/ | ||
Parser.prototype._joinStringValues = function(lex){ | ||
Parser.prototype._joinStringValues = function(lex) { | ||
var lastNode, response = []; | ||
for(var i=0, len = lex.length; i<len; i++){ | ||
if(lastNode && lex[i].type == this.types.string && lastNode.type == this.types.string){ | ||
for (var i = 0, len = lex.length; i < len; i++) { | ||
if (lastNode && lex[i].type === this.types.string && lastNode.type === this.types.string) { | ||
lastNode.value += lex[i].value; | ||
}else if(lastNode && lex[i].type == this.types.comments && lastNode.type == this.types.comments){ | ||
lastNode.value += "\n" + lex[i].value; | ||
}else{ | ||
} else if (lastNode && lex[i].type === this.types.comments && lastNode.type === this.types.comments) { | ||
lastNode.value += '\n' + lex[i].value; | ||
} else { | ||
response.push(lex[i]); | ||
@@ -218,26 +225,32 @@ lastNode = lex[i]; | ||
*/ | ||
Parser.prototype._parseComments = function(lex){ | ||
Parser.prototype._parseComments = function(lex) { | ||
// parse comments | ||
lex.forEach((function(node){ | ||
lex.forEach((function(node) { | ||
var comment, lines; | ||
if(node && node.type == this.types.comments){ | ||
comment = {translator: [], extracted: [], reference: [], flag: [], previous: []}; | ||
lines = (node.value || "").split(/\n/); | ||
lines.forEach(function(line){ | ||
switch(line.charAt(0) || ""){ | ||
case ":": | ||
if (node && node.type === this.types.comments) { | ||
comment = { | ||
translator: [], | ||
extracted: [], | ||
reference: [], | ||
flag: [], | ||
previous: [] | ||
}; | ||
lines = (node.value || '').split(/\n/); | ||
lines.forEach(function(line) { | ||
switch (line.charAt(0) || '') { | ||
case ':': | ||
comment.reference.push(line.substr(1).trim()); | ||
break; | ||
case ".": | ||
comment.extracted.push(line.substr(1).replace(/^\s+/, "")); | ||
case '.': | ||
comment.extracted.push(line.substr(1).replace(/^\s+/, '')); | ||
break; | ||
case ",": | ||
comment.flag.push(line.substr(1).replace(/^\s+/, "")); | ||
case ',': | ||
comment.flag.push(line.substr(1).replace(/^\s+/, '')); | ||
break; | ||
case "|": | ||
comment.previous.push(line.substr(1).replace(/^\s+/, "")); | ||
case '|': | ||
comment.previous.push(line.substr(1).replace(/^\s+/, '')); | ||
break; | ||
default: | ||
comment.translator.push(line.replace(/^\s+/, "")); | ||
comment.translator.push(line.replace(/^\s+/, '')); | ||
} | ||
@@ -248,5 +261,5 @@ }); | ||
Object.keys(comment).forEach(function(key){ | ||
if(comment[key] && comment[key].length){ | ||
node.value[key] = comment[key].join("\n"); | ||
Object.keys(comment).forEach(function(key) { | ||
if (comment[key] && comment[key].length) { | ||
node.value[key] = comment[key].join('\n'); | ||
} | ||
@@ -264,16 +277,17 @@ }); | ||
*/ | ||
Parser.prototype._handleKeys = function(lex){ | ||
var response = [], lastNode; | ||
Parser.prototype._handleKeys = function(lex) { | ||
var response = [], | ||
lastNode; | ||
for(var i=0, len = lex.length; i<len; i++){ | ||
if(lex[i].type == this.types.key){ | ||
for (var i = 0, len = lex.length; i < len; i++) { | ||
if (lex[i].type === this.types.key) { | ||
lastNode = { | ||
key: lex[i].value | ||
}; | ||
if(i && lex[i-1].type == this.types.comments){ | ||
lastNode.comments = lex[i-1].value; | ||
if (i && lex[i - 1].type === this.types.comments) { | ||
lastNode.comments = lex[i - 1].value; | ||
} | ||
lastNode.value = ""; | ||
lastNode.value = ''; | ||
response.push(lastNode); | ||
}else if(lex[i].type == this.types.string && lastNode){ | ||
} else if (lex[i].type === this.types.string && lastNode) { | ||
lastNode.value += lex[i].value; | ||
@@ -292,10 +306,11 @@ } | ||
*/ | ||
Parser.prototype._handleValues = function(lex){ | ||
var response = [], lastNode, curContext, curComments; | ||
Parser.prototype._handleValues = function(lex) { | ||
var response = [], | ||
lastNode, curContext, curComments; | ||
for(var i=0, len = lex.length; i<len; i++){ | ||
if(lex[i].key.toLowerCase() == "msgctxt"){ | ||
for (var i = 0, len = lex.length; i < len; i++) { | ||
if (lex[i].key.toLowerCase() === 'msgctxt') { | ||
curContext = lex[i].value; | ||
curComments = lex[i].comments; | ||
}else if(lex[i].key.toLowerCase() == "msgid"){ | ||
} else if (lex[i].key.toLowerCase() === 'msgid') { | ||
lastNode = { | ||
@@ -305,11 +320,11 @@ msgid: lex[i].value | ||
if(curContext){ | ||
if (curContext) { | ||
lastNode.msgctxt = curContext; | ||
} | ||
if(curComments){ | ||
if (curComments) { | ||
lastNode.comments = curComments; | ||
} | ||
if(lex[i].comments && !lastNode.comments){ | ||
if (lex[i].comments && !lastNode.comments) { | ||
lastNode.comments = lex[i].comments; | ||
@@ -321,8 +336,8 @@ } | ||
response.push(lastNode); | ||
}else if(lex[i].key.toLowerCase() == "msgid_plural"){ | ||
if(lastNode){ | ||
} else if (lex[i].key.toLowerCase() === 'msgid_plural') { | ||
if (lastNode) { | ||
lastNode.msgid_plural = lex[i].value; | ||
} | ||
if(lex[i].comments && !lastNode.comments){ | ||
if (lex[i].comments && !lastNode.comments) { | ||
lastNode.comments = lex[i].comments; | ||
@@ -333,8 +348,8 @@ } | ||
curComments = false; | ||
}else if(lex[i].key.substr(0, 6).toLowerCase() == "msgstr"){ | ||
if(lastNode){ | ||
} else if (lex[i].key.substr(0, 6).toLowerCase() === 'msgstr') { | ||
if (lastNode) { | ||
lastNode.msgstr = (lastNode.msgstr || []).concat(lex[i].value); | ||
} | ||
if(lex[i].comments && !lastNode.comments){ | ||
if (lex[i].comments && !lastNode.comments) { | ||
lastNode.comments = lex[i].comments; | ||
@@ -357,3 +372,3 @@ } | ||
*/ | ||
Parser.prototype._normalize = function(lex){ | ||
Parser.prototype._normalize = function(lex) { | ||
var msgctxt, | ||
@@ -366,10 +381,10 @@ table = { | ||
for(var i=0, len = lex.length; i < len; i++){ | ||
msgctxt = lex[i].msgctxt || ""; | ||
for (var i = 0, len = lex.length; i < len; i++) { | ||
msgctxt = lex[i].msgctxt || ''; | ||
if(!table.translations[msgctxt]){ | ||
if (!table.translations[msgctxt]) { | ||
table.translations[msgctxt] = {}; | ||
} | ||
if(!table.headers && !msgctxt && !lex[i].msgid){ | ||
if (!table.headers && !msgctxt && !lex[i].msgid) { | ||
table.headers = sharedFuncs.parseHeader(lex[i].msgstr[0]); | ||
@@ -389,3 +404,3 @@ } | ||
*/ | ||
Parser.prototype.parse = function(){ | ||
Parser.prototype.parse = function() { | ||
var lex = this._lexer(); | ||
@@ -399,2 +414,2 @@ | ||
return this._normalize(lex); | ||
}; | ||
}; |
@@ -1,2 +0,2 @@ | ||
"use strict"; | ||
'use strict'; | ||
@@ -15,17 +15,17 @@ // Expose to the world | ||
*/ | ||
function parseHeader(str){ | ||
var lines = (str || "").split("\n"), | ||
headers = {}; | ||
function parseHeader(str) { | ||
var lines = (str || '').split('\n'), | ||
headers = {}; | ||
lines.forEach(function(line){ | ||
var parts = line.trim().split(":"), | ||
key = (parts.shift() || "").trim().toLowerCase(), | ||
value = parts.join(":").trim(); | ||
if(!key){ | ||
return; | ||
} | ||
headers[key] = value; | ||
}); | ||
lines.forEach(function(line) { | ||
var parts = line.trim().split(':'), | ||
key = (parts.shift() || '').trim().toLowerCase(), | ||
value = parts.join(':').trim(); | ||
if (!key) { | ||
return; | ||
} | ||
headers[key] = value; | ||
}); | ||
return headers; | ||
return headers; | ||
} | ||
@@ -39,6 +39,6 @@ | ||
*/ | ||
function upperCaseWords(str){ | ||
return (str || "").toLowerCase().trim().replace(/^(MIME|POT?(?=\-)|[a-z])|\-[a-z]/gi, function(str){ | ||
return str.toUpperCase(); | ||
}); | ||
function upperCaseWords(str) { | ||
return (str || '').toLowerCase().trim().replace(/^(MIME|POT?(?=\-)|[a-z])|\-[a-z]/gi, function(str) { | ||
return str.toUpperCase(); | ||
}); | ||
} | ||
@@ -52,12 +52,12 @@ | ||
*/ | ||
function generateHeader(header){ | ||
var lines = []; | ||
function generateHeader(header) { | ||
var lines = []; | ||
Object.keys(header || {}).forEach(function(key){ | ||
if(key){ | ||
lines.push(upperCaseWords(key) + ": " + (header[key] || "").trim()); | ||
} | ||
}); | ||
Object.keys(header || {}).forEach(function(key) { | ||
if (key) { | ||
lines.push(upperCaseWords(key) + ': ' + (header[key] || '').trim()); | ||
} | ||
}); | ||
return lines.join("\n") + (lines.length ? "\n" : ""); | ||
return lines.join('\n') + (lines.length ? '\n' : ''); | ||
} | ||
@@ -71,10 +71,10 @@ | ||
*/ | ||
function formatCharset(charset, defaultCharset){ | ||
return (charset || "iso-8859-1").toString().toLowerCase(). | ||
replace(/^utf[\-_]?(\d+)$/, "utf-$1"). | ||
replace(/^win(?:dows)?[\-_]?(\d+)$/, "windows-$1"). | ||
replace(/^latin[\-_]?(\d+)$/, "iso-8859-$1"). | ||
replace(/^(us[\-_]?)?ascii$/, "ascii"). | ||
replace(/^charset$/, defaultCharset || "iso-8859-1"). | ||
trim(); | ||
function formatCharset(charset, defaultCharset) { | ||
return (charset || 'iso-8859-1').toString().toLowerCase(). | ||
replace(/^utf[\-_]?(\d+)$/, 'utf-$1'). | ||
replace(/^win(?:dows)?[\-_]?(\d+)$/, 'windows-$1'). | ||
replace(/^latin[\-_]?(\d+)$/, 'iso-8859-$1'). | ||
replace(/^(us[\-_]?)?ascii$/, 'ascii'). | ||
replace(/^charset$/, defaultCharset || 'iso-8859-1'). | ||
trim(); | ||
} | ||
@@ -89,3 +89,3 @@ | ||
*/ | ||
function foldLine(str, maxLen){ | ||
function foldLine(str, maxLen) { | ||
@@ -95,3 +95,3 @@ maxLen = maxLen || 76; | ||
var lines = [], | ||
curLine = "", | ||
curLine = '', | ||
pos = 0, | ||
@@ -101,3 +101,3 @@ len = str.length, | ||
while(pos < len){ | ||
while (pos < len) { | ||
curLine = str.substr(pos, maxLen); | ||
@@ -107,3 +107,3 @@ | ||
// make longer lines if needed | ||
while(curLine.substr(-1) == "\\" && pos + curLine.length < len){ | ||
while (curLine.substr(-1) === '\\' && pos + curLine.length < len) { | ||
curLine += str.charAt(pos + curLine.length); | ||
@@ -113,8 +113,8 @@ } | ||
// ensure that if possible, line breaks are done at reasonable places | ||
if((match = curLine.match(/\\n/))){ | ||
if ((match = curLine.match(/\\n/))) { | ||
curLine = curLine.substr(0, match.index + 2); | ||
}else if(pos + curLine.length < len){ | ||
if((match = curLine.match(/(\s+)[^\s]*$/)) && match.index > 0){ | ||
} else if (pos + curLine.length < len) { | ||
if ((match = curLine.match(/(\s+)[^\s]*$/)) && match.index > 0) { | ||
curLine = curLine.substr(0, match.index + match[1].length); | ||
}else if((match = curLine.match(/([\x21-\x40\x5b-\x60\x7b-\x7e]+)[^\x21-\x40\x5b-\x60\x7b-\x7e]*$/)) && match.index > 0){ | ||
} else if ((match = curLine.match(/([\x21-\x40\x5b-\x60\x7b-\x7e]+)[^\x21-\x40\x5b-\x60\x7b-\x7e]*$/)) && match.index > 0) { | ||
curLine = curLine.substr(0, match.index + match[1].length); | ||
@@ -129,2 +129,2 @@ } | ||
return lines; | ||
} | ||
} |
{ | ||
"name": "gettext-parser", | ||
"description": "Parse and compile gettext po and mo files to/from json, nothing more, nothing less", | ||
"version": "0.2.0", | ||
"author" : "Andris Reinman", | ||
"homepage": "http://github.com/andris9/gettext-parser", | ||
"repository" : { | ||
"type" : "git", | ||
"url" : "http://github.com/andris9/gettext-parser.git" | ||
}, | ||
"scripts":{ | ||
"test": "nodeunit test/" | ||
}, | ||
"main" : "./index", | ||
"license" : "MIT", | ||
"dependencies": { | ||
"encoding":"~0.1" | ||
}, | ||
"devDependencies": { | ||
"nodeunit": "*" | ||
}, | ||
"keywords": ["i18n", "l10n", "gettext", "mo", "po"] | ||
"name": "gettext-parser", | ||
"description": "Parse and compile gettext po and mo files to/from json, nothing more, nothing less", | ||
"version": "1.0.0", | ||
"author": "Andris Reinman", | ||
"homepage": "http://github.com/andris9/gettext-parser", | ||
"repository": { | ||
"type": "git", | ||
"url": "http://github.com/andris9/gettext-parser.git" | ||
}, | ||
"scripts": { | ||
"test": "grunt" | ||
}, | ||
"main": "./index", | ||
"license": "MIT", | ||
"dependencies": { | ||
"encoding": "^0.1.11" | ||
}, | ||
"devDependencies": { | ||
"chai": "^1.10.0", | ||
"grunt": "^0.4.5", | ||
"grunt-contrib-jshint": "^0.10.0", | ||
"grunt-mocha-test": "^0.12.7", | ||
"mocha": "^2.1.0" | ||
}, | ||
"keywords": [ | ||
"i18n", | ||
"l10n", | ||
"gettext", | ||
"mo", | ||
"po" | ||
] | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
64231
3.49%27
8%1522
1.53%0
-100%5
400%Updated