cspell-dictionary 6.28.0 → 6.29.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.
- package/dist/{SpellingDictionary → cjs/SpellingDictionary}/CachingDictionary.d.ts +3 -3
- package/dist/{SpellingDictionary → cjs/SpellingDictionary}/CachingDictionary.js +9 -9
- package/dist/{SpellingDictionary → cjs/SpellingDictionary}/FlagWordsDictionary.d.ts +1 -1
- package/dist/{SpellingDictionary → cjs/SpellingDictionary}/FlagWordsDictionary.js +11 -11
- package/dist/{SpellingDictionary → cjs/SpellingDictionary}/IgnoreWordsDictionary.d.ts +1 -1
- package/dist/{SpellingDictionary → cjs/SpellingDictionary}/IgnoreWordsDictionary.js +5 -5
- package/dist/{SpellingDictionary → cjs/SpellingDictionary}/SpellingDictionaryCollection.d.ts +1 -1
- package/dist/{SpellingDictionary → cjs/SpellingDictionary}/SpellingDictionaryCollection.js +12 -12
- package/dist/{SpellingDictionary → cjs/SpellingDictionary}/SpellingDictionaryFromTrie.d.ts +1 -1
- package/dist/{SpellingDictionary → cjs/SpellingDictionary}/SpellingDictionaryFromTrie.js +16 -16
- package/dist/{SpellingDictionary → cjs/SpellingDictionary}/SpellingDictionaryMethods.d.ts +1 -1
- package/dist/{SpellingDictionary → cjs/SpellingDictionary}/SpellingDictionaryMethods.js +5 -5
- package/dist/{SpellingDictionary → cjs/SpellingDictionary}/SuggestDictionary.d.ts +2 -2
- package/dist/{SpellingDictionary → cjs/SpellingDictionary}/SuggestDictionary.js +9 -9
- package/dist/{SpellingDictionary → cjs/SpellingDictionary}/Terms/index.d.ts +1 -1
- package/dist/cjs/SpellingDictionary/Typos/index.d.ts +4 -0
- package/dist/{SpellingDictionary → cjs/SpellingDictionary}/Typos/index.js +7 -7
- package/dist/{SpellingDictionary → cjs/SpellingDictionary}/Typos/typos.d.ts +1 -1
- package/dist/{SpellingDictionary → cjs/SpellingDictionary}/Typos/typosParser.d.ts +1 -1
- package/dist/{SpellingDictionary → cjs/SpellingDictionary}/Typos/typosParser.js +6 -6
- package/dist/{SpellingDictionary → cjs/SpellingDictionary}/Typos/util.d.ts +1 -1
- package/dist/{SpellingDictionary → cjs/SpellingDictionary}/TyposDictionary.d.ts +2 -2
- package/dist/{SpellingDictionary → cjs/SpellingDictionary}/TyposDictionary.js +10 -10
- package/dist/{SpellingDictionary → cjs/SpellingDictionary}/createInlineSpellingDictionary.d.ts +1 -1
- package/dist/cjs/SpellingDictionary/createInlineSpellingDictionary.js +25 -0
- package/dist/{SpellingDictionary → cjs/SpellingDictionary}/createSpellingDictionary.d.ts +2 -2
- package/dist/{SpellingDictionary → cjs/SpellingDictionary}/createSpellingDictionary.js +9 -9
- package/dist/{SpellingDictionary → cjs/SpellingDictionary}/index.d.ts +10 -10
- package/dist/{SpellingDictionary → cjs/SpellingDictionary}/index.js +20 -20
- package/dist/{index.d.ts → cjs/index.d.ts} +2 -2
- package/dist/{index.js → cjs/index.js} +11 -11
- package/dist/{util → cjs/util}/clean.d.ts +1 -1
- package/dist/{util → cjs/util}/repMap.js +4 -4
- package/dist/{util → cjs/util}/textMappers.js +2 -2
- package/dist/esm/SpellingDictionary/CachingDictionary.d.mts +30 -0
- package/dist/esm/SpellingDictionary/CachingDictionary.mjs +45 -0
- package/dist/esm/SpellingDictionary/FlagWordsDictionary.d.mts +11 -0
- package/dist/esm/SpellingDictionary/FlagWordsDictionary.mjs +134 -0
- package/dist/esm/SpellingDictionary/IgnoreWordsDictionary.d.mts +11 -0
- package/dist/esm/SpellingDictionary/IgnoreWordsDictionary.mjs +96 -0
- package/dist/esm/SpellingDictionary/SpellingDictionary.d.mts +150 -0
- package/dist/esm/SpellingDictionary/SpellingDictionary.mjs +4 -0
- package/dist/esm/SpellingDictionary/SpellingDictionaryCollection.d.mts +16 -0
- package/dist/esm/SpellingDictionary/SpellingDictionaryCollection.mjs +111 -0
- package/dist/esm/SpellingDictionary/SpellingDictionaryFromTrie.d.mts +50 -0
- package/dist/esm/SpellingDictionary/SpellingDictionaryFromTrie.mjs +172 -0
- package/dist/esm/SpellingDictionary/SpellingDictionaryMethods.d.mts +26 -0
- package/dist/esm/SpellingDictionary/SpellingDictionaryMethods.mjs +96 -0
- package/dist/esm/SpellingDictionary/SuggestDictionary.d.mts +20 -0
- package/dist/esm/SpellingDictionary/SuggestDictionary.mjs +97 -0
- package/dist/esm/SpellingDictionary/Terms/index.d.mts +2 -0
- package/dist/esm/SpellingDictionary/Terms/index.mjs +1 -0
- package/dist/esm/SpellingDictionary/Terms/terms.d.mts +12 -0
- package/dist/esm/SpellingDictionary/Terms/terms.mjs +1 -0
- package/dist/esm/SpellingDictionary/Typos/index.d.mts +4 -0
- package/dist/esm/SpellingDictionary/Typos/index.mjs +2 -0
- package/dist/esm/SpellingDictionary/Typos/typos.d.mts +18 -0
- package/dist/esm/SpellingDictionary/Typos/typos.mjs +1 -0
- package/dist/esm/SpellingDictionary/Typos/typosParser.d.mts +34 -0
- package/dist/esm/SpellingDictionary/Typos/typosParser.mjs +131 -0
- package/dist/esm/SpellingDictionary/Typos/util.d.mts +31 -0
- package/dist/esm/SpellingDictionary/Typos/util.mjs +105 -0
- package/dist/esm/SpellingDictionary/TyposDictionary.d.mts +21 -0
- package/dist/esm/SpellingDictionary/TyposDictionary.mjs +129 -0
- package/dist/esm/SpellingDictionary/createInlineSpellingDictionary.d.mts +3 -0
- package/dist/esm/SpellingDictionary/createInlineSpellingDictionary.mjs +20 -0
- package/dist/esm/SpellingDictionary/createSpellingDictionary.d.mts +23 -0
- package/dist/esm/SpellingDictionary/createSpellingDictionary.mjs +68 -0
- package/dist/esm/SpellingDictionary/defaults.d.mts +3 -0
- package/dist/esm/SpellingDictionary/defaults.mjs +2 -0
- package/dist/esm/SpellingDictionary/index.d.mts +11 -0
- package/dist/esm/SpellingDictionary/index.mjs +9 -0
- package/dist/esm/index.d.mts +3 -0
- package/dist/esm/index.mjs +1 -0
- package/dist/esm/util/AutoCache.d.mts +25 -0
- package/dist/esm/util/AutoCache.mjs +67 -0
- package/dist/esm/util/AutoResolve.d.mts +21 -0
- package/dist/esm/util/AutoResolve.mjs +52 -0
- package/dist/esm/util/IterableLike.d.mts +4 -0
- package/dist/esm/util/IterableLike.mjs +1 -0
- package/dist/esm/util/clean.d.mts +7 -0
- package/dist/esm/util/clean.mjs +13 -0
- package/dist/esm/util/regexHelper.d.mts +7 -0
- package/dist/esm/util/regexHelper.mjs +8 -0
- package/dist/esm/util/repMap.d.mts +27 -0
- package/dist/esm/util/repMap.mjs +152 -0
- package/dist/esm/util/simpleCache.d.mts +46 -0
- package/dist/esm/util/simpleCache.mjs +135 -0
- package/dist/esm/util/text.d.mts +10 -0
- package/dist/esm/util/text.mjs +46 -0
- package/dist/esm/util/textMappers.d.mts +3 -0
- package/dist/esm/util/textMappers.mjs +15 -0
- package/dist/esm/util/types.d.mts +7 -0
- package/dist/esm/util/types.mjs +1 -0
- package/dist/esm/util/util.d.mts +2 -0
- package/dist/esm/util/util.mjs +3 -0
- package/package.json +27 -18
- package/dist/SpellingDictionary/Typos/index.d.ts +0 -4
- package/dist/SpellingDictionary/createInlineSpellingDictionary.js +0 -25
- /package/dist/{SpellingDictionary → cjs/SpellingDictionary}/SpellingDictionary.d.ts +0 -0
- /package/dist/{SpellingDictionary → cjs/SpellingDictionary}/SpellingDictionary.js +0 -0
- /package/dist/{SpellingDictionary → cjs/SpellingDictionary}/Terms/index.js +0 -0
- /package/dist/{SpellingDictionary → cjs/SpellingDictionary}/Terms/terms.d.ts +0 -0
- /package/dist/{SpellingDictionary → cjs/SpellingDictionary}/Terms/terms.js +0 -0
- /package/dist/{SpellingDictionary → cjs/SpellingDictionary}/Typos/typos.js +0 -0
- /package/dist/{SpellingDictionary → cjs/SpellingDictionary}/Typos/util.js +0 -0
- /package/dist/{SpellingDictionary → cjs/SpellingDictionary}/defaults.d.ts +0 -0
- /package/dist/{SpellingDictionary → cjs/SpellingDictionary}/defaults.js +0 -0
- /package/dist/{util → cjs/util}/AutoCache.d.ts +0 -0
- /package/dist/{util → cjs/util}/AutoCache.js +0 -0
- /package/dist/{util → cjs/util}/AutoResolve.d.ts +0 -0
- /package/dist/{util → cjs/util}/AutoResolve.js +0 -0
- /package/dist/{util → cjs/util}/IterableLike.d.ts +0 -0
- /package/dist/{util → cjs/util}/IterableLike.js +0 -0
- /package/dist/{util → cjs/util}/clean.js +0 -0
- /package/dist/{util → cjs/util}/regexHelper.d.ts +0 -0
- /package/dist/{util → cjs/util}/regexHelper.js +0 -0
- /package/dist/{util → cjs/util}/repMap.d.ts +0 -0
- /package/dist/{util → cjs/util}/simpleCache.d.ts +0 -0
- /package/dist/{util → cjs/util}/simpleCache.js +0 -0
- /package/dist/{util → cjs/util}/text.d.ts +0 -0
- /package/dist/{util → cjs/util}/text.js +0 -0
- /package/dist/{util → cjs/util}/textMappers.d.ts +0 -0
- /package/dist/{util → cjs/util}/types.d.ts +0 -0
- /package/dist/{util → cjs/util}/types.js +0 -0
- /package/dist/{util → cjs/util}/util.d.ts +0 -0
- /package/dist/{util → cjs/util}/util.js +0 -0
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { pipe } from '@cspell/cspell-pipe/sync';
|
|
2
|
+
import { createAutoResolveWeakCache } from '../util/AutoResolve.mjs';
|
|
3
|
+
import { mapperRemoveCaseAndAccents } from '../util/textMappers.mjs';
|
|
4
|
+
import * as defaults from './defaults.mjs';
|
|
5
|
+
import { processEntriesToTyposDef } from './Typos/index.mjs';
|
|
6
|
+
import { extractAllSuggestions } from './Typos/util.mjs';
|
|
7
|
+
class SuggestDictionaryImpl {
|
|
8
|
+
constructor(name, source, typosDef) {
|
|
9
|
+
this.name = name;
|
|
10
|
+
this.source = source;
|
|
11
|
+
this.typosDef = typosDef;
|
|
12
|
+
this.containsNoSuggestWords = false;
|
|
13
|
+
this.options = {};
|
|
14
|
+
this.type = 'suggest';
|
|
15
|
+
this.isDictionaryCaseSensitive = true;
|
|
16
|
+
this.size = Object.keys(typosDef).length;
|
|
17
|
+
this.suggestions = extractAllSuggestions(typosDef);
|
|
18
|
+
this.suggestionsLower = new Set(pipe(this.suggestions, mapperRemoveCaseAndAccents));
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* A Forbidden word list does not "have" valid words.
|
|
22
|
+
* Therefore it always returns false.
|
|
23
|
+
* @param _word - the word
|
|
24
|
+
* @param _options - options
|
|
25
|
+
* @returns always false
|
|
26
|
+
*/
|
|
27
|
+
has(_word, _options) {
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
/** A more detailed search for a word, might take longer than `has` */
|
|
31
|
+
find(_word, _options) {
|
|
32
|
+
return undefined;
|
|
33
|
+
}
|
|
34
|
+
isForbidden(_word, _ignoreCaseAndAccents) {
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
isNoSuggestWord(_word, _options) {
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Determine if the word can appear in a list of suggestions.
|
|
42
|
+
* @param word - word
|
|
43
|
+
* @param ignoreCaseAndAccents - ignore case.
|
|
44
|
+
* @returns true if a word is suggested, otherwise false.
|
|
45
|
+
*/
|
|
46
|
+
isSuggestedWord(word, ignoreCaseAndAccents = defaults.isForbiddenIgnoreCaseAndAccents) {
|
|
47
|
+
if (this.suggestions.has(word))
|
|
48
|
+
return true;
|
|
49
|
+
const lcWord = word.toLowerCase();
|
|
50
|
+
return ignoreCaseAndAccents && (this.suggestions.has(lcWord) || this.suggestionsLower.has(lcWord));
|
|
51
|
+
}
|
|
52
|
+
suggest(word) {
|
|
53
|
+
return this._suggest(word) || this._suggest(word.toLowerCase()) || [];
|
|
54
|
+
}
|
|
55
|
+
_suggest(word) {
|
|
56
|
+
if (!(word in this.typosDef))
|
|
57
|
+
return undefined;
|
|
58
|
+
const sug = this.typosDef[word];
|
|
59
|
+
const isPreferred = true;
|
|
60
|
+
if (!sug)
|
|
61
|
+
return [];
|
|
62
|
+
if (typeof sug === 'string') {
|
|
63
|
+
return [
|
|
64
|
+
{
|
|
65
|
+
word: sug,
|
|
66
|
+
cost: 1,
|
|
67
|
+
isPreferred,
|
|
68
|
+
},
|
|
69
|
+
];
|
|
70
|
+
}
|
|
71
|
+
return sug.map((word, index) => ({ word, cost: index + 1, isPreferred }));
|
|
72
|
+
}
|
|
73
|
+
genSuggestions(collector) {
|
|
74
|
+
const sugs = this.suggest(collector.word);
|
|
75
|
+
sugs.forEach((result) => collector.add(result));
|
|
76
|
+
}
|
|
77
|
+
mapWord(word) {
|
|
78
|
+
return word;
|
|
79
|
+
}
|
|
80
|
+
getErrors() {
|
|
81
|
+
return [];
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
const createCache = createAutoResolveWeakCache();
|
|
85
|
+
/**
|
|
86
|
+
* Create a dictionary where all words are to be forbidden.
|
|
87
|
+
* @param entries - list of Typos Entries
|
|
88
|
+
* @param name - name of dictionary
|
|
89
|
+
* @param source - source
|
|
90
|
+
* @returns
|
|
91
|
+
*/
|
|
92
|
+
export function createSuggestDictionary(entries, name, source) {
|
|
93
|
+
return createCache.get(entries, () => {
|
|
94
|
+
const def = processEntriesToTyposDef(entries);
|
|
95
|
+
return new SuggestDictionaryImpl(name, source, def);
|
|
96
|
+
});
|
|
97
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export type TermValueTypoNoSuggestions = false;
|
|
2
|
+
type TermValueTypoSingleSuggestion = string;
|
|
3
|
+
type TermValueTypoMultipleSuggestions = string[];
|
|
4
|
+
export type TermValueTypoWithSuggestions = TermValueTypoSingleSuggestion | TermValueTypoMultipleSuggestions;
|
|
5
|
+
export type TermValueTypo = TermValueTypoWithSuggestions | TermValueTypoNoSuggestions;
|
|
6
|
+
export type TermValueIgnoreWord = null;
|
|
7
|
+
export type TermValueOk = true;
|
|
8
|
+
export type TermsDefValue = TermValueTypo | TermValueIgnoreWord | TermValueOk;
|
|
9
|
+
export type TermsDefKey = string;
|
|
10
|
+
export type TermsDef = Record<TermsDefKey, TermsDefValue>;
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=terms.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { TermsDefKey, TermValueTypo, TermValueTypoNoSuggestions, TermValueTypoWithSuggestions } from '../Terms/index.mjs';
|
|
2
|
+
export type TypoValueNoSuggestions = TermValueTypoNoSuggestions;
|
|
3
|
+
export type TypoValueWithSuggestions = TermValueTypoWithSuggestions;
|
|
4
|
+
export type TyposDefValue = TermValueTypo;
|
|
5
|
+
export type TyposDefKey = TermsDefKey;
|
|
6
|
+
/**
|
|
7
|
+
* Typos Definition
|
|
8
|
+
* key - the incorrect word
|
|
9
|
+
* value - the suggestions.
|
|
10
|
+
*/
|
|
11
|
+
export type TyposDef = Record<TyposDefKey, TyposDefValue>;
|
|
12
|
+
type TypoWithNoSuggestions = string;
|
|
13
|
+
type TypoWithSuggestionsArray = [forbidWord: string, ...suggestions: string[]];
|
|
14
|
+
type TypoWithSuggestionsObj = TyposDef;
|
|
15
|
+
type TypoWithSuggestions = TypoWithSuggestionsArray | TypoWithSuggestionsObj;
|
|
16
|
+
export type TypoEntry = TypoWithNoSuggestions | TypoWithSuggestions;
|
|
17
|
+
export {};
|
|
18
|
+
//# sourceMappingURL=typos.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { TypoEntry, TyposDef } from './typos.mjs';
|
|
2
|
+
export declare function createTyposDefFromEntries(entries: Iterable<TypoEntry>): TyposDef;
|
|
3
|
+
export declare function sanitizeIntoTypoDef(dirtyDef: TyposDef | Record<string, unknown> | unknown): TyposDef | undefined;
|
|
4
|
+
/**
|
|
5
|
+
* Parse Typos Entries
|
|
6
|
+
*
|
|
7
|
+
* Format:
|
|
8
|
+
* - `word:suggestion`
|
|
9
|
+
* - `word->suggestion`
|
|
10
|
+
* - `word: first, second, third suggestions`
|
|
11
|
+
*
|
|
12
|
+
* Note:
|
|
13
|
+
* ```plaintext
|
|
14
|
+
* yellow:blue, green
|
|
15
|
+
* ```
|
|
16
|
+
* Is the same as multiple entries with the same key and different suggestions.
|
|
17
|
+
* ```plaintext
|
|
18
|
+
* yellow:blue
|
|
19
|
+
* yellow:green
|
|
20
|
+
* ```
|
|
21
|
+
*
|
|
22
|
+
* Used to process entries found in a `cspell.json` file.
|
|
23
|
+
* @param entries - entries to process
|
|
24
|
+
* @returns a TyposDef
|
|
25
|
+
*/
|
|
26
|
+
export declare function processEntriesToTyposDef(entries: Iterable<TypoEntry> | TyposDef | Record<string, unknown>): TyposDef;
|
|
27
|
+
/**
|
|
28
|
+
* Tries to parse an entry.
|
|
29
|
+
* @param line - any valid TypoEntry.
|
|
30
|
+
* @returns a valid TypoEntry
|
|
31
|
+
*/
|
|
32
|
+
export declare function parseTyposLine(line: TypoEntry): TypoEntry | undefined;
|
|
33
|
+
export declare function parseTyposFile(content: string): TyposDef;
|
|
34
|
+
//# sourceMappingURL=typosParser.d.mts.map
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import assert from 'assert';
|
|
2
|
+
import { appendToDef, createTyposDef } from './util.mjs';
|
|
3
|
+
function assertString(v) {
|
|
4
|
+
assert(typeof v === 'string', 'A string was expected.');
|
|
5
|
+
return true;
|
|
6
|
+
}
|
|
7
|
+
const suggestionsSeparator = /[,]/;
|
|
8
|
+
const typoSuggestionsSeparator = /:|->/;
|
|
9
|
+
const typoEntrySeparator = /[\n;]/;
|
|
10
|
+
const inlineComment = /#.*/gm;
|
|
11
|
+
export function createTyposDefFromEntries(entries) {
|
|
12
|
+
const def = Object.create(null);
|
|
13
|
+
for (const entry of entries) {
|
|
14
|
+
appendToDef(def, entry);
|
|
15
|
+
}
|
|
16
|
+
return def;
|
|
17
|
+
}
|
|
18
|
+
function normalize(s) {
|
|
19
|
+
return s.normalize();
|
|
20
|
+
}
|
|
21
|
+
function trimAndFilter(lines) {
|
|
22
|
+
return lines
|
|
23
|
+
.map((s) => s.trim())
|
|
24
|
+
.filter((s) => !!s)
|
|
25
|
+
.map(normalize);
|
|
26
|
+
}
|
|
27
|
+
function cleanSugs(rawSugs) {
|
|
28
|
+
const sugs = trimAndFilter(rawSugs);
|
|
29
|
+
return sugs.length === 1 ? sugs[0] : sugs.length ? sugs : false;
|
|
30
|
+
}
|
|
31
|
+
function splitSuggestionsValue(value) {
|
|
32
|
+
return cleanSugs(value.split(suggestionsSeparator));
|
|
33
|
+
}
|
|
34
|
+
export function sanitizeIntoTypoDef(dirtyDef) {
|
|
35
|
+
if (!dirtyDef || typeof dirtyDef !== 'object')
|
|
36
|
+
return undefined;
|
|
37
|
+
const def = createTyposDef();
|
|
38
|
+
for (const [rawKey, value] of Object.entries(dirtyDef)) {
|
|
39
|
+
const key = normalize(rawKey.trim());
|
|
40
|
+
if (!key)
|
|
41
|
+
continue;
|
|
42
|
+
if (typeof value === 'string') {
|
|
43
|
+
def[key] = splitSuggestionsValue(value);
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
if (Array.isArray(value)) {
|
|
47
|
+
const sugs = cleanSugs(value.filter(assertString));
|
|
48
|
+
def[key] = sugs;
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
assert(value === false, 'Unexpected suggestion type.');
|
|
52
|
+
def[key] = false;
|
|
53
|
+
}
|
|
54
|
+
return def;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Parse Typos Entries
|
|
58
|
+
*
|
|
59
|
+
* Format:
|
|
60
|
+
* - `word:suggestion`
|
|
61
|
+
* - `word->suggestion`
|
|
62
|
+
* - `word: first, second, third suggestions`
|
|
63
|
+
*
|
|
64
|
+
* Note:
|
|
65
|
+
* ```plaintext
|
|
66
|
+
* yellow:blue, green
|
|
67
|
+
* ```
|
|
68
|
+
* Is the same as multiple entries with the same key and different suggestions.
|
|
69
|
+
* ```plaintext
|
|
70
|
+
* yellow:blue
|
|
71
|
+
* yellow:green
|
|
72
|
+
* ```
|
|
73
|
+
*
|
|
74
|
+
* Used to process entries found in a `cspell.json` file.
|
|
75
|
+
* @param entries - entries to process
|
|
76
|
+
* @returns a TyposDef
|
|
77
|
+
*/
|
|
78
|
+
export function processEntriesToTyposDef(entries) {
|
|
79
|
+
const def = isIterable(entries) ? reduceToTyposDef(entries) : entries;
|
|
80
|
+
const result = sanitizeIntoTypoDef(def);
|
|
81
|
+
assert(result);
|
|
82
|
+
return result;
|
|
83
|
+
}
|
|
84
|
+
function reduceToTyposDef(entries) {
|
|
85
|
+
const def = createTyposDef();
|
|
86
|
+
for (const entry of entries) {
|
|
87
|
+
appendToDef(def, parseTyposLine(entry));
|
|
88
|
+
}
|
|
89
|
+
return def;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Tries to parse an entry.
|
|
93
|
+
* @param line - any valid TypoEntry.
|
|
94
|
+
* @returns a valid TypoEntry
|
|
95
|
+
*/
|
|
96
|
+
export function parseTyposLine(line) {
|
|
97
|
+
if (!line)
|
|
98
|
+
return undefined;
|
|
99
|
+
if (typeof line === 'string') {
|
|
100
|
+
const def = createTyposDef();
|
|
101
|
+
for (const subEntry of splitIntoLines(line)) {
|
|
102
|
+
const [left, right] = splitEntry(subEntry);
|
|
103
|
+
const typo = left.trim();
|
|
104
|
+
if (!right)
|
|
105
|
+
return typo;
|
|
106
|
+
const sugs = splitSuggestionsValue(right);
|
|
107
|
+
def[typo] = sugs;
|
|
108
|
+
}
|
|
109
|
+
return def;
|
|
110
|
+
}
|
|
111
|
+
if (Array.isArray(line)) {
|
|
112
|
+
const [key, ...sugs] = line.filter(assertString).map((s) => s.trim());
|
|
113
|
+
if (!key)
|
|
114
|
+
return undefined;
|
|
115
|
+
return [key, ...sugs];
|
|
116
|
+
}
|
|
117
|
+
return sanitizeIntoTypoDef(line);
|
|
118
|
+
}
|
|
119
|
+
function splitIntoLines(content) {
|
|
120
|
+
return trimAndFilter(normalize(content).split(typoEntrySeparator));
|
|
121
|
+
}
|
|
122
|
+
function splitEntry(line) {
|
|
123
|
+
return line.split(typoSuggestionsSeparator, 2);
|
|
124
|
+
}
|
|
125
|
+
export function parseTyposFile(content) {
|
|
126
|
+
const lines = splitIntoLines(content.replace(inlineComment, ''));
|
|
127
|
+
return reduceToTyposDef(lines);
|
|
128
|
+
}
|
|
129
|
+
function isIterable(v) {
|
|
130
|
+
return Symbol.iterator in v;
|
|
131
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { TypoEntry, TyposDef, TyposDefKey, TyposDefValue } from './typos.mjs';
|
|
2
|
+
export declare function mergeDefEntry(targetDef: TyposDef, key: string, value: TyposDefValue): TyposDef;
|
|
3
|
+
/**
|
|
4
|
+
* Merge in place the entries `fromDef` into `targetDef`
|
|
5
|
+
* @param targetDef - the target
|
|
6
|
+
* @param fromDef - the source
|
|
7
|
+
* @returns the target
|
|
8
|
+
*/
|
|
9
|
+
export declare function mergeDef(targetDef: TyposDef, fromDef: TyposDef): TyposDef;
|
|
10
|
+
/**
|
|
11
|
+
* Append an entry to a TyposDef.
|
|
12
|
+
* @param def - modified in place
|
|
13
|
+
* @param entry- entry to add.
|
|
14
|
+
* @returns def
|
|
15
|
+
*/
|
|
16
|
+
export declare function appendToDef(def: TyposDef, entry: TypoEntry | undefined): TyposDef;
|
|
17
|
+
export declare function createTyposDef(entries?: Iterable<[TyposDefKey, TyposDefValue]>): TyposDef;
|
|
18
|
+
/**
|
|
19
|
+
* Extract all suggestions.
|
|
20
|
+
* @param typosDef - the def
|
|
21
|
+
* @returns the set of suggestions.
|
|
22
|
+
*/
|
|
23
|
+
export declare function extractAllSuggestions(typosDef: TyposDef): Set<string>;
|
|
24
|
+
/**
|
|
25
|
+
* Extract all words that have been explicitly ignore because they contains the `ignorePrefix`.
|
|
26
|
+
* @param typosDef - the def
|
|
27
|
+
* @param ignorePrefix - prefix
|
|
28
|
+
* @returns set of ignored words with the prefix removed.
|
|
29
|
+
*/
|
|
30
|
+
export declare function extractIgnoreValues(typosDef: TyposDef, ignorePrefix: string): Set<string>;
|
|
31
|
+
//# sourceMappingURL=util.d.mts.map
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { opConcatMap, opFilter, pipe } from '@cspell/cspell-pipe/sync';
|
|
2
|
+
function normalizeTyposDefValue(value) {
|
|
3
|
+
if (!value)
|
|
4
|
+
return false;
|
|
5
|
+
if (typeof value === 'string')
|
|
6
|
+
return value;
|
|
7
|
+
const unique = [...new Set(value)];
|
|
8
|
+
return unique.length > 1 ? unique : unique.length === 1 ? unique[0] : false;
|
|
9
|
+
}
|
|
10
|
+
export function mergeDefEntry(targetDef, key, value) {
|
|
11
|
+
const curValue = targetDef[key];
|
|
12
|
+
if (!curValue) {
|
|
13
|
+
targetDef[key] = normalizeTyposDefValue(value);
|
|
14
|
+
return targetDef;
|
|
15
|
+
}
|
|
16
|
+
if (!value)
|
|
17
|
+
return targetDef;
|
|
18
|
+
const newValue = Array.isArray(curValue) ? curValue : [curValue];
|
|
19
|
+
if (Array.isArray(value)) {
|
|
20
|
+
newValue.push(...value);
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
newValue.push(value);
|
|
24
|
+
}
|
|
25
|
+
targetDef[key] = normalizeTyposDefValue(newValue);
|
|
26
|
+
return targetDef;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Merge in place the entries `fromDef` into `targetDef`
|
|
30
|
+
* @param targetDef - the target
|
|
31
|
+
* @param fromDef - the source
|
|
32
|
+
* @returns the target
|
|
33
|
+
*/
|
|
34
|
+
export function mergeDef(targetDef, fromDef) {
|
|
35
|
+
for (const key of Object.keys(fromDef)) {
|
|
36
|
+
mergeDefEntry(targetDef, key, fromDef[key]);
|
|
37
|
+
}
|
|
38
|
+
return targetDef;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Append an entry to a TyposDef.
|
|
42
|
+
* @param def - modified in place
|
|
43
|
+
* @param entry- entry to add.
|
|
44
|
+
* @returns def
|
|
45
|
+
*/
|
|
46
|
+
export function appendToDef(def, entry) {
|
|
47
|
+
if (!entry)
|
|
48
|
+
return def;
|
|
49
|
+
if (typeof entry === 'string') {
|
|
50
|
+
if (!def[entry]) {
|
|
51
|
+
def[entry] = false;
|
|
52
|
+
}
|
|
53
|
+
return def;
|
|
54
|
+
}
|
|
55
|
+
if (Array.isArray(entry)) {
|
|
56
|
+
const [key, ...sugs] = entry.map((s) => s.trim());
|
|
57
|
+
if (!key)
|
|
58
|
+
return def;
|
|
59
|
+
const s = sugs.map((s) => s.trim()).filter((s) => !!s);
|
|
60
|
+
return mergeDefEntry(def, key, s);
|
|
61
|
+
}
|
|
62
|
+
return mergeDef(def, entry);
|
|
63
|
+
}
|
|
64
|
+
export function createTyposDef(entries) {
|
|
65
|
+
const def = Object.create(null);
|
|
66
|
+
if (!entries)
|
|
67
|
+
return def;
|
|
68
|
+
for (const [key, value] of entries) {
|
|
69
|
+
def[key] = isDefined(value) ? value : false;
|
|
70
|
+
}
|
|
71
|
+
return def;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Extract all suggestions.
|
|
75
|
+
* @param typosDef - the def
|
|
76
|
+
* @returns the set of suggestions.
|
|
77
|
+
*/
|
|
78
|
+
export function extractAllSuggestions(typosDef) {
|
|
79
|
+
const allSugs = pipe(Object.values(typosDef), opFilter(hasSuggestions), opConcatMap((v) => (Array.isArray(v) ? v : [v])));
|
|
80
|
+
return new Set(allSugs);
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Extract all words that have been explicitly ignore because they contains the `ignorePrefix`.
|
|
84
|
+
* @param typosDef - the def
|
|
85
|
+
* @param ignorePrefix - prefix
|
|
86
|
+
* @returns set of ignored words with the prefix removed.
|
|
87
|
+
*/
|
|
88
|
+
export function extractIgnoreValues(typosDef, ignorePrefix) {
|
|
89
|
+
const pfxLen = ignorePrefix.length;
|
|
90
|
+
return new Set(Object.keys(typosDef)
|
|
91
|
+
.filter((k) => k.startsWith(ignorePrefix))
|
|
92
|
+
.map((k) => k.slice(pfxLen)));
|
|
93
|
+
}
|
|
94
|
+
function isDefined(v) {
|
|
95
|
+
return v !== undefined && v !== null;
|
|
96
|
+
}
|
|
97
|
+
function isString(v) {
|
|
98
|
+
return typeof v === 'string';
|
|
99
|
+
}
|
|
100
|
+
function isArray(v) {
|
|
101
|
+
return Array.isArray(v);
|
|
102
|
+
}
|
|
103
|
+
function hasSuggestions(v) {
|
|
104
|
+
return isString(v) || isArray(v);
|
|
105
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { IgnoreCaseOption, SpellingDictionary } from './SpellingDictionary.mjs';
|
|
2
|
+
import { type TypoEntry, type TyposDef } from './Typos/index.mjs';
|
|
3
|
+
export interface TyposDictionary extends SpellingDictionary {
|
|
4
|
+
isForbidden(word: string, ignoreCaseAndAccents?: IgnoreCaseOption): boolean;
|
|
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;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Create a dictionary where all words are to be forbidden.
|
|
15
|
+
* @param entries - list of Typos Entries
|
|
16
|
+
* @param name - name of dictionary
|
|
17
|
+
* @param source - source
|
|
18
|
+
* @returns
|
|
19
|
+
*/
|
|
20
|
+
export declare function createTyposDictionary(entries: readonly string[] | TyposDef | Iterable<TypoEntry>, name: string, source: string): TyposDictionary;
|
|
21
|
+
//# sourceMappingURL=TyposDictionary.d.mts.map
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { opAppend, pipe } from '@cspell/cspell-pipe/sync';
|
|
2
|
+
import { createAutoResolveWeakCache } from '../util/AutoResolve.mjs';
|
|
3
|
+
import { mapperRemoveCaseAndAccents } from '../util/textMappers.mjs';
|
|
4
|
+
import * as defaults from './defaults.mjs';
|
|
5
|
+
import { processEntriesToTyposDef } from './Typos/index.mjs';
|
|
6
|
+
import { extractAllSuggestions, extractIgnoreValues } from './Typos/util.mjs';
|
|
7
|
+
class TyposDictionaryImpl {
|
|
8
|
+
constructor(name, source, typosDef, ignoreList) {
|
|
9
|
+
this.name = name;
|
|
10
|
+
this.source = source;
|
|
11
|
+
this.typosDef = typosDef;
|
|
12
|
+
this.options = {};
|
|
13
|
+
this.type = 'typos';
|
|
14
|
+
this.isDictionaryCaseSensitive = true;
|
|
15
|
+
this.size = Object.keys(typosDef).length;
|
|
16
|
+
this.explicitIgnoreWords = extractIgnoreValues(typosDef, '!');
|
|
17
|
+
this.suggestions = extractAllSuggestions(typosDef);
|
|
18
|
+
this.ignoreWords = new Set(pipe(this.explicitIgnoreWords, opAppend(ignoreList || [])));
|
|
19
|
+
this.suggestionsLower = new Set(pipe(this.suggestions, mapperRemoveCaseAndAccents));
|
|
20
|
+
this.containsNoSuggestWords = this.ignoreWords.size > 0;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* A Forbidden word list does not "have" valid words.
|
|
24
|
+
* Therefore it always returns false.
|
|
25
|
+
* @param _word - the word
|
|
26
|
+
* @param _options - options
|
|
27
|
+
* @returns always false
|
|
28
|
+
*/
|
|
29
|
+
has(_word, _options) {
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
/** A more detailed search for a word, might take longer than `has` */
|
|
33
|
+
find(word, options) {
|
|
34
|
+
const result = this._findForms(word, options?.ignoreCase ?? defaults.ignoreCase);
|
|
35
|
+
if (result === false)
|
|
36
|
+
return undefined;
|
|
37
|
+
const { found, ignore } = result;
|
|
38
|
+
return { found, forbidden: !ignore, noSuggest: ignore };
|
|
39
|
+
}
|
|
40
|
+
_findForms(word, ignoreCaseAndAccents) {
|
|
41
|
+
const lcWord = word.toLowerCase();
|
|
42
|
+
if (this.ignoreWords.has(word)) {
|
|
43
|
+
return { found: word, ignore: true };
|
|
44
|
+
}
|
|
45
|
+
if (this.suggestions.has(word)) {
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
if (ignoreCaseAndAccents) {
|
|
49
|
+
if (this.suggestionsLower.has(lcWord)) {
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
if (this.ignoreWords.has(lcWord)) {
|
|
53
|
+
return { found: lcWord, ignore: true };
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
if (word in this.typosDef)
|
|
57
|
+
return { found: word, ignore: false };
|
|
58
|
+
if (lcWord in this.typosDef)
|
|
59
|
+
return { found: lcWord, ignore: false };
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
isForbidden(word, ignoreCaseAndAccents = defaults.isForbiddenIgnoreCaseAndAccents) {
|
|
63
|
+
const found = this._findForms(word, ignoreCaseAndAccents);
|
|
64
|
+
return found !== false && !found.ignore;
|
|
65
|
+
}
|
|
66
|
+
isNoSuggestWord(word, options) {
|
|
67
|
+
const result = this.find(word, options);
|
|
68
|
+
return result?.noSuggest ?? false;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Determine if the word can appear in a list of suggestions.
|
|
72
|
+
* @param word - word
|
|
73
|
+
* @param ignoreCaseAndAccents - ignore case.
|
|
74
|
+
* @returns true if a word is suggested, otherwise false.
|
|
75
|
+
*/
|
|
76
|
+
isSuggestedWord(word, ignoreCaseAndAccents = defaults.isForbiddenIgnoreCaseAndAccents) {
|
|
77
|
+
if (this.suggestions.has(word))
|
|
78
|
+
return true;
|
|
79
|
+
const lcWord = word.toLowerCase();
|
|
80
|
+
return ignoreCaseAndAccents && (this.suggestions.has(lcWord) || this.suggestionsLower.has(lcWord));
|
|
81
|
+
}
|
|
82
|
+
suggest(word) {
|
|
83
|
+
return this._suggest(word) || this._suggest(word.toLowerCase()) || [];
|
|
84
|
+
}
|
|
85
|
+
_suggest(word) {
|
|
86
|
+
if (this.ignoreWords.has(word))
|
|
87
|
+
return [];
|
|
88
|
+
if (!(word in this.typosDef))
|
|
89
|
+
return undefined;
|
|
90
|
+
const sug = this.typosDef[word];
|
|
91
|
+
const isPreferred = true;
|
|
92
|
+
if (!sug)
|
|
93
|
+
return [];
|
|
94
|
+
if (typeof sug === 'string') {
|
|
95
|
+
return [
|
|
96
|
+
{
|
|
97
|
+
word: sug,
|
|
98
|
+
cost: 1,
|
|
99
|
+
isPreferred,
|
|
100
|
+
},
|
|
101
|
+
];
|
|
102
|
+
}
|
|
103
|
+
return sug.map((word, index) => ({ word, cost: index + 1, isPreferred }));
|
|
104
|
+
}
|
|
105
|
+
genSuggestions(collector) {
|
|
106
|
+
const sugs = this.suggest(collector.word);
|
|
107
|
+
sugs.forEach((result) => collector.add(result));
|
|
108
|
+
}
|
|
109
|
+
mapWord(word) {
|
|
110
|
+
return word;
|
|
111
|
+
}
|
|
112
|
+
getErrors() {
|
|
113
|
+
return [];
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
const createCache = createAutoResolveWeakCache();
|
|
117
|
+
/**
|
|
118
|
+
* Create a dictionary where all words are to be forbidden.
|
|
119
|
+
* @param entries - list of Typos Entries
|
|
120
|
+
* @param name - name of dictionary
|
|
121
|
+
* @param source - source
|
|
122
|
+
* @returns
|
|
123
|
+
*/
|
|
124
|
+
export function createTyposDictionary(entries, name, source) {
|
|
125
|
+
return createCache.get(entries, () => {
|
|
126
|
+
const def = processEntriesToTyposDef(entries);
|
|
127
|
+
return new TyposDictionaryImpl(name, source, def);
|
|
128
|
+
});
|
|
129
|
+
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { DictionaryDefinitionInline, SpellingDictionary } from './SpellingDictionary.mjs';
|
|
2
|
+
export declare function createInlineSpellingDictionary(inlineDict: DictionaryDefinitionInline, source: string): SpellingDictionary;
|
|
3
|
+
//# sourceMappingURL=createInlineSpellingDictionary.d.mts.map
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { createAutoResolveWeakCache } from '../util/AutoResolve.mjs';
|
|
2
|
+
import { isDefined } from '../util/util.mjs';
|
|
3
|
+
import { createSpellingDictionary } from './createSpellingDictionary.mjs';
|
|
4
|
+
import { createFlagWordsDictionary } from './FlagWordsDictionary.mjs';
|
|
5
|
+
import { createIgnoreWordsDictionary } from './IgnoreWordsDictionary.mjs';
|
|
6
|
+
import { createCollection } from './SpellingDictionaryCollection.mjs';
|
|
7
|
+
import { createSuggestDictionary } from './SuggestDictionary.mjs';
|
|
8
|
+
const cache = createAutoResolveWeakCache();
|
|
9
|
+
export function createInlineSpellingDictionary(inlineDict, source) {
|
|
10
|
+
return cache.get(inlineDict, () => {
|
|
11
|
+
const { words, flagWords, ignoreWords, suggestWords, name } = inlineDict;
|
|
12
|
+
const dictSources = [
|
|
13
|
+
words && createSpellingDictionary(words, name + '-words', source, inlineDict),
|
|
14
|
+
flagWords && createFlagWordsDictionary(flagWords, name + '-flag-words', source),
|
|
15
|
+
ignoreWords && createIgnoreWordsDictionary(ignoreWords, name + '-ignore-words', source),
|
|
16
|
+
suggestWords && createSuggestDictionary(suggestWords, name + '-suggest', source),
|
|
17
|
+
].filter(isDefined);
|
|
18
|
+
return createCollection(dictSources, name, source);
|
|
19
|
+
});
|
|
20
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { IterableLike } from '../util/IterableLike.mjs';
|
|
2
|
+
import type { DictionaryInfo, SpellingDictionary, SpellingDictionaryOptions } from './SpellingDictionary.mjs';
|
|
3
|
+
/**
|
|
4
|
+
* Create a SpellingDictionary
|
|
5
|
+
* @param wordList - list of words
|
|
6
|
+
* @param name - name of dictionary
|
|
7
|
+
* @param source - filename or uri
|
|
8
|
+
* @param options - dictionary options
|
|
9
|
+
* @returns a Spelling Dictionary
|
|
10
|
+
*/
|
|
11
|
+
export declare function createSpellingDictionary(wordList: readonly string[] | IterableLike<string>, name: string, source: string, options?: SpellingDictionaryOptions | undefined): SpellingDictionary;
|
|
12
|
+
export interface SpellingDictionaryLoadError extends Error {
|
|
13
|
+
/** The Error Name */
|
|
14
|
+
readonly name: string;
|
|
15
|
+
/** Possible Cause */
|
|
16
|
+
readonly cause?: Error | undefined;
|
|
17
|
+
/** Message to Display */
|
|
18
|
+
readonly message: string;
|
|
19
|
+
/** Dictionary Information */
|
|
20
|
+
readonly info: DictionaryInfo;
|
|
21
|
+
}
|
|
22
|
+
export declare function createFailedToLoadDictionary(name: string, source: string, error: Error, options?: SpellingDictionaryOptions | undefined): SpellingDictionary;
|
|
23
|
+
//# sourceMappingURL=createSpellingDictionary.d.mts.map
|