Tests about support of HTML tags in translations keys with GetText (#172)
- Verify that html tags are supported in translation keys - Add typed support of gettext-parser
This commit is contained in:
parent
73f39d625c
commit
71f4f42b33
@ -100,3 +100,7 @@ Examples:
|
|||||||
ngx-translate-extract -i './src/**/*.{ts,tsx,html}' -o strings.json Extract from ts, tsx and html
|
ngx-translate-extract -i './src/**/*.{ts,tsx,html}' -o strings.json Extract from ts, tsx and html
|
||||||
ngx-translate-extract -i './src/**/!(*.spec).{ts,html}' -o Extract from ts, html, excluding files with ".spec"
|
ngx-translate-extract -i './src/**/!(*.spec).{ts,html}' -o Extract from ts, html, excluding files with ".spec"
|
||||||
strings.json
|
strings.json
|
||||||
|
|
||||||
|
## Note for GetText users
|
||||||
|
|
||||||
|
Please pay attention of which version of `gettext-parser` you actually use in your project. For instance, `gettext-parser:1.2.2` does not support HTML tags in translation keys.
|
9
package-lock.json
generated
9
package-lock.json
generated
@ -136,6 +136,15 @@
|
|||||||
"integrity": "sha512-GcgAp7RXXGmA61spVEKZYpIy3/iV6GHbTW9f9kaKwHVQgnWitt6X026e+3N6j8ep1bkIWj83qPHQ3Y9Ft8FqiQ==",
|
"integrity": "sha512-GcgAp7RXXGmA61spVEKZYpIy3/iV6GHbTW9f9kaKwHVQgnWitt6X026e+3N6j8ep1bkIWj83qPHQ3Y9Ft8FqiQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"@types/gettext-parser": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/gettext-parser/-/gettext-parser-4.0.0.tgz",
|
||||||
|
"integrity": "sha512-I/wvhr+l5M7IwBF1ADBfNQ6qGfUg85UTjj/AZWn09Y+POqyLe1cfbdJSMWzCobiJ3EJNY23MQCbP6jxQT81OTQ==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"@types/node": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"@types/glob": {
|
"@types/glob": {
|
||||||
"version": "7.1.1",
|
"version": "7.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz",
|
||||||
|
@ -69,6 +69,7 @@
|
|||||||
"@types/mocha": "^7.0.2",
|
"@types/mocha": "^7.0.2",
|
||||||
"@types/node": "^12.12.31",
|
"@types/node": "^12.12.31",
|
||||||
"@types/yargs": "^15.0.4",
|
"@types/yargs": "^15.0.4",
|
||||||
|
"@types/gettext-parser": "4.0.0",
|
||||||
"braces": "^3.0.2",
|
"braces": "^3.0.2",
|
||||||
"chai": "^4.2.0",
|
"chai": "^4.2.0",
|
||||||
"husky": "^4.2.3",
|
"husky": "^4.2.3",
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { CompilerInterface } from './compiler.interface';
|
import { CompilerInterface } from './compiler.interface';
|
||||||
import { TranslationCollection, TranslationType } from '../utils/translation.collection';
|
import { TranslationCollection, TranslationType } from '../utils/translation.collection';
|
||||||
|
|
||||||
import * as gettext from 'gettext-parser';
|
import { po } from 'gettext-parser';
|
||||||
|
|
||||||
export class PoCompiler implements CompilerInterface {
|
export class PoCompiler implements CompilerInterface {
|
||||||
public extension: string = 'po';
|
public extension: string = 'po';
|
||||||
@ -34,23 +34,24 @@ export class PoCompiler implements CompilerInterface {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return gettext.po.compile(data);
|
return po.compile(data).toString('utf8');
|
||||||
}
|
}
|
||||||
|
|
||||||
public parse(contents: string): TranslationCollection {
|
public parse(contents: string): TranslationCollection {
|
||||||
const collection = new TranslationCollection();
|
const collection = new TranslationCollection();
|
||||||
|
|
||||||
const po = gettext.po.parse(contents, 'utf8');
|
const parsedPo = po.parse(contents, 'utf8');
|
||||||
if (!po.translations.hasOwnProperty(this.domain)) {
|
|
||||||
|
if (!parsedPo.translations.hasOwnProperty(this.domain)) {
|
||||||
return collection;
|
return collection;
|
||||||
}
|
}
|
||||||
|
|
||||||
const values = Object.keys(po.translations[this.domain])
|
const values = Object.keys(parsedPo.translations[this.domain])
|
||||||
.filter((key) => key.length > 0)
|
.filter((key) => key.length > 0)
|
||||||
.reduce((result, key) => {
|
.reduce((result, key) => {
|
||||||
return {
|
return {
|
||||||
...result,
|
...result,
|
||||||
[key]: po.translations[this.domain][key].msgstr.pop()
|
[key]: parsedPo.translations[this.domain][key].msgstr.pop()
|
||||||
};
|
};
|
||||||
}, {} as TranslationType);
|
}, {} as TranslationType);
|
||||||
|
|
||||||
|
1
src/declarations.d.ts
vendored
1
src/declarations.d.ts
vendored
@ -1 +0,0 @@
|
|||||||
declare module 'gettext-parser';
|
|
24
tests/compilers/po.compiler.spec.ts
Normal file
24
tests/compilers/po.compiler.spec.ts
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
import { expect } from 'chai';
|
||||||
|
|
||||||
|
import { TranslationCollection } from '../../src/utils/translation.collection';
|
||||||
|
import { PoCompiler } from '../../src/compilers/po.compiler';
|
||||||
|
|
||||||
|
describe('PoCompiler', () => {
|
||||||
|
let compiler: PoCompiler;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
compiler = new PoCompiler();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should still include html ', () => {
|
||||||
|
const collection = new TranslationCollection({
|
||||||
|
'A <strong>test</strong>': 'Un <strong>test</strong>',
|
||||||
|
'With a lot of <em>html</em> included': 'Avec beaucoup d\'<em>html</em> inclus'
|
||||||
|
});
|
||||||
|
const result: Buffer = Buffer.from(compiler.compile(collection));
|
||||||
|
expect(result.toString('utf8')).to.equal('msgid ""\nmsgstr ""\n"mime-version: 1.0\\n"\n"Content-Type: text/plain; charset=utf-8\\n"\n"Content-Transfer-Encoding: 8bit\\n"\n\nmsgid "A <strong>test</strong>"\nmsgstr "Un <strong>test</strong>"\n\nmsgid "With a lot of <em>html</em> included"\nmsgstr "Avec beaucoup d\'<em>html</em> inclus"');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -36,6 +36,12 @@ describe('DirectiveParser', () => {
|
|||||||
expect(keys).to.deep.equal(['Hello <strong translate>World</strong>']);
|
expect(keys).to.deep.equal(['Hello <strong translate>World</strong>']);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should not exclude html tags in children', () => {
|
||||||
|
const contents = `<div translate>Hello <strong>World</strong></div>`;
|
||||||
|
const keys = parser.extract(contents, templateFilename).keys();
|
||||||
|
expect(keys).to.deep.equal(['Hello <strong>World</strong>']);
|
||||||
|
});
|
||||||
|
|
||||||
it('should extract and parse inline template', () => {
|
it('should extract and parse inline template', () => {
|
||||||
const contents = `
|
const contents = `
|
||||||
@Component({
|
@Component({
|
||||||
|
@ -36,6 +36,17 @@ describe('MarkerParser', () => {
|
|||||||
expect(keys).to.deep.equal(['Hello world', 'This is a very very very very long line.', 'Mix of different types']);
|
expect(keys).to.deep.equal(['Hello world', 'This is a very very very very long line.', 'Mix of different types']);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should extract split strings while keeping html tags', () => {
|
||||||
|
const contents = `
|
||||||
|
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||||
|
_('Hello ' + 'world');
|
||||||
|
_('This <em>is</em> a ' + 'very ' + 'very ' + 'very ' + 'very ' + 'long line.');
|
||||||
|
_('Mix ' + \`of \` + 'different ' + \`types\`);
|
||||||
|
`;
|
||||||
|
const keys = parser.extract(contents, componentFilename).keys();
|
||||||
|
expect(keys).to.deep.equal(['Hello world', 'This <em>is</em> a very very very very long line.', 'Mix of different types']);
|
||||||
|
});
|
||||||
|
|
||||||
it('should extract the strings', () => {
|
it('should extract the strings', () => {
|
||||||
const contents = `
|
const contents = `
|
||||||
import { marker } from '@biesbjerg/ngx-translate-extract-marker';
|
import { marker } from '@biesbjerg/ngx-translate-extract-marker';
|
||||||
|
Loading…
Reference in New Issue
Block a user