Skip to content

extract-i18n with HTML entities and interpolation #41034

Closed

Description

@pKrupaJunior

🐞 Bug report

Command (mark with an x)

  • new
  • build
  • serve
  • test
  • e2e
  • generate
  • add
  • update
  • lint
  • extract-i18n
  • run
  • config
  • help
  • version
  • doc

Is this a regression?

Yes, I also tested this with the old extraction tool ("@angular/cli": "~9.1.15") and it works correctly with ng xi18n.

Description

Placing an HTML entity (e.g.  ) inside a translated text which also contains interpolated variables
(<div i18n>&nbsp;Interpolation: {{ variable }}</div>)
results in an incorrect value of the equiv-text attribute inside the extracted message's INTERPOLATION tag
(<x id="INTERPOLATION_1" equiv-text="ion: {{ v"/>).
Seems like the value is shifted by the difference in amount of characters taken up by the HTML entity and it's actual representation.

This is a minor and rather unimportant issue since it does not affect the actual interpolation or translation. From what I understand this equiv-text attribute has an informative role for translators.

🔬 Minimal Reproduction

https://github.com/pKrupaJunior/extract-i18n-issue

  1. Create project:
ng new extract-i18n-issue -s -t --minimal -g -S --style css --create-application false
  1. Create sample application:
ng g application demo -s -t --minimal --style css -S --routing false
  1. Add localization support:
ng add @angular/localize
  1. Add an HTML template containing i18n attribute on a tag with interpolated variables and HTML entities:
<div i18n>Interpolation: {{ one }}&nbsp;Interpolation: {{ two }}</div>
  1. Run extract-i18n:
ng extract-i18n --output-path projects/demo/src/i18n

🔥 Result

The generated messages.xlf file contains this:

<trans-unit id="4906579891802234912" datatype="html">
  <source>Interpolation: <x id="INTERPOLATION" equiv-text="{{ one }}"/> Interpolation: <x id="INTERPOLATION_1" equiv-text="ion: {{ t"/></source>
  ...
</trans-unit>

The second equiv-text attribute value is incorrect: <x id="INTERPOLATION_1" equiv-text="ion: {{ t"/>.
While it should be: <x id="INTERPOLATION_1" equiv-text="{{ two }}"/>.

🌍 Your Environment

Angular CLI: 11.1.4
Node: 12.13.0
OS: win32 x64

Angular: 11.1.2
... animations, common, compiler, compiler-cli, core, forms
... localize, platform-browser, platform-browser-dynamic, router
Ivy Workspace: Yes

Package                         Version
---------------------------------------------------------
@angular-devkit/architect       0.1101.4
@angular-devkit/build-angular   0.1101.4
@angular-devkit/core            11.1.4
@angular-devkit/schematics      11.1.4
@angular/cli                    11.1.4
@schematics/angular             11.1.4
@schematics/update              0.1101.4
rxjs                            6.6.6
typescript                      4.1.5

Activity

  1. added
    area: i18nIssues related to localization and internationalization
    on Feb 28, 2021
  2. added this to the needsTriage milestone on Feb 28, 2021
  3. added
    P4A relatively minor issue that is not relevant to core functions
    on Mar 1, 2021
  4. modified the milestones: needsTriage, Backlog on Mar 1, 2021
  5. petebacondarwin commented on May 4, 2021

    @petebacondarwin
    Contributor

    So the problem is that our lexer decodes such entities into their actual characters but the whole decoded text block is passed to the parser that then splits out the interpolation blocks. The parser then works with the characters in the text blocks, which have lost the original positions of the encoded characters...

    For example the tokens lexed fron the example given include:

    TAG_OPEN_START: 'div'
    ATTR_NAME: 'i18n'
    TAG_OPEN_END: 'div'
    TEXT: 'Interpolation: {{ one }} Interpolation: {{ two }}'
    TAG_CLOSE: 'div'
    

    Notice that the TEXT token holds both interpolations but the &nbsp; sequence has been decoded into a single NBSP character.

  6. petebacondarwin commented on May 4, 2021

    @petebacondarwin
    Contributor

    The only real solution is to actually capture these interpolations as tokens in their own right with their own source-spans, and then change the parsers to handle this.

  7. 13 remaining items

  8. added 2 commits that reference this issue on Aug 2, 2021
    11ef03b
    82ca69d
  9. angular-automatic-lock-bot commented on Sep 2, 2021

    @angular-automatic-lock-bot

    This issue has been automatically locked due to inactivity.
    Please file a new issue if you are encountering a similar or related problem.

    Read more about our automatic conversation locking policy.

    This action has been performed automatically by a bot.

  10. locked and limited conversation to collaborators on Sep 2, 2021
  11. added 2 commits that reference this issue on Sep 16, 2021
    feba4d2
    9c8a1f8
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

P4A relatively minor issue that is not relevant to core functionsarea: i18nIssues related to localization and internationalizationstate: has PR

Type

No type

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions