%PDF- %PDF-
Direktori : /var/www/projetos/stb.ind.br/wp-content/themes/stb/node_modules/gettext-parser/lib/ |
Current File : /var/www/projetos/stb.ind.br/wp-content/themes/stb/node_modules/gettext-parser/lib/pocompiler.js |
const { Buffer } = require('safe-buffer'); const encoding = require('encoding'); const 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 ({ msgid: left }, { msgid: right }) { if (left > right) { return 1; } if (right > left) { return -1; } return 0; } /** * Exposes general compiler function. Takes a translation * object as a parameter and returns PO object * * @param {Object} table Translation object * @return {Buffer} Compiled PO object */ module.exports = function (table, options) { const compiler = new Compiler(table, options); return compiler.compile(); }; /** * Creates a PO compiler object. * * @constructor * @param {Object} table Translation table to be compiled */ function Compiler (table = {}, options = {}) { this._table = table; this._table.headers = this._table.headers || {}; this._table.translations = this._table.translations || {}; this._options = options; if (!('foldLength' in this._options)) { this._options.foldLength = 76; } if (!('sort' in this._options)) { this._options.sort = false; } this._translations = []; this._handleCharset(); } /** * Converts a comments object to a comment string. The comment object is * in the form of {translator:'', reference: '', extracted: '', flag: '', previous:''} * * @param {Object} comments A comments object * @return {String} A comment string for the PO file */ Compiler.prototype._drawComments = function (comments) { const lines = []; const types = [{ key: 'translator', prefix: '# ' }, { key: 'reference', prefix: '#: ' }, { key: 'extracted', prefix: '#. ' }, { key: 'flag', prefix: '#, ' }, { key: 'previous', prefix: '#| ' }]; types.forEach(type => { if (!comments[type.key]) { return; } comments[type.key].split(/\r?\n|\r/).forEach(line => { lines.push(`${type.prefix}${line}`); }); }); return lines.join('\n'); }; /** * Builds a PO string for a single translation object * * @param {Object} block Translation object * @param {Object} [override] Properties of this object will override `block` properties * @return {String} Translation string for a single object */ 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; // add comments if (comments && (comments = this._drawComments(comments))) { response.push(comments); } if (msgctxt) { response.push(this._addPOString('msgctxt', msgctxt)); } response.push(this._addPOString('msgid', msgid || '')); if (msgidPlural) { response.push(this._addPOString('msgid_plural', msgidPlural)); msgstr.forEach((msgstr, i) => { response.push(this._addPOString(`msgstr[${i}]`, msgstr || '')); }); } else { response.push(this._addPOString('msgstr', msgstr[0] || '')); } return response.join('\n'); }; /** * Escapes and joins a key and a value for the PO string * * @param {String} key Key name * @param {String} value Key value * @return {String} Joined and escaped key-value pair */ Compiler.prototype._addPOString = function (key = '', value = '') { 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'); let lines = [value]; if (this._options.foldLength > 0) { lines = sharedFuncs.foldLine(value, this._options.foldLength); } if (lines.length < 2) { return `${key} "${lines.shift() || ''}"`; } return `${key} ""\n"${lines.join('"\n"')}"`; }; /** * Handles header values, replaces or adds (if needed) a charset property */ Compiler.prototype._handleCharset = function () { const parts = (this._table.headers['content-type'] || 'text/plain').split(';'); const contentType = parts.shift(); let charset = sharedFuncs.formatCharset(this._table.charset); const params = parts.map(part => { const parts = part.split('='); const key = parts.shift().trim(); const value = parts.join('='); 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}`); } this._table.charset = charset; this._table.headers['content-type'] = `${contentType}; ${params.join('; ')}`; this._charset = charset; }; /** * Compiles translation object into a PO object * * @return {Buffer} Compiled PO object */ Compiler.prototype.compile = function () { const headerBlock = (this._table.translations[''] && this._table.translations['']['']) || {}; let response = []; Object.keys(this._table.translations).forEach(msgctxt => { if (typeof this._table.translations[msgctxt] !== 'object') { return; } Object.keys(this._table.translations[msgctxt]).forEach(msgid => { if (typeof this._table.translations[msgctxt][msgid] !== 'object') { return; } if (msgctxt === '' && msgid === '') { return; } response.push(this._table.translations[msgctxt][msgid]); }); }); if (this._options.sort !== false) { if (typeof this._options.sort === 'function') { response = response.sort(this._options.sort); } else { response = response.sort(compare); } } response = response.map(r => this._drawBlock(r)); response.unshift(this._drawBlock(headerBlock, { msgstr: sharedFuncs.generateHeader(this._table.headers) })); if (this._charset === 'utf-8' || this._charset === 'ascii') { return Buffer.from(response.join('\n\n'), 'utf-8'); } return encoding.convert(response.join('\n\n'), this._charset); };