cspell-dictionary 9.3.2 → 9.6.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/SpellingDictionary/CachingDictionary.d.ts +21 -3
- package/dist/SpellingDictionary/CachingDictionary.js +29 -3
- package/dist/SpellingDictionary/FlagWordsDictionary.d.ts +56 -1
- package/dist/SpellingDictionary/FlagWordsDictionary.js +17 -14
- package/dist/SpellingDictionary/IgnoreWordsDictionary.js +1 -3
- package/dist/SpellingDictionary/SpellingDictionary.d.ts +26 -4
- package/dist/SpellingDictionary/SpellingDictionaryCollection.js +1 -4
- package/dist/SpellingDictionary/SpellingDictionaryFromTrie.d.ts +9 -7
- package/dist/SpellingDictionary/SpellingDictionaryFromTrie.js +59 -21
- package/dist/SpellingDictionary/SuggestDictionary.d.ts +4 -10
- package/dist/SpellingDictionary/SuggestDictionary.js +1 -3
- package/dist/SpellingDictionary/Typos/typosParser.d.ts +1 -0
- package/dist/SpellingDictionary/Typos/typosParser.js +29 -4
- package/dist/SpellingDictionary/Typos/util.d.ts +1 -0
- package/dist/SpellingDictionary/Typos/util.js +5 -0
- package/dist/SpellingDictionary/TyposDictionary.js +1 -3
- package/dist/SpellingDictionary/createSpellingDictionary.d.ts +1 -1
- package/dist/SpellingDictionary/createSpellingDictionary.js +17 -6
- package/dist/SpellingDictionary/index.d.ts +1 -1
- package/dist/index.d.ts +2 -9
- package/dist/index.js +1 -8
- package/dist/util/performance.d.ts +9 -0
- package/dist/util/performance.js +19 -0
- package/dist/util/repMap.d.ts +10 -3
- package/dist/util/repMap.js +26 -8
- package/package.json +7 -6
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { SuggestionResult } from 'cspell-trie-lib';
|
|
1
2
|
import type { CacheStats } from '../util/AutoCache.js';
|
|
2
3
|
import type { PreferredSuggestion, SearchOptions, SpellingDictionary } from './SpellingDictionary.js';
|
|
3
4
|
import type { SpellingDictionaryCollection } from './SpellingDictionaryCollection.js';
|
|
@@ -21,7 +22,7 @@ export interface CachingDictionary {
|
|
|
21
22
|
isForbidden(word: string): boolean;
|
|
22
23
|
stats(): CallStats;
|
|
23
24
|
getPreferredSuggestions(word: string): PreferredSuggestion[] | undefined;
|
|
24
|
-
suggest(word: string, suggestOptions?: SuggestOptionsRO):
|
|
25
|
+
suggest(word: string, suggestOptions?: SuggestOptionsRO): SuggestionResult[];
|
|
25
26
|
}
|
|
26
27
|
interface LogEntryBase extends SearchOptions {
|
|
27
28
|
time: number;
|
|
@@ -32,6 +33,7 @@ interface LogEntryBase extends SearchOptions {
|
|
|
32
33
|
interface LogEntryHas extends LogEntryBase {
|
|
33
34
|
method: 'has';
|
|
34
35
|
value: boolean;
|
|
36
|
+
miss: boolean;
|
|
35
37
|
}
|
|
36
38
|
export type LogEntry = LogEntryHas;
|
|
37
39
|
/**
|
|
@@ -41,7 +43,23 @@ export type LogEntry = LogEntryHas;
|
|
|
41
43
|
* @returns CachingDictionary
|
|
42
44
|
*/
|
|
43
45
|
export declare function createCachingDictionary(dict: SpellingDictionary | SpellingDictionaryCollection, options: SearchOptions): CachingDictionary;
|
|
44
|
-
|
|
45
|
-
|
|
46
|
+
/**
|
|
47
|
+
* Enable or disable logging of dictionary requests. Every call to `has` will be logged.
|
|
48
|
+
*
|
|
49
|
+
* This should be set prior to creating any caching dictionaries to ensure all requests are logged.
|
|
50
|
+
*
|
|
51
|
+
* @param enabled - optional - if undefined, it will toggle the setting.
|
|
52
|
+
* @returns the current state of logging.
|
|
53
|
+
*/
|
|
54
|
+
export declare function dictionaryCacheEnableLogging(enabled?: boolean): boolean;
|
|
55
|
+
/**
|
|
56
|
+
* Get the log of dictionary requests.
|
|
57
|
+
* @returns the log
|
|
58
|
+
*/
|
|
59
|
+
export declare function dictionaryCacheGetLog(): readonly Readonly<LogEntryBase>[];
|
|
60
|
+
/**
|
|
61
|
+
* Clear the log of dictionary requests.
|
|
62
|
+
*/
|
|
63
|
+
export declare function dictionaryCacheClearLog(): void;
|
|
46
64
|
export {};
|
|
47
65
|
//# sourceMappingURL=CachingDictionary.d.ts.map
|
|
@@ -19,8 +19,12 @@ class CachedDict {
|
|
|
19
19
|
const has = autoCache((word) => this.dict.has(word, this.options), DefaultAutoCacheSize);
|
|
20
20
|
const hasAndLog = (word) => {
|
|
21
21
|
const time = performance.now() - startTime;
|
|
22
|
+
const misses = has.misses;
|
|
22
23
|
const value = has(word);
|
|
23
|
-
|
|
24
|
+
if (logRequests) {
|
|
25
|
+
const miss = has.misses > misses;
|
|
26
|
+
log.push({ time, method: 'has', word, value, miss });
|
|
27
|
+
}
|
|
24
28
|
return value;
|
|
25
29
|
};
|
|
26
30
|
this.#has = has;
|
|
@@ -63,10 +67,32 @@ export function createCachingDictionary(dict, options) {
|
|
|
63
67
|
knownOptions.set(dict, cached);
|
|
64
68
|
return cached;
|
|
65
69
|
}
|
|
66
|
-
|
|
70
|
+
/**
|
|
71
|
+
* Enable or disable logging of dictionary requests. Every call to `has` will be logged.
|
|
72
|
+
*
|
|
73
|
+
* This should be set prior to creating any caching dictionaries to ensure all requests are logged.
|
|
74
|
+
*
|
|
75
|
+
* @param enabled - optional - if undefined, it will toggle the setting.
|
|
76
|
+
* @returns the current state of logging.
|
|
77
|
+
*/
|
|
78
|
+
export function dictionaryCacheEnableLogging(enabled = !logRequests) {
|
|
79
|
+
if (enabled && !logRequests) {
|
|
80
|
+
knownDicts.clear();
|
|
81
|
+
}
|
|
67
82
|
logRequests = enabled;
|
|
83
|
+
return logRequests;
|
|
68
84
|
}
|
|
69
|
-
|
|
85
|
+
/**
|
|
86
|
+
* Get the log of dictionary requests.
|
|
87
|
+
* @returns the log
|
|
88
|
+
*/
|
|
89
|
+
export function dictionaryCacheGetLog() {
|
|
70
90
|
return log;
|
|
71
91
|
}
|
|
92
|
+
/**
|
|
93
|
+
* Clear the log of dictionary requests.
|
|
94
|
+
*/
|
|
95
|
+
export function dictionaryCacheClearLog() {
|
|
96
|
+
log.length = 0;
|
|
97
|
+
}
|
|
72
98
|
//# sourceMappingURL=CachingDictionary.js.map
|
|
@@ -1,4 +1,59 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { CompoundWordsMethod, ITrie, SuggestionResult } from 'cspell-trie-lib';
|
|
2
|
+
import type { FindResult, HasOptions, IgnoreCaseOption, PreferredSuggestion, SpellingDictionary, SpellingDictionaryOptions } from './SpellingDictionary.js';
|
|
3
|
+
import { SpellingDictionaryFromTrie } from './SpellingDictionaryFromTrie.js';
|
|
4
|
+
import type { SuggestOptions } from './SuggestOptions.js';
|
|
5
|
+
import type { TyposDictionary } from './TyposDictionary.js';
|
|
6
|
+
export declare class FlagWordsDictionaryTrie extends SpellingDictionaryFromTrie {
|
|
7
|
+
readonly name: string;
|
|
8
|
+
readonly source: string;
|
|
9
|
+
readonly containsNoSuggestWords = false;
|
|
10
|
+
readonly options: SpellingDictionaryOptions;
|
|
11
|
+
constructor(trie: ITrie, name: string, source: string);
|
|
12
|
+
/**
|
|
13
|
+
* A Forbidden word list does not "have" valid words.
|
|
14
|
+
* Therefore it always returns false.
|
|
15
|
+
* @param _word - the word
|
|
16
|
+
* @param _options - options
|
|
17
|
+
* @returns always false
|
|
18
|
+
*/
|
|
19
|
+
has(_word: string, _options?: HasOptions): boolean;
|
|
20
|
+
find(word: string, hasOptions?: HasOptions): FindResult | undefined;
|
|
21
|
+
suggest(word: string, numSuggestions?: number, compoundMethod?: CompoundWordsMethod, numChanges?: number, ignoreCase?: boolean): SuggestionResult[];
|
|
22
|
+
suggest(word: string, suggestOptions: SuggestOptions): SuggestionResult[];
|
|
23
|
+
genSuggestions(): void;
|
|
24
|
+
readonly isDictionaryCaseSensitive: boolean;
|
|
25
|
+
terms(): Iterable<string>;
|
|
26
|
+
}
|
|
27
|
+
export declare class FlagWordsDictionary implements SpellingDictionary {
|
|
28
|
+
readonly name: string;
|
|
29
|
+
readonly source: string;
|
|
30
|
+
private dictTypos;
|
|
31
|
+
private dictTrie;
|
|
32
|
+
readonly containsNoSuggestWords = false;
|
|
33
|
+
readonly options: SpellingDictionaryOptions;
|
|
34
|
+
readonly type = "flag-words";
|
|
35
|
+
readonly mapWord: undefined;
|
|
36
|
+
constructor(name: string, source: string, dictTypos: TyposDictionary, dictTrie: FlagWordsDictionaryTrie | undefined);
|
|
37
|
+
/**
|
|
38
|
+
* A Forbidden word list does not "have" valid words.
|
|
39
|
+
* Therefore it always returns false.
|
|
40
|
+
* @param word - the word
|
|
41
|
+
* @param options - options
|
|
42
|
+
* @returns always false
|
|
43
|
+
*/
|
|
44
|
+
has(word: string, options?: HasOptions): boolean;
|
|
45
|
+
/** A more detailed search for a word, might take longer than `has` */
|
|
46
|
+
find(word: string, options?: HasOptions): FindResult | undefined;
|
|
47
|
+
isForbidden(word: string, ignoreCaseAndAccents?: IgnoreCaseOption): boolean;
|
|
48
|
+
isNoSuggestWord(word: string, options: HasOptions): boolean;
|
|
49
|
+
suggest(word: string, suggestOptions?: SuggestOptions): SuggestionResult[];
|
|
50
|
+
getPreferredSuggestions(word: string): PreferredSuggestion[];
|
|
51
|
+
genSuggestions(): void;
|
|
52
|
+
get size(): number;
|
|
53
|
+
readonly isDictionaryCaseSensitive: boolean;
|
|
54
|
+
getErrors?(): Error[];
|
|
55
|
+
terms(): Iterable<string>;
|
|
56
|
+
}
|
|
2
57
|
/**
|
|
3
58
|
* Create a dictionary where all words are to be forbidden.
|
|
4
59
|
* @param wordList - list of words
|
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { buildITrieFromWords, parseDictionaryLines } from 'cspell-trie-lib';
|
|
1
|
+
import { parseDictionary, parseDictionaryLines } from 'cspell-trie-lib';
|
|
3
2
|
import { createAutoResolveWeakCache } from '../util/AutoResolve.js';
|
|
4
3
|
import * as Defaults from './defaults.js';
|
|
5
4
|
import { defaultOptions } from './SpellingDictionary.js';
|
|
6
5
|
import { SpellingDictionaryFromTrie } from './SpellingDictionaryFromTrie.js';
|
|
7
6
|
import { createTyposDictionary } from './TyposDictionary.js';
|
|
8
|
-
class FlagWordsDictionaryTrie extends SpellingDictionaryFromTrie {
|
|
7
|
+
export class FlagWordsDictionaryTrie extends SpellingDictionaryFromTrie {
|
|
9
8
|
name;
|
|
10
9
|
source;
|
|
11
10
|
containsNoSuggestWords = false;
|
|
@@ -38,8 +37,11 @@ class FlagWordsDictionaryTrie extends SpellingDictionaryFromTrie {
|
|
|
38
37
|
return;
|
|
39
38
|
}
|
|
40
39
|
isDictionaryCaseSensitive = true;
|
|
40
|
+
terms() {
|
|
41
|
+
return this.trie.words();
|
|
42
|
+
}
|
|
41
43
|
}
|
|
42
|
-
class FlagWordsDictionary {
|
|
44
|
+
export class FlagWordsDictionary {
|
|
43
45
|
name;
|
|
44
46
|
source;
|
|
45
47
|
dictTypos;
|
|
@@ -47,6 +49,7 @@ class FlagWordsDictionary {
|
|
|
47
49
|
containsNoSuggestWords = false;
|
|
48
50
|
options = {};
|
|
49
51
|
type = 'flag-words';
|
|
52
|
+
mapWord = undefined;
|
|
50
53
|
constructor(name, source, dictTypos, dictTrie) {
|
|
51
54
|
this.name = name;
|
|
52
55
|
this.source = source;
|
|
@@ -89,9 +92,6 @@ class FlagWordsDictionary {
|
|
|
89
92
|
genSuggestions() {
|
|
90
93
|
return;
|
|
91
94
|
}
|
|
92
|
-
mapWord(word) {
|
|
93
|
-
return word;
|
|
94
|
-
}
|
|
95
95
|
get size() {
|
|
96
96
|
return this.dictTypos.size + (this.dictTrie?.size || 0);
|
|
97
97
|
}
|
|
@@ -99,6 +99,13 @@ class FlagWordsDictionary {
|
|
|
99
99
|
getErrors() {
|
|
100
100
|
return [];
|
|
101
101
|
}
|
|
102
|
+
*terms() {
|
|
103
|
+
if (this.dictTrie) {
|
|
104
|
+
yield* this.dictTrie.terms();
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
102
109
|
}
|
|
103
110
|
const createCache = createAutoResolveWeakCache();
|
|
104
111
|
/**
|
|
@@ -113,18 +120,14 @@ export function createFlagWordsDictionary(wordList, name, source) {
|
|
|
113
120
|
return createCache.get(wordList, () => {
|
|
114
121
|
const testSpecialCharacters = /[~*+]/;
|
|
115
122
|
const { t: specialWords, f: typoWords } = bisect(parseDictionaryLines(wordList, { stripCaseAndAccents: false }), (line) => testSpecialCharacters.test(line));
|
|
116
|
-
const
|
|
123
|
+
const trie = parseDictionary(specialWords, { stripCaseAndAccents: false, makeWordsForbidden: true });
|
|
124
|
+
const trieDict = new FlagWordsDictionaryTrie(trie, name, source);
|
|
117
125
|
const typosDict = createTyposDictionary(typoWords, name, source);
|
|
118
|
-
if (!
|
|
126
|
+
if (!specialWords.size)
|
|
119
127
|
return typosDict;
|
|
120
128
|
return new FlagWordsDictionary(name, source, typosDict, trieDict);
|
|
121
129
|
});
|
|
122
130
|
}
|
|
123
|
-
const regExpCleanIgnore = /^(!!)+/;
|
|
124
|
-
function buildTrieDict(words, name, source) {
|
|
125
|
-
const trie = buildITrieFromWords(pipe(words, opMap((w) => '!' + w), opMap((w) => w.replace(regExpCleanIgnore, ''))));
|
|
126
|
-
return new FlagWordsDictionaryTrie(trie, name, source);
|
|
127
|
-
}
|
|
128
131
|
function bisect(values, predicate) {
|
|
129
132
|
const t = new Set();
|
|
130
133
|
const f = new Set();
|
|
@@ -12,6 +12,7 @@ class IgnoreWordsDictionary {
|
|
|
12
12
|
containsNoSuggestWords = true;
|
|
13
13
|
options = {};
|
|
14
14
|
type = 'ignore';
|
|
15
|
+
mapWord = undefined;
|
|
15
16
|
constructor(name, source, words) {
|
|
16
17
|
this.name = name;
|
|
17
18
|
this.source = source;
|
|
@@ -62,9 +63,6 @@ class IgnoreWordsDictionary {
|
|
|
62
63
|
genSuggestions() {
|
|
63
64
|
return;
|
|
64
65
|
}
|
|
65
|
-
mapWord(word) {
|
|
66
|
-
return word;
|
|
67
|
-
}
|
|
68
66
|
get size() {
|
|
69
67
|
return this.dict.size;
|
|
70
68
|
}
|
|
@@ -15,7 +15,12 @@ export interface SearchOptions {
|
|
|
15
15
|
ignoreCase?: boolean | undefined;
|
|
16
16
|
}
|
|
17
17
|
export type SearchOptionsRO = Readonly<SearchOptions>;
|
|
18
|
-
export
|
|
18
|
+
export interface FindOptions extends SearchOptions {
|
|
19
|
+
/**
|
|
20
|
+
* Separate compound words using the specified separator.
|
|
21
|
+
*/
|
|
22
|
+
compoundSeparator?: string | undefined;
|
|
23
|
+
}
|
|
19
24
|
export type FindOptionsRO = Readonly<FindOptions>;
|
|
20
25
|
export interface Suggestion {
|
|
21
26
|
word: string;
|
|
@@ -86,12 +91,14 @@ export interface DictionaryInfo {
|
|
|
86
91
|
/** Options */
|
|
87
92
|
readonly options: SpellingDictionaryOptions;
|
|
88
93
|
}
|
|
94
|
+
export type MapWordSingleFn = (word: string) => string;
|
|
95
|
+
export type MapWordMultipleFn = (word: string) => string[];
|
|
89
96
|
export interface SpellingDictionary extends DictionaryInfo {
|
|
90
97
|
readonly type: string;
|
|
91
98
|
readonly containsNoSuggestWords: boolean;
|
|
92
99
|
has(word: string, options?: HasOptionsRO): boolean;
|
|
93
100
|
/** A more detailed search for a word, might take longer than `has` */
|
|
94
|
-
find(word: string, options?:
|
|
101
|
+
find(word: string, options?: FindOptionsRO): FindResult | undefined;
|
|
95
102
|
/**
|
|
96
103
|
* Checks if a word is forbidden.
|
|
97
104
|
* @param word - word to check.
|
|
@@ -113,17 +120,32 @@ export interface SpellingDictionary extends DictionaryInfo {
|
|
|
113
120
|
suggest(word: string, suggestOptions?: SuggestOptionsRO): SuggestionResult[];
|
|
114
121
|
getPreferredSuggestions?: (word: string) => PreferredSuggestion[];
|
|
115
122
|
genSuggestions(collector: SuggestionCollector, suggestOptions: SuggestOptionsRO): void;
|
|
116
|
-
mapWord
|
|
123
|
+
mapWord?: MapWordSingleFn | undefined;
|
|
117
124
|
/**
|
|
118
125
|
* Generates all possible word combinations by applying `repMap`.
|
|
119
126
|
* This acts a bit like brace expansions in globs.
|
|
120
127
|
* @param word - the word to map
|
|
121
128
|
* @returns array of adjusted words.
|
|
122
129
|
*/
|
|
123
|
-
remapWord?:
|
|
130
|
+
remapWord?: MapWordMultipleFn | undefined;
|
|
124
131
|
readonly size: number;
|
|
125
132
|
readonly isDictionaryCaseSensitive: boolean;
|
|
126
133
|
getErrors?(): Error[];
|
|
134
|
+
/**
|
|
135
|
+
* Get all the terms in the dictionary, they may be formatted according to the dictionary options.
|
|
136
|
+
* @returns the terms in the dictionary.
|
|
137
|
+
*/
|
|
138
|
+
terms?: () => Iterable<string>;
|
|
139
|
+
}
|
|
140
|
+
export interface SuggestDictionary extends SpellingDictionary {
|
|
141
|
+
getPreferredSuggestions: (word: string) => PreferredSuggestion[];
|
|
142
|
+
/**
|
|
143
|
+
* Determine if the word can appear in a list of suggestions.
|
|
144
|
+
* @param word - word
|
|
145
|
+
* @param ignoreCaseAndAccents - ignore case.
|
|
146
|
+
* @returns true if a word is suggested, otherwise false.
|
|
147
|
+
*/
|
|
148
|
+
isSuggestedWord(word: string, ignoreCaseAndAccents?: IgnoreCaseOption): boolean;
|
|
127
149
|
}
|
|
128
150
|
export declare const defaultOptions: SpellingDictionaryOptions;
|
|
129
151
|
//# sourceMappingURL=SpellingDictionary.d.ts.map
|
|
@@ -2,14 +2,11 @@ import { CASE_INSENSITIVE_PREFIX, CompoundWordsMethod } from 'cspell-trie-lib';
|
|
|
2
2
|
import { isDefined } from '../util/util.js';
|
|
3
3
|
import * as Defaults from './defaults.js';
|
|
4
4
|
import { defaultNumSuggestions, hasOptionToSearchOption, suggestionCollector } from './SpellingDictionaryMethods.js';
|
|
5
|
-
function identityString(w) {
|
|
6
|
-
return w;
|
|
7
|
-
}
|
|
8
5
|
class SpellingDictionaryCollectionImpl {
|
|
9
6
|
dictionaries;
|
|
10
7
|
name;
|
|
11
8
|
options = { weightMap: undefined };
|
|
12
|
-
mapWord =
|
|
9
|
+
mapWord = undefined;
|
|
13
10
|
type = 'SpellingDictionaryCollection';
|
|
14
11
|
source;
|
|
15
12
|
isDictionaryCaseSensitive;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { Buffer } from 'node:buffer';
|
|
2
1
|
import type { ITrie, SuggestionCollector, SuggestionResult } from 'cspell-trie-lib';
|
|
3
|
-
import type {
|
|
2
|
+
import type { RepMapper } from '../util/repMap.js';
|
|
3
|
+
import type { FindOptionsRO, FindResult, HasOptionsRO, MapWordMultipleFn, MapWordSingleFn, PreferredSuggestion, SpellingDictionary, SpellingDictionaryOptionsRO } from './SpellingDictionary.js';
|
|
4
4
|
import type { SuggestOptions } from './SuggestOptions.js';
|
|
5
5
|
export declare class SpellingDictionaryFromTrie implements SpellingDictionary {
|
|
6
6
|
#private;
|
|
@@ -11,8 +11,9 @@ export declare class SpellingDictionaryFromTrie implements SpellingDictionary {
|
|
|
11
11
|
private _size;
|
|
12
12
|
readonly knownWords: Set<string>;
|
|
13
13
|
readonly unknownWords: Set<string>;
|
|
14
|
-
readonly mapWord:
|
|
15
|
-
readonly remapWord:
|
|
14
|
+
readonly mapWord: MapWordSingleFn | undefined;
|
|
15
|
+
readonly remapWord: MapWordMultipleFn | undefined;
|
|
16
|
+
readonly repMapper: RepMapper | undefined;
|
|
16
17
|
readonly type = "SpellingDictionaryFromTrie";
|
|
17
18
|
readonly isDictionaryCaseSensitive: boolean;
|
|
18
19
|
readonly containsNoSuggestWords: boolean;
|
|
@@ -20,7 +21,7 @@ export declare class SpellingDictionaryFromTrie implements SpellingDictionary {
|
|
|
20
21
|
constructor(trie: ITrie, name: string, options: SpellingDictionaryOptionsRO, source?: string, size?: number);
|
|
21
22
|
get size(): number;
|
|
22
23
|
has(word: string, hasOptions?: HasOptionsRO): boolean;
|
|
23
|
-
find(word: string, hasOptions?:
|
|
24
|
+
find(word: string, hasOptions?: FindOptionsRO): FindResult | undefined;
|
|
24
25
|
private resolveOptions;
|
|
25
26
|
private _find;
|
|
26
27
|
private findAnyForm;
|
|
@@ -30,6 +31,7 @@ export declare class SpellingDictionaryFromTrie implements SpellingDictionary {
|
|
|
30
31
|
suggest(word: string, suggestOptions?: SuggestOptions): SuggestionResult[];
|
|
31
32
|
private _suggest;
|
|
32
33
|
genSuggestions(collector: SuggestionCollector, suggestOptions: SuggestOptions): void;
|
|
34
|
+
getPreferredSuggestions(word: string): PreferredSuggestion[];
|
|
33
35
|
getErrors(): Error[];
|
|
34
36
|
}
|
|
35
37
|
/**
|
|
@@ -40,8 +42,8 @@ export declare class SpellingDictionaryFromTrie implements SpellingDictionary {
|
|
|
40
42
|
* @param options - options.
|
|
41
43
|
* @returns SpellingDictionary
|
|
42
44
|
*/
|
|
43
|
-
export declare function createSpellingDictionaryFromTrieFile(data: string |
|
|
44
|
-
declare function outerWordForms(word: string,
|
|
45
|
+
export declare function createSpellingDictionaryFromTrieFile(data: string | Uint8Array<ArrayBuffer>, name: string, source: string, options: SpellingDictionaryOptionsRO): SpellingDictionary;
|
|
46
|
+
declare function outerWordForms(word: string, repMapper: RepMapper | undefined): Iterable<string>;
|
|
45
47
|
export declare const __testing__: {
|
|
46
48
|
outerWordForms: typeof outerWordForms;
|
|
47
49
|
};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { CompoundWordsMethod, decodeTrie, suggestionCollector } from 'cspell-trie-lib';
|
|
2
2
|
import { clean } from '../util/clean.js';
|
|
3
|
+
import { measurePerf } from '../util/performance.js';
|
|
3
4
|
import { createMapper, createRepMapper } from '../util/repMap.js';
|
|
4
5
|
import * as Defaults from './defaults.js';
|
|
5
6
|
import { createWeightMapFromDictionaryInformation, defaultNumSuggestions, hasOptionToSearchOption, impersonateCollector, wordSearchForms, wordSuggestForms, } from './SpellingDictionaryMethods.js';
|
|
@@ -13,6 +14,7 @@ export class SpellingDictionaryFromTrie {
|
|
|
13
14
|
unknownWords = new Set();
|
|
14
15
|
mapWord;
|
|
15
16
|
remapWord;
|
|
17
|
+
repMapper;
|
|
16
18
|
type = 'SpellingDictionaryFromTrie';
|
|
17
19
|
isDictionaryCaseSensitive;
|
|
18
20
|
containsNoSuggestWords;
|
|
@@ -25,9 +27,12 @@ export class SpellingDictionaryFromTrie {
|
|
|
25
27
|
this.name = name;
|
|
26
28
|
this.options = options;
|
|
27
29
|
this.source = source;
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
this.
|
|
30
|
+
const mapWord = createMapper(options.repMap, options.dictionaryInformation?.ignore);
|
|
31
|
+
const repMapper = createRepMapper(options.repMap, options.dictionaryInformation?.ignore);
|
|
32
|
+
this.mapWord = mapWord?.fn;
|
|
33
|
+
this.remapWord = repMapper?.fn;
|
|
34
|
+
this.repMapper = repMapper;
|
|
35
|
+
this.isDictionaryCaseSensitive = options.caseSensitive ?? true;
|
|
31
36
|
this.containsNoSuggestWords = options.noSuggest || false;
|
|
32
37
|
this._size = size || 0;
|
|
33
38
|
this.weightMap = options.weightMap || createWeightMapFromDictionaryInformation(options.dictionaryInformation);
|
|
@@ -55,12 +60,12 @@ export class SpellingDictionaryFromTrie {
|
|
|
55
60
|
}
|
|
56
61
|
has(word, hasOptions) {
|
|
57
62
|
const { useCompounds, ignoreCase } = this.resolveOptions(hasOptions);
|
|
58
|
-
const r = this._find(word, useCompounds, ignoreCase);
|
|
63
|
+
const r = this._find(word, useCompounds, ignoreCase, undefined);
|
|
59
64
|
return (r && !r.forbidden && !!r.found) || false;
|
|
60
65
|
}
|
|
61
66
|
find(word, hasOptions) {
|
|
62
67
|
const { useCompounds, ignoreCase } = this.resolveOptions(hasOptions);
|
|
63
|
-
const r = this._find(word, useCompounds, ignoreCase);
|
|
68
|
+
const r = this._find(word, useCompounds, ignoreCase, hasOptions?.compoundSeparator);
|
|
64
69
|
const { forbidden = this.#isForbidden(word) } = r || {};
|
|
65
70
|
if (this.#ignoreForbiddenWords && forbidden) {
|
|
66
71
|
return undefined;
|
|
@@ -75,20 +80,23 @@ export class SpellingDictionaryFromTrie {
|
|
|
75
80
|
const { useCompounds = this.options.useCompounds, ignoreCase = Defaults.ignoreCase } = hasOptionToSearchOption(hasOptions);
|
|
76
81
|
return { useCompounds, ignoreCase };
|
|
77
82
|
}
|
|
78
|
-
_find = (word, useCompounds, ignoreCase) => this.findAnyForm(word, useCompounds, ignoreCase);
|
|
79
|
-
findAnyForm(word, useCompounds, ignoreCase) {
|
|
80
|
-
const outerForms = outerWordForms(word, this.
|
|
83
|
+
_find = (word, useCompounds, ignoreCase, compoundSeparator) => this.findAnyForm(word, useCompounds, ignoreCase, compoundSeparator);
|
|
84
|
+
findAnyForm(word, useCompounds, ignoreCase, compoundSeparator) {
|
|
85
|
+
const outerForms = outerWordForms(word, this.repMapper);
|
|
81
86
|
for (const form of outerForms) {
|
|
82
|
-
const r = this._findAnyForm(form, useCompounds, ignoreCase);
|
|
87
|
+
const r = this._findAnyForm(form, useCompounds, ignoreCase, compoundSeparator);
|
|
83
88
|
if (r)
|
|
84
89
|
return r;
|
|
85
90
|
}
|
|
86
91
|
return undefined;
|
|
87
92
|
}
|
|
88
|
-
_findAnyForm(mWord, useCompounds, ignoreCase) {
|
|
89
|
-
|
|
93
|
+
_findAnyForm(mWord, useCompounds, ignoreCase, compoundSeparator) {
|
|
94
|
+
let opts = ignoreCase
|
|
90
95
|
? this.#findWordOptionsNotCaseSensitive
|
|
91
96
|
: this.#findWordOptionsCaseSensitive;
|
|
97
|
+
if (compoundSeparator) {
|
|
98
|
+
opts = { ...opts, compoundSeparator };
|
|
99
|
+
}
|
|
92
100
|
const findResult = this.trie.findWord(mWord, opts);
|
|
93
101
|
if (findResult.found !== false) {
|
|
94
102
|
return findResult;
|
|
@@ -149,6 +157,12 @@ export class SpellingDictionaryFromTrie {
|
|
|
149
157
|
this.trie.genSuggestions(impersonateCollector(collector, w), _compoundMethod);
|
|
150
158
|
}
|
|
151
159
|
}
|
|
160
|
+
getPreferredSuggestions(word) {
|
|
161
|
+
if (!this.trie.hasPreferredSuggestions)
|
|
162
|
+
return [];
|
|
163
|
+
const sugs = [...this.trie.getPreferredSuggestions(word)];
|
|
164
|
+
return sugs.map((sug, i) => ({ word: sug, cost: i + 1, isPreferred: true }));
|
|
165
|
+
}
|
|
152
166
|
getErrors() {
|
|
153
167
|
return [];
|
|
154
168
|
}
|
|
@@ -162,25 +176,49 @@ export class SpellingDictionaryFromTrie {
|
|
|
162
176
|
* @returns SpellingDictionary
|
|
163
177
|
*/
|
|
164
178
|
export function createSpellingDictionaryFromTrieFile(data, name, source, options) {
|
|
179
|
+
const endPerf = measurePerf('createSpellingDictionaryFromTrieFile');
|
|
165
180
|
const trie = decodeTrie(data);
|
|
166
|
-
|
|
181
|
+
const d = new SpellingDictionaryFromTrie(trie, name, options, source);
|
|
182
|
+
endPerf();
|
|
183
|
+
return d;
|
|
167
184
|
}
|
|
168
|
-
|
|
185
|
+
// eslint-disable-next-line no-control-regex
|
|
186
|
+
const isAsciiRange = /^[\u0000-\u007F]*$/;
|
|
187
|
+
function* outerWordForms(word, repMapper) {
|
|
169
188
|
// Only generate the needed forms.
|
|
170
189
|
const sent = new Set();
|
|
171
190
|
let w = word;
|
|
172
191
|
const ww = w;
|
|
173
192
|
yield w;
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
if (w
|
|
177
|
-
yield w;
|
|
193
|
+
// this function is called for every word lookup, so needs to be efficient.
|
|
194
|
+
// Check to see if it is a pure ascii word.
|
|
195
|
+
if (!isAsciiRange.test(w)) {
|
|
178
196
|
sent.add(w);
|
|
197
|
+
w = word.normalize('NFC');
|
|
198
|
+
if (w !== ww) {
|
|
199
|
+
yield w;
|
|
200
|
+
sent.add(w);
|
|
201
|
+
}
|
|
202
|
+
w = word.normalize('NFD');
|
|
203
|
+
if (w !== ww && !sent.has(w)) {
|
|
204
|
+
yield w;
|
|
205
|
+
sent.add(w);
|
|
206
|
+
}
|
|
179
207
|
}
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
208
|
+
if (!repMapper)
|
|
209
|
+
return;
|
|
210
|
+
const mapWord = repMapper.fn;
|
|
211
|
+
// nothing was added to the set, just do the map.
|
|
212
|
+
if (!sent.size) {
|
|
213
|
+
if (!repMapper.test.test(ww))
|
|
214
|
+
return;
|
|
215
|
+
for (const m of mapWord(ww)) {
|
|
216
|
+
if (m !== ww && !sent.has(m)) {
|
|
217
|
+
yield m;
|
|
218
|
+
sent.add(m);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
return;
|
|
184
222
|
}
|
|
185
223
|
for (const f of sent) {
|
|
186
224
|
for (const m of mapWord(f)) {
|
|
@@ -1,14 +1,8 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { SuggestionResult } from 'cspell-trie-lib';
|
|
2
|
+
import type { SuggestDictionary } from './SpellingDictionary.js';
|
|
2
3
|
import { type TypoEntry, type TyposDef } from './Typos/index.js';
|
|
3
|
-
export interface
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Determine if the word can appear in a list of suggestions.
|
|
7
|
-
* @param word - word
|
|
8
|
-
* @param ignoreCaseAndAccents - ignore case.
|
|
9
|
-
* @returns true if a word is suggested, otherwise false.
|
|
10
|
-
*/
|
|
11
|
-
isSuggestedWord(word: string, ignoreCaseAndAccents?: IgnoreCaseOption): boolean;
|
|
4
|
+
export interface PreferredSuggestionResult extends SuggestionResult {
|
|
5
|
+
isPreferred: true;
|
|
12
6
|
}
|
|
13
7
|
/**
|
|
14
8
|
* Create a dictionary where all words are to be forbidden.
|
|
@@ -12,6 +12,7 @@ class SuggestDictionaryImpl {
|
|
|
12
12
|
options = {};
|
|
13
13
|
type = 'suggest';
|
|
14
14
|
size;
|
|
15
|
+
mapWord = undefined;
|
|
15
16
|
/**
|
|
16
17
|
* Note: ignoreWordsLower is only suggestions with the case and accents removed.
|
|
17
18
|
* The logic is that if someone explicity ignored an upper case version, it does not
|
|
@@ -89,9 +90,6 @@ class SuggestDictionaryImpl {
|
|
|
89
90
|
const sugs = this.suggest(collector.word);
|
|
90
91
|
sugs.forEach((result) => collector.add(result));
|
|
91
92
|
}
|
|
92
|
-
mapWord(word) {
|
|
93
|
-
return word;
|
|
94
|
-
}
|
|
95
93
|
isDictionaryCaseSensitive = true;
|
|
96
94
|
getErrors() {
|
|
97
95
|
return [];
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { TypoEntry, TyposDef } from './typos.js';
|
|
2
|
+
export declare function isSuggestion(v: string): boolean;
|
|
2
3
|
export declare function createTyposDefFromEntries(entries: Iterable<TypoEntry>): TyposDef;
|
|
3
4
|
export declare function sanitizeIntoTypoDef(dirtyDef: TyposDef | Record<string, unknown> | unknown): TyposDef | undefined;
|
|
4
5
|
/**
|
|
@@ -1,13 +1,16 @@
|
|
|
1
|
-
import assert from '
|
|
2
|
-
import { appendToDef, createTyposDef } from './util.js';
|
|
1
|
+
import { appendToDef, assert, createTyposDef } from './util.js';
|
|
3
2
|
function assertString(v) {
|
|
4
3
|
assert(typeof v === 'string', 'A string was expected.');
|
|
5
4
|
return true;
|
|
6
5
|
}
|
|
7
6
|
const suggestionsSeparator = /[,]/;
|
|
8
|
-
const typoSuggestionsSeparator = /:|->/;
|
|
7
|
+
// const typoSuggestionsSeparator = /:|->/;
|
|
9
8
|
const typoEntrySeparator = /[\n;]/;
|
|
10
9
|
const inlineComment = /#.*/gm;
|
|
10
|
+
const sugFormatRegex = /^\s*(?:[!~:])*(?<word>.*?)(?<separator>(->|:([0-9a-f]{1,2}:)?))(?<sugs>.*)$/;
|
|
11
|
+
export function isSuggestion(v) {
|
|
12
|
+
return sugFormatRegex.test(v);
|
|
13
|
+
}
|
|
11
14
|
export function createTyposDefFromEntries(entries) {
|
|
12
15
|
const def = Object.create(null);
|
|
13
16
|
for (const entry of entries) {
|
|
@@ -116,11 +119,33 @@ export function parseTyposLine(line) {
|
|
|
116
119
|
}
|
|
117
120
|
return sanitizeIntoTypoDef(line);
|
|
118
121
|
}
|
|
122
|
+
/**
|
|
123
|
+
* Split text into multiple lines
|
|
124
|
+
* @param content - text content
|
|
125
|
+
* @returns
|
|
126
|
+
*/
|
|
119
127
|
function splitIntoLines(content) {
|
|
120
128
|
return trimAndFilter(normalize(content).split(typoEntrySeparator));
|
|
121
129
|
}
|
|
130
|
+
/**
|
|
131
|
+
* Split a typo entry into key and value
|
|
132
|
+
* Entry format:
|
|
133
|
+
* - `word:suggestion`
|
|
134
|
+
* - `word->suggestion`
|
|
135
|
+
* - `word: first, second, third suggestions`
|
|
136
|
+
* - sequencing values are ignored, e.g.: `:0:`, `:1:`, `:a:`
|
|
137
|
+
* - `word:0:first`
|
|
138
|
+
* - `word:1:second`
|
|
139
|
+
* @param line - the line of text
|
|
140
|
+
* @returns
|
|
141
|
+
*/
|
|
122
142
|
function splitEntry(line) {
|
|
123
|
-
|
|
143
|
+
// Remove any sequencing values like `:1:` or `:a:`
|
|
144
|
+
const m = line.match(sugFormatRegex);
|
|
145
|
+
if (!m?.groups) {
|
|
146
|
+
return [line.trim(), undefined];
|
|
147
|
+
}
|
|
148
|
+
return [m.groups.word.trim(), m.groups.sugs.trim()];
|
|
124
149
|
}
|
|
125
150
|
export function parseTyposFile(content) {
|
|
126
151
|
const lines = splitIntoLines(content.replaceAll(inlineComment, ''));
|
|
@@ -28,4 +28,5 @@ export declare function extractAllSuggestions(typosDef: TyposDef): Set<string>;
|
|
|
28
28
|
* @returns set of ignored words with the prefix removed.
|
|
29
29
|
*/
|
|
30
30
|
export declare function extractIgnoreValues(typosDef: TyposDef, ignorePrefix: string): Set<string>;
|
|
31
|
+
export declare function assert(condition: unknown, message?: string): asserts condition;
|
|
31
32
|
//# sourceMappingURL=util.d.ts.map
|
|
@@ -103,4 +103,9 @@ function isArray(v) {
|
|
|
103
103
|
function hasSuggestions(v) {
|
|
104
104
|
return isString(v) || isArray(v);
|
|
105
105
|
}
|
|
106
|
+
export function assert(condition, message = 'Assert Failed') {
|
|
107
|
+
if (condition)
|
|
108
|
+
return;
|
|
109
|
+
throw new Error(message);
|
|
110
|
+
}
|
|
106
111
|
//# sourceMappingURL=util.js.map
|
|
@@ -12,6 +12,7 @@ class TyposDictionaryImpl {
|
|
|
12
12
|
options = {};
|
|
13
13
|
type = 'typos';
|
|
14
14
|
size;
|
|
15
|
+
mapWord = undefined;
|
|
15
16
|
ignoreWords;
|
|
16
17
|
/**
|
|
17
18
|
* Note: ignoreWordsLower is only suggestions with the case and accents removed.
|
|
@@ -122,9 +123,6 @@ class TyposDictionaryImpl {
|
|
|
122
123
|
getPreferredSuggestions(word) {
|
|
123
124
|
return this._suggest(word) || this._suggest(word.toLowerCase()) || [];
|
|
124
125
|
}
|
|
125
|
-
mapWord(word) {
|
|
126
|
-
return word;
|
|
127
|
-
}
|
|
128
126
|
isDictionaryCaseSensitive = true;
|
|
129
127
|
getErrors() {
|
|
130
128
|
return [];
|
|
@@ -8,7 +8,7 @@ import type { DictionaryInfo, SpellingDictionary, SpellingDictionaryOptions } fr
|
|
|
8
8
|
* @param options - dictionary options
|
|
9
9
|
* @returns a Spelling Dictionary
|
|
10
10
|
*/
|
|
11
|
-
export declare function createSpellingDictionary(wordList: readonly string[] | IterableLike<string>, name: string, source: string, options?: SpellingDictionaryOptions | undefined): SpellingDictionary;
|
|
11
|
+
export declare function createSpellingDictionary(wordList: readonly string[] | IterableLike<string>, name: string, source: string, options?: SpellingDictionaryOptions | undefined, disableSuggestionsHandling?: boolean): SpellingDictionary;
|
|
12
12
|
export interface SpellingDictionaryLoadError extends Error {
|
|
13
13
|
/** The Error Name */
|
|
14
14
|
readonly name: string;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { fileURLToPath } from 'node:url';
|
|
2
2
|
import { buildITrieFromWords, parseDictionaryLines } from 'cspell-trie-lib';
|
|
3
3
|
import { deepEqual } from 'fast-equals';
|
|
4
|
+
import { measurePerf } from '../util/performance.js';
|
|
4
5
|
import { AutoWeakCache, SimpleCache } from '../util/simpleCache.js';
|
|
5
6
|
import { defaultOptions } from './SpellingDictionary.js';
|
|
6
7
|
import { SpellingDictionaryFromTrie } from './SpellingDictionaryFromTrie.js';
|
|
@@ -16,8 +17,14 @@ const cachedParamsByWordList = new SimpleCache(64);
|
|
|
16
17
|
* @param options - dictionary options
|
|
17
18
|
* @returns a Spelling Dictionary
|
|
18
19
|
*/
|
|
19
|
-
export function createSpellingDictionary(wordList, name, source, options) {
|
|
20
|
-
const params = [
|
|
20
|
+
export function createSpellingDictionary(wordList, name, source, options, disableSuggestionsHandling) {
|
|
21
|
+
const params = [
|
|
22
|
+
wordList,
|
|
23
|
+
name,
|
|
24
|
+
source.toString(),
|
|
25
|
+
options,
|
|
26
|
+
disableSuggestionsHandling,
|
|
27
|
+
];
|
|
21
28
|
if (!Array.isArray(wordList)) {
|
|
22
29
|
return _createSpellingDictionary(params);
|
|
23
30
|
}
|
|
@@ -34,16 +41,20 @@ export function createSpellingDictionary(wordList, name, source, options) {
|
|
|
34
41
|
return cachedDictionaries.get(params);
|
|
35
42
|
}
|
|
36
43
|
function _createSpellingDictionary(params) {
|
|
37
|
-
const [
|
|
44
|
+
const n = ''; // ':' + params[1]; // Add name to perf name for easier debugging.
|
|
45
|
+
const endPerf = measurePerf('createSpellingDictionary' + n);
|
|
46
|
+
const [wordList, name, source, options, disableSuggestionHandling = false] = params;
|
|
38
47
|
// console.log(`createSpellingDictionary ${name} ${source}`);
|
|
39
|
-
const parseOptions = { stripCaseAndAccents: options?.supportNonStrictSearches ?? true };
|
|
48
|
+
const parseOptions = { stripCaseAndAccents: options?.supportNonStrictSearches ?? true, disableSuggestionHandling };
|
|
40
49
|
const words = parseDictionaryLines(wordList, parseOptions);
|
|
41
50
|
const trie = buildITrieFromWords(words);
|
|
42
51
|
const opts = { ...(options || defaultOptions) };
|
|
43
52
|
if (opts.weightMap === undefined && opts.dictionaryInformation) {
|
|
44
53
|
opts.weightMap = createWeightMapFromDictionaryInformation(opts.dictionaryInformation);
|
|
45
54
|
}
|
|
46
|
-
|
|
55
|
+
const d = new SpellingDictionaryFromTrie(trie, name, opts, source);
|
|
56
|
+
endPerf();
|
|
57
|
+
return d;
|
|
47
58
|
}
|
|
48
59
|
export function createFailedToLoadDictionary(name, sourceUrl, error, options) {
|
|
49
60
|
const sourceHref = typeof sourceUrl === 'string' ? sourceUrl : sourceUrl.href;
|
|
@@ -59,7 +70,7 @@ export function createFailedToLoadDictionary(name, sourceUrl, error, options) {
|
|
|
59
70
|
isNoSuggestWord: () => false,
|
|
60
71
|
isForbidden: () => false,
|
|
61
72
|
suggest: () => [],
|
|
62
|
-
mapWord:
|
|
73
|
+
mapWord: undefined,
|
|
63
74
|
genSuggestions: () => {
|
|
64
75
|
return;
|
|
65
76
|
},
|
|
@@ -3,7 +3,7 @@ export { createInlineSpellingDictionary } from './createInlineSpellingDictionary
|
|
|
3
3
|
export { createFailedToLoadDictionary, createSpellingDictionary } from './createSpellingDictionary.js';
|
|
4
4
|
export { createFlagWordsDictionary, createFlagWordsDictionary as createForbiddenWordsDictionary, } from './FlagWordsDictionary.js';
|
|
5
5
|
export { createIgnoreWordsDictionary } from './IgnoreWordsDictionary.js';
|
|
6
|
-
export type { DictionaryDefinitionInline, FindOptions, FindResult, HasOptions, PreferredSuggestion, SearchOptions, SpellingDictionary, SpellingDictionaryOptions, } from './SpellingDictionary.js';
|
|
6
|
+
export type { DictionaryDefinitionInline, FindOptions, FindResult, HasOptions, PreferredSuggestion, SearchOptions, SpellingDictionary, SpellingDictionaryOptions, Suggestion, } from './SpellingDictionary.js';
|
|
7
7
|
export { createCollection, SpellingDictionaryCollection } from './SpellingDictionaryCollection.js';
|
|
8
8
|
export { createSpellingDictionaryFromTrieFile } from './SpellingDictionaryFromTrie.js';
|
|
9
9
|
export { createSuggestDictionary } from './SuggestDictionary.js';
|
package/dist/index.d.ts
CHANGED
|
@@ -1,11 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
export type { CachingDictionary, FindOptions, FindResult, HasOptions, PreferredSuggestion, SearchOptions, SpellingDictionary, SpellingDictionaryCollection, SpellingDictionaryOptions, SuggestionCollector, SuggestionResult, SuggestOptions, } from './SpellingDictionary/index.js';
|
|
1
|
+
export { dictionaryCacheClearLog, dictionaryCacheEnableLogging, dictionaryCacheGetLog, } from './SpellingDictionary/CachingDictionary.js';
|
|
2
|
+
export type { CachingDictionary, FindOptions, FindResult, HasOptions, PreferredSuggestion, SearchOptions, SpellingDictionary, SpellingDictionaryCollection, SpellingDictionaryOptions, Suggestion, SuggestionCollector, SuggestionResult, SuggestOptions, } from './SpellingDictionary/index.js';
|
|
3
3
|
export { createCachingDictionary, createCollection, createFailedToLoadDictionary, createFlagWordsDictionary, createForbiddenWordsDictionary, createIgnoreWordsDictionary, createInlineSpellingDictionary, createSpellingDictionary, createSpellingDictionaryFromTrieFile, createSuggestDictionary, createSuggestOptions, } from './SpellingDictionary/index.js';
|
|
4
|
-
/**
|
|
5
|
-
* Debugging utilities.
|
|
6
|
-
*/
|
|
7
|
-
export declare const _debug: {
|
|
8
|
-
cacheDictionaryEnableLogging: typeof cacheDictionaryEnableLogging;
|
|
9
|
-
cacheDictionaryGetLog: typeof cacheDictionaryGetLog;
|
|
10
|
-
};
|
|
11
4
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.js
CHANGED
|
@@ -1,10 +1,3 @@
|
|
|
1
|
-
|
|
1
|
+
export { dictionaryCacheClearLog, dictionaryCacheEnableLogging, dictionaryCacheGetLog, } from './SpellingDictionary/CachingDictionary.js';
|
|
2
2
|
export { createCachingDictionary, createCollection, createFailedToLoadDictionary, createFlagWordsDictionary, createForbiddenWordsDictionary, createIgnoreWordsDictionary, createInlineSpellingDictionary, createSpellingDictionary, createSpellingDictionaryFromTrieFile, createSuggestDictionary, createSuggestOptions, } from './SpellingDictionary/index.js';
|
|
3
|
-
/**
|
|
4
|
-
* Debugging utilities.
|
|
5
|
-
*/
|
|
6
|
-
export const _debug = {
|
|
7
|
-
cacheDictionaryEnableLogging,
|
|
8
|
-
cacheDictionaryGetLog,
|
|
9
|
-
};
|
|
10
3
|
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export declare function measurePerfStart(name: string): void;
|
|
2
|
+
export declare function measurePerfEnd(name: string): void;
|
|
3
|
+
/**
|
|
4
|
+
* Creates performance marks and measures the time taken between them.
|
|
5
|
+
* @param name - name of the performance entry
|
|
6
|
+
* @returns a function to stop the timer.
|
|
7
|
+
*/
|
|
8
|
+
export declare function measurePerf(name: string): () => void;
|
|
9
|
+
//# sourceMappingURL=performance.d.ts.map
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export function measurePerfStart(name) {
|
|
2
|
+
performance.mark(name + '-start');
|
|
3
|
+
}
|
|
4
|
+
export function measurePerfEnd(name) {
|
|
5
|
+
performance.mark(name + '-end');
|
|
6
|
+
performance.measure(name, name + '-start', name + '-end');
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Creates performance marks and measures the time taken between them.
|
|
10
|
+
* @param name - name of the performance entry
|
|
11
|
+
* @returns a function to stop the timer.
|
|
12
|
+
*/
|
|
13
|
+
export function measurePerf(name) {
|
|
14
|
+
measurePerfStart(name);
|
|
15
|
+
return () => {
|
|
16
|
+
measurePerfEnd(name);
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=performance.js.map
|
package/dist/util/repMap.d.ts
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import type { CharacterSet, ReplaceMap } from '@cspell/cspell-types';
|
|
2
|
-
export
|
|
3
|
-
|
|
2
|
+
export interface ReplaceMapper {
|
|
3
|
+
test?: RegExp;
|
|
4
|
+
fn: (src: string) => string;
|
|
5
|
+
}
|
|
6
|
+
export declare function createMapper(repMap: ReplaceMap | undefined, ignoreCharset?: string): ReplaceMapper | undefined;
|
|
4
7
|
declare function charsetToRepMapRegEx(charset: CharacterSet | undefined, replaceWith?: string): ReplaceMap | undefined;
|
|
5
8
|
declare function createMapperRegExp(repMap: ReplaceMap): RegExp;
|
|
6
9
|
interface RepTrieNode {
|
|
@@ -12,7 +15,11 @@ interface Edit {
|
|
|
12
15
|
e: number;
|
|
13
16
|
r: string;
|
|
14
17
|
}
|
|
15
|
-
export
|
|
18
|
+
export interface RepMapper {
|
|
19
|
+
test: RegExp;
|
|
20
|
+
fn: (word: string) => string[];
|
|
21
|
+
}
|
|
22
|
+
export declare function createRepMapper(repMap: ReplaceMap | undefined, ignoreCharset?: string): RepMapper | undefined;
|
|
16
23
|
declare function applyEdits(word: string, edits: Edit[]): string[];
|
|
17
24
|
declare function calcAllEdits(root: RepTrieNode, word: string): Edit[];
|
|
18
25
|
declare function createTrie(repMap: ReplaceMap | undefined, ignoreCharset?: string): RepTrieNode;
|
package/dist/util/repMap.js
CHANGED
|
@@ -3,7 +3,7 @@ import { escapeRegEx } from './regexHelper.js';
|
|
|
3
3
|
import { isDefined } from './util.js';
|
|
4
4
|
export function createMapper(repMap, ignoreCharset) {
|
|
5
5
|
if (!repMap && !ignoreCharset)
|
|
6
|
-
return
|
|
6
|
+
return undefined;
|
|
7
7
|
repMap = repMap || [];
|
|
8
8
|
const charsetMap = charsetToRepMapRegEx(ignoreCharset);
|
|
9
9
|
if (charsetMap) {
|
|
@@ -11,7 +11,7 @@ export function createMapper(repMap, ignoreCharset) {
|
|
|
11
11
|
}
|
|
12
12
|
const filteredMap = repMap.filter(([match, _]) => !!match);
|
|
13
13
|
if (!filteredMap.length) {
|
|
14
|
-
return
|
|
14
|
+
return undefined;
|
|
15
15
|
}
|
|
16
16
|
const regEx = createMapperRegExp(repMap);
|
|
17
17
|
const values = repMap.filter(([match, _]) => !!match).map(([_, into]) => into);
|
|
@@ -19,8 +19,12 @@ export function createMapper(repMap, ignoreCharset) {
|
|
|
19
19
|
const index = matches.findIndex((a) => !!a);
|
|
20
20
|
return 0 <= index && index < values.length ? values[index] : m;
|
|
21
21
|
}
|
|
22
|
-
|
|
22
|
+
function fn(s) {
|
|
23
23
|
return s.replace(regEx, resolve);
|
|
24
|
+
}
|
|
25
|
+
return {
|
|
26
|
+
test: regexpRemoveFlags(regEx, 'gm'),
|
|
27
|
+
fn,
|
|
24
28
|
};
|
|
25
29
|
}
|
|
26
30
|
function charsetToRepMapRegEx(charset, replaceWith = '') {
|
|
@@ -68,13 +72,22 @@ function createMapperRegExp(repMap) {
|
|
|
68
72
|
return regEx;
|
|
69
73
|
}
|
|
70
74
|
export function createRepMapper(repMap, ignoreCharset) {
|
|
71
|
-
if (!repMap && !ignoreCharset)
|
|
72
|
-
return
|
|
75
|
+
if (!repMap?.length && !ignoreCharset)
|
|
76
|
+
return undefined;
|
|
77
|
+
let tRepMap = repMap || [];
|
|
78
|
+
const charsetMap = charsetToRepMapRegEx(ignoreCharset);
|
|
79
|
+
if (charsetMap) {
|
|
80
|
+
tRepMap = [...tRepMap, ...charsetMap];
|
|
81
|
+
}
|
|
82
|
+
const regEx = createMapperRegExp(tRepMap);
|
|
73
83
|
const trie = createTrie(repMap, ignoreCharset);
|
|
74
84
|
// const root = createTrie(repMap, ignoreCharset);
|
|
75
|
-
return
|
|
76
|
-
|
|
77
|
-
|
|
85
|
+
return {
|
|
86
|
+
test: regexpRemoveFlags(regEx, 'gm'),
|
|
87
|
+
fn: (word) => {
|
|
88
|
+
const edits = calcAllEdits(trie, word);
|
|
89
|
+
return applyEdits(word, edits);
|
|
90
|
+
},
|
|
78
91
|
};
|
|
79
92
|
}
|
|
80
93
|
function applyEdits(word, edits) {
|
|
@@ -143,6 +156,11 @@ function addToTrie(node, match, replaceWith) {
|
|
|
143
156
|
s.add(replaceWith);
|
|
144
157
|
node.rep = [...s];
|
|
145
158
|
}
|
|
159
|
+
function regexpRemoveFlags(re, flagsToRemove) {
|
|
160
|
+
const toRemove = new Set(flagsToRemove);
|
|
161
|
+
const flags = [...re.flags].filter((f) => !toRemove.has(f)).join('');
|
|
162
|
+
return new RegExp(re.source, flags);
|
|
163
|
+
}
|
|
146
164
|
export const __testing__ = {
|
|
147
165
|
charsetToRepMap: charsetToRepMapRegEx,
|
|
148
166
|
createMapperRegExp,
|
package/package.json
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"access": "public",
|
|
5
5
|
"provenance": true
|
|
6
6
|
},
|
|
7
|
-
"version": "9.
|
|
7
|
+
"version": "9.6.0",
|
|
8
8
|
"description": "A spelling dictionary library useful for checking words and getting suggestions.",
|
|
9
9
|
"type": "module",
|
|
10
10
|
"sideEffects": false,
|
|
@@ -54,14 +54,15 @@
|
|
|
54
54
|
"node": ">=20"
|
|
55
55
|
},
|
|
56
56
|
"dependencies": {
|
|
57
|
-
"@cspell/cspell-pipe": "9.
|
|
58
|
-
"@cspell/cspell-types": "9.
|
|
59
|
-
"cspell-trie-lib": "9.
|
|
60
|
-
"fast-equals": "^
|
|
57
|
+
"@cspell/cspell-pipe": "9.6.0",
|
|
58
|
+
"@cspell/cspell-types": "9.6.0",
|
|
59
|
+
"cspell-trie-lib": "9.6.0",
|
|
60
|
+
"fast-equals": "^6.0.0"
|
|
61
61
|
},
|
|
62
62
|
"devDependencies": {
|
|
63
|
+
"@cspell/dict-de-de": "^4.1.2",
|
|
63
64
|
"gensequence": "^8.0.8",
|
|
64
65
|
"lorem-ipsum": "^2.0.8"
|
|
65
66
|
},
|
|
66
|
-
"gitHead": "
|
|
67
|
+
"gitHead": "163793ddf2a0ad90bc7c90351698a106003297af"
|
|
67
68
|
}
|