gettext-parser
Advanced tools
Comparing version 3.1.0 to 4.0.0-alpha.0
# Change Log | ||
## [4.0.0-alpha.0] - 2019-03-15 | ||
- Update code to ES6 | ||
## [3.1.1] - 2019-03-14 | ||
- Update code to ES6 | ||
## [3.1.0] - 2018-11-19 | ||
- Add error when PO contains unescaped double quotes (thx @probertson) | ||
## [3.0.0] - 2018-11-10 | ||
@@ -61,2 +70,5 @@ - Remove support for old node versions | ||
[4.0.0-alpha.0]: https://github.com/smhg/gettext-parser/compare/v3.1.1...v4.0.0-alpha.0 | ||
[3.1.1]: https://github.com/smhg/gettext-parser/compare/v3.1.0...v3.1.1 | ||
[3.1.0]: https://github.com/smhg/gettext-parser/compare/v3.0.0...v3.1.0 | ||
[3.0.0]: https://github.com/smhg/gettext-parser/compare/v2.1.0...v3.0.0 | ||
@@ -63,0 +75,0 @@ [2.1.0]: https://github.com/smhg/gettext-parser/compare/v2.0.0...v2.1.0 |
@@ -1,7 +0,6 @@ | ||
'use strict'; | ||
const { Buffer } = require('safe-buffer'); | ||
const encoding = require('encoding'); | ||
const sharedFuncs = require('./shared'); | ||
const contentType = require('content-type'); | ||
var Buffer = require('safe-buffer').Buffer; | ||
var encoding = require('encoding'); | ||
var sharedFuncs = require('./shared'); | ||
/** | ||
@@ -15,3 +14,4 @@ * Exposes general compiler function. Takes a translation | ||
module.exports = function (table) { | ||
var compiler = new Compiler(table); | ||
const compiler = new Compiler(table); | ||
return compiler.compile(); | ||
@@ -26,7 +26,45 @@ }; | ||
*/ | ||
function Compiler (table) { | ||
this._table = table || {}; | ||
this._table.headers = this._table.headers || {}; | ||
this._table.translations = this._table.translations || {}; | ||
function Compiler (table = {}) { | ||
this._table = table; | ||
let { headers = {}, translations = {} } = this._table; | ||
headers = Object.keys(headers).reduce((result, key) => { | ||
const lowerKey = key.toLowerCase(); | ||
if (sharedFuncs.HEADERS.has(lowerKey)) { | ||
// POT-Creation-Date is removed in MO (see https://savannah.gnu.org/bugs/?49654) | ||
if (lowerKey !== 'pot-creation-date') { | ||
result[sharedFuncs.HEADERS.get(lowerKey)] = headers[key]; | ||
} | ||
} else { | ||
result[key] = headers[key]; | ||
} | ||
return result; | ||
}, {}); | ||
// filter out empty translations | ||
translations = Object.keys(translations).reduce((result, msgctxt) => { | ||
const context = translations[msgctxt]; | ||
const msgs = Object.keys(context).reduce((result, msgid) => { | ||
const hasTranslation = context[msgid].msgstr.some(item => !!item.length); | ||
if (hasTranslation) { | ||
result[msgid] = context[msgid]; | ||
} | ||
return result; | ||
}, {}); | ||
if (Object.keys(msgs).length) { | ||
result[msgctxt] = msgs; | ||
} | ||
return result; | ||
}, {}); | ||
this._table.translations = translations; | ||
this._table.headers = headers; | ||
this._translations = []; | ||
@@ -48,31 +86,13 @@ | ||
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 = []; | ||
const ct = contentType.parse(this._table.headers['Content-Type'] || 'text/plain'); | ||
params = parts.map(function (part) { | ||
var parts = part.split('='); | ||
var key = parts.shift().trim(); | ||
var value = parts.join('='); | ||
let charset = sharedFuncs.formatCharset(this._table.charset || ct.parameters.charset || 'utf-8'); | ||
if (key.toLowerCase() === 'charset') { | ||
if (!charset) { | ||
charset = sharedFuncs.formatCharset(value.trim() || 'utf-8'); | ||
} | ||
return 'charset=' + charset; | ||
} | ||
return part; | ||
}); | ||
if (!charset) { | ||
charset = this._table.charset || 'utf-8'; | ||
params.push('charset=' + charset); | ||
// clean up content-type charset independently using fallback if missing | ||
if (ct.parameters.charset) { | ||
ct.parameters.charset = sharedFuncs.formatCharset(ct.parameters.charset); | ||
} | ||
this._table.charset = charset; | ||
this._table.headers['content-type'] = contentType + '; ' + params.join('; '); | ||
this._charset = charset; | ||
this._table.headers['Content-Type'] = contentType.format(ct); | ||
}; | ||
@@ -87,17 +107,19 @@ | ||
Compiler.prototype._generateList = function () { | ||
var list = []; | ||
const list = []; | ||
list.push({ | ||
msgid: Buffer.alloc(0), | ||
msgstr: encoding.convert(sharedFuncs.generateHeader(this._table.headers), this._charset) | ||
msgstr: encoding.convert(sharedFuncs.generateHeader(this._table.headers), this._table.charset) | ||
}); | ||
Object.keys(this._table.translations).forEach(function (msgctxt) { | ||
Object.keys(this._table.translations).forEach(msgctxt => { | ||
if (typeof this._table.translations[msgctxt] !== 'object') { | ||
return; | ||
} | ||
Object.keys(this._table.translations[msgctxt]).forEach(function (msgid) { | ||
Object.keys(this._table.translations[msgctxt]).forEach(msgid => { | ||
if (typeof this._table.translations[msgctxt][msgid] !== 'object') { | ||
return; | ||
} | ||
if (msgctxt === '' && msgid === '') { | ||
@@ -107,5 +129,4 @@ return; | ||
var msgidPlural = this._table.translations[msgctxt][msgid].msgid_plural; | ||
var key = msgid; | ||
var value; | ||
const msgidPlural = this._table.translations[msgctxt][msgid].msgid_plural; | ||
let key = msgid; | ||
@@ -120,10 +141,10 @@ if (msgctxt) { | ||
value = [].concat(this._table.translations[msgctxt][msgid].msgstr || []).join('\u0000'); | ||
let value = [].concat(this._table.translations[msgctxt][msgid].msgstr || []).join('\u0000'); | ||
list.push({ | ||
msgid: encoding.convert(key, this._charset), | ||
msgstr: encoding.convert(value, this._charset) | ||
msgid: encoding.convert(key, this._table.charset), | ||
msgstr: encoding.convert(value, this._table.charset) | ||
}); | ||
}.bind(this)); | ||
}.bind(this)); | ||
}); | ||
}); | ||
@@ -140,7 +161,7 @@ return list; | ||
Compiler.prototype._calculateSize = function (list) { | ||
var msgidLength = 0; | ||
var msgstrLength = 0; | ||
var totalLength = 0; | ||
let msgidLength = 0; | ||
let msgstrLength = 0; | ||
let totalLength = 0; | ||
list.forEach(function (translation) { | ||
list.forEach(translation => { | ||
msgidLength += translation.msgid.length + 1; // + extra 0x00 | ||
@@ -177,6 +198,6 @@ msgstrLength += translation.msgstr.length + 1; // + extra 0x00 | ||
Compiler.prototype._build = function (list, size) { | ||
var returnBuffer = Buffer.alloc(size.total); | ||
var curPosition = 0; | ||
var i; | ||
var len; | ||
const returnBuffer = Buffer.alloc(size.total); | ||
let curPosition = 0; | ||
let i; | ||
let len; | ||
@@ -232,17 +253,8 @@ // magic | ||
Compiler.prototype.compile = function () { | ||
var list = this._generateList(); | ||
var size = this._calculateSize(list); | ||
const list = this._generateList(); | ||
const size = this._calculateSize(list); | ||
// sort by msgid | ||
list.sort(function (a, b) { | ||
if (a.msgid > b.msgid) { | ||
return 1; | ||
} | ||
if (a.msgid < b.msgid) { | ||
return -1; | ||
} | ||
return 0; | ||
}); | ||
list.sort(sharedFuncs.compareMsgid); | ||
return this._build(list, size); | ||
}; |
@@ -1,6 +0,4 @@ | ||
'use strict'; | ||
const encoding = require('encoding'); | ||
const sharedFuncs = require('./shared'); | ||
var encoding = require('encoding'); | ||
var sharedFuncs = require('./shared'); | ||
/** | ||
@@ -14,3 +12,4 @@ * Parses a binary MO object into translation table | ||
module.exports = function (buffer, defaultCharset) { | ||
var parser = new Parser(buffer, defaultCharset); | ||
const parser = new Parser(buffer, defaultCharset); | ||
return parser.parse(); | ||
@@ -26,3 +25,3 @@ }; | ||
*/ | ||
function Parser (fileContents, defaultCharset) { | ||
function Parser (fileContents, defaultCharset = 'iso-8859-1') { | ||
this._fileContents = fileContents; | ||
@@ -40,3 +39,3 @@ | ||
this._charset = defaultCharset || 'iso-8859-1'; | ||
this._charset = defaultCharset; | ||
@@ -64,2 +63,3 @@ this._table = { | ||
this._writeFunc = 'writeUInt32LE'; | ||
return true; | ||
@@ -69,6 +69,7 @@ } else if (this._fileContents.readUInt32BE(0) === this.MAGIC) { | ||
this._writeFunc = 'writeUInt32BE'; | ||
return true; | ||
} else { | ||
return false; | ||
} | ||
return false; | ||
}; | ||
@@ -81,10 +82,10 @@ | ||
Parser.prototype._loadTranslationTable = function () { | ||
var offsetOriginals = this._offsetOriginals; | ||
var offsetTranslations = this._offsetTranslations; | ||
var position; | ||
var length; | ||
var msgid; | ||
var msgstr; | ||
let offsetOriginals = this._offsetOriginals; | ||
let offsetTranslations = this._offsetTranslations; | ||
let position; | ||
let length; | ||
let msgid; | ||
let msgstr; | ||
for (var i = 0; i < this._total; i++) { | ||
for (let i = 0; i < this._total; i++) { | ||
// msgid string | ||
@@ -108,4 +109,6 @@ length = this._fileContents[this._readFunc](offsetOriginals); | ||
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('utf8'); | ||
msgstr = encoding.convert(msgstr, 'utf-8', this._charset) | ||
.toString('utf8'); | ||
@@ -125,4 +128,4 @@ this._addString(msgid, msgstr); | ||
Parser.prototype._handleCharset = function (headers) { | ||
var headersStr = headers.toString(); | ||
var match; | ||
const headersStr = headers.toString(); | ||
let match; | ||
@@ -133,3 +136,4 @@ if ((match = headersStr.match(/[; ]charset\s*=\s*([\w-]+)/i))) { | ||
headers = encoding.convert(headers, 'utf-8', this._charset).toString('utf-8'); | ||
headers = encoding.convert(headers, 'utf-8', this._charset) | ||
.toString('utf8'); | ||
@@ -146,6 +150,6 @@ this._table.headers = sharedFuncs.parseHeader(headers); | ||
Parser.prototype._addString = function (msgid, msgstr) { | ||
var translation = {}; | ||
var parts; | ||
var msgctxt; | ||
var msgidPlural; | ||
const translation = {}; | ||
let parts; | ||
let msgctxt; | ||
let msgidPlural; | ||
@@ -152,0 +156,0 @@ msgid = msgid.split('\u0004'); |
@@ -1,23 +0,7 @@ | ||
'use strict'; | ||
const { Buffer } = require('safe-buffer'); | ||
const encoding = require('encoding'); | ||
const sharedFuncs = require('./shared'); | ||
const contentType = require('content-type'); | ||
var Buffer = require('safe-buffer').Buffer; | ||
var encoding = require('encoding'); | ||
var sharedFuncs = require('./shared'); | ||
/** | ||
* Comparator function for comparing msgid | ||
* @param {Object} object with msgid prev | ||
* @param {Object} object with msgid next | ||
* @returns {number} comparator index | ||
*/ | ||
function compare (r1, r2) { | ||
if (r1.msgid > r2.msgid) { | ||
return 1; | ||
} | ||
if (r2.msgid > r1.msgid) { | ||
return -1; | ||
} | ||
return 0; | ||
} | ||
/** | ||
* Exposes general compiler function. Takes a translation | ||
@@ -30,3 +14,4 @@ * object as a parameter and returns PO object | ||
module.exports = function (table, options) { | ||
var compiler = new Compiler(table, options); | ||
const compiler = new Compiler(table, options); | ||
return compiler.compile(); | ||
@@ -41,14 +26,34 @@ }; | ||
*/ | ||
function Compiler (table, options) { | ||
this._table = table || {}; | ||
this._table.headers = this._table.headers || {}; | ||
function Compiler (table = {}, options = {}) { | ||
this._table = table; | ||
this._options = options; | ||
this._table.translations = this._table.translations || {}; | ||
this._options = options || {}; | ||
let { headers = {} } = this._table; | ||
headers = Object.keys(headers).reduce((result, key) => { | ||
const lowerKey = key.toLowerCase(); | ||
if (sharedFuncs.HEADERS.has(lowerKey)) { | ||
result[sharedFuncs.HEADERS.get(lowerKey)] = headers[key]; | ||
} else { | ||
result[key] = headers[key]; | ||
} | ||
return result; | ||
}, {}); | ||
this._table.headers = headers; | ||
if (!('foldLength' in this._options)) { | ||
this._options.foldLength = 76; | ||
} | ||
if (!('sort' in this._options)) { | ||
this._options.sort = false; | ||
} | ||
this._translations = []; | ||
this._handleCharset(); | ||
@@ -65,4 +70,4 @@ } | ||
Compiler.prototype._drawComments = function (comments) { | ||
var lines = []; | ||
var types = [{ | ||
const lines = []; | ||
const types = [{ | ||
key: 'translator', | ||
@@ -84,8 +89,9 @@ prefix: '# ' | ||
types.forEach(function (type) { | ||
types.forEach(type => { | ||
if (!comments[type.key]) { | ||
return; | ||
} | ||
comments[type.key].split(/\r?\n|\r/).forEach(function (line) { | ||
lines.push(type.prefix + line); | ||
comments[type.key].split(/\r?\n|\r/).forEach(line => { | ||
lines.push(`${type.prefix}${line}`); | ||
}); | ||
@@ -104,12 +110,10 @@ }); | ||
*/ | ||
Compiler.prototype._drawBlock = function (block, override) { | ||
override = override || {}; | ||
Compiler.prototype._drawBlock = function (block, override = {}) { | ||
const response = []; | ||
const msgctxt = override.msgctxt || block.msgctxt; | ||
const msgid = override.msgid || block.msgid; | ||
const msgidPlural = override.msgid_plural || block.msgid_plural; | ||
const msgstr = [].concat(override.msgstr || block.msgstr); | ||
let comments = override.comments || block.comments; | ||
var response = []; | ||
var comments = override.comments || block.comments; | ||
var msgctxt = override.msgctxt || block.msgctxt; | ||
var msgid = override.msgid || block.msgid; | ||
var msgidPlural = override.msgid_plural || block.msgid_plural; | ||
var msgstr = [].concat(override.msgstr || block.msgstr); | ||
// add comments | ||
@@ -128,5 +132,6 @@ if (comments && (comments = this._drawComments(comments))) { | ||
response.push(this._addPOString('msgid_plural', msgidPlural)); | ||
msgstr.forEach(function (msgstr, i) { | ||
response.push(this._addPOString('msgstr[' + i + ']', msgstr || '')); | ||
}.bind(this)); | ||
msgstr.forEach((msgstr, i) => { | ||
response.push(this._addPOString(`msgstr[${i}]`, msgstr || '')); | ||
}); | ||
} else { | ||
@@ -146,7 +151,7 @@ response.push(this._addPOString('msgstr', msgstr[0] || '')); | ||
*/ | ||
Compiler.prototype._addPOString = function (key, value) { | ||
key = (key || '').toString(); | ||
Compiler.prototype._addPOString = function (key = '', value = '') { | ||
key = key.toString(); | ||
// escape newlines and quotes | ||
value = (value || '').toString() | ||
value = value.toString() | ||
.replace(/\\/g, '\\\\') | ||
@@ -158,3 +163,3 @@ .replace(/"/g, '\\"') | ||
var lines = [value]; | ||
let lines = [value]; | ||
@@ -166,6 +171,6 @@ if (this._options.foldLength > 0) { | ||
if (lines.length < 2) { | ||
return key + ' "' + (lines.shift() || '') + '"'; | ||
} else { | ||
return key + ' ""\n"' + lines.join('"\n"') + '"'; | ||
return `${key} "${lines.shift() || ''}"`; | ||
} | ||
return `${key} ""\n"${lines.join('"\n"')}"`; | ||
}; | ||
@@ -177,31 +182,13 @@ | ||
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 = []; | ||
const ct = contentType.parse(this._table.headers['Content-Type'] || 'text/plain'); | ||
params = parts.map(function (part) { | ||
var parts = part.split('='); | ||
var key = parts.shift().trim(); | ||
var value = parts.join('='); | ||
let charset = sharedFuncs.formatCharset(this._table.charset || ct.parameters.charset || 'utf-8'); | ||
if (key.toLowerCase() === 'charset') { | ||
if (!charset) { | ||
charset = sharedFuncs.formatCharset(value.trim() || 'utf-8'); | ||
} | ||
return 'charset=' + charset; | ||
} | ||
return part; | ||
}); | ||
if (!charset) { | ||
charset = this._table.charset || 'utf-8'; | ||
params.push('charset=' + charset); | ||
// clean up content-type charset independently using fallback if missing | ||
if (ct.parameters.charset) { | ||
ct.parameters.charset = sharedFuncs.formatCharset(ct.parameters.charset); | ||
} | ||
this._table.charset = charset; | ||
this._table.headers['content-type'] = contentType + '; ' + params.join('; '); | ||
this._charset = charset; | ||
this._table.headers['Content-Type'] = contentType.format(ct); | ||
}; | ||
@@ -215,13 +202,15 @@ | ||
Compiler.prototype.compile = function () { | ||
var response = []; | ||
var headerBlock = (this._table.translations[''] && this._table.translations['']['']) || {}; | ||
const headerBlock = (this._table.translations[''] && this._table.translations['']['']) || {}; | ||
let response = []; | ||
Object.keys(this._table.translations).forEach(function (msgctxt) { | ||
Object.keys(this._table.translations).forEach(msgctxt => { | ||
if (typeof this._table.translations[msgctxt] !== 'object') { | ||
return; | ||
} | ||
Object.keys(this._table.translations[msgctxt]).forEach(function (msgid) { | ||
Object.keys(this._table.translations[msgctxt]).forEach(msgid => { | ||
if (typeof this._table.translations[msgctxt][msgid] !== 'object') { | ||
return; | ||
} | ||
if (msgctxt === '' && msgid === '') { | ||
@@ -232,4 +221,4 @@ return; | ||
response.push(this._table.translations[msgctxt][msgid]); | ||
}.bind(this)); | ||
}.bind(this)); | ||
}); | ||
}); | ||
@@ -240,9 +229,8 @@ if (this._options.sort !== false) { | ||
} else { | ||
response = response.sort(compare); | ||
response = response.sort(sharedFuncs.compareMsgid); | ||
} | ||
} | ||
response = response.map(function (r) { | ||
return this._drawBlock(r); | ||
}.bind(this)); | ||
response = response.map(r => this._drawBlock(r)); | ||
response.unshift(this._drawBlock(headerBlock, { | ||
@@ -252,7 +240,7 @@ msgstr: sharedFuncs.generateHeader(this._table.headers) | ||
if (this._charset === 'utf-8' || this._charset === 'ascii') { | ||
if (this._table.charset === 'utf-8' || this._table.charset === 'ascii') { | ||
return Buffer.from(response.join('\n\n'), 'utf-8'); | ||
} else { | ||
return encoding.convert(response.join('\n\n'), this._charset); | ||
} | ||
return encoding.convert(response.join('\n\n'), this._table.charset); | ||
}; |
@@ -1,8 +0,6 @@ | ||
'use strict'; | ||
const encoding = require('encoding'); | ||
const sharedFuncs = require('./shared'); | ||
const Transform = require('readable-stream').Transform; | ||
const util = require('util'); | ||
var encoding = require('encoding'); | ||
var sharedFuncs = require('./shared'); | ||
var Transform = require('readable-stream').Transform; | ||
var util = require('util'); | ||
/** | ||
@@ -16,3 +14,4 @@ * Parses a PO object into translation table | ||
module.exports.parse = function (buffer, defaultCharset) { | ||
var parser = new Parser(buffer, defaultCharset); | ||
const parser = new Parser(buffer, defaultCharset); | ||
return parser.parse(); | ||
@@ -40,4 +39,4 @@ }; | ||
*/ | ||
function Parser (fileContents, defaultCharset) { | ||
this._charset = defaultCharset || 'iso-8859-1'; | ||
function Parser (fileContents, defaultCharset = 'iso-8859-1') { | ||
this._charset = defaultCharset; | ||
@@ -73,7 +72,7 @@ this._lex = []; | ||
*/ | ||
Parser.prototype._handleCharset = function (buf) { | ||
var str = (buf || '').toString(); | ||
var pos; | ||
var headers = ''; | ||
var match; | ||
Parser.prototype._handleCharset = function (buf = '') { | ||
const str = buf.toString(); | ||
let pos; | ||
let headers = ''; | ||
let match; | ||
@@ -137,5 +136,5 @@ if ((pos = str.search(/^\s*msgid/im)) >= 0) { | ||
Parser.prototype._lexer = function (chunk) { | ||
var chr; | ||
let chr; | ||
for (var i = 0, len = chunk.length; i < len; i++) { | ||
for (let i = 0, len = chunk.length; i < len; i++) { | ||
chr = chunk.charAt(i); | ||
@@ -211,4 +210,6 @@ | ||
if (!this._node.value.match(this.symbols.keyNames)) { | ||
var err = new SyntaxError('Error parsing PO data: Invalid key name "' + this._node.value + '" at line ' + this._lineNumber + '. This can be caused by an unescaped quote character in a msgid or msgstr value.'); | ||
const err = new SyntaxError(`Error parsing PO data: Invalid key name "${this._node.value}" at line ${this._lineNumber}. This can be caused by an unescaped quote character in a msgid or msgstr value.`); | ||
err.lineNumber = this._lineNumber; | ||
throw err; | ||
@@ -233,6 +234,6 @@ } | ||
Parser.prototype._joinStringValues = function (tokens) { | ||
var lastNode; | ||
var response = []; | ||
const response = []; | ||
let lastNode; | ||
for (var i = 0, len = tokens.length; i < len; i++) { | ||
for (let i = 0, len = tokens.length; i < len; i++) { | ||
if (lastNode && tokens[i].type === this.types.string && lastNode.type === this.types.string) { | ||
@@ -258,4 +259,5 @@ lastNode.value += tokens[i].value; | ||
// parse comments | ||
tokens.forEach(function (node) { | ||
var comment, lines; | ||
tokens.forEach(node => { | ||
let comment; | ||
let lines; | ||
@@ -270,4 +272,6 @@ if (node && node.type === this.types.comments) { | ||
}; | ||
lines = (node.value || '').split(/\n/); | ||
lines.forEach(function (line) { | ||
lines.forEach(line => { | ||
switch (line.charAt(0) || '') { | ||
@@ -293,3 +297,3 @@ case ':': | ||
Object.keys(comment).forEach(function (key) { | ||
Object.keys(comment).forEach(key => { | ||
if (comment[key] && comment[key].length) { | ||
@@ -300,3 +304,3 @@ node.value[key] = comment[key].join('\n'); | ||
} | ||
}.bind(this)); | ||
}); | ||
}; | ||
@@ -311,6 +315,6 @@ | ||
Parser.prototype._handleKeys = function (tokens) { | ||
var response = []; | ||
var lastNode; | ||
const response = []; | ||
let lastNode; | ||
for (var i = 0, len = tokens.length; i < len; i++) { | ||
for (let i = 0, len = tokens.length; i < len; i++) { | ||
if (tokens[i].type === this.types.key) { | ||
@@ -340,8 +344,8 @@ lastNode = { | ||
Parser.prototype._handleValues = function (tokens) { | ||
var response = []; | ||
var lastNode; | ||
var curContext; | ||
var curComments; | ||
const response = []; | ||
let lastNode; | ||
let curContext; | ||
let curComments; | ||
for (var i = 0, len = tokens.length; i < len; i++) { | ||
for (let i = 0, len = tokens.length; i < len; i++) { | ||
if (tokens[i].key.toLowerCase() === 'msgctxt') { | ||
@@ -405,4 +409,3 @@ curContext = tokens[i].value; | ||
Parser.prototype._normalize = function (tokens) { | ||
var msgctxt; | ||
var table = { | ||
const table = { | ||
charset: this._charset, | ||
@@ -412,4 +415,5 @@ headers: undefined, | ||
}; | ||
let msgctxt; | ||
for (var i = 0, len = tokens.length; i < len; i++) { | ||
for (let i = 0, len = tokens.length; i < len; i++) { | ||
msgctxt = tokens[i].msgctxt || ''; | ||
@@ -438,4 +442,6 @@ | ||
Parser.prototype._finalize = function (tokens) { | ||
var data = this._joinStringValues(tokens); | ||
let data = this._joinStringValues(tokens); | ||
this._parseComments(data); | ||
data = this._handleKeys(data); | ||
@@ -479,4 +485,4 @@ data = this._handleValues(data); | ||
PoParserTransform.prototype._transform = function (chunk, encoding, done) { | ||
var i; | ||
var len = 0; | ||
let i; | ||
let len = 0; | ||
@@ -531,5 +537,6 @@ if (!chunk || !chunk.length) { | ||
} catch (error) { | ||
setImmediate(function () { | ||
setImmediate(() => { | ||
done(error); | ||
}); | ||
return; | ||
@@ -546,3 +553,3 @@ } | ||
PoParserTransform.prototype._flush = function (done) { | ||
var chunk; | ||
let chunk; | ||
@@ -561,5 +568,6 @@ if (this._cacheSize) { | ||
} catch (error) { | ||
setImmediate(function () { | ||
setImmediate(() => { | ||
done(error); | ||
}); | ||
return; | ||
@@ -566,0 +574,0 @@ } |
@@ -1,4 +0,1 @@ | ||
'use strict'; | ||
// Expose to the world | ||
module.exports.parseHeader = parseHeader; | ||
@@ -8,3 +5,19 @@ module.exports.generateHeader = generateHeader; | ||
module.exports.foldLine = foldLine; | ||
module.exports.compareMsgid = compareMsgid; | ||
const HEADERS = new Map([ | ||
['project-id-version', 'Project-Id-Version'], | ||
['report-msgid-bugs-to', 'Report-Msgid-Bugs-To'], | ||
['pot-creation-date', 'POT-Creation-Date'], | ||
['po-revision-date', 'PO-Revision-Date'], | ||
['last-translator', 'Last-Translator'], | ||
['language-team', 'Language-Team'], | ||
['language', 'Language'], | ||
['content-type', 'Content-Type'], | ||
['content-transfer-encoding', 'Content-Transfer-Encoding'], | ||
['plural-forms', 'Plural-Forms'] | ||
]); | ||
module.exports.HEADERS = HEADERS; | ||
/** | ||
@@ -16,13 +29,15 @@ * Parses a header string into an object of key-value pairs | ||
*/ | ||
function parseHeader (str) { | ||
var lines = (str || '').split('\n'); | ||
var headers = {}; | ||
function parseHeader (str = '') { | ||
const lines = str.split('\n'); | ||
const headers = {}; | ||
lines.forEach(function (line) { | ||
var parts = line.trim().split(':'); | ||
var key = (parts.shift() || '').trim().toLowerCase(); | ||
var value = parts.join(':').trim(); | ||
lines.forEach(line => { | ||
const parts = line.trim().split(':'); | ||
const key = (parts.shift() || '').trim().toLowerCase(); | ||
const value = parts.join(':').trim(); | ||
if (!key) { | ||
return; | ||
} | ||
headers[key] = value; | ||
@@ -35,17 +50,2 @@ }); | ||
/** | ||
* Convert first letters after - to uppercase, other lowercase | ||
* | ||
* @param {String} str String to be updated | ||
* @return {String} A string with uppercase words | ||
*/ | ||
function upperCaseWords (str) { | ||
return (str || '') | ||
.toLowerCase() | ||
.trim() | ||
.replace(/^(MIME|POT?(?=-)|[a-z])|-[a-z]/gi, function (str) { | ||
return str.toUpperCase(); | ||
}); | ||
} | ||
/** | ||
* Joins a header object of key value pairs into a header string | ||
@@ -56,12 +56,14 @@ * | ||
*/ | ||
function generateHeader (header) { | ||
var lines = []; | ||
function generateHeader (header = {}) { | ||
const keys = Object.keys(header) | ||
.filter(key => !!key); | ||
Object.keys(header || {}).forEach(function (key) { | ||
if (key) { | ||
lines.push(upperCaseWords(key) + ': ' + (header[key] || '').trim()); | ||
} | ||
}); | ||
if (!keys.length) { | ||
return ''; | ||
} | ||
return lines.join('\n') + (lines.length ? '\n' : ''); | ||
return keys.map(key => | ||
`${key}: ${(header[key] || '').trim()}` | ||
) | ||
.join('\n') + '\n'; | ||
} | ||
@@ -75,4 +77,5 @@ | ||
*/ | ||
function formatCharset (charset, defaultCharset) { | ||
return (charset || 'iso-8859-1').toString().toLowerCase() | ||
function formatCharset (charset = 'iso-8859-1', defaultCharset = 'iso-8859-1') { | ||
return charset.toString() | ||
.toLowerCase() | ||
.replace(/^utf[-_]?(\d+)$/, 'utf-$1') | ||
@@ -82,3 +85,3 @@ .replace(/^win(?:dows)?[-_]?(\d+)$/, 'windows-$1') | ||
.replace(/^(us[-_]?)?ascii$/, 'ascii') | ||
.replace(/^charset$/, defaultCharset || 'iso-8859-1') | ||
.replace(/^charset$/, defaultCharset) | ||
.trim(); | ||
@@ -94,11 +97,9 @@ } | ||
*/ | ||
function foldLine (str, maxLen) { | ||
maxLen = maxLen || 76; | ||
function foldLine (str, maxLen = 76) { | ||
const lines = []; | ||
const len = str.length; | ||
let curLine = ''; | ||
let pos = 0; | ||
let match; | ||
var lines = []; | ||
var curLine = ''; | ||
var pos = 0; | ||
var len = str.length; | ||
var match; | ||
while (pos < len) { | ||
@@ -134,1 +135,19 @@ curLine = str.substr(pos, maxLen); | ||
} | ||
/** | ||
* Comparator function for comparing msgid | ||
* @param {Object} object with msgid prev | ||
* @param {Object} object with msgid next | ||
* @returns {number} comparator index | ||
*/ | ||
function compareMsgid ({ msgid: left }, { msgid: right }) { | ||
if (left < right) { | ||
return -1; | ||
} | ||
if (left > right) { | ||
return 1; | ||
} | ||
return 0; | ||
} |
{ | ||
"name": "gettext-parser", | ||
"description": "Parse and compile gettext po and mo files to/from json, nothing more, nothing less", | ||
"version": "3.1.0", | ||
"version": "4.0.0-alpha.0", | ||
"author": "Andris Reinman", | ||
@@ -18,2 +18,3 @@ "contributors": [ | ||
"lint": "eslint lib/*.js test/*.js index.js", | ||
"test-generate-mo": "msgfmt test/fixtures/latin13.po -o test/fixtures/latin13.mo & msgfmt test/fixtures/utf8.po -o test/fixtures/utf8.mo", | ||
"test": "mocha", | ||
@@ -26,4 +27,5 @@ "preversion": "npm run lint && npm test", | ||
"dependencies": { | ||
"content-type": "^1.0.4", | ||
"encoding": "^0.1.12", | ||
"readable-stream": "^3.0.6", | ||
"readable-stream": "^3.2.0", | ||
"safe-buffer": "^5.1.2" | ||
@@ -33,9 +35,9 @@ }, | ||
"chai": "^4.2.0", | ||
"eslint": "^5.9.0", | ||
"eslint": "^5.15.1", | ||
"eslint-config-standard": "^12.0.0", | ||
"eslint-plugin-import": "^2.14.0", | ||
"eslint-plugin-node": "^8.0.0", | ||
"eslint-plugin-import": "^2.16.0", | ||
"eslint-plugin-node": "^8.0.1", | ||
"eslint-plugin-promise": "^4.0.1", | ||
"eslint-plugin-standard": "^4.0.0", | ||
"mocha": "^5.2.0" | ||
"mocha": "^6.0.2" | ||
}, | ||
@@ -42,0 +44,0 @@ "keywords": [ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
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
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
49617
4
1185
1
+ Addedcontent-type@^1.0.4
+ Addedcontent-type@1.0.5(transitive)
Updatedreadable-stream@^3.2.0