Skip to content

Commit

Permalink
fix(compiler): add location note to extracted xliff2 files
Browse files Browse the repository at this point in the history
When we added the xliff2 serializer, we forgot to add the source location at the same time because both PR were merged at about the same time.
This PR adds a note with the location of source files to the xliff2 units of extracted files.
There is no clear definition of where to store the location of the source files in the official XLIFF 2.0 specification (http://docs.oasis-open.org/xliff/xliff-core/v2.0/os/xliff-core-v2.0-os.html) so we decided to add it to the notes section, since it was simple to implement/understand and already present for meaning/description.
The location note is defined like this: `<note category="location">path/to/file.ts:1,2</note>`. It gives the path, followed by start line, and last line if different from the start line.

Fixes  angular#16531
  • Loading branch information
ocombe committed May 17, 2017
1 parent 238c523 commit 4c29acb
Show file tree
Hide file tree
Showing 4 changed files with 111 additions and 10 deletions.
8 changes: 8 additions & 0 deletions packages/compiler-cli/integrationtest/test/i18n_spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,17 +88,25 @@ const EXPECTED_XLIFF2 = `<?xml version="1.0" encoding="UTF-8" ?>
<notes>
<note category="description">desc</note>
<note category="meaning">meaning</note>
<note category="location">src/basic.ts:1</note>
</notes>
<segment>
<source>translate me</source>
</segment>
</unit>
<unit id="3492007542396725315">
<notes>
<note category="location">src/basic.ts:5</note>
<note category="location">src/entry_components.ts:1</note>
</notes>
<segment>
<source>Welcome</source>
</segment>
</unit>
<unit id="126808141597411718">
<notes>
<note category="location">node_modules/third_party/other_comp.d.ts:1,2</note>
</notes>
<segment>
<source>other-3rdP-component
multi-lines</source>
Expand Down
17 changes: 12 additions & 5 deletions packages/compiler/src/i18n/serializers/xliff2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,9 @@ export class Xliff2 extends Serializer {

messages.forEach(message => {
const unit = new xml.Tag(_UNIT_TAG, {id: message.id});
const notes = new xml.Tag('notes');

if (message.description || message.meaning) {
const notes = new xml.Tag('notes');
if (message.description) {
notes.children.push(
new xml.CR(8),
Expand All @@ -49,11 +49,18 @@ export class Xliff2 extends Serializer {
new xml.CR(8),
new xml.Tag('note', {category: 'meaning'}, [new xml.Text(message.meaning)]));
}

notes.children.push(new xml.CR(6));
unit.children.push(new xml.CR(6), notes);
}

message.sources.forEach((source: i18n.MessageSpan) => {
notes.children.push(new xml.CR(8), new xml.Tag('note', {category: 'location'}, [
new xml.Text(
`${source.filePath}:${source.startLine}${source.endLine !== source.startLine ? ',' + source.endLine : ''}`)
]));
});

notes.children.push(new xml.CR(6));
unit.children.push(new xml.CR(6), notes);

const segment = new xml.Tag('segment');

segment.children.push(
Expand Down Expand Up @@ -367,4 +374,4 @@ function getTypeForTag(tag: string): string {
default:
return 'other';
}
}
}
70 changes: 66 additions & 4 deletions packages/compiler/test/i18n/serializers/xliff2_spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,22 +24,33 @@ const HTML = `
<p i18n="empty element">hello <span></span></p>
<p i18n="@@baz">{ count, plural, =0 { { sex, select, other {<p>deeply nested</p>}} }}</p>
<p i18n>{ count, plural, =0 { { sex, select, other {<p>deeply nested</p>}} }}</p>
<p i18n>multi
lines</p>
`;

const WRITE_XLIFF = `<?xml version="1.0" encoding="UTF-8" ?>
<xliff version="2.0" xmlns="urn:oasis:names:tc:xliff:document:2.0" srcLang="en">
<file original="ng.template" id="ngi18n">
<unit id="1933478729560469763">
<notes>
<note category="location">file.ts:2</note>
</notes>
<segment>
<source>translatable attribute</source>
</segment>
</unit>
<unit id="7056919470098446707">
<notes>
<note category="location">file.ts:3</note>
</notes>
<segment>
<source>translatable element <pc id="0" equivStart="START_BOLD_TEXT" equivEnd="CLOSE_BOLD_TEXT" type="fmt" dispStart="&lt;b&gt;" dispEnd="&lt;/b&gt;">with placeholders</pc> <ph id="1" equiv="INTERPOLATION" disp="{{ interpolation}}"/></source>
</segment>
</unit>
<unit id="2981514368455622387">
<notes>
<note category="location">file.ts:4</note>
</notes>
<segment>
<source>{VAR_PLURAL, plural, =0 {<pc id="0" equivStart="START_PARAGRAPH" equivEnd="CLOSE_PARAGRAPH" type="other" dispStart="&lt;p&gt;" dispEnd="&lt;/p&gt;">test</pc>} }</source>
</segment>
Expand All @@ -48,6 +59,7 @@ const WRITE_XLIFF = `<?xml version="1.0" encoding="UTF-8" ?>
<notes>
<note category="description">d</note>
<note category="meaning">m</note>
<note category="location">file.ts:5</note>
</notes>
<segment>
<source>foo</source>
Expand All @@ -56,6 +68,7 @@ const WRITE_XLIFF = `<?xml version="1.0" encoding="UTF-8" ?>
<unit id="6440235004920703622">
<notes>
<note category="description">nested</note>
<note category="location">file.ts:6</note>
</notes>
<segment>
<source><pc id="0" equivStart="START_BOLD_TEXT" equivEnd="CLOSE_BOLD_TEXT" type="fmt" dispStart="&lt;b&gt;" dispEnd="&lt;/b&gt;"><pc id="1" equivStart="START_UNDERLINED_TEXT" equivEnd="CLOSE_UNDERLINED_TEXT" type="fmt" dispStart="&lt;u&gt;" dispEnd="&lt;/u&gt;"><ph id="2" equiv="INTERPOLATION" disp="{{interpolation}}"/> Text</pc></pc></source>
Expand All @@ -64,6 +77,7 @@ const WRITE_XLIFF = `<?xml version="1.0" encoding="UTF-8" ?>
<unit id="8779402634269838862">
<notes>
<note category="description">ph names</note>
<note category="location">file.ts:7</note>
</notes>
<segment>
<source><ph id="0" equiv="LINE_BREAK" type="fmt" disp="&lt;br/&gt;"/><ph id="1" equiv="TAG_IMG" type="image" disp="&lt;img/&gt;"/><ph id="2" equiv="TAG_IMG_1" type="image" disp="&lt;img/&gt;"/></source>
Expand All @@ -72,21 +86,37 @@ const WRITE_XLIFF = `<?xml version="1.0" encoding="UTF-8" ?>
<unit id="6536355551500405293">
<notes>
<note category="description">empty element</note>
<note category="location">file.ts:8</note>
</notes>
<segment>
<source>hello <pc id="0" equivStart="START_TAG_SPAN" equivEnd="CLOSE_TAG_SPAN" type="other" dispStart="&lt;span&gt;" dispEnd="&lt;/span&gt;"></pc></source>
</segment>
</unit>
<unit id="baz">
<notes>
<note category="location">file.ts:9</note>
</notes>
<segment>
<source>{VAR_PLURAL, plural, =0 {{VAR_SELECT, select, other {<pc id="0" equivStart="START_PARAGRAPH" equivEnd="CLOSE_PARAGRAPH" type="other" dispStart="&lt;p&gt;" dispEnd="&lt;/p&gt;">deeply nested</pc>} } } }</source>
</segment>
</unit>
<unit id="2015957479576096115">
<notes>
<note category="location">file.ts:10</note>
</notes>
<segment>
<source>{VAR_PLURAL, plural, =0 {{VAR_SELECT, select, other {<pc id="0" equivStart="START_PARAGRAPH" equivEnd="CLOSE_PARAGRAPH" type="other" dispStart="&lt;p&gt;" dispEnd="&lt;/p&gt;">deeply nested</pc>} } } }</source>
</segment>
</unit>
<unit id="2340165783990709777">
<notes>
<note category="location">file.ts:11,12</note>
</notes>
<segment>
<source>multi
lines</source>
</segment>
</unit>
</file>
</xliff>
`;
Expand All @@ -95,18 +125,27 @@ const LOAD_XLIFF = `<?xml version="1.0" encoding="UTF-8" ?>
<xliff version="2.0" xmlns="urn:oasis:names:tc:xliff:document:2.0" srcLang="en" trgLang="fr">
<file original="ng.template" id="ngi18n">
<unit id="1933478729560469763">
<notes>
<note category="location">file.ts:2</note>
</notes>
<segment>
<source>translatable attribute</source>
<target>etubirtta elbatalsnart</target>
</segment>
</unit>
<unit id="7056919470098446707">
<notes>
<note category="location">file.ts:3</note>
</notes>
<segment>
<source>translatable element <pc id="0" equivStart="START_BOLD_TEXT" equivEnd="CLOSE_BOLD_TEXT" type="fmt" dispStart="&lt;b&gt;" dispEnd="&lt;/b&gt;">with placeholders</pc> <ph id="1" equiv="INTERPOLATION" disp="{{ interpolation}}"/></source>
<target><ph id="1" equiv="INTERPOLATION" disp="{{ interpolation}}"/> <pc id="0" equivStart="START_BOLD_TEXT" equivEnd="CLOSE_BOLD_TEXT" type="fmt" dispStart="&lt;b&gt;" dispEnd="&lt;/b&gt;">sredlohecalp htiw</pc> tnemele elbatalsnart</target>
</segment>
</unit>
<unit id="2981514368455622387">
<notes>
<note category="location">file.ts:4</note>
</notes>
<segment>
<source>{VAR_PLURAL, plural, =0 {<pc id="0" equivStart="START_PARAGRAPH" equivEnd="CLOSE_PARAGRAPH" type="other" dispStart="&lt;p&gt;" dispEnd="&lt;/p&gt;">test</pc>} }</source>
<target>{VAR_PLURAL, plural, =0 {<pc id="0" equivStart="START_PARAGRAPH" equivEnd="CLOSE_PARAGRAPH" type="other" dispStart="&lt;p&gt;" dispEnd="&lt;/p&gt;">TEST</pc>} }</target>
Expand All @@ -116,6 +155,7 @@ const LOAD_XLIFF = `<?xml version="1.0" encoding="UTF-8" ?>
<notes>
<note category="description">d</note>
<note category="meaning">m</note>
<note category="location">file.ts:5</note>
</notes>
<segment>
<source>foo</source>
Expand All @@ -125,6 +165,7 @@ const LOAD_XLIFF = `<?xml version="1.0" encoding="UTF-8" ?>
<unit id="6440235004920703622">
<notes>
<note category="description">nested</note>
<note category="location">file.ts:6</note>
</notes>
<segment>
<source><pc id="0" equivStart="START_BOLD_TEXT" equivEnd="CLOSE_BOLD_TEXT" type="fmt" dispStart="&lt;b&gt;" dispEnd="&lt;/b&gt;"><pc id="1" equivStart="START_UNDERLINED_TEXT" equivEnd="CLOSE_UNDERLINED_TEXT" type="fmt" dispStart="&lt;u&gt;" dispEnd="&lt;/u&gt;"><ph id="2" equiv="INTERPOLATION" disp="{{interpolation}}"/> Text</pc></pc></source>
Expand All @@ -134,6 +175,7 @@ const LOAD_XLIFF = `<?xml version="1.0" encoding="UTF-8" ?>
<unit id="8779402634269838862">
<notes>
<note category="description">ph names</note>
<note category="location">file.ts:7</note>
</notes>
<segment>
<source><ph id="0" equiv="LINE_BREAK" type="fmt" disp="&lt;br/&gt;"/><ph id="1" equiv="TAG_IMG" type="image" disp="&lt;img/&gt;"/><ph id="2" equiv="TAG_IMG_1" type="image" disp="&lt;img/&gt;"/></source>
Expand All @@ -143,24 +185,42 @@ const LOAD_XLIFF = `<?xml version="1.0" encoding="UTF-8" ?>
<unit id="6536355551500405293">
<notes>
<note category="description">empty element</note>
<note category="location">file.ts:8</note>
</notes>
<segment>
<source>hello <pc id="0" equivStart="START_TAG_SPAN" equivEnd="CLOSE_TAG_SPAN" type="other" dispStart="&lt;span&gt;" dispEnd="&lt;/span&gt;"></pc></source>
<target><pc id="0" equivStart="START_TAG_SPAN" equivEnd="CLOSE_TAG_SPAN" type="other" dispStart="&lt;span&gt;" dispEnd="&lt;/span&gt;"></pc> olleh</target>
</segment>
</unit>
<unit id="baz">
<notes>
<note category="location">file.ts:9</note>
</notes>
<segment>
<source>{VAR_PLURAL, plural, =0 {{VAR_SELECT, select, other {<pc id="0" equivStart="START_PARAGRAPH" equivEnd="CLOSE_PARAGRAPH" type="other" dispStart="&lt;p&gt;" dispEnd="&lt;/p&gt;">deeply nested</pc>} } } }</source>
<target>{VAR_PLURAL, plural, =0 {{VAR_SELECT, select, other {<pc id="0" equivStart="START_PARAGRAPH" equivEnd="CLOSE_PARAGRAPH" type="other" dispStart="&lt;p&gt;" dispEnd="&lt;/p&gt;">profondément imbriqué</pc>} } } }</target>
</segment>
</unit>
<unit id="2015957479576096115">
<notes>
<note category="location">file.ts:10</note>
</notes>
<segment>
<source>{VAR_PLURAL, plural, =0 {{VAR_SELECT, select, other {<pc id="0" equivStart="START_PARAGRAPH" equivEnd="CLOSE_PARAGRAPH" type="other" dispStart="&lt;p&gt;" dispEnd="&lt;/p&gt;">deeply nested</pc>} } } }</source>
<target>{VAR_PLURAL, plural, =0 {{VAR_SELECT, select, other {<pc id="0" equivStart="START_PARAGRAPH" equivEnd="CLOSE_PARAGRAPH" type="other" dispStart="&lt;p&gt;" dispEnd="&lt;/p&gt;">profondément imbriqué</pc>} } } }</target>
</segment>
</unit>
<unit id="2340165783990709777">
<notes>
<note category="location">file.ts:11,12</note>
</notes>
<segment>
<source>multi
lines</source>
<target>multi
lignes</target>
</segment>
</unit>
</file>
</xliff>
`;
Expand All @@ -170,7 +230,7 @@ export function main(): void {

function toXliff(html: string, locale: string | null = null): string {
const catalog = new MessageBundle(new HtmlParser, [], {}, locale);
catalog.updateFromTemplate(html, '', DEFAULT_INTERPOLATION_CONFIG);
catalog.updateFromTemplate(html, 'file.ts', DEFAULT_INTERPOLATION_CONFIG);
return catalog.write(serializer);
}

Expand Down Expand Up @@ -208,8 +268,10 @@ export function main(): void {
'6536355551500405293': '<ph name="START_TAG_SPAN"/><ph name="CLOSE_TAG_SPAN"/> olleh',
'baz':
'{VAR_PLURAL, plural, =0 {[{VAR_SELECT, select, other {[<ph name="START_PARAGRAPH"/>, profondément imbriqué, <ph name="CLOSE_PARAGRAPH"/>]}}, ]}}',
'2015957479576096115':
'{VAR_PLURAL, plural, =0 {[{VAR_SELECT, select, other {[<ph name="START_PARAGRAPH"/>, profondément imbriqué, <ph name="CLOSE_PARAGRAPH"/>]}}, ]}}'
'2015957479576096115': '{VAR_PLURAL, plural, =0 {[{VAR_SELECT, select, other {[<ph' +
' name="START_PARAGRAPH"/>, profondément imbriqué, <ph name="CLOSE_PARAGRAPH"/>]}}, ]}}',
'2340165783990709777': `multi
lignes`
});
});

Expand Down Expand Up @@ -333,4 +395,4 @@ export function main(): void {
});
});
});
}
}
26 changes: 25 additions & 1 deletion packages/compiler/test/i18n/serializers/xliff_spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ const HTML = `
<p i18n="ph names"><br><img><div></div></p>
<p i18n="@@baz">{ count, plural, =0 { { sex, select, other {<p>deeply nested</p>}} }}</p>
<p i18n>{ count, plural, =0 { { sex, select, other {<p>deeply nested</p>}} }}</p>
<p i18n>multi
lines</p>
`;

const WRITE_XLIFF = `<?xml version="1.0" encoding="UTF-8" ?>
Expand Down Expand Up @@ -112,6 +114,15 @@ const WRITE_XLIFF = `<?xml version="1.0" encoding="UTF-8" ?>
<context context-type="linenumber">11</context>
</context-group>
</trans-unit>
<trans-unit id="fcfa109b0e152d4c217dbc02530be0bcb8123ad1" datatype="html">
<source>multi
lines</source>
<target/>
<context-group purpose="location">
<context context-type="sourcefile">file.ts</context>
<context context-type="linenumber">12</context>
</context-group>
</trans-unit>
</body>
</file>
</xliff>
Expand Down Expand Up @@ -195,6 +206,16 @@ const LOAD_XLIFF = `<?xml version="1.0" encoding="UTF-8" ?>
<source>{VAR_PLURAL, plural, =0 {{VAR_SELECT, select, other {<x id="START_PARAGRAPH" ctype="x-p"/>deeply nested<x id="CLOSE_PARAGRAPH" ctype="x-p"/>} } } }</source>
<target>{VAR_PLURAL, plural, =0 {{VAR_SELECT, select, other {<x id="START_PARAGRAPH" ctype="x-p"/>profondément imbriqué<x id="CLOSE_PARAGRAPH" ctype="x-p"/>} } } }</target>
</trans-unit>
<trans-unit id="fcfa109b0e152d4c217dbc02530be0bcb8123ad1" datatype="html">
<source>multi
lines</source>
<target>multi
lignes</target>
<context-group purpose="location">
<context context-type="sourcefile">file.ts</context>
<context context-type="linenumber">12</context>
</context-group>
</trans-unit>
</body>
</file>
</xliff>
Expand Down Expand Up @@ -243,7 +264,10 @@ export function main(): void {
'baz':
'{VAR_PLURAL, plural, =0 {[{VAR_SELECT, select, other {[<ph name="START_PARAGRAPH"/>, profondément imbriqué, <ph name="CLOSE_PARAGRAPH"/>]}}, ]}}',
'0e16a673a5a7a135c9f7b957ec2c5c6f6ee6e2c4':
'{VAR_PLURAL, plural, =0 {[{VAR_SELECT, select, other {[<ph name="START_PARAGRAPH"/>, profondément imbriqué, <ph name="CLOSE_PARAGRAPH"/>]}}, ]}}'
'{VAR_PLURAL, plural, =0 {[{VAR_SELECT, select, other {[<ph' +
' name="START_PARAGRAPH"/>, profondément imbriqué, <ph name="CLOSE_PARAGRAPH"/>]}}, ]}}',
'fcfa109b0e152d4c217dbc02530be0bcb8123ad1': `multi
lignes`
});
});

Expand Down

0 comments on commit 4c29acb

Please sign in to comment.