i18next-gettext-converter
Introduction
Project goal is to convert files from gettext to i18next json format and vice versa.
Installation
- first install node.js from nodejs.org.
npm install i18next-conv -g
For i18next < 2.0.0 use [email protected], for i18next < 3.0.0 use [email protected], for i18next < 12.0.0 use i18next-conv@<8.
Usage
convert .mo or .po to i18next json
in your console type:
for help:
i18next-conv -h
to convert a .mo or .po file to i8next json:
i18next-conv -l [locale] -s [sourcePath] -t [targetPath]
eg.: i18next-conv -l en -s ./locales/en.po -t ./locales/en/translation.json
if no target (-t) is specified file will be stored to [sourceDir]/[locale]/translation.json.
to convert i18next json to a .mo or .po file:
i18next-conv -l [locale] -s [sourcePath] -t [targetPath]
eg.: i18next-conv -l en -s ./locales/en.translation.json -t ./locales/en/translation.mo (or .po)
if no target (-t) is specified file will be stored to [sourceDir]/[locale]/translation.po.
for utf8-encoded po-files add these lines to your po file:
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
It is necessary if you get corrupted output from the command above.
to filter incoming po-file translations, pass the path to a module that exports a filter function:
i18next-conv -l [locale] -s [sourcePath] -t [targetPath] -f [filterPath]
eg.: i18next-conv -l en -s ./locales/en.po -t ./locales/en/translation.json -f ./filter.js
The filter module should export a single function that accepts the gettext object, the locale and a callback as its arguments. For the full API of the gettext object, check node-gettext. The function can then add/edit/delete translations, invoking the callback with an error object and the translation table.
eg.
// Delete all keys which do not belong to the frontend
module.exports = function (gt, locale, callback) {
const clientSideSource = '/frontend/';
const domain = 'messages';
const translations = gt.catalogs[locale][domain].translations;
gt.setLocale(locale); // Needed for when getComment is called
Object.keys(translations).forEach(ctxt => {
Object.keys(translations[ctxt]).forEach(key => {
const comment = gt.getComment('messages', ctxt, key);
if (comment) {
if (comment.reference && comment.reference.indexOf(clientSideSource) === -1) {
delete translations[ctxt][key];
}
}
});
});
callback(null, translations);
};
Options
program
.version(i18nextConv.version)
.option('-b, --base [path]', 'Specify path for the base language file. only take effect with -K option', '')
.option('-f, --filter <path>', 'Specify path to gettext filter')
.option('-l, --language <locale>', 'Specify the language code, eg. \'en\'')
.option('-p, --pot', 'Generate POT file.')
.option('-s, --source <path>', 'Specify path to read from')
.option('-t, --target [path]', 'Specify path to write to', '')
.option('-K, --keyasareference', 'Deal with the reference comment as a key', false)
.option('-k, --keyseparator [path]', 'Specify keyseparator you want to use, defaults to ##', '##')
.option('-P, --plurals <path>', 'Specify path to plural forms definitions')
.option('--project <project>', 'Specify the project-id-version when converting json to gettext')
.option('--quiet', 'Silence output', false)
.option('--gettextDefaultCharset', 'Default charset when parsing gettext files with gettext-parser', 'UTF-8')
.option('--skipUntranslated', 'Skip untranslated keys when converting into json', false)
.option('--splitNewLine', 'Silence output', false)
.option('--ctxSeparator [sep]', 'Specify the context separator', '_')
.option('--ignorePlurals', 'Do not process the plurals')
.option('--compatibilityJSON <ver>', "Set to 'v4' to generate i18next@21 compatible json files")
.option('--foldLength', 'Specify the character fold length for strings', 76)
.option('--noDate', 'Removes timestamp related lines from output file (POT-Creation-Date and PO-Revision-Date lines)')
.parse(process.argv);
API
This module exposes a few functions to convert json to gettext and gettext to json. It accepts the same options as the cli.
const path = require('path');
const { readFileSync, writeFileSync } = require('fs');
const {
i18nextToPo,
i18nextToPot,
i18nextToMo,
gettextToI18next,
} = require('i18next-conv');
const source = path.join(__dirname, '../locales/ua-UK/translation.json');
const options = {/* you options here */}
function save(target) {
return result => {
writeFileSync(target, result);
};
}
i18nextToPo('ua-UK', readFileSync(source), options).then(save('../locales/ua-UK/translation.po'));
i18nextToPot('ua-UK', readFileSync(source), options).then(save('../locales/ua-UK/translation.pot'));
i18nextToMo('ua-UK', readFileSync(source), options).then(save('../locales/ua-UK/translation.mo'));
gettextToI18next('ua-UK', readFileSync('../locales/ua-UK/translation.po'), options)
.then(save('../locales/ua-UK/translation.json'));
All credits go to
- andri9's node-gettext for parsing .mo and .po files
- TJ Holowaychuk's commander.js for console program
License
See the LICENSE file for license rights and limitations.