cspell-trie-lib 5.16.0 → 5.17.0-alpha.0
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.
- package/dist/lib/TrieNode.d.ts +1 -0
- package/dist/lib/distance/distance.d.ts +2 -2
- package/dist/lib/distance/distanceAStarWeighted.d.ts +12 -0
- package/dist/lib/distance/distanceAStarWeighted.js +38 -10
- package/dist/lib/distance/index.d.ts +0 -1
- package/dist/lib/distance/weightedMaps.d.ts +3 -2
- package/dist/lib/distance/weightedMaps.js +27 -18
- package/dist/lib/find.d.ts +1 -0
- package/dist/lib/find.js +2 -2
- package/dist/lib/index.d.ts +2 -1
- package/dist/lib/mappers/mapDictionaryInfoToWeightMap.d.ts +26 -0
- package/dist/lib/mappers/mapDictionaryInfoToWeightMap.js +175 -0
- package/dist/lib/models/DictionaryInformation.d.ts +7 -0
- package/dist/lib/models/DictionaryInformation.js +3 -0
- package/dist/lib/{distance → models}/suggestionCostsDef.d.ts +0 -0
- package/dist/lib/{distance → models}/suggestionCostsDef.js +0 -0
- package/dist/lib/suggestions/suggestCollector.js +1 -1
- package/dist/lib/trie-util.d.ts +2 -1
- package/dist/lib/trie-util.js +1 -1
- package/dist/lib/types.d.ts +10 -0
- package/dist/lib/types.js +3 -0
- package/dist/lib/utils/util.d.ts +2 -0
- package/dist/lib/utils/util.js +8 -0
- package/package.json +5 -5
package/dist/lib/TrieNode.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { SuggestionCostMapDef } from '
|
|
1
|
+
import type { SuggestionCostMapDef } from '../models/suggestionCostsDef';
|
|
2
2
|
import type { WeightMap } from './weightedMaps';
|
|
3
|
-
export type { SuggestionCostMapDef } from '
|
|
3
|
+
export type { SuggestionCostMapDef } from '../models/suggestionCostsDef';
|
|
4
4
|
export type { WeightMap } from './weightedMaps';
|
|
5
5
|
/**
|
|
6
6
|
* Calculate the edit distance between any two words.
|
|
@@ -5,4 +5,16 @@ import { WeightMap } from './weightedMaps';
|
|
|
5
5
|
* Using basic weights, this algorithm has the same results as the Damerau-Levenshtein algorithm.
|
|
6
6
|
*/
|
|
7
7
|
export declare function distanceAStarWeighted(wordA: string, wordB: string, map: WeightMap, cost?: number): number;
|
|
8
|
+
export interface ExResult {
|
|
9
|
+
a: string;
|
|
10
|
+
b: string;
|
|
11
|
+
cost: number;
|
|
12
|
+
segments: {
|
|
13
|
+
a: string;
|
|
14
|
+
b: string;
|
|
15
|
+
c: number;
|
|
16
|
+
p: number;
|
|
17
|
+
}[];
|
|
18
|
+
}
|
|
19
|
+
export declare function distanceAStarWeightedEx(wordA: string, wordB: string, map: WeightMap, cost?: number): ExResult | undefined;
|
|
8
20
|
//# sourceMappingURL=distanceAStarWeighted.d.ts.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.distanceAStarWeighted = void 0;
|
|
3
|
+
exports.distanceAStarWeightedEx = exports.distanceAStarWeighted = void 0;
|
|
4
4
|
const PairingHeap_1 = require("../utils/PairingHeap");
|
|
5
5
|
/**
|
|
6
6
|
* Calculate the edit distance between two words using an A* algorithm.
|
|
@@ -8,40 +8,70 @@ const PairingHeap_1 = require("../utils/PairingHeap");
|
|
|
8
8
|
* Using basic weights, this algorithm has the same results as the Damerau-Levenshtein algorithm.
|
|
9
9
|
*/
|
|
10
10
|
function distanceAStarWeighted(wordA, wordB, map, cost = 100) {
|
|
11
|
+
const best = _distanceAStarWeightedEx(wordA, wordB, map, cost);
|
|
12
|
+
return best ? best.c + best.p : -1;
|
|
13
|
+
}
|
|
14
|
+
exports.distanceAStarWeighted = distanceAStarWeighted;
|
|
15
|
+
function distanceAStarWeightedEx(wordA, wordB, map, cost = 100) {
|
|
16
|
+
const best = _distanceAStarWeightedEx(wordA, wordB, map, cost);
|
|
17
|
+
if (!best)
|
|
18
|
+
return undefined;
|
|
19
|
+
const aa = '^' + wordA + '$';
|
|
20
|
+
const bb = '^' + wordB + '$';
|
|
21
|
+
const result = {
|
|
22
|
+
a: aa,
|
|
23
|
+
b: bb,
|
|
24
|
+
cost: best.c + best.p,
|
|
25
|
+
segments: [],
|
|
26
|
+
};
|
|
27
|
+
const segments = result.segments;
|
|
28
|
+
for (let n = best; n.f; n = n.f) {
|
|
29
|
+
const f = n.f;
|
|
30
|
+
const a = aa.slice(f.ai, n.ai);
|
|
31
|
+
const b = bb.slice(f.bi, n.bi);
|
|
32
|
+
const c = n.c - f.c;
|
|
33
|
+
const p = n.p - f.p;
|
|
34
|
+
segments.push({ a, b, c, p });
|
|
35
|
+
}
|
|
36
|
+
segments.reverse();
|
|
37
|
+
return result;
|
|
38
|
+
}
|
|
39
|
+
exports.distanceAStarWeightedEx = distanceAStarWeightedEx;
|
|
40
|
+
function _distanceAStarWeightedEx(wordA, wordB, map, cost = 100) {
|
|
11
41
|
// Add ^ and $ for begin/end detection.
|
|
12
42
|
const a = '^' + wordA + '$';
|
|
13
43
|
const b = '^' + wordB + '$';
|
|
14
44
|
const aN = a.length;
|
|
15
45
|
const bN = b.length;
|
|
16
46
|
const candidates = new PairingHeap_1.PairingHeap(compare);
|
|
17
|
-
candidates.add({ ai: 0, bi: 0, c: 0, p: 0 });
|
|
47
|
+
candidates.add({ ai: 0, bi: 0, c: 0, p: 0, f: undefined });
|
|
18
48
|
/** Substitute / Replace */
|
|
19
49
|
function opSub(n) {
|
|
20
50
|
const { ai, bi, c, p } = n;
|
|
21
51
|
if (ai < aN && bi < bN) {
|
|
22
52
|
const cc = a[ai] === b[bi] ? c : c + cost;
|
|
23
|
-
candidates.add({ ai: ai + 1, bi: bi + 1, c: cc, p });
|
|
53
|
+
candidates.add({ ai: ai + 1, bi: bi + 1, c: cc, p, f: n });
|
|
24
54
|
}
|
|
25
55
|
}
|
|
26
56
|
/** Insert */
|
|
27
57
|
function opIns(n) {
|
|
28
58
|
const { ai, bi, c, p } = n;
|
|
29
59
|
if (bi < bN) {
|
|
30
|
-
candidates.add({ ai: ai, bi: bi + 1, c: c + cost, p });
|
|
60
|
+
candidates.add({ ai: ai, bi: bi + 1, c: c + cost, p, f: n });
|
|
31
61
|
}
|
|
32
62
|
}
|
|
33
63
|
/** Delete */
|
|
34
64
|
function opDel(n) {
|
|
35
65
|
const { ai, bi, c, p } = n;
|
|
36
66
|
if (ai < aN) {
|
|
37
|
-
candidates.add({ ai: ai + 1, bi: bi, c: c + cost, p });
|
|
67
|
+
candidates.add({ ai: ai + 1, bi: bi, c: c + cost, p, f: n });
|
|
38
68
|
}
|
|
39
69
|
}
|
|
40
70
|
/** Swap adjacent letters */
|
|
41
71
|
function opSwap(n) {
|
|
42
72
|
const { ai, bi, c, p } = n;
|
|
43
73
|
if (a[ai] === b[bi + 1] && a[ai + 1] === b[bi]) {
|
|
44
|
-
candidates.add({ ai: ai + 2, bi: bi + 2, c: c + cost, p });
|
|
74
|
+
candidates.add({ ai: ai + 2, bi: bi + 2, c: c + cost, p, f: n });
|
|
45
75
|
}
|
|
46
76
|
}
|
|
47
77
|
function opMap(n) {
|
|
@@ -50,7 +80,7 @@ function distanceAStarWeighted(wordA, wordB, map, cost = 100) {
|
|
|
50
80
|
const costCalculations = [map.calcInsDelCosts(pos), map.calcSwapCosts(pos), map.calcReplaceCosts(pos)];
|
|
51
81
|
costCalculations.forEach((iter) => {
|
|
52
82
|
for (const nn of iter) {
|
|
53
|
-
candidates.add(nn);
|
|
83
|
+
candidates.add({ ...nn, f: n });
|
|
54
84
|
}
|
|
55
85
|
});
|
|
56
86
|
}
|
|
@@ -65,10 +95,8 @@ function distanceAStarWeighted(wordA, wordB, map, cost = 100) {
|
|
|
65
95
|
opMap(best);
|
|
66
96
|
opSub(best);
|
|
67
97
|
}
|
|
68
|
-
|
|
69
|
-
return best ? best.c + best.p : -1;
|
|
98
|
+
return best;
|
|
70
99
|
}
|
|
71
|
-
exports.distanceAStarWeighted = distanceAStarWeighted;
|
|
72
100
|
function compare(a, b) {
|
|
73
101
|
// Choose lowest cost or farthest Manhattan distance.
|
|
74
102
|
return a.c - b.c || b.ai + b.bi - a.ai - a.bi;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { SuggestionCostMapDef } from '
|
|
1
|
+
import { SuggestionCostMapDef } from '../models/suggestionCostsDef';
|
|
2
2
|
export declare type WeightedRepMapTrie = Record<string, WeightedRepTrieNode>;
|
|
3
3
|
interface WeightedRepTrieNode {
|
|
4
4
|
/** The nested Trie nodes */
|
|
@@ -51,12 +51,13 @@ export interface WeightMap {
|
|
|
51
51
|
}
|
|
52
52
|
export declare function createWeightMap(...defs: SuggestionCostMapDef[]): WeightMap;
|
|
53
53
|
export declare function addDefToWeightMap(map: WeightMap, def: SuggestionCostMapDef, ...defs: SuggestionCostMapDef[]): WeightMap;
|
|
54
|
+
export declare function splitMapSubstringsIterable(map: string): Iterable<string>;
|
|
55
|
+
export declare function splitMapSubstrings(map: string): string[];
|
|
54
56
|
/**
|
|
55
57
|
* Splits a WeightedMapDef.map
|
|
56
58
|
* @param map
|
|
57
59
|
*/
|
|
58
60
|
declare function splitMap(def: Pick<SuggestionCostMapDef, 'map'>): string[][];
|
|
59
|
-
declare function splitMapSubstrings(map: string): string[];
|
|
60
61
|
interface MatchTrieCost {
|
|
61
62
|
i: number;
|
|
62
63
|
c: number;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.__testing__ = exports.lookupReplaceCost = exports.prettyPrintWeightMap = exports.prettyPrintSwap = exports.prettyPrintReplace = exports.addDefToWeightMap = exports.createWeightMap = void 0;
|
|
3
|
+
exports.__testing__ = exports.lookupReplaceCost = exports.prettyPrintWeightMap = exports.prettyPrintSwap = exports.prettyPrintReplace = exports.splitMapSubstrings = exports.splitMapSubstringsIterable = exports.addDefToWeightMap = exports.createWeightMap = void 0;
|
|
4
4
|
function createWeightMap(...defs) {
|
|
5
5
|
const map = _createWeightMap();
|
|
6
6
|
_addDefToWeightMap(map, ...defs);
|
|
@@ -40,6 +40,32 @@ function highest(a, b) {
|
|
|
40
40
|
return a;
|
|
41
41
|
return a >= b ? a : b;
|
|
42
42
|
}
|
|
43
|
+
function* splitMapSubstringsIterable(map) {
|
|
44
|
+
let seq = '';
|
|
45
|
+
let mode = 0;
|
|
46
|
+
for (const char of map) {
|
|
47
|
+
if (mode && char === ')') {
|
|
48
|
+
yield seq;
|
|
49
|
+
mode = 0;
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
if (mode) {
|
|
53
|
+
seq += char;
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
if (char === '(') {
|
|
57
|
+
mode = 1;
|
|
58
|
+
seq = '';
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
yield char;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
exports.splitMapSubstringsIterable = splitMapSubstringsIterable;
|
|
65
|
+
function splitMapSubstrings(map) {
|
|
66
|
+
return [...splitMapSubstringsIterable(map)];
|
|
67
|
+
}
|
|
68
|
+
exports.splitMapSubstrings = splitMapSubstrings;
|
|
43
69
|
/**
|
|
44
70
|
* Splits a WeightedMapDef.map
|
|
45
71
|
* @param map
|
|
@@ -49,23 +75,6 @@ function splitMap(def) {
|
|
|
49
75
|
const sets = map.split('|');
|
|
50
76
|
return sets.map(splitMapSubstrings).filter((s) => s.length > 0);
|
|
51
77
|
}
|
|
52
|
-
function splitMapSubstrings(map) {
|
|
53
|
-
const values = [];
|
|
54
|
-
const len = map.length;
|
|
55
|
-
for (let i = 0; i < len; ++i) {
|
|
56
|
-
const c = map[i];
|
|
57
|
-
if (c !== '(') {
|
|
58
|
-
values.push(c);
|
|
59
|
-
continue;
|
|
60
|
-
}
|
|
61
|
-
const s = i + 1;
|
|
62
|
-
while (map[++i] !== ')' && i < len) {
|
|
63
|
-
// empty
|
|
64
|
-
}
|
|
65
|
-
values.push(map.slice(s, i));
|
|
66
|
-
}
|
|
67
|
-
return values.map((s) => s.trim()).filter((s) => !!s);
|
|
68
|
-
}
|
|
69
78
|
function addToTrieCost(trie, str, cost, penalties) {
|
|
70
79
|
if (!str)
|
|
71
80
|
return;
|
package/dist/lib/find.d.ts
CHANGED
package/dist/lib/find.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.__testing__ = exports.createFindOptions = exports.isForbiddenWord = exports.isEndOfWordNode = exports.findWordExact = exports.findCompoundNode = exports.findLegacyCompound = exports.findWordNode = exports.findWord = void 0;
|
|
4
|
-
const TrieNode_1 = require("./TrieNode");
|
|
5
|
-
const trie_util_1 = require("./trie-util");
|
|
6
4
|
const constants_1 = require("./constants");
|
|
5
|
+
const trie_util_1 = require("./trie-util");
|
|
6
|
+
const TrieNode_1 = require("./TrieNode");
|
|
7
7
|
const defaultLegacyMinCompoundLength = 3;
|
|
8
8
|
const _defaultFindOptions = {
|
|
9
9
|
matchCase: false,
|
package/dist/lib/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export { consolidate } from './consolidate';
|
|
2
2
|
export { createWeightedMap, editDistance, editDistanceWeighted } from './distance';
|
|
3
|
-
export type {
|
|
3
|
+
export type { WeightMap } from './distance';
|
|
4
|
+
export type { SuggestionCostMapDef } from './models/suggestionCostsDef';
|
|
4
5
|
export type { FindFullResult } from './find';
|
|
5
6
|
export { ExportOptions, importTrie, serializeTrie } from './io/importExport';
|
|
6
7
|
export { parseDictionary, parseDictionaryLines } from './SimpleDictionaryParser';
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { WeightMap } from '../distance/weightedMaps';
|
|
2
|
+
import type { DictionaryInformation, HunspellCosts, HunspellInformation } from '../models/DictionaryInformation';
|
|
3
|
+
import type { SuggestionCostMapDef } from '../models/suggestionCostsDef';
|
|
4
|
+
declare type Costs = Required<HunspellCosts>;
|
|
5
|
+
export declare function dictionaryInformationToWeightMap(dictInfo: DictionaryInformation): WeightMap;
|
|
6
|
+
export declare function hunspellInformationToSuggestionCostDef(hunInfo: HunspellInformation): SuggestionCostMapDef[];
|
|
7
|
+
declare function calcCosts(costs?: HunspellCosts): Costs;
|
|
8
|
+
declare function affMap(line: string, costs: Costs): SuggestionCostMapDef | undefined;
|
|
9
|
+
declare function affTry(line: string, costs: Costs): SuggestionCostMapDef | undefined;
|
|
10
|
+
declare function affTryFirstCharacterReplace(line: string, costs: Costs): SuggestionCostMapDef | undefined;
|
|
11
|
+
declare function affNoTry(line: string, costs: Costs): SuggestionCostMapDef | undefined;
|
|
12
|
+
declare function affRepConv(line: string, costs: Costs): SuggestionCostMapDef | undefined;
|
|
13
|
+
declare function affKey(line: string, costs: Costs): SuggestionCostMapDef | undefined;
|
|
14
|
+
declare function split(map: string): Iterable<string>;
|
|
15
|
+
export declare const __testing__: {
|
|
16
|
+
affKey: typeof affKey;
|
|
17
|
+
affMap: typeof affMap;
|
|
18
|
+
affNoTry: typeof affNoTry;
|
|
19
|
+
affRepConv: typeof affRepConv;
|
|
20
|
+
affTry: typeof affTry;
|
|
21
|
+
affTryFirstCharacterReplace: typeof affTryFirstCharacterReplace;
|
|
22
|
+
split: typeof split;
|
|
23
|
+
calcCosts: typeof calcCosts;
|
|
24
|
+
};
|
|
25
|
+
export {};
|
|
26
|
+
//# sourceMappingURL=mapDictionaryInfoToWeightMap.d.ts.map
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.__testing__ = exports.hunspellInformationToSuggestionCostDef = exports.dictionaryInformationToWeightMap = void 0;
|
|
4
|
+
const weightedMaps_1 = require("../distance/weightedMaps");
|
|
5
|
+
const util_1 = require("../utils/util");
|
|
6
|
+
function dictionaryInformationToWeightMap(dictInfo) {
|
|
7
|
+
const defsEC = dictInfo.suggestionEditCosts || [];
|
|
8
|
+
const defsHI = dictInfo.hunspellInformation
|
|
9
|
+
? hunspellInformationToSuggestionCostDef(dictInfo.hunspellInformation)
|
|
10
|
+
: [];
|
|
11
|
+
return (0, weightedMaps_1.createWeightMap)(...defsEC, ...defsHI);
|
|
12
|
+
}
|
|
13
|
+
exports.dictionaryInformationToWeightMap = dictionaryInformationToWeightMap;
|
|
14
|
+
function hunspellInformationToSuggestionCostDef(hunInfo) {
|
|
15
|
+
const defs = [];
|
|
16
|
+
const costs = calcCosts(hunInfo.costs);
|
|
17
|
+
function parseAff(aff, costs) {
|
|
18
|
+
// cspell:ignore OCONV
|
|
19
|
+
const regSupportedAff = /^(?:MAP|KEY|TRY|NO-TRY|ICONV|OCONV|REP)\s/;
|
|
20
|
+
const rejectAff = /^(?:MAP|KEY|TRY|ICONV|OCONV|REP)\s+\d+$/;
|
|
21
|
+
const lines = aff
|
|
22
|
+
.split('\n')
|
|
23
|
+
.map((a) => a.replace(/#.*/, ''))
|
|
24
|
+
.map((a) => a.trim())
|
|
25
|
+
.filter((a) => regSupportedAff.test(a))
|
|
26
|
+
.filter((a) => !rejectAff.test(a));
|
|
27
|
+
lines.forEach((line) => {
|
|
28
|
+
[affMap, affNoTry, affRepConv, affTry, affTryFirstCharacterReplace, affKey]
|
|
29
|
+
.map((fn) => fn(line, costs))
|
|
30
|
+
.filter(util_1.isDefined)
|
|
31
|
+
.forEach((def) => defs.push(def));
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
parseAff(hunInfo.aff, costs);
|
|
35
|
+
return defs;
|
|
36
|
+
}
|
|
37
|
+
exports.hunspellInformationToSuggestionCostDef = hunspellInformationToSuggestionCostDef;
|
|
38
|
+
function calcCosts(costs = {}) {
|
|
39
|
+
const { firstLetterPenalty = 4, ioConvertCost = 30, keyboardCost = 94, mapCost = 25, replaceCosts = 75, tryCharCost = 95, } = costs;
|
|
40
|
+
const c = { tryCharCost, keyboardCost, mapCost, ioConvertCost, replaceCosts, firstLetterPenalty };
|
|
41
|
+
return c;
|
|
42
|
+
}
|
|
43
|
+
const regExpMap = /^(?:MAP)\s+(\S+)$/;
|
|
44
|
+
function affMap(line, costs) {
|
|
45
|
+
const m = line.match(regExpMap);
|
|
46
|
+
if (!m)
|
|
47
|
+
return undefined;
|
|
48
|
+
const map = m[1];
|
|
49
|
+
const cost = costs.mapCost;
|
|
50
|
+
return {
|
|
51
|
+
map,
|
|
52
|
+
replace: cost,
|
|
53
|
+
swap: cost,
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
const regExpTry = /^(?:TRY)\s+(\S+)$/;
|
|
57
|
+
function affTry(line, costs) {
|
|
58
|
+
const m = line.match(regExpTry);
|
|
59
|
+
if (!m)
|
|
60
|
+
return undefined;
|
|
61
|
+
const map = m[1];
|
|
62
|
+
const cost = costs.tryCharCost;
|
|
63
|
+
return {
|
|
64
|
+
map,
|
|
65
|
+
insDel: cost,
|
|
66
|
+
replace: cost,
|
|
67
|
+
swap: cost,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
function affTryFirstCharacterReplace(line, costs) {
|
|
71
|
+
const m = line.match(regExpTry);
|
|
72
|
+
if (!m)
|
|
73
|
+
return undefined;
|
|
74
|
+
const map = [...split(m[1])].map((char) => `(^${char})`).join('');
|
|
75
|
+
const cost = costs.tryCharCost;
|
|
76
|
+
const penalty = costs.firstLetterPenalty;
|
|
77
|
+
return {
|
|
78
|
+
map,
|
|
79
|
+
replace: cost - penalty,
|
|
80
|
+
penalty,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
const regExpNoTry = /^NO-TRY\s+(\S+)$/;
|
|
84
|
+
function affNoTry(line, costs) {
|
|
85
|
+
const m = line.match(regExpNoTry);
|
|
86
|
+
if (!m)
|
|
87
|
+
return undefined;
|
|
88
|
+
const map = m[1];
|
|
89
|
+
return {
|
|
90
|
+
map,
|
|
91
|
+
insDel: Math.max(100 - costs.tryCharCost, 0),
|
|
92
|
+
penalty: 100 + costs.tryCharCost,
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
// cspell:ignore conv
|
|
96
|
+
const regExpRepConv = /^(?:REP|(?:I|O)CONV)\s+(\S+)\s+(\S+)$/;
|
|
97
|
+
function affRepConv(line, costs) {
|
|
98
|
+
const m = line.match(regExpRepConv);
|
|
99
|
+
if (!m)
|
|
100
|
+
return undefined;
|
|
101
|
+
const cost = line.startsWith('REP') ? costs.replaceCosts : costs.ioConvertCost;
|
|
102
|
+
const from = m[1];
|
|
103
|
+
let into = m[2];
|
|
104
|
+
into = into.replace(/^0$/, '');
|
|
105
|
+
if (from.startsWith('^') && !into.startsWith('^')) {
|
|
106
|
+
into = '^' + into;
|
|
107
|
+
}
|
|
108
|
+
if (from.endsWith('$') && !into.endsWith('$')) {
|
|
109
|
+
into = into + '$';
|
|
110
|
+
}
|
|
111
|
+
return {
|
|
112
|
+
map: `(${from})(${into})`,
|
|
113
|
+
replace: cost,
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
const regExpKey = /^(?:KEY)\s+(\S+)$/;
|
|
117
|
+
function affKey(line, costs) {
|
|
118
|
+
const m = line.match(regExpKey);
|
|
119
|
+
if (!m)
|
|
120
|
+
return undefined;
|
|
121
|
+
const kbd = m[1];
|
|
122
|
+
const pairs = [...split(kbd)]
|
|
123
|
+
.map(reducer((p, v) => ({ a: p.b, b: v }), { a: '|', b: '|' }))
|
|
124
|
+
.filter((ab) => ab.a !== '|' && ab.b !== '|')
|
|
125
|
+
.map((ab) => ab.a + ab.b);
|
|
126
|
+
const map = pairs.join('|');
|
|
127
|
+
const cost = costs.keyboardCost;
|
|
128
|
+
return {
|
|
129
|
+
map,
|
|
130
|
+
replace: cost,
|
|
131
|
+
swap: cost,
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
function* split(map) {
|
|
135
|
+
let seq = '';
|
|
136
|
+
let mode = 0;
|
|
137
|
+
for (const char of map) {
|
|
138
|
+
if (mode && char === ')') {
|
|
139
|
+
yield seq;
|
|
140
|
+
mode = 0;
|
|
141
|
+
continue;
|
|
142
|
+
}
|
|
143
|
+
if (mode) {
|
|
144
|
+
seq += char;
|
|
145
|
+
continue;
|
|
146
|
+
}
|
|
147
|
+
if (char === '(') {
|
|
148
|
+
mode = 1;
|
|
149
|
+
seq = '';
|
|
150
|
+
continue;
|
|
151
|
+
}
|
|
152
|
+
yield char;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
function reducer(fn, initialVal) {
|
|
156
|
+
let acc = initialVal;
|
|
157
|
+
return (val, i) => (acc = fn(acc, val, i));
|
|
158
|
+
}
|
|
159
|
+
// function pipe<T>(v: T, ...fns: ((v: T) => T)[]): T {
|
|
160
|
+
// for (const fn of fns) {
|
|
161
|
+
// v = fn(v);
|
|
162
|
+
// }
|
|
163
|
+
// return v;
|
|
164
|
+
// }
|
|
165
|
+
exports.__testing__ = {
|
|
166
|
+
affKey,
|
|
167
|
+
affMap,
|
|
168
|
+
affNoTry,
|
|
169
|
+
affRepConv,
|
|
170
|
+
affTry,
|
|
171
|
+
affTryFirstCharacterReplace,
|
|
172
|
+
split,
|
|
173
|
+
calcCosts,
|
|
174
|
+
};
|
|
175
|
+
//# sourceMappingURL=mapDictionaryInfoToWeightMap.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { DictionaryDefinitionAugmented } from '@cspell/cspell-types';
|
|
2
|
+
export declare type DictionaryInformation = Exclude<DictionaryDefinitionAugmented['dictionaryInformation'], undefined>;
|
|
3
|
+
export declare type SuggestionEditCosts = Exclude<DictionaryInformation['suggestionEditCosts'], undefined>;
|
|
4
|
+
export declare type HunspellInformation = Exclude<DictionaryInformation['hunspellInformation'], undefined>;
|
|
5
|
+
export declare type HunspellCosts = Exclude<HunspellInformation['costs'], undefined>;
|
|
6
|
+
export declare type HunspellAff = HunspellInformation['aff'];
|
|
7
|
+
//# sourceMappingURL=DictionaryInformation.d.ts.map
|
|
File without changes
|
|
File without changes
|
|
@@ -37,7 +37,7 @@ function suggestionCollector(wordToMatch, options) {
|
|
|
37
37
|
let maxCost = BASE_COST * Math.min(wordToMatch.length * MAX_ALLOWED_COST_SCALE, changeLimit);
|
|
38
38
|
let timeRemaining = timeout;
|
|
39
39
|
function dropMax() {
|
|
40
|
-
if (sugs.size < 2) {
|
|
40
|
+
if (sugs.size < 2 || !numSuggestions) {
|
|
41
41
|
sugs.clear();
|
|
42
42
|
return;
|
|
43
43
|
}
|
package/dist/lib/trie-util.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Sequence } from 'gensequence';
|
|
2
|
-
import {
|
|
2
|
+
import { PartialTrieOptions, TrieNode, TrieOptions, TrieRoot } from './TrieNode';
|
|
3
|
+
import type { Mandatory, PartialWithUndefined } from './types';
|
|
3
4
|
import { YieldResult } from './walker';
|
|
4
5
|
export declare function insert(text: string, node?: TrieNode): TrieNode;
|
|
5
6
|
export declare function isWordTerminationNode(node: TrieNode): boolean;
|
package/dist/lib/trie-util.js
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.clean = exports.isDefined = exports.normalizeWordForCaseInsensitive = exports.normalizeWordToLowercase = exports.normalizeWord = exports.trieNodeToRoot = exports.mergeDefaults = exports.isCircular = exports.countWords = exports.countNodes = exports.findNode = exports.has = exports.createTriFromList = exports.createTrieRoot = exports.mergeOptionalWithDefaults = exports.iteratorTrieWords = exports.iterateTrie = exports.walk = exports.orderTrie = exports.isWordTerminationNode = exports.insert = void 0;
|
|
4
4
|
const gensequence_1 = require("gensequence");
|
|
5
|
+
const constants_1 = require("./constants");
|
|
5
6
|
const TrieNode_1 = require("./TrieNode");
|
|
6
7
|
const walker_1 = require("./walker");
|
|
7
|
-
const constants_1 = require("./constants");
|
|
8
8
|
function insert(text, node = {}) {
|
|
9
9
|
if (text.length) {
|
|
10
10
|
const head = text[0];
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Make all properties in T optional and Possibly undefined
|
|
3
|
+
*/
|
|
4
|
+
export declare type PartialWithUndefined<T> = {
|
|
5
|
+
[P in keyof T]?: T[P] | undefined;
|
|
6
|
+
};
|
|
7
|
+
export declare type Mandatory<T> = {
|
|
8
|
+
[P in keyof T]-?: Exclude<T[P], undefined>;
|
|
9
|
+
};
|
|
10
|
+
//# sourceMappingURL=types.d.ts.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cspell-trie-lib",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.17.0-alpha.0",
|
|
4
4
|
"description": "Trie Data Structure to support cspell.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -44,14 +44,14 @@
|
|
|
44
44
|
"node": ">=12.13.0"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
|
-
"@cspell/cspell-types": "^5.
|
|
47
|
+
"@cspell/cspell-types": "^5.17.0-alpha.0",
|
|
48
48
|
"@cspell/dict-en_us": "^2.1.4",
|
|
49
49
|
"@cspell/dict-es-es": "^2.1.0",
|
|
50
50
|
"@types/fs-extra": "^9.0.13",
|
|
51
|
-
"@types/node": "^17.0.
|
|
52
|
-
"hunspell-reader": "^5.
|
|
51
|
+
"@types/node": "^17.0.12",
|
|
52
|
+
"hunspell-reader": "^5.17.0-alpha.0",
|
|
53
53
|
"jest": "^27.4.7",
|
|
54
54
|
"rimraf": "^3.0.2"
|
|
55
55
|
},
|
|
56
|
-
"gitHead": "
|
|
56
|
+
"gitHead": "d884218703cac72186fd69e8ba1e9eb78558c7ca"
|
|
57
57
|
}
|