i18next-conv
Advanced tools
Comparing version 0.1.2 to 0.1.3
@@ -1,2 +0,1 @@ | ||
module.exports = { | ||
@@ -8,3 +7,2 @@ | ||
function recurse(appendTo, obj, parentKey) { | ||
@@ -27,12 +25,16 @@ | ||
if (key.indexOf('_plural') > -1) { | ||
ctxKey = ctxKey.replace(new RegExp('_plural_*', 'g'), ''); | ||
ctxKey = ctxKey.replace(new RegExp('_plural', 'g'), ''); | ||
ctxKey = ctxKey.substring(0, key.indexOf('_plural')); | ||
if (ctxKey.indexOf('_') > -1) context = ctxKey.substring(ctxKey.lastIndexOf('_') + 1, ctxKey.length); | ||
} | ||
if (ctxKey.indexOf('context_') > -1) { | ||
context = 'context' + ctxKey.substring(ctxKey.lastIndexOf('_'), ctxKey.length); | ||
} else { | ||
context = ctxKey.substring(ctxKey.lastIndexOf('_'), ctxKey.length); | ||
else if (key.indexOf('_') > -1) { | ||
context = ctxKey.substring(ctxKey.lastIndexOf('_') + 1, ctxKey.length); | ||
} | ||
else { | ||
context = ""; | ||
} | ||
if (context === key) context = ''; | ||
if (context !== '') key = key.replace('_' + context, ''); | ||
// append or recurse | ||
@@ -47,3 +49,3 @@ if (typeof value === 'string') { | ||
}; | ||
appendTo[kv.key] = kv; | ||
appendTo[kv.key + kv.context] = kv; | ||
} else if (Object.prototype.toString.apply(value) === '[object Array]') { | ||
@@ -58,3 +60,3 @@ kv = { | ||
}; | ||
appendTo[kv.key] = kv; | ||
appendTo[kv.key + kv.context] = kv; | ||
} else { | ||
@@ -76,3 +78,3 @@ recurse(appendTo, value, key); | ||
var single = flat[parts[0]]; | ||
var single = flat[parts[0] + kv.context]; | ||
kv.pluralNumber = parts[1].replace('_', ''); | ||
@@ -85,3 +87,3 @@ if (kv.pluralNumber === '') kv.pluralNumber = '1'; | ||
delete flat[kv.key]; | ||
delete flat[m]; | ||
} | ||
@@ -93,2 +95,2 @@ } | ||
} | ||
}; | ||
}; |
@@ -6,3 +6,4 @@ var Gettext = require("node-gettext") | ||
, path = require("path") | ||
, colors = require("colors"); | ||
, colors = require("colors") | ||
, mkdirp = require('mkdirp'); | ||
@@ -16,2 +17,8 @@ var gt = new Gettext(); | ||
if (options.plurals) { | ||
var plurals_path = path.join(process.cwd(), options.plurals); | ||
plurals.rules = require(plurals_path); | ||
if (!options.quiet) console.log(('\nuse custom plural forms ' + plurals_path + '\n').blue); | ||
} | ||
if (ext === '.mo' || ext === '.po') { | ||
@@ -24,3 +31,2 @@ return this.gettextToI18next(domain, source, target, options, callback); | ||
} | ||
}, | ||
@@ -41,2 +47,6 @@ | ||
if(!fs.existsSync(target)){ | ||
mkdirp.sync(path.dirname(target)); | ||
} | ||
var dirname = path.dirname(source) | ||
@@ -46,2 +56,6 @@ , ext = path.extname(source) | ||
if(!fs.existsSync(target)){ | ||
mkdirp.sync(path.dirname(target)); | ||
} | ||
if (!target) { | ||
@@ -56,3 +70,3 @@ var dir; | ||
} | ||
if (!fs.statSync(dir)) fs.mkdirSync(dir); | ||
@@ -62,4 +76,2 @@ } | ||
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, options, function(err, gt) { | ||
@@ -78,4 +90,2 @@ | ||
flattenI18nextJSON: function(source, options, callback) { | ||
var self = this; | ||
if (!options.quiet) console.log(('\n --> reading file from: ' + source)); | ||
@@ -111,3 +121,3 @@ | ||
var pArray = []; | ||
pArray.splice(this.getGettextPluralPosition(ext, '-1'), 0, kv.value); | ||
for (var i = 0, len = kv.plurals.length; i < len; i++) { | ||
@@ -117,4 +127,7 @@ var plural = kv.plurals[i]; | ||
gt.setTranslation(domain, kv.context, kv.key, pArray); | ||
} | ||
pArray.splice(this.getGettextPluralPosition(0,0), 0, kv.value); | ||
gt.setTranslation(domain, kv.context, kv.key, pArray); | ||
} else { | ||
@@ -132,22 +145,12 @@ gt.setTranslation(domain, kv.context, kv.key, kv.value); | ||
getGettextPluralPosition: function(ext, suffix) { | ||
if (ext) { | ||
if (ext.numbers.length === 2) { | ||
// germanic like en | ||
if (ext.numbers[0] === 2) { | ||
if (suffix === '-1') { // regular plural | ||
suffix = '1'; | ||
} else if (suffix === '1') { // singular | ||
suffix = '2'; | ||
} | ||
} | ||
// romanic like fr | ||
else if (ext.numbers[0] === 1) { | ||
if (suffix === '-1') { // regular plural | ||
suffix = '2'; | ||
} else if (suffix === '1') { // singular | ||
suffix = '1'; | ||
} | ||
if (suffix === '-1') { // regular plural | ||
suffix = '1'; | ||
} else if (suffix === '1') { // singular | ||
suffix = '2'; | ||
} | ||
} | ||
} | ||
@@ -181,2 +184,6 @@ for (var i = 0, len = ext.numbers.length; i < len; i++) { | ||
if(!fs.existsSync(target)){ | ||
mkdirp.sync(path.dirname(target)); | ||
} | ||
if (!target) { | ||
@@ -196,7 +203,6 @@ var dir; | ||
self.addTextDomain(domain, source, options, function(err, data) { | ||
// console.log(data); | ||
self.parseJSON(domain, data, options, function(err, json) { | ||
var jsonData = JSON.stringify(json, null, 4); | ||
// console.log(jsonData); | ||
@@ -212,6 +218,4 @@ self.writeFile(target, jsonData, options, callback); | ||
addTextDomain: function(domain, source, options, callback) { | ||
var self = this; | ||
if (!options.quiet) console.log(('\n --> reading file from: ' + source)); | ||
if (!options.quiet) console.log(('\n --> reading file from: ' + source)); | ||
fs.readFile(source, function(err, body) { | ||
@@ -223,5 +227,9 @@ if(err) { | ||
gt.addTextdomain("et", body); | ||
gt.addTextdomain(domain, body); | ||
callback(null, gt._domains[gt._textdomain]._translationTable); | ||
if (options.filter) { | ||
options.filter(gt, domain, callback); | ||
} else { | ||
callback(null, gt._domains[domain]._translationTable); | ||
} | ||
}); | ||
@@ -236,3 +244,3 @@ }, | ||
console.log('\n <-> parsing data to i18next json format'.cyan); | ||
if (!options.quiet) console.log('\n <-> parsing data to i18next json format'.cyan); | ||
var json = {}; | ||
@@ -270,3 +278,3 @@ | ||
if (m !== '') key = key + '_' + m; | ||
if (m !== '') targetKey = targetKey + '_' + m; | ||
@@ -296,3 +304,2 @@ if (values.length === 1) { | ||
getI18nextPluralExtension: function(ext, i) { | ||
if (ext) { | ||
@@ -304,3 +311,3 @@ var number = ext.numbers[i]; | ||
if (ext.numbers[0] === 2) { | ||
if (number === 2) { | ||
if (number === 2) { | ||
number = 1; // singular | ||
@@ -310,6 +317,6 @@ } else if (number === 1) { | ||
} | ||
} | ||
} | ||
// romanic like fr | ||
else if (ext.numbers[0] === 1) { | ||
if (number === 2) { | ||
if (number === 2) { | ||
number = -1; // regular plural | ||
@@ -320,3 +327,3 @@ } else if (number === 1) { | ||
} | ||
} | ||
} | ||
return number > 0 ? '' : '_plural'; | ||
@@ -338,10 +345,7 @@ } else { | ||
writeFile: function(target, data, options, callback) { | ||
if (!options.quiet) console.log(('\n <-- writting file to: ' + target)); | ||
if (!options.quiet) console.log(('\n <-- writing file to: ' + target)); | ||
fs.writeFile(target, data, function(err) { | ||
callback(err); | ||
}); | ||
} | ||
}; |
@@ -214,3 +214,3 @@ // definition http://translate.sourceforge.net/wiki/l10n/pluralforms | ||
"numbers": [ | ||
1, | ||
1, | ||
2 | ||
@@ -217,0 +217,0 @@ ], |
{ | ||
"author": "jamuhl" | ||
, "name": "i18next-conv" | ||
, "description": "converts .mo and .po files to i18next's json format and vice versa." | ||
, "keywords": ["i18next", "gettext"] | ||
, "version": "0.1.2" | ||
, "private": false | ||
, "preferGlobal": "true" | ||
, "main": "index.js" | ||
, "repository": { | ||
"type": "git", | ||
"url": "https://github.com/jamuhl/i18next-gettext-converter.git" | ||
} | ||
, "engines": { | ||
"node": ">= 0.6.0" | ||
} | ||
, "dependencies": { | ||
"node-gettext": "*" | ||
, "commander": "*" | ||
, "colors": "*" | ||
"author": "jamuhl", | ||
"name": "i18next-conv", | ||
"description": "converts .mo and .po files to i18next's json format and vice versa.", | ||
"keywords": [ | ||
"i18next", | ||
"gettext" | ||
], | ||
"version": "0.1.3", | ||
"private": false, | ||
"preferGlobal": "true", | ||
"main": "index.js", | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/jamuhl/i18next-gettext-converter.git" | ||
}, | ||
"engines": { | ||
"node": ">= 0.6.0" | ||
}, | ||
"dependencies": { | ||
"colors": "^1.0.3", | ||
"commander": "^2.5.0", | ||
"mkdirp": "^0.5.0" | ||
}, | ||
"devDependencies": { | ||
"async": "^0.9.0", | ||
"chai": "^1.10.0", | ||
"grunt": "^0.4.5", | ||
"grunt-mocha-test": "^0.12.4", | ||
"node-gettext": "^0.2.14" | ||
}, | ||
"scripts": { | ||
"test": "grunt mochaTest" | ||
}, | ||
"bin": { | ||
"i18next-conv": "program.js" | ||
} | ||
, "scripts": { | ||
} | ||
, "bin": { "i18next-conv": "program.js" } | ||
} | ||
} |
#!/usr/bin/env node | ||
var program = require('commander') | ||
, fs = require('fs') | ||
, converter = require("./lib/gettextWrapper") | ||
@@ -10,10 +11,13 @@ , colors = require("colors"); | ||
// 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 | ||
// node program.js -l en -s ./test/_testfiles/en/translation.utf8.po -t ./test/_tmp/en.json | ||
// node program.js -l de -s ./test/_testfiles/de/translation.utf8.po -t ./test/_tmp/de.json | ||
// node program.js -l ru -s ./test/_testfiles/ru/translation.utf8.po -t ./test/_tmp/ru.json | ||
// | ||
// With filter: | ||
// node program.js -l en -s ./test/_testfiles/en/translation.utf8.po -t ./test/_tmp/en.json -f path/to/filter.js | ||
// 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 | ||
// node program.js -l de -s ./test/_testfiles/de/translation.utf8.json -t ./test/_tmp/de.po | ||
// and back | ||
// node program.js -l de -s ./testfiles/de/translation.de.po | ||
// node program.js -l de -s ./test/_tmp/de.po -t ./test/_tmp/de.json | ||
@@ -27,2 +31,4 @@ // program | ||
.option('-ks, --keyseparator [path]', 'Specify keyseparator you want to use, defaults to ##', '##') | ||
.option('-f, --filter [path]', 'Specify path to gettext filter') | ||
.option('-P, --plurals [path]', 'Specify path to plural forms definitions') | ||
.option('--quiet', 'Silence output', false) | ||
@@ -34,5 +40,10 @@ .parse(process.argv); | ||
keyseparator: program.keyseparator, | ||
plurals: program.plurals, | ||
quiet: program.quiet | ||
}; | ||
if (program.filter && fs.existsSync(program.filter)) { | ||
options.filter = require(program.filter); | ||
} | ||
if (!options.quiet) console.log('\nstart converting'.yellow); | ||
@@ -54,3 +65,1 @@ | ||
module.exports = converter; | ||
@@ -45,2 +45,41 @@ # Introduction | ||
__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 [domain] -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 domain and a callback | ||
as its arguments. The function can then add/edit/delete translations, invoking the callback with an error object | ||
and the translation table. | ||
eg. | ||
```javascript | ||
module.exports = function(gt, domain, callback) { | ||
var err; | ||
// Delete all keys without comments | ||
gt.listKeys(domain).forEach(function(key) { | ||
var comment = gt.getComment(domain, "", key); | ||
if (!comment) { | ||
gt.deleteTranslation(domain, "", key); | ||
} | ||
}); | ||
callback(err, gt._domains[gt._textdomain]._translationTable); | ||
}; | ||
``` | ||
# All credits go to | ||
@@ -71,2 +110,2 @@ | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
THE SOFTWARE. | ||
THE SOFTWARE. |
Sorry, the diff of this file is not supported yet
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
Floating dependency
QualityPackage has a dependency with a floating version range. This can cause issues if the dependency publishes a new major version.
Found 3 instances in 1 package
30
2589
0
110
106112
5
21
1
+ Addedmkdirp@^0.5.0
+ Addedcommander@2.20.3(transitive)
+ Addedminimist@1.2.8(transitive)
+ Addedmkdirp@0.5.6(transitive)
- Removednode-gettext@*
- Removedcommander@12.1.0(transitive)
- Removedlodash.get@4.4.2(transitive)
- Removednode-gettext@3.0.0(transitive)
Updatedcolors@^1.0.3
Updatedcommander@^2.5.0