UNPKG

lumen-react-javascript

Version:
163 lines (132 loc) 4.38 kB
import { parse } from 'intl-messageformat-parser'; import * as fs from 'fs'; import { sync as globSync } from 'glob'; import { sync as mkdirpSync } from 'mkdirp'; const MESSAGES_PATTERN = './i18n/**/*.json'; const LANG_DIR = './static/locale/'; const LANGS = require('./src/languages.json'); const ESCAPED_CHARS = { '\\' : '\\\\', '\\#': '\\#', '{' : '\\{', '}' : '\\}', }; const ESAPE_CHARS_REGEXP = /\\#|[{}\\]/g; export default function printICUMessage(ast) { return ast.elements.reduce((message, el) => { let {format, id, type, value} = el; if (type === 'messageTextElement') { return message + value.replace(ESAPE_CHARS_REGEXP, (char) => { return ESCAPED_CHARS[char]; }); } if (!format) { return message + `{${id}}`; } let formatType = format.type.replace(/Format$/, ''); let style, offset, options; switch (formatType) { case 'number': case 'date': case 'time': style = format.style ? `, ${format.style}` : ''; return message + `{${id}, ${formatType}${style}}`; case 'plural': case 'selectOrdinal': case 'select': offset = format.offset ? `, offset:${format.offset}` : ''; options = format.options.reduce((str, option) => { let optionValue = printICUMessage(option.value); return str + ` ${option.selector} {${optionValue}}`; }, ''); return message + `{${id}, ${formatType}${offset},${options}}`; } }, ''); } class Translator { constructor(translateText) { this.translateText = translateText; } translate(message) { let ast = parse(message); let translated = this.transform(ast); return print(translated); } transform(ast) { ast.elements.forEach((el) => { if (el.type === 'messageTextElement') { el.value = this.translateText(el.value); } else { let options = el.format && el.format.options; if (options) { options.forEach((option) => this.transform(option.value)); } } }); return ast; } } const defaultMessages = () => { return globSync(MESSAGES_PATTERN) .map((filename) => fs.readFileSync(filename, 'utf8')) .map((file) => JSON.parse(file)) .reduce((collection, descriptors) => { descriptors.forEach(({id, defaultMessage}) => { if (collection.hasOwnProperty(id) && collection[id] != defaultMessage) { throw new Error(`Duplicate message id with different message: ${id}, ${collection[id]}`); } collection[id] = defaultMessage; }); return collection; }, {}); }; mkdirpSync(LANG_DIR); let newnew = defaultMessages(); let oldDefault = null; if (fs.existsSync(LANG_DIR + 'default.json')) { oldDefault = require(LANG_DIR + 'default.json'); } for (let lang in LANGS.supported) { let filename = LANG_DIR + lang +'.json'; let messages; if (fs.existsSync(filename)) { let current = require(filename); messages = {...newnew, ...current}; } else { messages = newnew; } fs.writeFileSync(LANG_DIR + lang +'.json', JSON.stringify(messages, null, 2)); } fs.writeFileSync(LANG_DIR + 'default.json', JSON.stringify(newnew, null, 2)); function arr_diff (a1, a2) { let a = [], diff = []; for (let i = 0; i < a1.length; i++) { a[a1[i]] = true; } for (let i = 0; i < a2.length; i++) { if (a[a2[i]]) { delete a[a2[i]]; } else { a[a2[i]] = true; } } for (let k in a) { diff.push(k); } return diff; } if (oldDefault) { let oldDefaultKeys = []; for (let key in oldDefault) { oldDefaultKeys.push(key); } let newDefaultKeys = []; for (let key in newnew) { newDefaultKeys.push(key); } let diff = arr_diff(oldDefaultKeys, newDefaultKeys); if (diff) { diff = diff.join("\n"); fs.writeFileSync(LANG_DIR + 'LANG_DIFF', "THE FOLLOWING NEW TRANSLATION KEYS HAVE BEEN ADDED:\n" + diff); } }