diff --git a/README.md b/README.md index 1984a11..1e0ca14 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ Add an `extract` script to your project's `package.json`: ``` You can now run `npm run extract` to extract strings. -## Commandline examples +## Extract examples **Extract from dir and save to file** @@ -39,6 +39,17 @@ You can now run `npm run extract` to extract strings. `ngx-translate-extract -i ./src -o ./src/i18n/*.json` +**or (update only)** + +## Custom indentation +By default, tabs are used for indentation when writing extracted strings to json formats: + +`ngx-translate-extract -i ./src -o ./src/i18n/en.json --format-indentation $'\t'` + +If you want to use spaces instead, you can do the following: + +`ngx-translate-extract -i ./src -o ./src/i18n/en.json --format-indentation ' '` + Modify the scripts arguments as required. @@ -48,20 +59,23 @@ Usage: ngx-translate-extract [options] Options: - --version, -v Show version number [boolean] - --help, -h Show help [boolean] - --input, -i Paths you would like to extract strings from. You can use path - expansion, glob patterns and multiple paths - [array] [default: "/Users/kim/ionic/ngx-translate-extract"] - --patterns, -p Extract strings from the following file patterns + --version, -v Show version number [boolean] + --help, -h Show help [boolean] + --input, -i Paths you would like to extract strings from. You + can use path expansion, glob patterns and multiple + paths + [array] [default: current working path] + --patterns, -p Extract strings from the following file patterns [array] [default: ["/**/*.html","/**/*.ts"]] - --output, -o Paths where you would like to save extracted strings. You can - use path expansion, glob patterns and multiple paths - [array] [required] - --format, -f Output format + --output, -o Paths where you would like to save extracted + strings. You can use path expansion, glob patterns + and multiple paths [array] [required] + --format, -f Output format [string] [choices: "json", "namespaced-json", "pot"] [default: "json"] - --replace, -r Replace the contents of output file if it exists (Merges by - default) [boolean] [default: false] - --sort, -s Sort strings in alphabetical order when saving + --format-indentation, --fi Output format indentation [string] [default: "\t"] + --replace, -r Replace the contents of output file if it exists + (Merges by default) [boolean] [default: false] + --sort, -s Sort strings in alphabetical order when saving + [boolean] [default: false] + --clean, -c Remove obsolete strings when merging [boolean] [default: false] - --clean, -c Remove obsolete strings when merging[boolean] [default: false] diff --git a/package.json b/package.json index 66e96d9..91b2a10 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@biesbjerg/ngx-translate-extract", - "version": "2.0.1", + "version": "2.1.0", "description": "Extract strings from projects using ngx-translate", "main": "dist/index.js", "typings": "dist/index.d.ts", @@ -50,17 +50,17 @@ "@types/chai": "3.4.35", "@types/glob": "5.0.30", "@types/mocha": "2.2.40", - "@types/cheerio": "0.22.0", + "@types/cheerio": "0.22.1", "@types/chalk": "0.4.31", "@types/flat": "0.0.28", "@types/yargs": "6.6.0", "@types/mkdirp": "0.3.29", "chai": "3.5.0", "mocha": "3.2.0", - "ts-node": "2.1.0", + "ts-node": "3.0.2", "tslint": "4.5.1", "tslint-eslint-rules": "3.5.1", - "typescript": "2.2.1" + "typescript": "2.2.2" }, "dependencies": { "chalk": "1.1.3", diff --git a/src/cli/cli.ts b/src/cli/cli.ts index f3ea9c8..5317b27 100755 --- a/src/cli/cli.ts +++ b/src/cli/cli.ts @@ -1,7 +1,10 @@ import { ExtractTask } from './tasks/extract.task'; +import { ParserInterface } from '../parsers/parser.interface'; import { PipeParser } from '../parsers/pipe.parser'; import { DirectiveParser } from '../parsers/directive.parser'; import { ServiceParser } from '../parsers/service.parser'; +import { CompilerInterface } from '../compilers/compiler.interface'; +import { CompilerFactory } from '../compilers/compiler.factory'; import * as fs from 'fs'; import * as yargs from 'yargs'; @@ -48,6 +51,12 @@ export const cli = yargs type: 'string', choices: ['json', 'namespaced-json', 'pot'] }) + .option('format-indentation', { + alias: 'fi', + describe: 'Output format indentation', + default: '\t', + type: 'string' + }) .option('replace', { alias: 'r', describe: 'Replace the contents of output file if it exists (Merges by default)', @@ -69,19 +78,22 @@ export const cli = yargs .exitProcess(true) .parse(process.argv); -const extractTask = new ExtractTask(cli.input, cli.output, { +const parsers: ParserInterface[] = [ + new ServiceParser(), + new PipeParser(), + new DirectiveParser() +]; + +const compiler: CompilerInterface = CompilerFactory.create(cli.format, { + indentation: cli.formatIndentation +}); + +new ExtractTask(cli.input, cli.output, { replace: cli.replace, sort: cli.sort, clean: cli.clean, patterns: cli.patterns -}); - -extractTask - .setParsers([ - new ServiceParser(), - new PipeParser(), - new DirectiveParser() - ]) - .setCompiler(cli.format) - .execute(); - +}) +.setParsers(parsers) +.setCompiler(compiler) +.execute(); diff --git a/src/cli/tasks/extract.task.ts b/src/cli/tasks/extract.task.ts index d3dec1e..8f628af 100644 --- a/src/cli/tasks/extract.task.ts +++ b/src/cli/tasks/extract.task.ts @@ -2,7 +2,6 @@ import { TranslationCollection } from '../../utils/translation.collection'; import { TaskInterface } from './task.interface'; import { ParserInterface } from '../../parsers/parser.interface'; import { CompilerInterface } from '../../compilers/compiler.interface'; -import { CompilerFactory } from '../../compilers/compiler.factory'; import * as chalk from 'chalk'; import * as glob from 'glob'; @@ -56,13 +55,8 @@ export class ExtractTask implements TaskInterface { return this; } - public setCompiler(compiler: CompilerInterface | string): this { - if (typeof compiler === 'string') { - this._compiler = CompilerFactory.create(compiler) - } else { - this._compiler = compiler; - } - + public setCompiler(compiler: CompilerInterface): this { + this._compiler = compiler; return this; } @@ -70,10 +64,9 @@ export class ExtractTask implements TaskInterface { * Extract strings from input dirs using configured parsers */ protected _extract(): TranslationCollection { - let collection: TranslationCollection = new TranslationCollection(); - this._out(chalk.bold('Extracting strings...')); + let collection: TranslationCollection = new TranslationCollection(); this._input.forEach(dir => { this._readDir(dir, this._options.patterns).forEach(path => { this._out(chalk.gray('- %s'), path); @@ -83,6 +76,7 @@ export class ExtractTask implements TaskInterface { }); }); }); + return collection; } diff --git a/src/compilers/compiler.factory.ts b/src/compilers/compiler.factory.ts index e6ba41e..eb9870b 100644 --- a/src/compilers/compiler.factory.ts +++ b/src/compilers/compiler.factory.ts @@ -5,11 +5,11 @@ import { PoCompiler } from '../compilers/po.compiler'; export class CompilerFactory { - public static create(format: string): CompilerInterface { + public static create(format: string, options?: {}): CompilerInterface { switch (format) { - case 'pot': return new PoCompiler(); - case 'json': return new JsonCompiler(); - case 'namespaced-json': return new NamespacedJsonCompiler(); + case 'pot': return new PoCompiler(options); + case 'json': return new JsonCompiler(options); + case 'namespaced-json': return new NamespacedJsonCompiler(options); default: throw new Error(`Unknown format: ${format}`); } } diff --git a/src/compilers/json.compiler.ts b/src/compilers/json.compiler.ts index 3d0b601..5d92244 100644 --- a/src/compilers/json.compiler.ts +++ b/src/compilers/json.compiler.ts @@ -3,10 +3,18 @@ import { TranslationCollection } from '../utils/translation.collection'; export class JsonCompiler implements CompilerInterface { + public indentation: string = '\t'; + public extension = 'json'; + public constructor(options?: any) { + if (options && typeof options.indentation !== 'undefined') { + this.indentation = options.indentation; + } + } + public compile(collection: TranslationCollection): string { - return JSON.stringify(collection.values, null, '\t'); + return JSON.stringify(collection.values, null, this.indentation); } public parse(contents: string): TranslationCollection { diff --git a/src/compilers/namespaced-json.compiler.ts b/src/compilers/namespaced-json.compiler.ts index 2a32157..39e5b11 100644 --- a/src/compilers/namespaced-json.compiler.ts +++ b/src/compilers/namespaced-json.compiler.ts @@ -5,13 +5,21 @@ import * as flat from 'flat'; export class NamespacedJsonCompiler implements CompilerInterface { + public indentation: string = '\t'; + public extension = 'json'; + public constructor(options?: any) { + if (options && typeof options.indentation !== 'undefined') { + this.indentation = options.indentation; + } + } + public compile(collection: TranslationCollection): string { const values: {} = flat.unflatten(collection.values, { object: true }); - return JSON.stringify(values, null, '\t'); + return JSON.stringify(values, null, this.indentation); } public parse(contents: string): TranslationCollection { diff --git a/src/compilers/po.compiler.ts b/src/compilers/po.compiler.ts index 141ff1f..6aa42eb 100644 --- a/src/compilers/po.compiler.ts +++ b/src/compilers/po.compiler.ts @@ -12,6 +12,8 @@ export class PoCompiler implements CompilerInterface { */ public domain = ''; + public constructor(options?: any) { } + public compile(collection: TranslationCollection): string { const data = { charset: 'utf-8', diff --git a/tests/compilers/namespaced-compiler.spec.ts b/tests/compilers/namespaced-json.compiler.spec.ts similarity index 75% rename from tests/compilers/namespaced-compiler.spec.ts rename to tests/compilers/namespaced-json.compiler.spec.ts index 8d352f1..8d74dd1 100644 --- a/tests/compilers/namespaced-compiler.spec.ts +++ b/tests/compilers/namespaced-json.compiler.spec.ts @@ -45,4 +45,16 @@ describe('NamespacedJsonCompiler', () => { expect(result).to.equal('{\n\t"option": {\n\t\t"0": "",\n\t\t"1": "",\n\t\t"2": ""\n\t}\n}'); }); + it('should use custom indentation chars', () => { + const collection = new TranslationCollection({ + 'NAMESPACE.KEY.FIRST_KEY': '', + 'NAMESPACE.KEY.SECOND_KEY': 'VALUE' + }); + const customCompiler = new NamespacedJsonCompiler({ + indentation: ' ' + }); + const result: string = customCompiler.compile(collection); + expect(result).to.equal('{\n "NAMESPACE": {\n "KEY": {\n "FIRST_KEY": "",\n "SECOND_KEY": "VALUE"\n }\n }\n}'); + }); + });