diff --git a/src/builder.spec.ts b/src/builder.spec.ts index 8073f3b..5f18ccc 100644 --- a/src/builder.spec.ts +++ b/src/builder.spec.ts @@ -1041,6 +1041,47 @@ describe('Builder', () => { '' }); }); + test('extract-and-merge xlf 1.2 with ampersand in meaning', async () => { + await runTest( + { + messagesBefore: '\n' + + ' \n' + + ' \n' + + ' \n' + + ' source & val\n' + + ' description & and\n' + + ' meaning & and\n' + + ' \n' + + ' \n' + + ' \n' + + '', + messagesFrBefore: '\n' + + ' \n' + + ' \n' + + ' \n' + + ' \n' + + '', + options: { + format: 'xlf', + targetFiles: ['messages.fr.xlf'], + outputPath: 'builder-test', + includeContext: true, + removeIdsWithPrefix: ['removeMe'] + }, + messagesFrExpected: '\n' + + ' \n' + + ' \n' + + ' \n' + + ' source & val\n' + + ' source & val\n' + + ' description & and\n' + + ' meaning & and\n' + + ' \n' + + ' \n' + + ' \n' + + '' + }); + }); test('extract-and-merge xlf 1.2 with newTranslationTargetsBlank', async () => { await runTest( { diff --git a/src/model/translationFileSerialization.spec.ts b/src/model/translationFileSerialization.spec.ts index 60ef2dc..9174316 100644 --- a/src/model/translationFileSerialization.spec.ts +++ b/src/model/translationFileSerialization.spec.ts @@ -28,7 +28,7 @@ describe('translationFileSerialization', () => { target: 'target val', state: 'initial', meaning: 'greeting', - description: 'Greeting message that includes the user\'s name.', + description: 'Greeting message that includes the user's name.', locations: [ { file: 'app/app.component.ts', @@ -168,7 +168,7 @@ describe('translationFileSerialization', () => { target: 'target val', state: 'initial', meaning: 'greeting', - description: 'Greeting message that includes the user\'s name.', + description: 'Greeting message that includes the user's name.', locations: [ { file: 'app/app.component.ts', diff --git a/src/model/translationFileSerialization.ts b/src/model/translationFileSerialization.ts index 4c3507d..274d19a 100644 --- a/src/model/translationFileSerialization.ts +++ b/src/model/translationFileSerialization.ts @@ -17,10 +17,10 @@ export function fromXlf2(xlf2: string): TranslationFile { return { id: unit.attr.id, source: toString(...segment.childNamed('source')!.children), - target: segment.childNamed('target') ? toString(...segment.childNamed('target')!.children) : undefined, + target: toStringOrUndefined(segment.childNamed('target')?.children), state: segment.attr.state, - meaning: notes?.childWithAttribute('category', 'meaning')?.val, - description: notes?.childWithAttribute('category', 'description')?.val, + meaning: toStringOrUndefined(notes?.childWithAttribute('category', 'meaning')?.children), + description: toStringOrUndefined(notes?.childWithAttribute('category', 'description')?.children), locations: notes?.children .filter((n): n is XmlElement => n.type === 'element' && n.attr.category === 'location') .map(note => { @@ -49,10 +49,10 @@ export function fromXlf1(xlf1: string): TranslationFile { return { id: unit.attr.id, source: toString(...unit.childNamed('source')!.children), - target: target ? toString(...target.children) : undefined, + target: toStringOrUndefined(target?.children), state: target?.attr.state, - meaning: notes?.find(note => note.attr.from === 'meaning')?.val, - description: notes?.find(note => note.attr.from === 'description')?.val, + meaning: toStringOrUndefined(notes?.find(note => note.attr.from === 'meaning')?.children), + description: toStringOrUndefined(notes?.find(note => note.attr.from === 'description')?.children), locations: unit.childrenNamed('context-group') .map(contextGroup => ({ file: contextGroup.childWithAttribute('context-type', 'sourcefile')!.val, @@ -67,6 +67,10 @@ function toString(...nodes: XmlNode[]): string { return nodes.map(n => n.toString({preserveWhitespace: true, compressed: true})).join(''); } +function toStringOrUndefined(nodes: XmlNode[] | undefined): string | undefined { + return nodes ? toString(...nodes) : undefined; +} + export function toXlf2(translationFile: TranslationFile, options: Pick): string { const doc = new XmlDocument(`