diff --git a/README.md b/README.md index 96c7bfe..df98552 100644 --- a/README.md +++ b/README.md @@ -38,17 +38,17 @@ const HappyBirthdayComponent = (props) => { Next, you can extract these strings from your code into `.po` files using the `extract-strings` command: ``` -$(npm bin)/extract-strings --default-locale en \ - --locale es \ - --locale fr \ - --locale de \ - **/*.js +$(npm bin)/extract-strings **/*.js ``` -This will create a `.po` file for each non-default locale in a directory called `./locales` (pass `--target` if you want to change this). +This will extract the strings from all matching files and print a `.po` file to stdout. Use the standard `gettext` tools like `msgmerge` and `msgcat` to combine the output with existing `.po` files. Refer to `extract-strings --help` for a full list of options +#### Why not just use `xgettext` + +While `xgettext` works perfectly fine on ES5 code, it will choke on ES6+ syntax and also does not support parsing JSX, which `l10nify` supports. + ### Apply the transform at bundle time Apply the transform to your Browserify setup passing the target `locale`. In development, you can omit this parameter to make the transform return the default locale, i.e. the strings you defined in code. diff --git a/bin/cmd.js b/bin/cmd.js index 26feea3..6e0b151 100755 --- a/bin/cmd.js +++ b/bin/cmd.js @@ -5,21 +5,14 @@ * SPDX-License-Identifier: MIT */ -var path = require('path') var arg = require('arg') var extractStrings = require('./../extract.js') var args = arg({ '--help': Boolean, - '--default-locale': String, - '--locale': [String], - '--target': String, '--global': String, '-h': '--help', - '-d': '--default-locale', - '-l': '--locale', - '-t': '--target', '-g': '--global' }) @@ -30,12 +23,6 @@ files defines the files to extract strings from. Usually this will be a glob pattern like "**/*.js" or similar. Options: - -l, --locale [LOCALE] Specify the locales to extract. Pass multiple - locales by passing multiple flags. - -d, --default-locale [LOCALE] Specify the default locale that is used in code. - Defaults to "en". - -t, --target [DIRECTORY] Specify the target directory for saving .po - files. Defaults to "./locales". -g, --global [IDENTIFIER] Specify the global identifier used as l10n function in code, Defaults to "__" -h, --help Display this help message. @@ -44,35 +31,21 @@ Options: } args = Object.assign({ - '--default-locale': 'en', - '--locale': [], - '--target': './locales/', '--global': '__' }, args) -var eligible = args['--locale'] - .filter(function (locale) { - return locale !== args['--default-locale'] - }) +var stream = extractStrings(args._, args['--global']) -if (eligible.length === 0) { - console.log('No non-default locales were configured. Nothing to do.') - console.log('If this is unintended, check the locales passed to this task.') - process.exit(0) -} +stream.on('data', function (line) { + process.stdout.write(line) +}) -Promise.all(eligible.map(function (locale) { - return extractStrings( - path.join(process.cwd(), args['--target'], locale + '.po'), - args._, - args['--global'] - ) -})) - .then(() => { - console.log('Successfully extracted %d locales.', eligible.length) - }) - .catch(function (err) { - console.error('Error extracting strings: %s', err.message) - console.error(err) - process.exit(1) - }) +stream.on('error', function (err) { + console.error('Error extracting strings: %s', err.message) + console.error(err) + process.exit(1) +}) + +stream.on('end', function () { + process.exit(0) +}) diff --git a/extract.js b/extract.js index 204f66d..767616e 100644 --- a/extract.js +++ b/extract.js @@ -4,58 +4,21 @@ */ var fs = require('fs') -var util = require('util') var jscodeshift = require('jscodeshift') -var touch = require('touch') var PO = require('pofile') +var events = require('events') module.exports = extractStrings -function extractStrings (destination, files, globalFunctionIdentifier) { +function extractStrings (files, globalFunctionIdentifier) { if (!files || !files.length) { - console.log('No files found using given pattern, exiting') - return null + throw new Error('No files found using given pattern, exiting') } return parse(files, globalFunctionIdentifier) - .then(function (allStrings) { - return merge(destination, allStrings) - }) - .then(function () { - console.log('Successfully saved strings to %s', destination) - }) -} - -function merge (file, allStrings) { - var currentPo = new PO() - currentPo.items = allStrings - - return util.promisify(PO.load)(file) - .catch(function (err) { - if (err.code === 'ENOENT') { - return null - } - throw err - }) - .then(function (existingPo) { - if (existingPo) { - currentPo.items = currentPo.items.map(function (item) { - var exists = existingPo.items.filter(function (existingItem) { - return existingItem.msgid === item.msgid - }) - if (exists.length && exists[0].msgstr.length) { - item.msgstr = exists[0].msgstr - } - return item - }) - } - return util.promisify(touch)(file) - }) - .then(function () { - return util.promisify(currentPo.save).bind(currentPo)(file) - }) } function parse (files, globalFunctionIdentifier) { + var stream = new events.EventEmitter() var all = files .filter(function (fileName) { return !(/node_modules/.test(fileName)) @@ -86,15 +49,20 @@ function parse (files, globalFunctionIdentifier) { item.comments = [ fileName + ':' + node.node.loc.start.line ] - strings.push(item) + stream.emit('data', item.toString() + '\n\n') } }) - resolve(strings) + resolve() }) }) }) - return Promise.all(all) + Promise.all(all) .then(function (results) { - return [].concat.apply([], results) + stream.emit('end') }) + .catch(function (err) { + stream.emit('error', err) + }) + + return stream } diff --git a/package.json b/package.json index e8fc432..bb4bb45 100644 --- a/package.json +++ b/package.json @@ -39,7 +39,6 @@ "arg": "^4.1.3", "jscodeshift": "^0.10.0", "pofile": "^1.1.0", - "through2": "^4.0.2", - "touch": "^3.1.0" + "through2": "^4.0.2" } }