hybridtm 0.8.0 → 0.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. package/README.md +7 -5
  2. package/dist/backupHandler.d.ts +1 -1
  3. package/dist/backupHandler.js +1 -1
  4. package/dist/backupReader.d.ts +1 -1
  5. package/dist/backupReader.js +1 -1
  6. package/dist/batchImporter.d.ts +1 -1
  7. package/dist/batchImporter.js +1 -1
  8. package/dist/cli/backupCommand.d.ts +5 -3
  9. package/dist/cli/backupCommand.js +33 -31
  10. package/dist/cli/backupCommand.js.map +1 -1
  11. package/dist/cli/cliUtils.d.ts +2 -1
  12. package/dist/cli/cliUtils.js +13 -1
  13. package/dist/cli/cliUtils.js.map +1 -1
  14. package/dist/cli/createCommand.d.ts +5 -3
  15. package/dist/cli/createCommand.js +33 -31
  16. package/dist/cli/createCommand.js.map +1 -1
  17. package/dist/cli/hybridtmCli.d.ts +1 -1
  18. package/dist/cli/hybridtmCli.js +24 -14
  19. package/dist/cli/hybridtmCli.js.map +1 -1
  20. package/dist/cli/importCommand.d.ts +11 -3
  21. package/dist/cli/importCommand.js +75 -76
  22. package/dist/cli/importCommand.js.map +1 -1
  23. package/dist/cli/matchCommand.d.ts +17 -3
  24. package/dist/cli/matchCommand.js +88 -234
  25. package/dist/cli/matchCommand.js.map +1 -1
  26. package/dist/cli/registryCommands.d.ts +8 -5
  27. package/dist/cli/registryCommands.js +63 -61
  28. package/dist/cli/registryCommands.js.map +1 -1
  29. package/dist/cli/restoreCommand.d.ts +8 -3
  30. package/dist/cli/restoreCommand.js +80 -78
  31. package/dist/cli/restoreCommand.js.map +1 -1
  32. package/dist/cli/serveCommand.d.ts +17 -0
  33. package/dist/cli/serveCommand.js +87 -0
  34. package/dist/cli/serveCommand.js.map +1 -0
  35. package/dist/cli/stopCommand.d.ts +15 -0
  36. package/dist/cli/stopCommand.js +73 -0
  37. package/dist/cli/stopCommand.js.map +1 -0
  38. package/dist/hybridtm.d.ts +3 -1
  39. package/dist/hybridtm.js +62 -27
  40. package/dist/hybridtm.js.map +1 -1
  41. package/dist/hybridtmFactory.d.ts +1 -1
  42. package/dist/hybridtmFactory.js +6 -1
  43. package/dist/hybridtmFactory.js.map +1 -1
  44. package/dist/importOptions.d.ts +5 -4
  45. package/dist/importOptions.js +11 -10
  46. package/dist/importOptions.js.map +1 -1
  47. package/dist/index.d.ts +2 -1
  48. package/dist/index.js +2 -1
  49. package/dist/index.js.map +1 -1
  50. package/dist/langEntry.d.ts +1 -1
  51. package/dist/langEntry.js +1 -1
  52. package/dist/match.d.ts +1 -1
  53. package/dist/match.js +1 -1
  54. package/dist/matchQuality.d.ts +1 -1
  55. package/dist/matchQuality.js +1 -1
  56. package/dist/pendingEntry.d.ts +1 -1
  57. package/dist/pendingEntry.js +1 -1
  58. package/dist/searchFilters.d.ts +1 -1
  59. package/dist/searchFilters.js +1 -1
  60. package/dist/server/hybridtmServer.d.ts +40 -0
  61. package/dist/server/hybridtmServer.js +527 -0
  62. package/dist/server/hybridtmServer.js.map +1 -0
  63. package/dist/server/hybridtmServerMain.d.ts +12 -0
  64. package/dist/server/hybridtmServerMain.js +18 -0
  65. package/dist/server/hybridtmServerMain.js.map +1 -0
  66. package/dist/tmxHandler.d.ts +1 -1
  67. package/dist/tmxHandler.js +5 -5
  68. package/dist/tmxHandler.js.map +1 -1
  69. package/dist/tmxReader.d.ts +1 -1
  70. package/dist/tmxReader.js +4 -4
  71. package/dist/tmxReader.js.map +1 -1
  72. package/dist/utils.d.ts +26 -2
  73. package/dist/utils.js +153 -2
  74. package/dist/utils.js.map +1 -1
  75. package/dist/xliffHandler.d.ts +1 -1
  76. package/dist/xliffHandler.js +8 -8
  77. package/dist/xliffHandler.js.map +1 -1
  78. package/dist/xliffReader.d.ts +1 -1
  79. package/dist/xliffReader.js +4 -4
  80. package/dist/xliffReader.js.map +1 -1
  81. package/package.json +1 -1
@@ -2,7 +2,7 @@
2
2
  * Copyright (c) 2025-2026 Maxprograms.
3
3
  *
4
4
  * This program and the accompanying materials
5
- * are made available under the terms of the Eclipse License 1.0
5
+ * are made available under the terms of the Eclipse Public License v1.0
6
6
  * which accompanies this distribution, and is available at
7
7
  * https://www.eclipse.org/org/documents/epl-v10.html
8
8
  *
@@ -12,92 +12,91 @@
12
12
  import { extname } from "node:path";
13
13
  import { HybridTMFactory } from '../index.js';
14
14
  import { CliUtils } from './cliUtils.js';
15
- export function usage() {
16
- console.log('Usage: hybridtm import -name <name> -file <path> [-type xliff|tmx|sdltm]');
17
- console.log(' [-minState initial|translated|reviewed|final]');
18
- console.log(' [-keepEmpty] [-noMetadata]');
19
- console.log();
20
- console.log(' -name Instance to import into (required)');
21
- console.log(' -file File to import (required)');
22
- console.log(' -type Import format; inferred from the file extension when omitted');
23
- console.log(' -minState Minimum segment state to import (default: translated)');
24
- console.log(' -keepEmpty Import segments with an empty target (default: skipped)');
25
- console.log(' -noMetadata Skip extracting notes/metadata/extension attributes');
26
- }
27
- export async function runImportCommand(args) {
28
- if (CliUtils.hasFlag(args, '-help')) {
29
- usage();
30
- return;
31
- }
32
- const name = CliUtils.getFlag(args, '-name');
33
- const rawFile = CliUtils.getFlag(args, '-file');
34
- if (!name || !rawFile) {
35
- usage();
36
- CliUtils.fail('Missing required -name or -file.');
15
+ export class ImportCommand {
16
+ static usage() {
17
+ console.log('Usage: hybridtm import -name <name> -file <path> [-type xliff|tmx|sdltm]');
18
+ console.log(' [-minState initial|translated|reviewed|final]');
19
+ console.log(' [-noMetadata]');
20
+ console.log();
21
+ console.log(' -name Instance to import into (required)');
22
+ console.log(' -file File to import (required)');
23
+ console.log(' -type Import format; inferred from the file extension when omitted');
24
+ console.log(' -minState Minimum segment state to import (default: translated)');
25
+ console.log(' -noMetadata Skip extracting notes/metadata/extension attributes');
37
26
  }
38
- const filePath = CliUtils.requireExistingFile(rawFile, 'Import file');
39
- const type = resolveImportType(CliUtils.getFlag(args, '-type'), filePath);
40
- const options = buildImportOptions(args);
41
- const tm = HybridTMFactory.getInstance(name);
42
- if (!tm) {
43
- CliUtils.fail('No instance named "' + name + '". Run "hybridtm create" or "hybridtm list" first.');
27
+ static async run(args) {
28
+ if (CliUtils.hasFlag(args, '-help')) {
29
+ ImportCommand.usage();
30
+ return;
31
+ }
32
+ const name = CliUtils.getFlag(args, '-name');
33
+ const rawFile = CliUtils.getFlag(args, '-file');
34
+ if (!name || !rawFile) {
35
+ ImportCommand.usage();
36
+ CliUtils.fail('Missing required -name or -file.');
37
+ }
38
+ const filePath = CliUtils.requireExistingFile(rawFile, 'Import file');
39
+ const options = ImportCommand.buildImportOptions(args);
40
+ const tm = HybridTMFactory.getInstance(name);
41
+ if (!tm) {
42
+ CliUtils.fail('No instance named "' + name + '". Run "hybridtm create" or "hybridtm list" first.');
43
+ }
44
+ try {
45
+ const type = ImportCommand.resolveImportType(CliUtils.getFlag(args, '-type'), filePath);
46
+ const count = await ImportCommand.importFile(tm, filePath, type, options);
47
+ console.log('Imported ' + count + ' entries from ' + filePath + ' into "' + name + '".');
48
+ }
49
+ catch (error) {
50
+ CliUtils.fail(error instanceof Error ? error.message : String(error));
51
+ }
52
+ finally {
53
+ await tm.close();
54
+ }
44
55
  }
45
- try {
46
- let count;
56
+ static async importFile(tm, filePath, type, options) {
47
57
  switch (type) {
48
58
  case 'xliff':
49
- count = await tm.importXLIFF(filePath, options);
50
- break;
59
+ return await tm.importXLIFF(filePath, options);
51
60
  case 'tmx':
52
- count = await tm.importTMX(filePath, options);
53
- break;
61
+ return await tm.importTMX(filePath, options);
54
62
  case 'sdltm':
55
- count = await tm.importSDLTM(filePath, options);
56
- break;
63
+ return await tm.importSDLTM(filePath, options);
57
64
  }
58
- console.log('Imported ' + count + ' entries from ' + filePath + ' into "' + name + '".');
59
- }
60
- catch (error) {
61
- CliUtils.fail(error instanceof Error ? error.message : String(error));
62
65
  }
63
- finally {
64
- await tm.close();
65
- }
66
- }
67
- function resolveImportType(explicit, filePath) {
68
- if (explicit === 'xliff' || explicit === 'tmx' || explicit === 'sdltm') {
69
- return explicit;
70
- }
71
- if (explicit !== undefined) {
72
- CliUtils.fail('Unknown -type value "' + explicit + '". Expected xliff, tmx, or sdltm.');
73
- }
74
- const ext = extname(filePath).toLowerCase();
75
- if (ext === '.xlf' || ext === '.xliff') {
76
- return 'xliff';
77
- }
78
- if (ext === '.tmx') {
79
- return 'tmx';
66
+ static resolveImportType(explicit, filePath) {
67
+ if (explicit === 'xliff' || explicit === 'tmx' || explicit === 'sdltm') {
68
+ return explicit;
69
+ }
70
+ if (explicit !== undefined) {
71
+ throw new Error('Unknown import type "' + explicit + '". Expected xliff, tmx, or sdltm.');
72
+ }
73
+ const ext = extname(filePath).toLowerCase();
74
+ if (ext === '.xlf' || ext === '.xliff') {
75
+ return 'xliff';
76
+ }
77
+ if (ext === '.tmx') {
78
+ return 'tmx';
79
+ }
80
+ if (ext === '.sdltm') {
81
+ return 'sdltm';
82
+ }
83
+ throw new Error('Could not infer import type from "' + filePath + '". Pass an explicit type.');
80
84
  }
81
- if (ext === '.sdltm') {
82
- return 'sdltm';
85
+ static isTranslationState(value) {
86
+ return value === 'initial' || value === 'translated' || value === 'reviewed' || value === 'final';
83
87
  }
84
- CliUtils.fail('Could not infer import type from "' + filePath + '". Pass -type explicitly.');
85
- }
86
- function buildImportOptions(args) {
87
- const options = {
88
- skipEmpty: !CliUtils.hasFlag(args, '-keepEmpty'),
89
- extractMetadata: !CliUtils.hasFlag(args, '-noMetadata')
90
- };
91
- const minState = CliUtils.getFlag(args, '-minState');
92
- if (minState !== undefined) {
93
- if (!isTranslationState(minState)) {
94
- CliUtils.fail('Unknown -minState value "' + minState + '". Expected initial, translated, reviewed, or final.');
88
+ static buildImportOptions(args) {
89
+ const options = {
90
+ extractMetadata: !CliUtils.hasFlag(args, '-noMetadata')
91
+ };
92
+ const minState = CliUtils.getFlag(args, '-minState');
93
+ if (minState !== undefined) {
94
+ if (!ImportCommand.isTranslationState(minState)) {
95
+ CliUtils.fail('Unknown -minState value "' + minState + '". Expected initial, translated, reviewed, or final.');
96
+ }
97
+ options.minState = minState;
95
98
  }
96
- options.minState = minState;
99
+ return options;
97
100
  }
98
- return options;
99
- }
100
- function isTranslationState(value) {
101
- return value === 'initial' || value === 'translated' || value === 'reviewed' || value === 'final';
102
101
  }
103
102
  //# sourceMappingURL=importCommand.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"importCommand.js","sourceRoot":"","sources":["../../ts/cli/importCommand.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"importCommand.js","sourceRoot":"","sources":["../../ts/cli/importCommand.ts"],"names":[],"mappings":"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"}
@@ -2,12 +2,26 @@
2
2
  * Copyright (c) 2025-2026 Maxprograms.
3
3
  *
4
4
  * This program and the accompanying materials
5
- * are made available under the terms of the Eclipse License 1.0
5
+ * are made available under the terms of the Eclipse Public License v1.0
6
6
  * which accompanies this distribution, and is available at
7
7
  * https://www.eclipse.org/org/documents/epl-v10.html
8
8
  *
9
9
  * Contributors:
10
10
  * Maxprograms - initial API and implementation
11
11
  *******************************************************************************/
12
- export declare function usage(): void;
13
- export declare function runMatchCommand(args: string[]): Promise<void>;
12
+ import { HybridTM } from '../index.js';
13
+ export interface MatchResult {
14
+ segmentsProcessed: number;
15
+ segmentsWithMatches: number;
16
+ totalMatches: number;
17
+ outputPath: string;
18
+ }
19
+ export declare class MatchCommand {
20
+ static usage(): void;
21
+ static run(args: string[]): Promise<void>;
22
+ static matchXliffFile(tm: HybridTM, filePath: string, outputPath: string, similarity: number, limit?: number): Promise<MatchResult>;
23
+ static resolveOutputPath(explicit: string | undefined, inputPath: string): string;
24
+ private static collectUnits;
25
+ private static declareMatchesNamespace;
26
+ private static parseIntOption;
27
+ }
@@ -2,7 +2,7 @@
2
2
  * Copyright (c) 2025-2026 Maxprograms.
3
3
  *
4
4
  * This program and the accompanying materials
5
- * are made available under the terms of the Eclipse License 1.0
5
+ * are made available under the terms of the Eclipse Public License v1.0
6
6
  * which accompanies this distribution, and is available at
7
7
  * https://www.eclipse.org/org/documents/epl-v10.html
8
8
  *
@@ -10,68 +10,75 @@
10
10
  * Maxprograms - initial API and implementation
11
11
  *******************************************************************************/
12
12
  import { basename, dirname, extname, join } from "node:path";
13
- import { XliffData, XliffGroup, XliffMatch, XliffMatches, XliffMrk, XliffOriginalData, XliffParser, XliffPc, XliffPh, XliffSegment, XliffSource, XliffTarget } from 'typesxliff';
14
- import { TextNode, XMLElement } from "typesxml";
13
+ import { XliffGroup, XliffMatches, XliffParser, XliffSegment } from 'typesxliff';
15
14
  import { HybridTMFactory, Utils } from '../index.js';
16
15
  import { CliUtils } from './cliUtils.js';
17
- const MATCHES_NAMESPACE = 'urn:oasis:names:tc:xliff:matches:2.0';
18
- const DEFAULT_PREFIX = 'mtc';
19
- const DEFAULT_LIMIT = 5;
20
- const DEFAULT_SIMILARITY = 60;
21
- const PLACEHOLDER_TAGS = new Set(['ph', 'bpt', 'ept', 'it', 'sc', 'ec', 'cp']);
22
- export function usage() {
23
- console.log('Usage: hybridtm match -name <name> -file <path> [-output <path>]');
24
- console.log(' [-limit N] [-similarity N] [-all]');
25
- console.log();
26
- console.log(' -name TM instance to search against (required)');
27
- console.log(' -file XLIFF file to enrich with match candidates (required)');
28
- console.log(' -output Output path (default: <file-without-ext>.matches.xlf)');
29
- console.log(' -limit Max candidates per segment (default: ' + DEFAULT_LIMIT + ')');
30
- console.log(' -similarity Minimum hybrid match score 0-100 (default: ' + DEFAULT_SIMILARITY + ')');
31
- console.log(' -all Consider every segment, not just untranslated ones');
32
- console.log();
33
- console.log('Never modifies <target>. Adds spec Translation Candidates module');
34
- console.log('(<mtc:matches>/<mtc:match>) entries and writes the result to a new file.');
35
- }
36
- export async function runMatchCommand(args) {
37
- if (CliUtils.hasFlag(args, '-help')) {
38
- usage();
39
- return;
40
- }
41
- const name = CliUtils.getFlag(args, '-name');
42
- const rawFile = CliUtils.getFlag(args, '-file');
43
- if (!name || !rawFile) {
44
- usage();
45
- CliUtils.fail('Missing required -name or -file.');
46
- }
47
- const filePath = CliUtils.requireExistingFile(rawFile, 'XLIFF file');
48
- const limit = parseIntOption(CliUtils.getFlag(args, '-limit'), DEFAULT_LIMIT, '-limit', 1);
49
- const similarity = parseIntOption(CliUtils.getFlag(args, '-similarity'), DEFAULT_SIMILARITY, '-similarity', 0, 100);
50
- const processAll = CliUtils.hasFlag(args, '-all');
51
- const outputPath = resolveOutputPath(CliUtils.getFlag(args, '-output'), filePath);
52
- const tm = HybridTMFactory.getInstance(name);
53
- if (!tm) {
54
- CliUtils.fail('No instance named "' + name + '". Run "hybridtm create" or "hybridtm list" first.');
16
+ export class MatchCommand {
17
+ static usage() {
18
+ console.log('Usage: hybridtm match -name <name> -file <path> -similarity N [-output <path>]');
19
+ console.log(' [-limit N]');
20
+ console.log();
21
+ console.log(' -name TM instance to search against (required)');
22
+ console.log(' -file XLIFF file to enrich with match candidates (required)');
23
+ console.log(' -similarity Minimum hybrid match score 0-100 (required)');
24
+ console.log(' -output Output path (default: <file-without-ext>.matches.xlf)');
25
+ console.log(' -limit Max candidates per segment (default: HybridTM.semanticTranslationSearch\'s own default)');
26
+ console.log();
27
+ }
28
+ static async run(args) {
29
+ if (CliUtils.hasFlag(args, '-help')) {
30
+ MatchCommand.usage();
31
+ return;
32
+ }
33
+ const name = CliUtils.getFlag(args, '-name');
34
+ const rawFile = CliUtils.getFlag(args, '-file');
35
+ const rawSimilarity = CliUtils.getFlag(args, '-similarity');
36
+ if (!name || !rawFile || !rawSimilarity) {
37
+ MatchCommand.usage();
38
+ CliUtils.fail('Missing required -name, -file, or -similarity.');
39
+ }
40
+ const filePath = CliUtils.requireExistingFile(rawFile, 'XLIFF file');
41
+ const rawLimit = CliUtils.getFlag(args, '-limit');
42
+ const limit = rawLimit !== undefined ? MatchCommand.parseIntOption(rawLimit, '-limit', 1) : undefined;
43
+ const similarity = MatchCommand.parseIntOption(rawSimilarity, '-similarity', 0, 100);
44
+ const outputPath = MatchCommand.resolveOutputPath(CliUtils.getFlag(args, '-output'), filePath);
45
+ const tm = HybridTMFactory.getInstance(name);
46
+ if (!tm) {
47
+ CliUtils.fail('No instance named "' + name + '". Run "hybridtm create" or "hybridtm list" first.');
48
+ }
49
+ try {
50
+ const result = await MatchCommand.matchXliffFile(tm, filePath, outputPath, similarity, limit);
51
+ console.log('Segments processed: ' + result.segmentsProcessed);
52
+ console.log('Segments with matches: ' + result.segmentsWithMatches);
53
+ console.log('Total match candidates: ' + result.totalMatches);
54
+ console.log('Output: ' + result.outputPath);
55
+ }
56
+ catch (error) {
57
+ CliUtils.fail(error instanceof Error ? error.message : String(error));
58
+ }
59
+ finally {
60
+ await tm.close();
61
+ }
55
62
  }
56
- try {
63
+ static async matchXliffFile(tm, filePath, outputPath, similarity, limit) {
57
64
  const parser = new XliffParser();
58
65
  parser.parseFile(filePath);
59
66
  const document = parser.getXliffDocument();
60
67
  if (!document) {
61
- CliUtils.fail('Unable to parse "' + filePath + '".');
68
+ throw new Error('Unable to parse "' + filePath + '".');
62
69
  }
63
70
  const rawSrcLang = document.getSrcLang();
64
71
  const srcLang = Utils.normalizeLanguage(rawSrcLang);
65
72
  if (!srcLang) {
66
- CliUtils.fail('"' + filePath + '" has an invalid @srcLang value "' + rawSrcLang + '".');
73
+ throw new Error('"' + filePath + '" has an invalid @srcLang value "' + rawSrcLang + '".');
67
74
  }
68
75
  const rawTgtLang = document.getTrgLang();
69
76
  if (!rawTgtLang) {
70
- CliUtils.fail('"' + filePath + '" is missing @trgLang; nothing to match against.');
77
+ throw new Error('"' + filePath + '" is missing @trgLang; nothing to match against.');
71
78
  }
72
79
  const tgtLang = Utils.normalizeLanguage(rawTgtLang);
73
80
  if (!tgtLang) {
74
- CliUtils.fail('"' + filePath + '" has an invalid @trgLang value "' + rawTgtLang + '".');
81
+ throw new Error('"' + filePath + '" has an invalid @trgLang value "' + rawTgtLang + '".');
75
82
  }
76
83
  let segmentsProcessed = 0;
77
84
  let segmentsWithMatches = 0;
@@ -79,7 +86,7 @@ export async function runMatchCommand(args) {
79
86
  let usedModule = false;
80
87
  for (const file of document.getFiles()) {
81
88
  const fileId = file.getId();
82
- for (const unit of collectUnits(file.getEntries())) {
89
+ for (const unit of MatchCommand.collectUnits(file.getEntries())) {
83
90
  const unitMatches = [];
84
91
  const unitId = unit.getId();
85
92
  // shared so <ph>/<data> ids stay unique across the whole unit
@@ -88,27 +95,27 @@ export async function runMatchCommand(args) {
88
95
  if (!(item instanceof XliffSegment)) {
89
96
  continue;
90
97
  }
91
- if (!processAll && !needsMatches(item)) {
98
+ if (item.getState() === 'final') {
92
99
  continue;
93
100
  }
94
101
  const source = item.getSource();
95
- const pureSource = source ? getPureText(source.getContent()) : '';
102
+ const pureSource = source ? Utils.getPureText(source.toElement()) : '';
96
103
  if (pureSource.trim().length === 0) {
97
104
  continue;
98
105
  }
99
106
  segmentsProcessed++;
100
- const results = dedupeMatches(await tm.semanticTranslationSearch(pureSource, srcLang, tgtLang, similarity, limit));
107
+ const results = Utils.dedupeMatches(await tm.semanticTranslationSearch(pureSource, srcLang, tgtLang, similarity, limit));
101
108
  if (results.length === 0) {
102
109
  continue;
103
110
  }
104
111
  segmentsWithMatches++;
105
112
  totalMatches += results.length;
106
- const ref = '#/f=' + fileId + '/u=' + unitId + (item.getId() ? '/' + item.getId() : '');
107
- results.forEach((match) => unitMatches.push(buildXliffMatch(ref, match, dataCounter)));
113
+ const ref = item.getId() ? '#' + item.getId() : '#/f=' + fileId + '/u=' + unitId;
114
+ results.forEach((match) => unitMatches.push(Utils.buildXliffMatch(ref, match, dataCounter)));
108
115
  }
109
116
  if (unitMatches.length > 0) {
110
117
  const matches = new XliffMatches();
111
- matches.setNamespacePrefix(DEFAULT_PREFIX);
118
+ matches.setNamespacePrefix(Utils.MTC_PREFIX);
112
119
  unitMatches.forEach((match) => matches.addMatch(match));
113
120
  unit.setMatches(matches);
114
121
  usedModule = true;
@@ -116,196 +123,43 @@ export async function runMatchCommand(args) {
116
123
  }
117
124
  }
118
125
  if (usedModule) {
119
- declareMatchesNamespace(document);
126
+ MatchCommand.declareMatchesNamespace(document);
120
127
  }
121
128
  document.writeDocument(outputPath, true);
122
- console.log('Segments processed: ' + segmentsProcessed);
123
- console.log('Segments with matches: ' + segmentsWithMatches);
124
- console.log('Total match candidates: ' + totalMatches);
125
- console.log('Output: ' + outputPath);
126
- }
127
- catch (error) {
128
- CliUtils.fail(error instanceof Error ? error.message : String(error));
129
+ return { segmentsProcessed, segmentsWithMatches, totalMatches, outputPath };
129
130
  }
130
- finally {
131
- await tm.close();
132
- }
133
- }
134
- function dedupeMatches(matches) {
135
- const seen = new Set();
136
- return matches.filter((match) => {
137
- const key = extractElementText(match.source).trim() + '\u00A0' + extractElementText(match.target).trim();
138
- if (seen.has(key)) {
139
- return false;
131
+ static resolveOutputPath(explicit, inputPath) {
132
+ if (explicit) {
133
+ return CliUtils.resolvePath(explicit);
140
134
  }
141
- seen.add(key);
142
- return true;
143
- });
144
- }
145
- function collectUnits(entries) {
146
- const units = [];
147
- entries.forEach((entry) => {
148
- if (entry instanceof XliffGroup) {
149
- units.push(...collectUnits(entry.getEntries()));
150
- }
151
- else {
152
- units.push(entry);
153
- }
154
- });
155
- return units;
156
- }
157
- function needsMatches(segment) {
158
- const state = segment.getState();
159
- if (state === undefined || state === 'initial') {
160
- return true;
161
- }
162
- const target = segment.getTarget();
163
- if (!target) {
164
- return true;
165
- }
166
- return getPureText(target.getContent()).trim().length === 0;
167
- }
168
- function buildXliffMatch(ref, match, dataCounter) {
169
- const xliffMatch = new XliffMatch(ref);
170
- xliffMatch.setNamespacePrefix(DEFAULT_PREFIX);
171
- xliffMatch.setType('tm');
172
- xliffMatch.setOrigin(match.origin);
173
- // @similarity is source-text similarity; @matchQuality is the overall match rating
174
- xliffMatch.setSimilarity(String(match.fuzzy));
175
- xliffMatch.setMatchQuality(String(match.similarity));
176
- const originalData = new XliffOriginalData();
177
- const correlations = new Map();
178
- const source = new XliffSource();
179
- source.setContent(trimInlineContent(convertInlineContent(match.source, originalData, dataCounter, correlations, collectBptAnchors(match.source))));
180
- xliffMatch.setSource(source);
181
- const target = new XliffTarget();
182
- target.setContent(trimInlineContent(convertInlineContent(match.target, originalData, dataCounter, correlations, collectBptAnchors(match.target))));
183
- xliffMatch.setTarget(target);
184
- if (originalData.getDataItems().length > 0) {
185
- xliffMatch.setOriginalData(originalData);
186
- }
187
- return xliffMatch;
188
- }
189
- function collectBptAnchors(element) {
190
- const anchors = new Map();
191
- const walk = (node) => {
192
- node.getContent().forEach((child) => {
193
- if (!(child instanceof XMLElement)) {
194
- return;
195
- }
196
- if (child.getName() === 'bpt') {
197
- const i = child.getAttribute('i')?.getValue();
198
- const x = child.getAttribute('x')?.getValue();
199
- if (i && x) {
200
- anchors.set(i, x);
201
- }
202
- }
203
- walk(child);
204
- });
205
- };
206
- walk(element);
207
- return anchors;
208
- }
209
- function convertInlineContent(element, originalData, counter, correlations, bptAnchors) {
210
- const result = [];
211
- element.getContent().forEach((node) => {
212
- if (node instanceof TextNode) {
213
- result.push(node.getValue());
214
- }
215
- else if (node instanceof XMLElement) {
216
- const name = node.getName();
217
- if (PLACEHOLDER_TAGS.has(name)) {
218
- let anchor = node.getAttribute('x')?.getValue() ?? node.getAttribute('id')?.getValue();
219
- if (!anchor && name === 'ept') {
220
- const i = node.getAttribute('i')?.getValue();
221
- anchor = i ? bptAnchors.get(i) : undefined;
222
- }
223
- const key = anchor ? name + ':' + anchor : undefined;
224
- let ref = key ? correlations.get(key) : undefined;
225
- if (!ref) {
226
- counter.value++;
227
- ref = { phId: 'mtcph' + counter.value, dataId: 'mtcd' + counter.value };
228
- const data = new XliffData(ref.dataId);
229
- data.addText(extractElementText(node));
230
- originalData.addData(data);
231
- if (key) {
232
- correlations.set(key, ref);
233
- }
234
- }
235
- const ph = new XliffPh(ref.phId);
236
- ph.setDataRef(ref.dataId);
237
- result.push(ph);
135
+ const ext = extname(inputPath);
136
+ const stem = basename(inputPath, ext);
137
+ return join(dirname(inputPath), stem + '.matches.xlf');
138
+ }
139
+ static collectUnits(entries) {
140
+ const units = [];
141
+ entries.forEach((entry) => {
142
+ if (entry instanceof XliffGroup) {
143
+ units.push(...MatchCommand.collectUnits(entry.getEntries()));
238
144
  }
239
145
  else {
240
- result.push(...convertInlineContent(node, originalData, counter, correlations, bptAnchors));
146
+ units.push(entry);
241
147
  }
242
- }
243
- });
244
- return result;
245
- }
246
- function trimInlineContent(content) {
247
- const trimmed = [...content];
248
- while (trimmed.length > 0 && typeof trimmed[0] === 'string' && trimmed[0].trim().length === 0) {
249
- trimmed.shift();
250
- }
251
- while (trimmed.length > 0 && typeof trimmed[trimmed.length - 1] === 'string' && trimmed[trimmed.length - 1].trim().length === 0) {
252
- trimmed.pop();
253
- }
254
- if (trimmed.length > 0 && typeof trimmed[0] === 'string') {
255
- trimmed[0] = trimmed[0].replace(/^\s+/, '');
256
- }
257
- if (trimmed.length > 0 && typeof trimmed[trimmed.length - 1] === 'string') {
258
- trimmed[trimmed.length - 1] = trimmed[trimmed.length - 1].replace(/\s+$/, '');
259
- }
260
- return trimmed;
261
- }
262
- function declareMatchesNamespace(document) {
263
- const alreadyDeclared = document.getOtherAttributes().some((attribute) => attribute.getName().startsWith('xmlns:') && attribute.getValue() === MATCHES_NAMESPACE);
264
- if (!alreadyDeclared) {
265
- document.setOtherAttribute('xmlns:' + DEFAULT_PREFIX, MATCHES_NAMESPACE);
266
- }
267
- }
268
- function resolveOutputPath(explicit, inputPath) {
269
- if (explicit) {
270
- return CliUtils.resolvePath(explicit);
271
- }
272
- const ext = extname(inputPath);
273
- const stem = basename(inputPath, ext);
274
- return join(dirname(inputPath), stem + '.matches.xlf');
275
- }
276
- function parseIntOption(raw, fallback, flag, min, max) {
277
- if (raw === undefined) {
278
- return fallback;
279
- }
280
- const parsed = Number(raw);
281
- if (!Number.isInteger(parsed) || parsed < min || (max !== undefined && parsed > max)) {
282
- const range = max !== undefined ? 'an integer between ' + min + ' and ' + max : 'an integer of at least ' + min;
283
- CliUtils.fail('Invalid ' + flag + ' value "' + raw + '"; expected ' + range + '.');
148
+ });
149
+ return units;
284
150
  }
285
- return parsed;
286
- }
287
- function extractElementText(element) {
288
- let text = '';
289
- element.getContent().forEach((node) => {
290
- if (node instanceof TextNode) {
291
- text += node.getValue();
292
- }
293
- else if (node instanceof XMLElement) {
294
- text += extractElementText(node);
295
- }
296
- });
297
- return text;
298
- }
299
- function getPureText(content) {
300
- let text = '';
301
- content.forEach((item) => {
302
- if (typeof item === 'string') {
303
- text += item;
151
+ static declareMatchesNamespace(document) {
152
+ if (!Utils.isNamespaceDeclared(document.getOtherAttributes(), Utils.MATCHES_NAMESPACE)) {
153
+ document.setOtherAttribute('xmlns:' + Utils.MTC_PREFIX, Utils.MATCHES_NAMESPACE);
304
154
  }
305
- else if (item instanceof XliffPc || item instanceof XliffMrk) {
306
- text += getPureText(item.getContent());
155
+ }
156
+ static parseIntOption(raw, flag, min, max) {
157
+ const parsed = Number(raw);
158
+ if (!Number.isInteger(parsed) || parsed < min || (max !== undefined && parsed > max)) {
159
+ const range = max !== undefined ? 'an integer between ' + min + ' and ' + max : 'an integer of at least ' + min;
160
+ CliUtils.fail('Invalid ' + flag + ' value "' + raw + '"; expected ' + range + '.');
307
161
  }
308
- });
309
- return text;
162
+ return parsed;
163
+ }
310
164
  }
311
165
  //# sourceMappingURL=matchCommand.js.map