UNPKG

arb-convert

Version:

Convert Application Resource Bundle (ARB) translation files to other translation formats and back

262 lines (261 loc) 10.3 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.gettextToJs = exports.gettextString = exports.gettextComment = exports.timezoneOffset = exports.formatDate = exports.parse = exports.convert = void 0; var zeroPad_1 = __importDefault(require("../util/zeroPad")); var MAX_CHAR_WIDTH = 80; function convert(_a) { var source = _a.source, target = _a.target, original = _a.original, sourceLanguage = _a.sourceLanguage, targetLanguage = _a.targetLanguage; var sourceJs = JSON.parse(source); var targetJs = target ? JSON.parse(target) : ''; var content = ''; // Header content += ("\n# Translation converted from ARB\n# original: " + (original || '') + "\n# srcLang: " + (sourceLanguage || '') + "\n# trgLang: " + (targetLanguage || '') + "\nmsgid \"\"\nmsgstr \"\"\n\"PO-Revision-Date: " + formatDate(new Date(Date.now())) + "\"\n\"MIME-Version: 1.0\"\n\"Content-Type: text/plain; charset=UTF-8\"\n\"Content-Transfer-Encoding: 8bit\"\n ").trim(); // white-space // # translator-comments // #. extracted-comments // #: reference… // #, flag… // #| msgid previous-untranslated-string // msgctxt context // msgid untranslated-string // msgstr translated-string Object.keys(sourceJs) .filter(function (key) { return key[0] !== '@'; }) .forEach(function (key) { var sourceString = sourceJs[key]; var targetString = (targetJs && targetJs[key]) || ''; var _a = sourceJs["@" + key], description = _a.description, placeholders = _a.placeholders; content += '\n'; if (description) { content += "\n" + gettextComment('#.', description, MAX_CHAR_WIDTH); } Object.keys(placeholders).forEach(function (paramName) { Object.keys(placeholders[paramName]).forEach(function (property) { var example = "{" + paramName + "} " + property + ": " + placeholders[paramName][property]; content += "\n" + gettextComment('#.', example, MAX_CHAR_WIDTH); }); }); content += "\n" + gettextString('msgctxt', key, MAX_CHAR_WIDTH); content += "\n" + gettextString('msgid', sourceString, MAX_CHAR_WIDTH); content += "\n" + gettextString('msgstr', targetString, MAX_CHAR_WIDTH); }); content += '\n'; return { content: content }; } exports.convert = convert; function parse(_a) { var content = _a.content; var gettext = gettextToJs(content); var srcArb = {}; var trgArb = {}; var original = ''; var sourceLanguage = 'en-US'; var targetLanguage = ''; srcArb['@@locale'] = ''; srcArb['@@last_modified'] = ''; trgArb['@@locale'] = ''; trgArb['@@last_modified'] = ''; gettext.forEach(function (entry) { // Header if (entry.msgctxt === '' && entry.msgid === '') { entry.translatorCommentLines.forEach(function (comment) { if (comment.startsWith('original: ')) { original = comment.substr(10); } else if (comment.startsWith('srcLang: ')) { sourceLanguage = comment.substr(9); } else if (comment.startsWith('trgLang: ')) { targetLanguage = comment.substr(9); } }); } else { var key = entry.msgctxt.replace('\\n', '\n'); var srcString = entry.msgid.replace('\\n', '\n'); var trgString = entry.msgstr.replace('\\n', '\n'); var placeholders_1 = {}; var description_1 = ''; entry.extractedCommentLines.forEach(function (comment) { var match = comment.match(/^\{([\w-]+)\} (.*): (.*)$/); if (match) { var field = match[1], name_1 = match[2], value = match[3]; placeholders_1[field] = placeholders_1[field] || {}; placeholders_1[field][name_1] = value; } else { description_1 += comment; } }); srcArb[key] = srcString; srcArb["@" + key] = { description: description_1, type: 'text', placeholders: placeholders_1, }; if (targetLanguage) { trgArb[key] = trgString; trgArb["@" + key] = { description: description_1, type: 'text', placeholders: placeholders_1, }; } } }); srcArb['@@locale'] = sourceLanguage.replace('-', '_'); srcArb['@@last_modified'] = new Date(Date.now()).toISOString(); if (targetLanguage) { trgArb['@@locale'] = targetLanguage.replace('-', '_'); trgArb['@@last_modified'] = new Date(Date.now()).toISOString(); } var source = JSON.stringify(srcArb, null, 2); var target = targetLanguage ? JSON.stringify(trgArb, null, 2) : ''; return { source: source, target: target, original: original, sourceLanguage: sourceLanguage, targetLanguage: targetLanguage, }; } exports.parse = parse; // YEAR-MO-DA HO:MI+ZONE, e.g. 2008-07-22 18:13+0200 function formatDate(date) { return date.getFullYear() + "-" + zeroPad_1.default(date.getMonth() + 1) + "-" + zeroPad_1.default(date.getDate()) + " " + zeroPad_1.default(date.getHours()) + ":" + zeroPad_1.default(date.getMinutes()) + timezoneOffset(date); } exports.formatDate = formatDate; function timezoneOffset(date) { var offset = date.getTimezoneOffset(); var sign = offset <= 0 ? '+' : '-'; var hours = Math.floor(Math.abs(offset) / 60); var minutes = Math.abs(offset) % 60; return sign + zeroPad_1.default(hours) + zeroPad_1.default(minutes); } exports.timezoneOffset = timezoneOffset; function gettextComment(prefix, value, maxCharWidth) { var splitValue = []; var val = value; while (val.length > maxCharWidth - prefix.length - 1) { splitValue.push(prefix + " " + val.substr(0, maxCharWidth - prefix.length - 1)); val = val.substr(maxCharWidth - prefix.length - 1); } splitValue.push(prefix + " " + val); return splitValue.join('\n'); } exports.gettextComment = gettextComment; function gettextString(prefix, value, maxCharWidth) { var val = value.replace(/\n/, '\\n'); if (val.length <= maxCharWidth - prefix.length - 3) { return prefix + " \"" + val + "\""; } var splitValue = [prefix + " \"\""]; while (val.length > maxCharWidth - prefix.length - 2) { splitValue.push("\"" + val.substr(0, maxCharWidth - 2) + "\""); val = val.substr(maxCharWidth - 2); } splitValue.push("\"" + val + "\""); return splitValue.join('\n'); } exports.gettextString = gettextString; function gettextToJs(content) { var result = []; var multilineScope = ''; var translatorCommentLines = []; var extractedCommentLines = []; var references = []; var flags = []; var msgctxt = ''; var msgid = ''; var msgstr = ''; content.split('\n').forEach(function (line) { if (line.trim() === '') { // End of block result.push({ translatorCommentLines: translatorCommentLines, extractedCommentLines: extractedCommentLines, references: references, flags: flags, msgctxt: msgctxt, msgid: msgid, msgstr: msgstr, }); // Reset multilineScope = ''; translatorCommentLines = []; extractedCommentLines = []; references = []; flags = []; msgctxt = ''; msgid = ''; msgstr = ''; return; } if (multilineScope !== '') { if (line.startsWith('"')) { var continuedText = line.substr(1, line.length - 2); // eslint-disable-next-line default-case switch (multilineScope) { case 'msgctxt': msgctxt += continuedText; break; case 'msgid': msgid += continuedText; break; case 'msgstr': msgstr += continuedText; break; } } else { multilineScope = ''; } } var prefix = line.substr(0, line.indexOf(' ')); var text = line.substr(line.indexOf(' ') + 1); // eslint-disable-next-line default-case switch (prefix) { case '#': translatorCommentLines.push(text); break; case '#.': extractedCommentLines.push(text); break; case '#:': references = references.concat(text.split(',').map(function (part) { return part.trim(); })); break; case '#,': flags = flags.concat(text.split(',').map(function (part) { return part.trim(); })); break; case 'msgctxt': if (text === '""') { multilineScope = prefix; } else { msgctxt = text.substr(1, text.length - 2); } break; case 'msgid': if (text === '""') { multilineScope = prefix; } else { msgid = text.substr(1, text.length - 2); } break; case 'msgstr': if (text === '""') { multilineScope = prefix; } else { msgstr = text.substr(1, text.length - 2); } break; } }); return result; } exports.gettextToJs = gettextToJs;