i18next-conv
Advanced tools
Comparing version 0.0.3 to 0.0.5
var Gettext = require("node-gettext") | ||
, plurals = require("./plurals") | ||
, flatten = require("./flatten") | ||
, fs = require("fs") | ||
@@ -11,5 +12,28 @@ , path = require("path") | ||
gettextToI18next: function(domain, source, target, callback) { | ||
var self = this; | ||
process: function(domain, source, target, options, callback) { | ||
var ext = path.extname(source); | ||
if (ext === '.mo' || ext === '.po') { | ||
return this.gettextToI18next(domain, source, target, options, callback); | ||
} | ||
if (ext === '.json') { | ||
return this.i18nextToGettext(domain, source, target, options, callback); | ||
} | ||
}, | ||
/*************************** | ||
* | ||
* I18NEXT JSON --> GETTEXT | ||
* | ||
***************************/ | ||
i18nextToGettext: function(domain, source, target, options, callback) { | ||
if (typeof options === 'function') { | ||
callback = options; | ||
options = {}; | ||
} | ||
var self = this; | ||
var dirname = path.dirname(source) | ||
@@ -20,5 +44,127 @@ , ext = path.extname(source) | ||
if (!target) { | ||
target = path.join(dirname, domain, filename + '.json'); | ||
var dir; | ||
if (dirname.indexOf(domain) === dirname.length - domain.length) { | ||
dir = path.join(dirname); | ||
target = path.join(dirname, filename + '.po'); | ||
} else { | ||
dir = path.join(dirname, domain); | ||
target = path.join(dirname, domain, filename + '.po'); | ||
} | ||
if (!fs.statSync(dir)) fs.mkdirSync(dir); | ||
} | ||
var dir = path.join(dirname, domain); | ||
self.flattenI18nextJSON(source, options, function(err, flat) { | ||
//self.writeFile('./' + path.join(dirname, filename + '_tmp.json'), JSON.stringify(flat, null, 4), function(){}); | ||
self.parseGettext(domain, flat, function(err, gt) { | ||
var data = path.extname(target) === '.po' ? gt.compilePO(domain) : gt.compileMO(domain); | ||
self.writeFile(target, data, callback); | ||
}); | ||
}); | ||
}, | ||
/* i18next json --> flat json | ||
* | ||
*/ | ||
flattenI18nextJSON: function(source, options, callback) { | ||
var self = this; | ||
console.log(('\n --> reading file from: ' + source)); | ||
fs.readFile(source, function(err, body) { | ||
if(err) { | ||
callback(err); | ||
return; | ||
} | ||
var flat = flatten.flatten(JSON.parse(body), options); | ||
callback(null, flat); | ||
}); | ||
}, | ||
/* flat json --> gettext | ||
* | ||
*/ | ||
parseGettext: function(domain, data, callback) { | ||
var gt = new Gettext(); | ||
gt.addTextdomain(domain, ''); | ||
var ext = plurals.rules[domain.split('-')[0]]; | ||
console.log('\n <-> parsing data to gettext format'.cyan); | ||
for (var m in data) { | ||
var kv = data[m]; | ||
if (kv.plurals) { | ||
var pArray = []; | ||
pArray.splice(this.getGettextPluralPosition(ext, '-1'), 0, kv.value); | ||
for (var i = 0, len = kv.plurals.length; i < len; i++) { | ||
var plural = kv.plurals[i]; | ||
pArray.splice(this.getGettextPluralPosition(ext, plural.pluralNumber), 0, plural.value); | ||
gt.setTranslation(domain, kv.context, kv.key, pArray); | ||
} | ||
} else { | ||
gt.setTranslation(domain, kv.context, kv.key, kv.value); | ||
} | ||
} | ||
callback(null, gt); | ||
}, | ||
/* helper to get plural suffix | ||
* | ||
*/ | ||
getGettextPluralPosition: function(ext, suffix) { | ||
if (ext) { | ||
if (ext.numbers.length === 2) { | ||
if (suffix === '-1') { | ||
suffix = '1'; | ||
} else if (suffix === '1') { | ||
suffix = '2'; | ||
} | ||
} | ||
for (var i = 0, len = ext.numbers.length; i < len; i++) { | ||
if (ext.numbers[i].toString() === suffix) { | ||
return i; | ||
} | ||
} | ||
} | ||
return -1; | ||
}, | ||
/*************************** | ||
* | ||
* GETTEXT --> I18NEXT JSON | ||
* | ||
***************************/ | ||
gettextToI18next: function(domain, source, target, options, callback) { | ||
if (typeof options === 'function') { | ||
callback = options; | ||
options = {}; | ||
} | ||
var self = this; | ||
var dirname = path.dirname(source) | ||
, ext = path.extname(source) | ||
, filename = path.basename(source, ext); | ||
if (!target) { | ||
var dir; | ||
if (dirname.indexOf(domain) === dirname.length - domain.length) { | ||
dir = path.join(dirname); | ||
target = path.join(dirname, filename + '.json'); | ||
} else { | ||
dir = path.join(dirname, domain); | ||
target = path.join(dirname, domain, filename + '.json'); | ||
} | ||
if (!fs.statSync(dir)) fs.mkdirSync(dir); | ||
@@ -30,3 +176,3 @@ } | ||
self.parseJSON(domain, data, function(err, json) { | ||
self.parseJSON(domain, data, options, function(err, json) { | ||
var jsonData = JSON.stringify(json, null, 4); | ||
@@ -38,13 +184,12 @@ // console.log(jsonData); | ||
}); | ||
}, | ||
/* gettext --> barebone json | ||
* | ||
*/ | ||
addTextDomain: function(domain, source, callback) { | ||
var self = this; | ||
}, | ||
addTextDomain: function(domain, source, callback) { | ||
var self = this; | ||
console.log(('\n --> reading file from: ' + source)); | ||
fs.readFile(source, function(err, body) { | ||
fs.readFile(source, function(err, body) { | ||
if(err) { | ||
@@ -59,14 +204,9 @@ callback(err); | ||
}); | ||
}, | ||
writeFile: function(target, data, callback) { | ||
console.log(('\n <-- writting file to: ' + target)); | ||
fs.writeFile(target, data, function(err) { | ||
callback(err); | ||
}); | ||
}, | ||
parseJSON: function(domain, data, callback) { | ||
/* barebone json --> i18next json | ||
* | ||
*/ | ||
parseJSON: function(domain, data, options, callback) { | ||
var separator = options.keyseparator || '##'; | ||
@@ -76,7 +216,30 @@ console.log('\n <-> parsing data to i18next json format'.cyan); | ||
var toArrayIfNeeded = function(value) { | ||
var ret = value; | ||
if (ret.indexOf('\n') > -1) ret = ret.split('\n'); | ||
return ret; | ||
}; | ||
for (var m in data) { | ||
var context = data[m]; | ||
for (var key in context) { | ||
var appendTo = json | ||
, targetKey = key; | ||
if (key.indexOf(separator) > -1) { | ||
var keys = key.split(separator); | ||
var x = 0; | ||
while (keys[x]) { | ||
if (x < keys.length - 1) { | ||
appendTo[keys[x]] = appendTo[keys[x]] || {}; | ||
appendTo = appendTo[keys[x]]; | ||
} else { | ||
targetKey = keys[x]; | ||
} | ||
x++; | ||
} | ||
} | ||
var values = context[key]; | ||
@@ -87,3 +250,3 @@ | ||
if (values.length === 1) { | ||
json[key] = values[0]; | ||
appendTo[targetKey] = toArrayIfNeeded(values[0]); | ||
} else { | ||
@@ -93,6 +256,6 @@ var ext = plurals.rules[domain.split('-')[0]]; | ||
for (var i = 0, len = values.length; i < len; i++) { | ||
var pluralSuffix = this.getPluralExtension(ext, i); | ||
var pkey = key + pluralSuffix; | ||
var pluralSuffix = this.getI18nextPluralExtension(ext, i); | ||
var pkey = targetKey + pluralSuffix; | ||
json[pkey] = values[i]; | ||
appendTo[pkey] = toArrayIfNeeded(values[i]); | ||
} | ||
@@ -107,3 +270,6 @@ } | ||
getPluralExtension: function(ext, i) { | ||
/* helper to get plural suffix | ||
* | ||
*/ | ||
getI18nextPluralExtension: function(ext, i) { | ||
@@ -114,9 +280,9 @@ if (ext) { | ||
if (number === 2) { | ||
number = 1; | ||
number = 1; // is basic plural | ||
} else if (number === 1) { | ||
number = -1; | ||
number = -1; // is singular | ||
} | ||
return number > 0 ? '' : '_plural'; | ||
} else { | ||
return number === 1 ? '' : '_plural_' + number; | ||
return number === 1 ? '' : '_plural_' + number; // suffix all but singular | ||
} | ||
@@ -126,4 +292,19 @@ } else { | ||
} | ||
}, | ||
/*************************** | ||
* | ||
* SHARED | ||
* | ||
***************************/ | ||
writeFile: function(target, data, callback) { | ||
console.log(('\n <-- writting file to: ' + target)); | ||
fs.writeFile(target, data, function(err) { | ||
callback(err); | ||
}); | ||
} | ||
}; |
@@ -6,3 +6,3 @@ { | ||
, "keywords": ["i18next", "gettext"] | ||
, "version": "0.0.3" | ||
, "version": "0.0.5" | ||
, "private": false | ||
@@ -9,0 +9,0 @@ , "preferGlobal": "true" |
@@ -9,5 +9,12 @@ #!/usr/bin/env node | ||
// node index.js -l es -s ./testfiles/utf8.po | ||
// node index.js -l es -s ./testfiles/utf8.po -t ./testfiles/translation.es.json | ||
// gettext -> i18next | ||
// node program.js -l es -s ./testfiles/utf8.po | ||
// node program.js -l es -s ./testfiles/utf8.po -t ./testfiles/translation.es.json | ||
// i18next -> gettext | ||
// node program.js -l de -s ./testfiles/de/source.de.json | ||
// node program.js -l de -s ./testfiles/de/source.de.json -t ./testfiles/de/translation.de.po | ||
// and back | ||
// node program.js -l de -s ./testfiles/de/translation.de.po | ||
// program | ||
@@ -19,8 +26,13 @@ program | ||
.option('-l, --language [domain]', 'Specify the language code, eg. \'en\'') | ||
.option('-ks, --keyseparator [path]', 'Specify keyseparator you want to use, defaults to ##', '##') | ||
.parse(process.argv); | ||
if (program.source && program.language) { | ||
console.log('\nstarting converting'.red); | ||
console.log('\nstart converting'.yellow); | ||
converter.gettextToI18next(program.language, program.source, program.target, function(err) { | ||
var options = { | ||
keyseparator: program.keyseparator | ||
}; | ||
converter.process(program.language, program.source, program.target, options, function(err) { | ||
if (err) { | ||
@@ -27,0 +39,0 @@ console.log('\nfailed writing file\n\n'.red); |
@@ -23,3 +23,3 @@ # Introduction | ||
__to convert a .mo or .po file to json:__ | ||
__to convert a .mo or .po file to i8next json:__ | ||
@@ -35,3 +35,13 @@ ```` | ||
__to convert i18next json to a .mo or .po file:__ | ||
```` | ||
i18next-conv -l [domain] -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]/[domain]/translation.po._ | ||
# All credits go to | ||
@@ -38,0 +48,0 @@ |
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
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
110959
20
2558
70