diff --git a/Changelog.md b/Changelog.md index 6a5086f..a43adf8 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,3 +1,17 @@ + +# [0.3.1](https://github.com/martinroob/ngx-i18nsupport/compare/v0.3.0...v0.3.1) (2017-04-25) + +### Bug Fixes + +* **xliffmerge:** compilation problem in WriterToString ([#19](https://github.com/martinroob/ngx-i18nsupport/issues/19)) + + +# [0.3.0](https://github.com/martinroob/ngx-i18nsupport/compare/v0.2.3...v0.3.0) (2017-04-24) + +### Features + +* **xliffmerge:** Added useSourceAsTargetOption, allows empty translations if set to false. + # [0.2.1](https://github.com/martinroob/ngx-i18nsupport/compare/v0.2.0...v0.2.1) (2017-03-27) diff --git a/README.md b/README.md index 3364b5a..fd3d01a 100644 --- a/README.md +++ b/README.md @@ -82,21 +82,38 @@ Options: `json-configurationfile` is a json file with the following allowed content (every value is optional):
-"xliffmerge": { - "srcDir: "i18n", // directory, where the master file is expected - "genDir": "i18n", // directory, where files are written to (normally identical with srcDir) - "i18nFile": "messages.xlf", // master file (relativ to srcDir) - "i18nFormat": "xlf", // "xlf" for XLIFF or "xmb" for XML Message Bundles - "encoding": "UTF-8", // expected encoding of xlf or xmb files - "defaultLanguage": "en", // the native language used in your templates - "languages": ["en", "de"], // list of languages (if not spefified at command line) - "removeUnusedIds": true, // flag, if unused IDs should be removed during merge - "supportNgxTranslate": true, // flag to active json translation files for ngx-translate - "verbose": false, // controls output - "quiet": false, // controls output +{ + "xliffmergeOptions": { + "srcDir": "i18n", + "genDir": "i18n", + "i18nFile": "messages.xlf", + "i18nFormat": "xlf", + "encoding": "UTF-8", + "defaultLanguage": "en", + "languages": ["en", "de"], + "removeUnusedIds": true, + "supportNgxTranslate": true, + "useSourceAsTarget": false, + "verbose": false, + "quiet": false, + } }+The options are: +- `srcDir` (string, default "."): directory, where the master file is expected +- `genDir` (string, default "."): directory, where files are written to (normally identical with srcDir) +- `i18nFile` (string, default "messages.xlf"): master file (relativ to srcDir) +- `i18nFormat` (string, default "xlf"): "xlf" for XLIFF or "xmb" for XML Message Bundles +- `encoding` (string, default "UTF-8"): expected encoding of xlf or xmb files +- `defaultLanguage` (string, default "en"): the native language used in your templates +- `languages` (array of strings): list of languages (if not spefified at command line) +- `removeUnusedIds` (boolean, default `true`): flag, if unused IDs should be removed during merge +- `supportNgxTranslate` (boolean, default `false`): flag to active json translation files for ngx-translate +- `useSourceAsTarget` (boolean, default `true`): flag, if source should be copied to target for new trans-units +- `verbose` (boolean, default `false`): controls output +- `quiet` (boolean, default `false`): controls output + ### Generate (untranslated) language files, if not already there When you run `xliffmerge`, it will read the master xliff file **messages.xlf**. This is the file generated by the Angular extraction tool `ng-xi18n`. @@ -131,6 +148,9 @@ This is shown by the **state** `new`. The next step you have to do is to translate the file (or to let it translate). Depending on the software you use for translation you can filter for that state `new`. +>Have a look at my sister project [TinyTranslator](https://github.com/martinroob/tiny-translator). +It can filter for new untranslated entries and allows to edit xlf file very easily. + The file for English on the other hand is correct. So, due to the fact, that English is the **default language** here, the state is `translated`. @@ -161,6 +181,8 @@ it will remove it from the language file So after running it, you just have to translate the new parts. +>Once again: [TinyTranslator](https://github.com/martinroob/tiny-translator) might help you to do that. + ## Tests `npm test` @@ -179,7 +201,8 @@ But if you are interesting, send me an email, so that we can discuss it. * Phillippe Martin [Deploying an i18n Angular app with angular-cli](https://medium.com/@feloy/deploying-an-i18n-angular-app-with-angular-cli-fc788f17e358) * Roland Oldengarm: [Angular 2: Automated i18n workflow using gulp](http://rolandoldengarm.com/index.php/2016/10/17/angular-2-automated-i18n-workflow-using-gulp/) -* [XLIFF Spec](http://docs.oasis-open.org/xliff/xliff-core/xliff-core.html) +* XLIFF Specification: [XLIFF Spec](http://docs.oasis-open.org/xliff/xliff-core/xliff-core.html) +* My Tiny Translator Tool: [TinyTranslator](https://github.com/martinroob/tiny-translator) [travis-badge]: https://travis-ci.org/martinroob/ngx-i18nsupport.svg?branch=master [travis-badge-url]: https://travis-ci.org/martinroob/ngx-i18nsupport diff --git a/package.json b/package.json index aac62a3..123d61d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ngx-i18nsupport", - "version": "0.2.3", + "version": "0.3.1", "description": "Some tooling to be used with the Angular 2 i18n workflow", "main": "index.js", "module": "./src", @@ -49,6 +49,6 @@ "dependencies": { "chalk": "^1.1.3", "commander": "^2.9.0", - "ngx-i18nsupport-lib": "^0.0.3" + "ngx-i18nsupport-lib": "^0.0.6" } } diff --git a/src/common/file-util.ts b/src/common/file-util.ts index 050264a..a74dce2 100644 --- a/src/common/file-util.ts +++ b/src/common/file-util.ts @@ -93,4 +93,11 @@ export class FileUtil { } }; + /** + * Delete a file. + * @param path + */ + public static deleteFile(path: string) { + fs.unlinkSync(path); + } } \ No newline at end of file diff --git a/src/common/writer-to-string.ts b/src/common/writer-to-string.ts index 80b93c4..0d7c1d3 100644 --- a/src/common/writer-to-string.ts +++ b/src/common/writer-to-string.ts @@ -16,7 +16,7 @@ export class WriterToString extends Writable { this.resultString = ''; } - protected _write(chunk: any, encoding: string, callback: Function): void { + public _write(chunk: any, encoding: string, callback: Function): void { let chunkString; if (isString(chunk)) { chunkString = chunk; diff --git a/src/tsconfig.json b/src/tsconfig.json index db505ac..804e009 100644 --- a/src/tsconfig.json +++ b/src/tsconfig.json @@ -10,12 +10,15 @@ "moduleResolution": "node", "outDir": "../dist", "sourceMap": true, - "target": "es6", + "target": "es5", "typeRoots": [ "../node_modules/@types" ] }, "include": [ "**/*" + ], + "exclude": [ + "node_modules" ] } diff --git a/src/xliffmerge/i-xliff-merge-options.ts b/src/xliffmerge/i-xliff-merge-options.ts index ab87e21..c79b126 100644 --- a/src/xliffmerge/i-xliff-merge-options.ts +++ b/src/xliffmerge/i-xliff-merge-options.ts @@ -36,5 +36,6 @@ export interface IXliffMergeOptions { }; removeUnusedIds?: boolean; supportNgxTranslate?: boolean; // Flag, wether output for ngs-translate should be generated + useSourceAsTarget?: boolean; // Flag, whether source must be used as target for new trans-units } diff --git a/src/xliffmerge/ngx-translate-extractor.ts b/src/xliffmerge/ngx-translate-extractor.ts index 16c5a89..49c70a8 100644 --- a/src/xliffmerge/ngx-translate-extractor.ts +++ b/src/xliffmerge/ngx-translate-extractor.ts @@ -39,7 +39,13 @@ export class NgxTranslateExtractor { */ public extractTo(outputFile: string) { let translations: NgxTranslations = this.toNgxTranslations(this.extract()); - FileUtil.replaceContent(outputFile, JSON.stringify(translations, null, 4), 'UTF-8') + if (translations && Object.keys(translations).length > 0) { + FileUtil.replaceContent(outputFile, JSON.stringify(translations, null, 4), 'UTF-8') + } else { + if (FileUtil.exists(outputFile)) { + FileUtil.deleteFile(outputFile); + } + } } /** diff --git a/src/xliffmerge/xliff-merge-parameters.ts b/src/xliffmerge/xliff-merge-parameters.ts index f1b2732..80d2c44 100644 --- a/src/xliffmerge/xliff-merge-parameters.ts +++ b/src/xliffmerge/xliff-merge-parameters.ts @@ -24,6 +24,7 @@ export class XliffMergeParameters { private _languages: string[]; private _removeUnusedIds: boolean; private _supportNgxTranslate: boolean; + private _useSourceAsTarget: boolean; public errorsFound: XliffMergeError[]; public warningsFound: string[]; @@ -142,6 +143,9 @@ export class XliffMergeParameters { if (profile.supportNgxTranslate) { this._supportNgxTranslate = profile.supportNgxTranslate; } + if (!isNullOrUndefined(profile.useSourceAsTarget)) { + this._useSourceAsTarget = profile.useSourceAsTarget; + } } else { this.warningsFound.push('did not find "xliffmergeOptions" in profile, using defaults'); } @@ -225,6 +229,7 @@ export class XliffMergeParameters { commandOutput.debug('languages:\t%s', this.languages()); commandOutput.debug('removeUnusedIds:\t%s', this.removeUnusedIds()); commandOutput.debug('supportNgxTranslate:\t%s', this.supportNgxTranslate()); + commandOutput.debug('useSourceAsTarget:\t%s', this.useSourceAsTarget()); } /** @@ -310,4 +315,12 @@ export class XliffMergeParameters { public supportNgxTranslate(): boolean { return (isNullOrUndefined(this._supportNgxTranslate)) ? false : this._supportNgxTranslate; } + + /** + * Whether source must be used as target for new trans-units + * Default is true + */ + public useSourceAsTarget(): boolean { + return (isNullOrUndefined(this._useSourceAsTarget)) ? true : this._useSourceAsTarget; + } } \ No newline at end of file diff --git a/src/xliffmerge/xliff-merge.spec.ts b/src/xliffmerge/xliff-merge.spec.ts index 3833daf..681d331 100644 --- a/src/xliffmerge/xliff-merge.spec.ts +++ b/src/xliffmerge/xliff-merge.spec.ts @@ -354,6 +354,39 @@ describe('XliffMerge test spec', () => { done(); }); + it('should generate translated file for all languages with empty targets for non default languages', (done) => { + FileUtil.copy(MASTER1SRC, MASTER); + let ws: WriterToString = new WriterToString(); + let commandOut = new CommandOutput(ws); + let profileContent: IConfigFile = { + xliffmergeOptions: { + defaultLanguage: 'de', + srcDir: WORKDIR, + genDir: WORKDIR, + i18nFile: MASTERFILE, + useSourceAsTarget: false + } + }; + let xliffMergeCmd = XliffMerge.createFromOptions(commandOut, {languages: ['de', 'en']}, profileContent); + xliffMergeCmd.run(); + expect(ws.writtenData()).not.toContain('ERROR'); + let langFileGerman: ITranslationMessagesFile = readXliff(xliffMergeCmd.generatedI18nFile('de')); + expect(langFileGerman.sourceLanguage()).toBe('de'); + expect(langFileGerman.targetLanguage()).toBe('de'); + langFileGerman.forEachTransUnit((tu: ITransUnit) => { + expect(tu.targetContent()).toBe(tu.sourceContent()); + expect(tu.targetState()).toBe('final'); + }); + let langFileEnglish: ITranslationMessagesFile = readXliff(xliffMergeCmd.generatedI18nFile('en')); + expect(langFileEnglish.sourceLanguage()).toBe('de'); + expect(langFileEnglish.targetLanguage()).toBe('en'); + langFileEnglish.forEachTransUnit((tu: ITransUnit) => { + expect(tu.targetContent()).toBe(''); + expect(tu.targetState()).toBe('new'); + }); + done(); + }); + it('should merge translated file for all languages', (done) => { FileUtil.copy(MASTER1SRC, MASTER); let ws: WriterToString = new WriterToString(); @@ -422,7 +455,7 @@ describe('XliffMerge test spec', () => { // look, that the new file contains the translation langFileEnglish = readXliff(xliffMergeCmd.generatedI18nFile('en')); - expect(langFileEnglish.transUnitWithId(ID_WITH_PLACEHOLDER).targetContent()).toBe('Item