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.
Files changed (127) hide show
  1. package/dist/{SpellingDictionary → cjs/SpellingDictionary}/CachingDictionary.d.ts +3 -3
  2. package/dist/{SpellingDictionary → cjs/SpellingDictionary}/CachingDictionary.js +9 -9
  3. package/dist/{SpellingDictionary → cjs/SpellingDictionary}/FlagWordsDictionary.d.ts +1 -1
  4. package/dist/{SpellingDictionary → cjs/SpellingDictionary}/FlagWordsDictionary.js +11 -11
  5. package/dist/{SpellingDictionary → cjs/SpellingDictionary}/IgnoreWordsDictionary.d.ts +1 -1
  6. package/dist/{SpellingDictionary → cjs/SpellingDictionary}/IgnoreWordsDictionary.js +5 -5
  7. package/dist/{SpellingDictionary → cjs/SpellingDictionary}/SpellingDictionaryCollection.d.ts +1 -1
  8. package/dist/{SpellingDictionary → cjs/SpellingDictionary}/SpellingDictionaryCollection.js +12 -12
  9. package/dist/{SpellingDictionary → cjs/SpellingDictionary}/SpellingDictionaryFromTrie.d.ts +1 -1
  10. package/dist/{SpellingDictionary → cjs/SpellingDictionary}/SpellingDictionaryFromTrie.js +16 -16
  11. package/dist/{SpellingDictionary → cjs/SpellingDictionary}/SpellingDictionaryMethods.d.ts +1 -1
  12. package/dist/{SpellingDictionary → cjs/SpellingDictionary}/SpellingDictionaryMethods.js +5 -5
  13. package/dist/{SpellingDictionary → cjs/SpellingDictionary}/SuggestDictionary.d.ts +2 -2
  14. package/dist/{SpellingDictionary → cjs/SpellingDictionary}/SuggestDictionary.js +9 -9
  15. package/dist/{SpellingDictionary → cjs/SpellingDictionary}/Terms/index.d.ts +1 -1
  16. package/dist/cjs/SpellingDictionary/Typos/index.d.ts +4 -0
  17. package/dist/{SpellingDictionary → cjs/SpellingDictionary}/Typos/index.js +7 -7
  18. package/dist/{SpellingDictionary → cjs/SpellingDictionary}/Typos/typos.d.ts +1 -1
  19. package/dist/{SpellingDictionary → cjs/SpellingDictionary}/Typos/typosParser.d.ts +1 -1
  20. package/dist/{SpellingDictionary → cjs/SpellingDictionary}/Typos/typosParser.js +6 -6
  21. package/dist/{SpellingDictionary → cjs/SpellingDictionary}/Typos/util.d.ts +1 -1
  22. package/dist/{SpellingDictionary → cjs/SpellingDictionary}/TyposDictionary.d.ts +2 -2
  23. package/dist/{SpellingDictionary → cjs/SpellingDictionary}/TyposDictionary.js +10 -10
  24. package/dist/{SpellingDictionary → cjs/SpellingDictionary}/createInlineSpellingDictionary.d.ts +1 -1
  25. package/dist/cjs/SpellingDictionary/createInlineSpellingDictionary.js +25 -0
  26. package/dist/{SpellingDictionary → cjs/SpellingDictionary}/createSpellingDictionary.d.ts +2 -2
  27. package/dist/{SpellingDictionary → cjs/SpellingDictionary}/createSpellingDictionary.js +9 -9
  28. package/dist/{SpellingDictionary → cjs/SpellingDictionary}/index.d.ts +10 -10
  29. package/dist/{SpellingDictionary → cjs/SpellingDictionary}/index.js +20 -20
  30. package/dist/{index.d.ts → cjs/index.d.ts} +2 -2
  31. package/dist/{index.js → cjs/index.js} +11 -11
  32. package/dist/{util → cjs/util}/clean.d.ts +1 -1
  33. package/dist/{util → cjs/util}/repMap.js +4 -4
  34. package/dist/{util → cjs/util}/textMappers.js +2 -2
  35. package/dist/esm/SpellingDictionary/CachingDictionary.d.mts +30 -0
  36. package/dist/esm/SpellingDictionary/CachingDictionary.mjs +45 -0
  37. package/dist/esm/SpellingDictionary/FlagWordsDictionary.d.mts +11 -0
  38. package/dist/esm/SpellingDictionary/FlagWordsDictionary.mjs +134 -0
  39. package/dist/esm/SpellingDictionary/IgnoreWordsDictionary.d.mts +11 -0
  40. package/dist/esm/SpellingDictionary/IgnoreWordsDictionary.mjs +96 -0
  41. package/dist/esm/SpellingDictionary/SpellingDictionary.d.mts +150 -0
  42. package/dist/esm/SpellingDictionary/SpellingDictionary.mjs +4 -0
  43. package/dist/esm/SpellingDictionary/SpellingDictionaryCollection.d.mts +16 -0
  44. package/dist/esm/SpellingDictionary/SpellingDictionaryCollection.mjs +111 -0
  45. package/dist/esm/SpellingDictionary/SpellingDictionaryFromTrie.d.mts +50 -0
  46. package/dist/esm/SpellingDictionary/SpellingDictionaryFromTrie.mjs +172 -0
  47. package/dist/esm/SpellingDictionary/SpellingDictionaryMethods.d.mts +26 -0
  48. package/dist/esm/SpellingDictionary/SpellingDictionaryMethods.mjs +96 -0
  49. package/dist/esm/SpellingDictionary/SuggestDictionary.d.mts +20 -0
  50. package/dist/esm/SpellingDictionary/SuggestDictionary.mjs +97 -0
  51. package/dist/esm/SpellingDictionary/Terms/index.d.mts +2 -0
  52. package/dist/esm/SpellingDictionary/Terms/index.mjs +1 -0
  53. package/dist/esm/SpellingDictionary/Terms/terms.d.mts +12 -0
  54. package/dist/esm/SpellingDictionary/Terms/terms.mjs +1 -0
  55. package/dist/esm/SpellingDictionary/Typos/index.d.mts +4 -0
  56. package/dist/esm/SpellingDictionary/Typos/index.mjs +2 -0
  57. package/dist/esm/SpellingDictionary/Typos/typos.d.mts +18 -0
  58. package/dist/esm/SpellingDictionary/Typos/typos.mjs +1 -0
  59. package/dist/esm/SpellingDictionary/Typos/typosParser.d.mts +34 -0
  60. package/dist/esm/SpellingDictionary/Typos/typosParser.mjs +131 -0
  61. package/dist/esm/SpellingDictionary/Typos/util.d.mts +31 -0
  62. package/dist/esm/SpellingDictionary/Typos/util.mjs +105 -0
  63. package/dist/esm/SpellingDictionary/TyposDictionary.d.mts +21 -0
  64. package/dist/esm/SpellingDictionary/TyposDictionary.mjs +129 -0
  65. package/dist/esm/SpellingDictionary/createInlineSpellingDictionary.d.mts +3 -0
  66. package/dist/esm/SpellingDictionary/createInlineSpellingDictionary.mjs +20 -0
  67. package/dist/esm/SpellingDictionary/createSpellingDictionary.d.mts +23 -0
  68. package/dist/esm/SpellingDictionary/createSpellingDictionary.mjs +68 -0
  69. package/dist/esm/SpellingDictionary/defaults.d.mts +3 -0
  70. package/dist/esm/SpellingDictionary/defaults.mjs +2 -0
  71. package/dist/esm/SpellingDictionary/index.d.mts +11 -0
  72. package/dist/esm/SpellingDictionary/index.mjs +9 -0
  73. package/dist/esm/index.d.mts +3 -0
  74. package/dist/esm/index.mjs +1 -0
  75. package/dist/esm/util/AutoCache.d.mts +25 -0
  76. package/dist/esm/util/AutoCache.mjs +67 -0
  77. package/dist/esm/util/AutoResolve.d.mts +21 -0
  78. package/dist/esm/util/AutoResolve.mjs +52 -0
  79. package/dist/esm/util/IterableLike.d.mts +4 -0
  80. package/dist/esm/util/IterableLike.mjs +1 -0
  81. package/dist/esm/util/clean.d.mts +7 -0
  82. package/dist/esm/util/clean.mjs +13 -0
  83. package/dist/esm/util/regexHelper.d.mts +7 -0
  84. package/dist/esm/util/regexHelper.mjs +8 -0
  85. package/dist/esm/util/repMap.d.mts +27 -0
  86. package/dist/esm/util/repMap.mjs +152 -0
  87. package/dist/esm/util/simpleCache.d.mts +46 -0
  88. package/dist/esm/util/simpleCache.mjs +135 -0
  89. package/dist/esm/util/text.d.mts +10 -0
  90. package/dist/esm/util/text.mjs +46 -0
  91. package/dist/esm/util/textMappers.d.mts +3 -0
  92. package/dist/esm/util/textMappers.mjs +15 -0
  93. package/dist/esm/util/types.d.mts +7 -0
  94. package/dist/esm/util/types.mjs +1 -0
  95. package/dist/esm/util/util.d.mts +2 -0
  96. package/dist/esm/util/util.mjs +3 -0
  97. package/package.json +27 -18
  98. package/dist/SpellingDictionary/Typos/index.d.ts +0 -4
  99. package/dist/SpellingDictionary/createInlineSpellingDictionary.js +0 -25
  100. /package/dist/{SpellingDictionary → cjs/SpellingDictionary}/SpellingDictionary.d.ts +0 -0
  101. /package/dist/{SpellingDictionary → cjs/SpellingDictionary}/SpellingDictionary.js +0 -0
  102. /package/dist/{SpellingDictionary → cjs/SpellingDictionary}/Terms/index.js +0 -0
  103. /package/dist/{SpellingDictionary → cjs/SpellingDictionary}/Terms/terms.d.ts +0 -0
  104. /package/dist/{SpellingDictionary → cjs/SpellingDictionary}/Terms/terms.js +0 -0
  105. /package/dist/{SpellingDictionary → cjs/SpellingDictionary}/Typos/typos.js +0 -0
  106. /package/dist/{SpellingDictionary → cjs/SpellingDictionary}/Typos/util.js +0 -0
  107. /package/dist/{SpellingDictionary → cjs/SpellingDictionary}/defaults.d.ts +0 -0
  108. /package/dist/{SpellingDictionary → cjs/SpellingDictionary}/defaults.js +0 -0
  109. /package/dist/{util → cjs/util}/AutoCache.d.ts +0 -0
  110. /package/dist/{util → cjs/util}/AutoCache.js +0 -0
  111. /package/dist/{util → cjs/util}/AutoResolve.d.ts +0 -0
  112. /package/dist/{util → cjs/util}/AutoResolve.js +0 -0
  113. /package/dist/{util → cjs/util}/IterableLike.d.ts +0 -0
  114. /package/dist/{util → cjs/util}/IterableLike.js +0 -0
  115. /package/dist/{util → cjs/util}/clean.js +0 -0
  116. /package/dist/{util → cjs/util}/regexHelper.d.ts +0 -0
  117. /package/dist/{util → cjs/util}/regexHelper.js +0 -0
  118. /package/dist/{util → cjs/util}/repMap.d.ts +0 -0
  119. /package/dist/{util → cjs/util}/simpleCache.d.ts +0 -0
  120. /package/dist/{util → cjs/util}/simpleCache.js +0 -0
  121. /package/dist/{util → cjs/util}/text.d.ts +0 -0
  122. /package/dist/{util → cjs/util}/text.js +0 -0
  123. /package/dist/{util → cjs/util}/textMappers.d.ts +0 -0
  124. /package/dist/{util → cjs/util}/types.d.ts +0 -0
  125. /package/dist/{util → cjs/util}/types.js +0 -0
  126. /package/dist/{util → cjs/util}/util.d.ts +0 -0
  127. /package/dist/{util → cjs/util}/util.js +0 -0
@@ -0,0 +1,150 @@
1
+ import type { DictionaryInformation, ReplaceMap } from '@cspell/cspell-types';
2
+ import type { CompoundWordsMethod, SuggestionCollector, SuggestionResult, WeightMap } from 'cspell-trie-lib';
3
+ export type { DictionaryDefinitionInline } from '@cspell/cspell-types';
4
+ export { CompoundWordsMethod, type SuggestionCollector, type SuggestionResult } from 'cspell-trie-lib';
5
+ export interface SearchOptions {
6
+ /**
7
+ * Legacy compounds have been deprecated.
8
+ *
9
+ * @deprecated
10
+ */
11
+ useCompounds?: boolean | number | undefined;
12
+ /**
13
+ * Ignore Case and Accents
14
+ */
15
+ ignoreCase?: boolean | undefined;
16
+ }
17
+ export interface SuggestOptions {
18
+ /**
19
+ * Compounding Mode.
20
+ * `NONE` is the best option.
21
+ */
22
+ compoundMethod?: CompoundWordsMethod | undefined;
23
+ /**
24
+ * The limit on the number of suggestions to generate. If `allowTies` is true, it is possible
25
+ * for more suggestions to be generated.
26
+ */
27
+ numSuggestions?: number | undefined;
28
+ /**
29
+ * Max number of changes / edits to the word to get to a suggestion matching suggestion.
30
+ */
31
+ numChanges?: number | undefined;
32
+ /**
33
+ * Allow for case-ingestive checking.
34
+ */
35
+ ignoreCase?: boolean | undefined;
36
+ /**
37
+ * If multiple suggestions have the same edit / change "cost", then included them even if
38
+ * it causes more than `numSuggestions` to be returned.
39
+ * @default false
40
+ */
41
+ includeTies?: boolean | undefined;
42
+ /**
43
+ * Maximum amount of time to allow for generating suggestions.
44
+ */
45
+ timeout?: number | undefined;
46
+ }
47
+ export type FindOptions = SearchOptions;
48
+ export interface FindResult {
49
+ /** the text found, otherwise `false` */
50
+ found: string | false;
51
+ /** `true` if it is considered a forbidden word. */
52
+ forbidden: boolean;
53
+ /** `true` if it is a no-suggest word. */
54
+ noSuggest: boolean;
55
+ }
56
+ export type HasOptions = SearchOptions;
57
+ export type IgnoreCaseOption = boolean;
58
+ export interface SpellingDictionaryOptions {
59
+ repMap?: ReplaceMap;
60
+ /**
61
+ * The dictionary is case aware.
62
+ */
63
+ caseSensitive?: boolean;
64
+ /**
65
+ * This is a NO Suggest dictionary used for words to be ignored.
66
+ */
67
+ noSuggest?: boolean;
68
+ /**
69
+ * Extra dictionary information used in improving suggestions
70
+ * based upon locale.
71
+ */
72
+ dictionaryInformation?: DictionaryInformation;
73
+ /**
74
+ * Strip Case and Accents to allow for case insensitive searches and
75
+ * words without accents.
76
+ *
77
+ * Note: this setting only applies to word lists. It has no-impact on trie
78
+ * dictionaries.
79
+ *
80
+ * @default true
81
+ */
82
+ supportNonStrictSearches?: boolean;
83
+ /**
84
+ * Turns on legacy word compounds.
85
+ * @deprecated
86
+ */
87
+ useCompounds?: boolean;
88
+ /**
89
+ * Optional WeightMap used to improve suggestions.
90
+ */
91
+ weightMap?: WeightMap | undefined;
92
+ }
93
+ export interface DictionaryInfo {
94
+ /** The name of the dictionary */
95
+ readonly name: string;
96
+ /** The source, filename or URI */
97
+ readonly source: string;
98
+ /** Options */
99
+ readonly options: SpellingDictionaryOptions;
100
+ }
101
+ export interface SpellingDictionary extends DictionaryInfo {
102
+ readonly type: string;
103
+ readonly containsNoSuggestWords: boolean;
104
+ has(word: string, options?: HasOptions): boolean;
105
+ /** A more detailed search for a word, might take longer than `has` */
106
+ find(word: string, options?: SearchOptions): FindResult | undefined;
107
+ /**
108
+ * Checks if a word is forbidden.
109
+ * @param word - word to check.
110
+ */
111
+ isForbidden(word: string, ignoreCaseAndAccents?: IgnoreCaseOption): boolean;
112
+ /**
113
+ * No Suggest words are considered correct but will not be listed when
114
+ * suggestions are generated.
115
+ * No Suggest words and "Ignored" words are equivalent. Ignored / no suggest words override forbidden words.
116
+ * @param word - word to check
117
+ * @param options - options
118
+ */
119
+ isNoSuggestWord(word: string, options: HasOptions): boolean;
120
+ /**
121
+ * Generate suggestions for a word.
122
+ * @param word - word
123
+ * @param numSuggestions - max number of suggestions to generate.
124
+ * @param compoundMethod - Default NONE.
125
+ * @param numChanges - Default 5
126
+ * @param ignoreCase - true
127
+ */
128
+ suggest(word: string, numSuggestions?: number, compoundMethod?: CompoundWordsMethod, numChanges?: number, ignoreCase?: boolean): SuggestionResult[];
129
+ /**
130
+ * Generate suggestions for a word
131
+ * @param word - word
132
+ * @param suggestOptions - options
133
+ */
134
+ suggest(word: string, suggestOptions: SuggestOptions): SuggestionResult[];
135
+ genSuggestions(collector: SuggestionCollector, suggestOptions: SuggestOptions): void;
136
+ mapWord(word: string): string;
137
+ /**
138
+ * Generates all possible word combinations by applying `repMap`.
139
+ * This acts a bit like brace expansions in globs.
140
+ * @param word - the word to map
141
+ * @returns array of adjusted words.
142
+ */
143
+ remapWord?: (word: string) => string[];
144
+ readonly size: number;
145
+ readonly isDictionaryCaseSensitive: boolean;
146
+ getErrors?(): Error[];
147
+ }
148
+ export type SuggestArgs = Parameters<SpellingDictionary['suggest']> | Parameters<(word: string, numSuggestions?: number, compoundMethod?: CompoundWordsMethod, numChanges?: number, ignoreCase?: boolean) => SuggestionResult[]>;
149
+ export declare const defaultOptions: SpellingDictionaryOptions;
150
+ //# sourceMappingURL=SpellingDictionary.d.mts.map
@@ -0,0 +1,4 @@
1
+ export { CompoundWordsMethod } from 'cspell-trie-lib';
2
+ export const defaultOptions = Object.freeze({
3
+ weightMap: undefined,
4
+ });
@@ -0,0 +1,16 @@
1
+ import type { SearchOptions, SpellingDictionary } from './SpellingDictionary.mjs';
2
+ export interface SpellingDictionaryCollection extends SpellingDictionary {
3
+ readonly type: 'SpellingDictionaryCollection';
4
+ readonly dictionaries: SpellingDictionary[];
5
+ getErrors(): Error[];
6
+ }
7
+ export declare function createCollection(dictionaries: SpellingDictionary[], name: string, source?: string): SpellingDictionaryCollection;
8
+ declare function isWordInAnyDictionary(dicts: SpellingDictionary[], word: string, options: SearchOptions): SpellingDictionary | undefined;
9
+ declare function isWordForbiddenInAnyDictionary(dicts: SpellingDictionary[], word: string, ignoreCase: boolean | undefined): SpellingDictionary | undefined;
10
+ export declare function isSpellingDictionaryCollection(dict: SpellingDictionary): dict is SpellingDictionaryCollection;
11
+ export declare const __testing__: {
12
+ isWordInAnyDictionary: typeof isWordInAnyDictionary;
13
+ isWordForbiddenInAnyDictionary: typeof isWordForbiddenInAnyDictionary;
14
+ };
15
+ export {};
16
+ //# sourceMappingURL=SpellingDictionaryCollection.d.mts.map
@@ -0,0 +1,111 @@
1
+ import { CASE_INSENSITIVE_PREFIX } from 'cspell-trie-lib';
2
+ import { genSequence } from 'gensequence';
3
+ import { isDefined } from '../util/util.mjs';
4
+ import * as Defaults from './defaults.mjs';
5
+ import { CompoundWordsMethod } from './SpellingDictionary.mjs';
6
+ import { defaultNumSuggestions, hasOptionToSearchOption, suggestArgsToSuggestOptions, suggestionCollector, } from './SpellingDictionaryMethods.mjs';
7
+ function identityString(w) {
8
+ return w;
9
+ }
10
+ class SpellingDictionaryCollectionImpl {
11
+ constructor(dictionaries, name, source) {
12
+ this.dictionaries = dictionaries;
13
+ this.name = name;
14
+ this.options = { weightMap: undefined };
15
+ this.mapWord = identityString;
16
+ this.type = 'SpellingDictionaryCollection';
17
+ this._isNoSuggestWord = (word, options) => {
18
+ if (!this.containsNoSuggestWords)
19
+ return false;
20
+ return !!isNoSuggestWordInAnyDictionary(this.dictionaries, word, options || {});
21
+ };
22
+ this.dictionaries = this.dictionaries.sort((a, b) => b.size - a.size);
23
+ this.source = source || dictionaries.map((d) => d.name).join(', ');
24
+ this.isDictionaryCaseSensitive = this.dictionaries.reduce((a, b) => a || b.isDictionaryCaseSensitive, false);
25
+ this.containsNoSuggestWords = this.dictionaries.reduce((a, b) => a || b.containsNoSuggestWords, false);
26
+ }
27
+ has(word, hasOptions) {
28
+ const options = hasOptionToSearchOption(hasOptions);
29
+ return !!isWordInAnyDictionary(this.dictionaries, word, options) && !this.isForbidden(word);
30
+ }
31
+ find(word, hasOptions) {
32
+ const options = hasOptionToSearchOption(hasOptions);
33
+ return findInAnyDictionary(this.dictionaries, word, options);
34
+ }
35
+ isNoSuggestWord(word, options) {
36
+ return this._isNoSuggestWord(word, options);
37
+ }
38
+ isForbidden(word, ignoreCaseAndAccents) {
39
+ const ignoreCase = ignoreCaseAndAccents ?? Defaults.isForbiddenIgnoreCaseAndAccents;
40
+ return !!this._isForbiddenInDict(word, ignoreCase) && !this.isNoSuggestWord(word, { ignoreCase });
41
+ }
42
+ suggest(...args) {
43
+ const [word] = args;
44
+ const suggestOptions = suggestArgsToSuggestOptions(args);
45
+ return this._suggest(word, suggestOptions);
46
+ }
47
+ _suggest(word, suggestOptions) {
48
+ const { numSuggestions = defaultNumSuggestions, numChanges, ignoreCase, includeTies, timeout } = suggestOptions;
49
+ const prefixNoCase = CASE_INSENSITIVE_PREFIX;
50
+ const filter = (word, _cost) => {
51
+ return ((ignoreCase || word[0] !== prefixNoCase) &&
52
+ !this.isForbidden(word) &&
53
+ !this.isNoSuggestWord(word, suggestOptions));
54
+ };
55
+ const collectorOptions = {
56
+ numSuggestions,
57
+ filter,
58
+ changeLimit: numChanges,
59
+ includeTies,
60
+ ignoreCase,
61
+ timeout,
62
+ };
63
+ const collector = suggestionCollector(word, collectorOptions);
64
+ this.genSuggestions(collector, suggestOptions);
65
+ return collector.suggestions.map((r) => ({ ...r, word: r.word }));
66
+ }
67
+ get size() {
68
+ return this.dictionaries.reduce((a, b) => a + b.size, 0);
69
+ }
70
+ genSuggestions(collector, suggestOptions) {
71
+ const _suggestOptions = { ...suggestOptions };
72
+ const { compoundMethod = CompoundWordsMethod.SEPARATE_WORDS } = suggestOptions;
73
+ _suggestOptions.compoundMethod = this.options.useCompounds ? CompoundWordsMethod.JOIN_WORDS : compoundMethod;
74
+ this.dictionaries.forEach((dict) => dict.genSuggestions(collector, _suggestOptions));
75
+ }
76
+ getErrors() {
77
+ return this.dictionaries.reduce((errors, dict) => errors.concat(dict.getErrors?.() || []), []);
78
+ }
79
+ _isForbiddenInDict(word, ignoreCase) {
80
+ return isWordForbiddenInAnyDictionary(this.dictionaries, word, ignoreCase);
81
+ }
82
+ }
83
+ export function createCollection(dictionaries, name, source) {
84
+ return new SpellingDictionaryCollectionImpl(dictionaries, name, source);
85
+ }
86
+ function isWordInAnyDictionary(dicts, word, options) {
87
+ return genSequence(dicts).first((dict) => dict.has(word, options));
88
+ }
89
+ function findInAnyDictionary(dicts, word, options) {
90
+ const found = dicts.map((dict) => dict.find(word, options)).filter(isDefined);
91
+ if (!found.length)
92
+ return undefined;
93
+ return found.reduce((a, b) => ({
94
+ found: a.forbidden ? a.found : b.forbidden ? b.found : a.found || b.found,
95
+ forbidden: a.forbidden || b.forbidden,
96
+ noSuggest: a.noSuggest || b.noSuggest,
97
+ }));
98
+ }
99
+ function isNoSuggestWordInAnyDictionary(dicts, word, options) {
100
+ return genSequence(dicts).first((dict) => dict.isNoSuggestWord(word, options));
101
+ }
102
+ function isWordForbiddenInAnyDictionary(dicts, word, ignoreCase) {
103
+ return genSequence(dicts).first((dict) => dict.isForbidden(word, ignoreCase));
104
+ }
105
+ export function isSpellingDictionaryCollection(dict) {
106
+ return dict instanceof SpellingDictionaryCollectionImpl;
107
+ }
108
+ export const __testing__ = {
109
+ isWordInAnyDictionary,
110
+ isWordForbiddenInAnyDictionary,
111
+ };
@@ -0,0 +1,50 @@
1
+ import type { SuggestionCollector, SuggestionResult } from 'cspell-trie-lib';
2
+ import { CompoundWordsMethod, Trie } from 'cspell-trie-lib';
3
+ import type { FindResult, HasOptions, SpellingDictionary, SpellingDictionaryOptions, SuggestOptions } from './SpellingDictionary.mjs';
4
+ export declare class SpellingDictionaryFromTrie implements SpellingDictionary {
5
+ readonly trie: Trie;
6
+ readonly name: string;
7
+ readonly options: SpellingDictionaryOptions;
8
+ readonly source: string;
9
+ static readonly cachedWordsLimit = 50000;
10
+ private _size;
11
+ readonly knownWords: Set<string>;
12
+ readonly unknownWords: Set<string>;
13
+ readonly mapWord: (word: string) => string;
14
+ readonly remapWord: (word: string) => string[];
15
+ readonly type = "SpellingDictionaryFromTrie";
16
+ readonly isDictionaryCaseSensitive: boolean;
17
+ readonly containsNoSuggestWords: boolean;
18
+ private weightMap;
19
+ constructor(trie: Trie, name: string, options: SpellingDictionaryOptions, source?: string, size?: number);
20
+ get size(): number;
21
+ has(word: string, hasOptions?: HasOptions): boolean;
22
+ find(word: string, hasOptions?: HasOptions): FindResult | undefined;
23
+ private resolveOptions;
24
+ private _find;
25
+ private findAnyForm;
26
+ private _findAnyForm;
27
+ isNoSuggestWord(word: string, options?: HasOptions): boolean;
28
+ isForbidden(word: string, _ignoreCaseAndAccents?: boolean): boolean;
29
+ private _isForbidden;
30
+ suggest(word: string, numSuggestions?: number, compoundMethod?: CompoundWordsMethod, numChanges?: number, ignoreCase?: boolean): SuggestionResult[];
31
+ suggest(word: string, suggestOptions: SuggestOptions): SuggestionResult[];
32
+ private _suggest;
33
+ genSuggestions(collector: SuggestionCollector, suggestOptions: SuggestOptions): void;
34
+ getErrors(): Error[];
35
+ }
36
+ /**
37
+ * Create a dictionary from a trie file.
38
+ * @param data - contents of a trie file.
39
+ * @param name - name of dictionary
40
+ * @param source - filename or uri
41
+ * @param options - options.
42
+ * @returns SpellingDictionary
43
+ */
44
+ export declare function createSpellingDictionaryFromTrieFile(data: Iterable<string> | string, name: string, source: string, options: SpellingDictionaryOptions): SpellingDictionary;
45
+ declare function outerWordForms(word: string, mapWord: (word: string) => string[]): Set<string>;
46
+ export declare const __testing__: {
47
+ outerWordForms: typeof outerWordForms;
48
+ };
49
+ export {};
50
+ //# sourceMappingURL=SpellingDictionaryFromTrie.d.mts.map
@@ -0,0 +1,172 @@
1
+ import { opConcatMap, pipe } from '@cspell/cspell-pipe/sync';
2
+ import { CompoundWordsMethod, importTrie, suggestionCollector, Trie } from 'cspell-trie-lib';
3
+ import { autoCache, createCache01 } from '../util/AutoCache.mjs';
4
+ import { clean } from '../util/clean.mjs';
5
+ import { createMapper, createRepMapper } from '../util/repMap.mjs';
6
+ import * as Defaults from './defaults.mjs';
7
+ import { createWeightMapFromDictionaryInformation, defaultNumSuggestions, hasOptionToSearchOption, impersonateCollector, suggestArgsToSuggestOptions, wordSearchForms, wordSuggestFormsArray, } from './SpellingDictionaryMethods.mjs';
8
+ const findWordOptionsCaseSensitive = Object.freeze({ caseSensitive: true });
9
+ const findWordOptionsNotCaseSensitive = Object.freeze({ caseSensitive: false });
10
+ export class SpellingDictionaryFromTrie {
11
+ constructor(trie, name, options, source = 'from trie', size) {
12
+ this.trie = trie;
13
+ this.name = name;
14
+ this.options = options;
15
+ this.source = source;
16
+ this._size = 0;
17
+ this.knownWords = new Set();
18
+ this.unknownWords = new Set();
19
+ this.type = 'SpellingDictionaryFromTrie';
20
+ this._find = findCache((word, useCompounds, ignoreCase) => this.findAnyForm(word, useCompounds, ignoreCase));
21
+ this._isForbidden = autoCache((word) => {
22
+ return this.trie.isForbiddenWord(word);
23
+ });
24
+ this.mapWord = createMapper(options.repMap, options.dictionaryInformation?.ignore);
25
+ this.remapWord = createRepMapper(options.repMap, options.dictionaryInformation?.ignore);
26
+ this.isDictionaryCaseSensitive = options.caseSensitive ?? !trie.isLegacy;
27
+ this.containsNoSuggestWords = options.noSuggest || false;
28
+ this._size = size || 0;
29
+ this.weightMap = options.weightMap || createWeightMapFromDictionaryInformation(options.dictionaryInformation);
30
+ }
31
+ get size() {
32
+ if (!this._size) {
33
+ // walk the trie and get the approximate size.
34
+ const i = this.trie.iterate();
35
+ let deeper = true;
36
+ let size = 0;
37
+ for (let r = i.next(); !r.done; r = i.next(deeper)) {
38
+ // count all nodes even though they are not words.
39
+ // because we are not going to all the leaves, this should give a good enough approximation.
40
+ size += 1;
41
+ deeper = r.value.text.length < 5;
42
+ }
43
+ this._size = size;
44
+ }
45
+ return this._size;
46
+ }
47
+ has(word, hasOptions) {
48
+ const { useCompounds, ignoreCase } = this.resolveOptions(hasOptions);
49
+ const r = this._find(word, useCompounds, ignoreCase);
50
+ return !!r && !r.forbidden && !!r.found;
51
+ }
52
+ find(word, hasOptions) {
53
+ const { useCompounds, ignoreCase } = this.resolveOptions(hasOptions);
54
+ const r = this._find(word, useCompounds, ignoreCase);
55
+ const { forbidden = this.isForbidden(word) } = r || {};
56
+ if (!r && !forbidden)
57
+ return undefined;
58
+ const { found = forbidden ? word : false } = r || {};
59
+ const noSuggest = found !== false && this.containsNoSuggestWords;
60
+ return { found, forbidden, noSuggest };
61
+ }
62
+ resolveOptions(hasOptions) {
63
+ const { useCompounds = this.options.useCompounds, ignoreCase = Defaults.ignoreCase } = hasOptionToSearchOption(hasOptions);
64
+ return { useCompounds, ignoreCase };
65
+ }
66
+ findAnyForm(word, useCompounds, ignoreCase) {
67
+ const outerForms = outerWordForms(word, this.remapWord ? this.remapWord : (word) => [this.mapWord(word)]);
68
+ for (const form of outerForms) {
69
+ const r = this._findAnyForm(form, useCompounds, ignoreCase);
70
+ if (r)
71
+ return r;
72
+ }
73
+ return undefined;
74
+ }
75
+ _findAnyForm(mWord, useCompounds, ignoreCase) {
76
+ const opts = ignoreCase ? findWordOptionsNotCaseSensitive : findWordOptionsCaseSensitive;
77
+ const findResult = this.trie.findWord(mWord, opts);
78
+ if (findResult.found !== false) {
79
+ return findResult;
80
+ }
81
+ const forms = wordSearchForms(mWord, this.isDictionaryCaseSensitive, ignoreCase);
82
+ for (const w of forms) {
83
+ const findResult = this.trie.findWord(w, opts);
84
+ if (findResult.found !== false) {
85
+ return findResult;
86
+ }
87
+ }
88
+ if (useCompounds) {
89
+ const optsUseCompounds = { ...opts, useLegacyWordCompounds: useCompounds };
90
+ for (const w of forms) {
91
+ const findResult = this.trie.findWord(w, optsUseCompounds);
92
+ if (findResult.found !== false) {
93
+ return findResult;
94
+ }
95
+ }
96
+ }
97
+ return undefined;
98
+ }
99
+ isNoSuggestWord(word, options) {
100
+ return this.containsNoSuggestWords ? this.has(word, options) : false;
101
+ }
102
+ isForbidden(word, _ignoreCaseAndAccents) {
103
+ return this._isForbidden(word);
104
+ }
105
+ suggest(...args) {
106
+ const [word] = args;
107
+ const suggestOptions = suggestArgsToSuggestOptions(args);
108
+ return this._suggest(word, suggestOptions);
109
+ }
110
+ _suggest(word, suggestOptions) {
111
+ const { numSuggestions = defaultNumSuggestions, numChanges, includeTies, ignoreCase, timeout } = suggestOptions;
112
+ function filter(_word) {
113
+ return true;
114
+ }
115
+ const collector = suggestionCollector(word, clean({
116
+ numSuggestions,
117
+ filter,
118
+ changeLimit: numChanges,
119
+ includeTies,
120
+ ignoreCase,
121
+ timeout,
122
+ weightMap: this.weightMap,
123
+ }));
124
+ this.genSuggestions(collector, suggestOptions);
125
+ return collector.suggestions.map((r) => ({ ...r, word: r.word }));
126
+ }
127
+ genSuggestions(collector, suggestOptions) {
128
+ if (this.options.noSuggest)
129
+ return;
130
+ const _compoundMethod = suggestOptions.compoundMethod ??
131
+ (this.options.useCompounds ? CompoundWordsMethod.JOIN_WORDS : CompoundWordsMethod.NONE);
132
+ wordSuggestFormsArray(collector.word).forEach((w) => this.trie.genSuggestions(impersonateCollector(collector, w), _compoundMethod));
133
+ }
134
+ getErrors() {
135
+ return [];
136
+ }
137
+ }
138
+ SpellingDictionaryFromTrie.cachedWordsLimit = 50000;
139
+ /**
140
+ * Create a dictionary from a trie file.
141
+ * @param data - contents of a trie file.
142
+ * @param name - name of dictionary
143
+ * @param source - filename or uri
144
+ * @param options - options.
145
+ * @returns SpellingDictionary
146
+ */
147
+ export function createSpellingDictionaryFromTrieFile(data, name, source, options) {
148
+ data = typeof data === 'string' ? data.split('\n') : data;
149
+ const trieNode = importTrie(data);
150
+ const trie = new Trie(trieNode);
151
+ return new SpellingDictionaryFromTrie(trie, name, options, source);
152
+ }
153
+ function findCache(fn, size = 2000) {
154
+ const cache = createCache01(size);
155
+ function find(word, useCompounds, ignoreCase) {
156
+ const r = cache.get(word);
157
+ if (r !== undefined) {
158
+ if (r.useCompounds === useCompounds && r.ignoreCase === ignoreCase) {
159
+ return r.findResult;
160
+ }
161
+ }
162
+ const findResult = fn(word, useCompounds, ignoreCase);
163
+ cache.set(word, { useCompounds, ignoreCase, findResult });
164
+ return findResult;
165
+ }
166
+ return find;
167
+ }
168
+ function outerWordForms(word, mapWord) {
169
+ const forms = pipe([word], opConcatMap((word) => [word, word.normalize('NFC'), word.normalize('NFD')]), opConcatMap((word) => [word, ...mapWord(word)]));
170
+ return new Set(forms);
171
+ }
172
+ export const __testing__ = { outerWordForms };
@@ -0,0 +1,26 @@
1
+ import type { DictionaryInformation } from '@cspell/cspell-types';
2
+ import type { SuggestionResult, WeightMap } from 'cspell-trie-lib';
3
+ import type { HasOptions, SearchOptions, SuggestArgs, SuggestOptions } from './SpellingDictionary.mjs';
4
+ export { impersonateCollector, suggestionCollector } from 'cspell-trie-lib';
5
+ export type FilterSuggestionsPredicate = (word: SuggestionResult) => boolean;
6
+ export declare const defaultNumSuggestions = 10;
7
+ declare function wordSearchFormsArray(word: string, isDictionaryCaseSensitive: boolean, ignoreCase: boolean): string[];
8
+ export declare function wordSearchForms(word: string, isDictionaryCaseSensitive: boolean, ignoreCase: boolean): Set<string>;
9
+ export declare function wordSuggestFormsArray(word: string): string[];
10
+ export declare function wordSuggestForms(word: string): Set<string>;
11
+ export declare function hasOptionToSearchOption(opt: HasOptions | undefined): SearchOptions;
12
+ /**
13
+ * Find the canonical form for SearchOptions. Useful Maps and WeakMaps.
14
+ * @param opt - options to normalize
15
+ * @returns SearchOptions - the canonical form
16
+ */
17
+ export declare function canonicalSearchOptions(opt: SearchOptions): SearchOptions;
18
+ export declare function suggestArgsToSuggestOptions(args: SuggestArgs): SuggestOptions;
19
+ export declare function createWeightMapFromDictionaryInformation(di: undefined): undefined;
20
+ export declare function createWeightMapFromDictionaryInformation(di: DictionaryInformation): WeightMap;
21
+ export declare function createWeightMapFromDictionaryInformation(di: DictionaryInformation | undefined): WeightMap | undefined;
22
+ export declare const __testMethods__: {
23
+ wordSearchForms: typeof wordSearchForms;
24
+ wordSearchFormsArray: typeof wordSearchFormsArray;
25
+ };
26
+ //# sourceMappingURL=SpellingDictionaryMethods.d.mts.map
@@ -0,0 +1,96 @@
1
+ import { mapDictionaryInformationToWeightMap } from 'cspell-trie-lib';
2
+ import { isUpperCase, removeUnboundAccents, ucFirst } from '../util/text.mjs';
3
+ export { impersonateCollector, suggestionCollector } from 'cspell-trie-lib';
4
+ export const defaultNumSuggestions = 10;
5
+ function wordSearchFormsArray(word, isDictionaryCaseSensitive, ignoreCase) {
6
+ return [...wordSearchForms(word, isDictionaryCaseSensitive, ignoreCase)];
7
+ }
8
+ export function wordSearchForms(word, isDictionaryCaseSensitive, ignoreCase) {
9
+ const forms = new Set();
10
+ word = word.normalize('NFC');
11
+ const wordLc = word.toLowerCase();
12
+ if (ignoreCase) {
13
+ if (isDictionaryCaseSensitive) {
14
+ forms.add(wordLc);
15
+ }
16
+ else {
17
+ forms.add(wordLc);
18
+ // Legacy remove any unbound accents
19
+ forms.add(removeUnboundAccents(wordLc));
20
+ }
21
+ }
22
+ else {
23
+ if (isDictionaryCaseSensitive) {
24
+ forms.add(word);
25
+ forms.add(wordLc);
26
+ // HOUSE -> House, house
27
+ if (isUpperCase(word)) {
28
+ forms.add(ucFirst(wordLc));
29
+ }
30
+ }
31
+ else {
32
+ forms.add(wordLc);
33
+ // Legacy remove any unbound accents
34
+ forms.add(removeUnboundAccents(wordLc));
35
+ }
36
+ }
37
+ return forms;
38
+ }
39
+ export function wordSuggestFormsArray(word) {
40
+ return [...wordSuggestForms(word)];
41
+ }
42
+ export function wordSuggestForms(word) {
43
+ word = word.normalize('NFC');
44
+ const forms = new Set([word]);
45
+ const wordLc = word.toLowerCase();
46
+ forms.add(wordLc);
47
+ return forms;
48
+ }
49
+ const DEFAULT_HAS_OPTIONS = Object.freeze({});
50
+ export function hasOptionToSearchOption(opt) {
51
+ return canonicalSearchOptions(!opt ? DEFAULT_HAS_OPTIONS : opt);
52
+ }
53
+ const canonicalSearchOptionsMap = new Map();
54
+ const knownCanonicalOptions = new WeakMap();
55
+ /**
56
+ * Find the canonical form for SearchOptions. Useful Maps and WeakMaps.
57
+ * @param opt - options to normalize
58
+ * @returns SearchOptions - the canonical form
59
+ */
60
+ export function canonicalSearchOptions(opt) {
61
+ const known = knownCanonicalOptions.get(opt);
62
+ if (known)
63
+ return known;
64
+ const { ignoreCase, useCompounds } = opt;
65
+ const foundLevel1Map = canonicalSearchOptionsMap.get(ignoreCase);
66
+ const useLevel1Map = foundLevel1Map || new Map();
67
+ if (!foundLevel1Map) {
68
+ canonicalSearchOptionsMap.set(ignoreCase, useLevel1Map);
69
+ }
70
+ const foundCanOpts = useLevel1Map.get(useCompounds);
71
+ const canOpts = foundCanOpts || Object.freeze({ ignoreCase, useCompounds });
72
+ if (!foundCanOpts) {
73
+ useLevel1Map.set(useCompounds, canOpts);
74
+ }
75
+ knownCanonicalOptions.set(opt, canOpts);
76
+ return canOpts;
77
+ }
78
+ export function suggestArgsToSuggestOptions(args) {
79
+ const [_word, options, compoundMethod, numChanges, ignoreCase] = args;
80
+ const suggestOptions = typeof options === 'object'
81
+ ? options
82
+ : {
83
+ numSuggestions: options,
84
+ compoundMethod,
85
+ numChanges,
86
+ ignoreCase,
87
+ };
88
+ return suggestOptions;
89
+ }
90
+ export function createWeightMapFromDictionaryInformation(di) {
91
+ return di ? mapDictionaryInformationToWeightMap(di) : undefined;
92
+ }
93
+ export const __testMethods__ = {
94
+ wordSearchForms,
95
+ wordSearchFormsArray,
96
+ };
@@ -0,0 +1,20 @@
1
+ import type { IgnoreCaseOption, SpellingDictionary } from './SpellingDictionary.mjs';
2
+ import { type TypoEntry, type TyposDef } from './Typos/index.mjs';
3
+ export interface SuggestDictionary extends SpellingDictionary {
4
+ /**
5
+ * Determine if the word can appear in a list of suggestions.
6
+ * @param word - word
7
+ * @param ignoreCaseAndAccents - ignore case.
8
+ * @returns true if a word is suggested, otherwise false.
9
+ */
10
+ isSuggestedWord(word: string, ignoreCaseAndAccents?: IgnoreCaseOption): boolean;
11
+ }
12
+ /**
13
+ * Create a dictionary where all words are to be forbidden.
14
+ * @param entries - list of Typos Entries
15
+ * @param name - name of dictionary
16
+ * @param source - source
17
+ * @returns
18
+ */
19
+ export declare function createSuggestDictionary(entries: readonly string[] | TyposDef | Iterable<TypoEntry>, name: string, source: string): SuggestDictionary;
20
+ //# sourceMappingURL=SuggestDictionary.d.mts.map