Skip to content

Commit

Permalink
Merge pull request #72 from rvanbekkum/develop
Browse files Browse the repository at this point in the history
Release 0.7.0
  • Loading branch information
rvanbekkum authored Feb 4, 2021
2 parents 567462a + bc3e143 commit 9d4e48f
Show file tree
Hide file tree
Showing 9 changed files with 149 additions and 51 deletions.
19 changes: 19 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,19 @@
# Changelog

## [0.7.0] 04-02-2021

* Activate extension when any of the extension's commands are invoked.
* New setting `xliffSync.matchingOriginalOnly` that can be used to specify whether to sync. only to files where the `original` attribute of the `file`-node of an XLIFF file matches that of the base file (**Default**: `true`). (GitHub issue [#51](https://github.com/rvanbekkum/vsc-xliff-sync/issues/51) + (GitHub issue [#66](https://github.com/rvanbekkum/vsc-xliff-sync/issues/66)))
* New setting `xliffSync.clearTranslationAfterSourceTextChange` that can be used to specify whether the translation for trans-units should be cleared during syncing if a change in the source text is detected (instead of marking it as needs-work) (**Default**: `false`). (GitHub issue [#64](https://github.com/rvanbekkum/vsc-xliff-sync/issues/64))
* Fix: Do not add state to (new) target nodes in XLIFF 2.0 files. (GitHub issue [#57](https://github.com/rvanbekkum/vsc-xliff-sync/issues/57))
* Added more details about files and workspace to error messages. (GitHub issue [#65](https://github.com/rvanbekkum/vsc-xliff-sync/issues/65))

### Thank You

* **[antpyykk](https://github.com/antpyykk)** for filing issue [#57](https://github.com/rvanbekkum/vsc-xliff-sync/issues/57).
* **[catadumitru](https://github.com/catadumitru)** for filing issue [#64](https://github.com/rvanbekkum/vsc-xliff-sync/issues/64).
* **[waldo1001](https://github.com/waldo1001)** for filing issues [#65](https://github.com/rvanbekkum/vsc-xliff-sync/issues/65) and [#66](https://github.com/rvanbekkum/vsc-xliff-sync/issues/66).

## [0.6.0] 26-11-2020

* New setting `xliffSync.addNeedsWorkTranslationNote` that can be used to change whether an "XLIFF Sync" note should be added to trans-units that are being marked as needs-work by the extension (which are added to explain what was detected) (**Default**: `true`).
Expand All @@ -9,6 +23,11 @@ You can set files to be opened externally automatically after:
* Detecting problems
* Synchronizing translation files

### Thank You

* **[IceOnly](https://github.com/IceOnly)** for filing issue [#54](https://github.com/rvanbekkum/vsc-xliff-sync/issues/54).
* **[htmnk](https://github.com/htmnk)** for filing issue [#56](https://github.com/rvanbekkum/vsc-xliff-sync/issues/56).

## [0.5.1] 03-09-2020

* Fix: Do not add `xliffSync.baseFile` setting if there is only a single matching file.
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ Apart from synchronizing trans-units from a base-XLIFF file, this extension cont
| xliffSync.baseFile | `.g.xlf` | Specifies which XLIFF file to use as the base (e.g., the generated XLIFF). If the file does not exist, you will be prompted to specify the file to use as base-XLIFF file the first time you use the Synchronize command. |
| xliffSync.fileType | `xlf` | The file type (`xlf` or `xlf2`). |
| xliffSync.syncCrossWorkspaceFolders | `false` | Specifies whether the extension will sync from a base file to the translation files in all workspace folders. By default, the extension will always sync. per workspace folder. If you enable this setting, then you can have the base file in one workspace folder and target translation files in other workspace folders. |
| xliffSync.matchingOriginalOnly | `true` | Specifies whether the extension will sync only to files where the original-attribute is matching. |
| xliffSync.missingTranslation | `%EMPTY%` | The placeholder for missing translations for trans-units that were synced/merged into target XLIFF files. You can use `%EMPTY%` if you want to use an empty string for missing translations. |
| xliffSync.needsWorkTranslationSubstate | `xliffSync:needsWork` | Specifies the substate to use for translations that need work in xlf2 files. **Tip**: If you use [Poedit](https://poedit.net/), then you could also set this to `poedit:fuzzy`. |
| xliffSync.findByXliffGeneratorNoteAndSource | `true` | Specifies whether or not the extension will try to find trans-units by XLIFF generator note and source. |
Expand All @@ -76,6 +77,7 @@ Apart from synchronizing trans-units from a base-XLIFF file, this extension cont
| xliffSync.copyFromSourceOverwrite | `false` | Specifies whether translations copied from the source text should overwrite existing translations. |
| xliffSync.detectSourceTextChanges | `true` | Specifies whether changes in the source text of a trans-unit should be detected. If a change is detected, the target state is changed to needs-adaptation and a note is added to indicate the translation should be reviewed. |
| xliffSync.ignoreLineEndingTypeChanges | `false` | Specifies whether changes in line ending type (CRLF vs. LF) should not be considered as changes to the source text of a trans-unit. |
| xliffSync.clearTranslationAfterSourceTextChange | `false` | Specifies whether translations should be cleared when the source text of a trans-unit changed. |
| xliffSync.addNeedsWorkTranslationNote | `true` | Specifies whether an XLIFF Sync note should be added to explain why a trans-unit was marked as needs-work. |
| xliffSync.openExternallyAfterEvent | `[]` | Specifies after which event translation files should be opened automatically with the default XLIFF editor. Options: "Check", "ProblemDetected", "Sync" |
| xliffSync.developerNoteDesignation | `Developer` | Specifies the name that is used to designate a developer note. |
Expand Down
24 changes: 21 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "xliff-sync",
"displayName": "XLIFF Sync",
"description": "A tool to keep XLIFF translation files in sync.",
"version": "0.6.0",
"version": "0.7.0",
"publisher": "rvanbekkum",
"repository": {
"type": "git",
Expand Down Expand Up @@ -32,10 +32,16 @@
],
"main": "./out/extension",
"activationEvents": [
"onCommand:xliffSync.checkForMissingTranslations",
"onCommand:xliffSync.checkForNeedWorkTranslations",
"onCommand:xliffSync.createNewTargetFiles",
"onCommand:xliffSync.findNextMissingTarget",
"onCommand:xliffSync.findNextNeedsWorkTarget",
"onCommand:xliffSync.importTranslationsFromFiles",
"onCommand:xliffSync.synchronizeFile",
"onCommand:xliffSync.synchronizeSources",
"workspaceContains:**/*.xlf",
"workspaceContains:**/*.xlf2",
"onCommand:xliffSync.findNextMissingTarget"
"workspaceContains:**/*.xlf2"
],
"contributes": {
"configuration": {
Expand Down Expand Up @@ -63,6 +69,12 @@
"description": "Specifies whether the extension will sync from a base file to the translation files in all workspace folders.",
"scope": "window"
},
"xliffSync.matchingOriginalOnly": {
"type": "boolean",
"default": true,
"description": "Specifies whether the extension will sync only to files where the original-attribute is matching.",
"scope": "resource"
},
"xliffSync.findByXliffGeneratorNoteAndSource": {
"type": "boolean",
"default": true,
Expand Down Expand Up @@ -145,6 +157,12 @@
"description": "Specifies whether changes in line ending type (CRLF vs. LF) should not be considered as changes to the source text of a trans-unit.",
"scope": "resource"
},
"xliffSync.clearTranslationAfterSourceTextChange": {
"type": "boolean",
"default": false,
"description": "Specifies whether translations should be cleared when the source text of a trans-unit changed.",
"scope": "resource"
},
"xliffSync.addNeedsWorkTranslationNote": {
"type": "boolean",
"default": true,
Expand Down
2 changes: 1 addition & 1 deletion src/features/tools/files-helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ export class FilesHelper {
}

if (!uris.length) {
throw new Error('No translation file found');
throw new Error(`No translation file found (Workspace: "${workspaceFolder?.name}").`);
}

return uris;
Expand Down
11 changes: 9 additions & 2 deletions src/features/tools/xlf-translator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ export class XlfTranslator {
const parseFromDeveloperNote: boolean = xliffWorkspaceConfiguration['parseFromDeveloperNote'];
const parseFromDeveloperNoteOverwrite: boolean = xliffWorkspaceConfiguration['parseFromDeveloperNoteOverwrite'];
const detectSourceTextChanges: boolean = xliffWorkspaceConfiguration['detectSourceTextChanges'];
const clearTranslationAfterSourceTextChange: boolean = xliffWorkspaceConfiguration['clearTranslationAfterSourceTextChange'];
const ignoreLineEndingTypeChanges: boolean = xliffWorkspaceConfiguration['ignoreLineEndingTypeChanges'];
const missingTranslationKeyword: string = xliffWorkspaceConfiguration['missingTranslation'];

Expand Down Expand Up @@ -160,8 +161,14 @@ export class XlfTranslator {
}

if (mergedSourceText !== origSourceText) {
mergedDocument.setXliffSyncNote(unit, 'Source text has changed. Please review the translation.');
mergedDocument.setState(unit, translationState.needsWorkTranslation);
if (clearTranslationAfterSourceTextChange) {
mergedDocument.clearUnitTranslation(unit);
mergedDocument.setState(unit, translationState.missingTranslation);
}
else {
mergedDocument.setXliffSyncNote(unit, 'Source text has changed. Please review the translation.');
mergedDocument.setState(unit, translationState.needsWorkTranslation);
}
}
}
}
Expand Down
50 changes: 43 additions & 7 deletions src/features/tools/xlf/xlf-document.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,16 @@ export class XlfDocument {
}
}

public get original(): string | undefined {
switch (this.version) {
case '1.2': case '2.0':
const fileNode = this.root && this.getNode('file', this.root);
return fileNode && fileNode.attributes && fileNode.attributes['original'];
default:
return undefined;
}
}

public get translationUnitNodes(): XmlNode[] {
if (!this.root) {
return [];
Expand Down Expand Up @@ -177,10 +187,25 @@ export class XlfDocument {
this.addNeedsWorkTranslationNote = xliffWorkspaceConfiguration['addNeedsWorkTranslationNote'];
}

public static async loadFromUri(sourceUri: Uri, resourceUri: Uri | undefined): Promise<XlfDocument> {
try {
const source: string = (await workspace.openTextDocument(sourceUri)).getText();
return await this.load(source, resourceUri);
}
catch (ex) {
throw new Error(`${ex.message}; File: ${sourceUri}`);
}
}

public static async load(source: string, resourceUri: Uri | undefined): Promise<XlfDocument> {
const doc = new XlfDocument(resourceUri);
doc.root = await new XmlParser().parseDocument(source);
return doc;
try {
const doc = new XlfDocument(resourceUri);
doc.root = await new XmlParser().parseDocument(source);
return doc;
}
catch (ex) {
throw new Error(`Failed to load XLIFF document, error: ${ex.message}`);
}
}

public static create(version: '1.2' | '2.0', language: string, resourceUri: Uri | undefined): XlfDocument {
Expand Down Expand Up @@ -452,12 +477,14 @@ export class XlfDocument {
const needsTranslation: boolean = this.getUnitNeedsTranslation(sourceUnit);
if (needsTranslation && !targetNode) {
let attributes: { [key: string]: string; } = {};
let newTranslationState: translationState = translationState.translated;
if (!translation) {
translation = this.missingTranslation;
this.updateStateAttributes(attributes, translationState.missingTranslation);
newTranslationState = translationState.missingTranslation;
}
else {
this.updateStateAttributes(attributes, translationState.translated);

if (this.version == '1.2') {
this.updateStateAttributes(attributes, newTranslationState);
}

targetNode = this.createTargetNode(sourceUnit, attributes, translation);
Expand All @@ -472,7 +499,10 @@ export class XlfDocument {
if (!targetNode.attributes) {
targetNode.attributes = {};
}
this.updateStateAttributes(targetNode.attributes, translationState.translated);

if (this.version == '1.2') {
this.updateStateAttributes(targetNode.attributes, translationState.translated);
}
}
this.appendTargetNode(sourceUnit, targetNode);
}
Expand Down Expand Up @@ -638,6 +668,12 @@ export class XlfDocument {
return this.getNode(stateNodeTag, unit);
}

public clearUnitTranslation(unit: XmlNode) {
const targetNode = this.getNode('target', unit);
if (targetNode) {
targetNode.children = [];
}
}

public setTargetAttribute(unit: XmlNode, attribute: string, attributeValue: string) {
let targetNode: XmlNode | undefined = this.getNode('target', unit);
Expand Down
10 changes: 2 additions & 8 deletions src/features/trans-check.ts
Original file line number Diff line number Diff line change
Expand Up @@ -321,17 +321,11 @@ export async function runTranslationChecksForWorkspaceFolder(shouldCheckForMissi
if (!targetUri) {
continue;
}
const target = targetUri
? (await workspace.openTextDocument(targetUri)).getText()
: undefined;
if (!target) {
continue;
}

let missingCount: number = 0;
let needWorkCount: number = 0;
let problemResolvedInFile: boolean = false;
const targetDocument = await XlfDocument.load(target, checkWorkspaceFolder?.uri);
const targetDocument = await XlfDocument.loadFromUri(targetUri, checkWorkspaceFolder?.uri);
sourceEqualsTargetExpected = targetDocument.sourceLanguage === targetDocument.targetLanguage;
if (targetDocument.targetLanguage) {
sourceEqualsTargetExpected = sourceEqualsTargetExpected || (copyFromSourceForLanguages.indexOf(targetDocument.targetLanguage) >= 0);
Expand Down Expand Up @@ -383,7 +377,7 @@ export async function runTranslationChecksForWorkspaceFolder(shouldCheckForMissi
const newFileContents = targetDocument.extract();

if (!newFileContents) {
throw new Error('No ouput generated');
throw new Error(`No ouput generated. File ${targetUri}`);
}

await FilesHelper.createNewTargetFile(targetUri, newFileContents);
Expand Down
13 changes: 3 additions & 10 deletions src/features/trans-import.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,7 @@ async function importTranslationsFromFile(workspaceFolder: WorkspaceFolder, file
}
const replaceTranslationsDuringImport: boolean = workspace.getConfiguration('xliffSync', workspaceFolder.uri)['replaceTranslationsDuringImport'];

const selFileContents = (await workspace.openTextDocument(fileUri)).getText();
const selFileDocument = await XlfDocument.load(selFileContents, workspaceFolder.uri);
const selFileDocument = await XlfDocument.loadFromUri(fileUri, workspaceFolder.uri);
let sourceDevNoteTranslations: { [key: string]: string | undefined; } = {};
selFileDocument.translationUnitNodes.forEach((unit) => {
const sourceDevNoteText = getSourceDevNoteText(selFileDocument, unit);
Expand All @@ -108,14 +107,8 @@ async function importTranslationsFromFile(workspaceFolder: WorkspaceFolder, file
if (!targetUri) {
continue;
}
const target = targetUri
? (await workspace.openTextDocument(targetUri)).getText()
: undefined;
if (!target) {
continue;
}

const targetDocument = await XlfDocument.load(target, workspaceFolder.uri);
const targetDocument = await XlfDocument.loadFromUri(targetUri, workspaceFolder.uri);
if (targetDocument.targetLanguage !== selFileDocument.targetLanguage) {
continue;
}
Expand Down Expand Up @@ -155,7 +148,7 @@ async function importTranslationsFromFile(workspaceFolder: WorkspaceFolder, file
const newFileContents = targetDocument.extract();

if (!newFileContents) {
throw new Error('No ouput generated');
throw new Error(`No ouput generated. File: ${targetUri}`);
}

await FilesHelper.createNewTargetFile(targetUri, newFileContents);
Expand Down
Loading

0 comments on commit 9d4e48f

Please sign in to comment.