cspell-dictionary
Advanced tools
| export declare function measurePerfStart(name: string): void; | ||
| export declare function measurePerfEnd(name: string): void; | ||
| /** | ||
| * Creates performance marks and measures the time taken between them. | ||
| * @param name - name of the performance entry | ||
| * @returns a function to stop the timer. | ||
| */ | ||
| export declare function measurePerf(name: string): () => void; | ||
| //# sourceMappingURL=performance.d.ts.map |
| export function measurePerfStart(name) { | ||
| performance.mark(name + '-start'); | ||
| } | ||
| export function measurePerfEnd(name) { | ||
| performance.mark(name + '-end'); | ||
| performance.measure(name, name + '-start', name + '-end'); | ||
| } | ||
| /** | ||
| * Creates performance marks and measures the time taken between them. | ||
| * @param name - name of the performance entry | ||
| * @returns a function to stop the timer. | ||
| */ | ||
| export function measurePerf(name) { | ||
| measurePerfStart(name); | ||
| return () => { | ||
| measurePerfEnd(name); | ||
| }; | ||
| } | ||
| //# sourceMappingURL=performance.js.map |
+2
-9
@@ -1,11 +0,4 @@ | ||
| import { enableLogging as cacheDictionaryEnableLogging, getLog as cacheDictionaryGetLog } from './SpellingDictionary/CachingDictionary.js'; | ||
| export type { CachingDictionary, FindOptions, FindResult, HasOptions, PreferredSuggestion, SearchOptions, SpellingDictionary, SpellingDictionaryCollection, SpellingDictionaryOptions, SuggestionCollector, SuggestionResult, SuggestOptions, } from './SpellingDictionary/index.js'; | ||
| export { dictionaryCacheClearLog, dictionaryCacheEnableLogging, dictionaryCacheGetLog, } from './SpellingDictionary/CachingDictionary.js'; | ||
| export type { CachingDictionary, FindOptions, FindResult, HasOptions, PreferredSuggestion, SearchOptions, SpellingDictionary, SpellingDictionaryCollection, SpellingDictionaryOptions, Suggestion, SuggestionCollector, SuggestionResult, SuggestOptions, } from './SpellingDictionary/index.js'; | ||
| export { createCachingDictionary, createCollection, createFailedToLoadDictionary, createFlagWordsDictionary, createForbiddenWordsDictionary, createIgnoreWordsDictionary, createInlineSpellingDictionary, createSpellingDictionary, createSpellingDictionaryFromTrieFile, createSuggestDictionary, createSuggestOptions, } from './SpellingDictionary/index.js'; | ||
| /** | ||
| * Debugging utilities. | ||
| */ | ||
| export declare const _debug: { | ||
| cacheDictionaryEnableLogging: typeof cacheDictionaryEnableLogging; | ||
| cacheDictionaryGetLog: typeof cacheDictionaryGetLog; | ||
| }; | ||
| //# sourceMappingURL=index.d.ts.map |
+1
-8
@@ -1,10 +0,3 @@ | ||
| import { enableLogging as cacheDictionaryEnableLogging, getLog as cacheDictionaryGetLog, } from './SpellingDictionary/CachingDictionary.js'; | ||
| export { dictionaryCacheClearLog, dictionaryCacheEnableLogging, dictionaryCacheGetLog, } from './SpellingDictionary/CachingDictionary.js'; | ||
| export { createCachingDictionary, createCollection, createFailedToLoadDictionary, createFlagWordsDictionary, createForbiddenWordsDictionary, createIgnoreWordsDictionary, createInlineSpellingDictionary, createSpellingDictionary, createSpellingDictionaryFromTrieFile, createSuggestDictionary, createSuggestOptions, } from './SpellingDictionary/index.js'; | ||
| /** | ||
| * Debugging utilities. | ||
| */ | ||
| export const _debug = { | ||
| cacheDictionaryEnableLogging, | ||
| cacheDictionaryGetLog, | ||
| }; | ||
| //# sourceMappingURL=index.js.map |
@@ -0,1 +1,2 @@ | ||
| import type { SuggestionResult } from 'cspell-trie-lib'; | ||
| import type { CacheStats } from '../util/AutoCache.js'; | ||
@@ -24,3 +25,3 @@ import type { PreferredSuggestion, SearchOptions, SpellingDictionary } from './SpellingDictionary.js'; | ||
| getPreferredSuggestions(word: string): PreferredSuggestion[] | undefined; | ||
| suggest(word: string, suggestOptions?: SuggestOptionsRO): import('cspell-trie-lib').SuggestionResult[]; | ||
| suggest(word: string, suggestOptions?: SuggestOptionsRO): SuggestionResult[]; | ||
| } | ||
@@ -36,2 +37,3 @@ interface LogEntryBase extends SearchOptions { | ||
| value: boolean; | ||
| miss: boolean; | ||
| } | ||
@@ -46,5 +48,21 @@ export type LogEntry = LogEntryHas; | ||
| export declare function createCachingDictionary(dict: SpellingDictionary | SpellingDictionaryCollection, options: SearchOptions): CachingDictionary; | ||
| export declare function enableLogging(enabled?: boolean): void; | ||
| export declare function getLog(): LogEntryBase[]; | ||
| /** | ||
| * Enable or disable logging of dictionary requests. Every call to `has` will be logged. | ||
| * | ||
| * This should be set prior to creating any caching dictionaries to ensure all requests are logged. | ||
| * | ||
| * @param enabled - optional - if undefined, it will toggle the setting. | ||
| * @returns the current state of logging. | ||
| */ | ||
| export declare function dictionaryCacheEnableLogging(enabled?: boolean): boolean; | ||
| /** | ||
| * Get the log of dictionary requests. | ||
| * @returns the log | ||
| */ | ||
| export declare function dictionaryCacheGetLog(): readonly Readonly<LogEntryBase>[]; | ||
| /** | ||
| * Clear the log of dictionary requests. | ||
| */ | ||
| export declare function dictionaryCacheClearLog(): void; | ||
| export {}; | ||
| //# sourceMappingURL=CachingDictionary.d.ts.map |
@@ -22,4 +22,8 @@ import { autoCache, extractStats } from '../util/AutoCache.js'; | ||
| const time = performance.now() - startTime; | ||
| const misses = has.misses; | ||
| const value = has(word); | ||
| log.push({ time, method: 'has', word, value }); | ||
| if (logRequests) { | ||
| const miss = has.misses > misses; | ||
| log.push({ time, method: 'has', word, value, miss }); | ||
| } | ||
| return value; | ||
@@ -67,8 +71,30 @@ }; | ||
| } | ||
| export function enableLogging(enabled = !logRequests) { | ||
| /** | ||
| * Enable or disable logging of dictionary requests. Every call to `has` will be logged. | ||
| * | ||
| * This should be set prior to creating any caching dictionaries to ensure all requests are logged. | ||
| * | ||
| * @param enabled - optional - if undefined, it will toggle the setting. | ||
| * @returns the current state of logging. | ||
| */ | ||
| export function dictionaryCacheEnableLogging(enabled = !logRequests) { | ||
| if (enabled && !logRequests) { | ||
| knownDicts.clear(); | ||
| } | ||
| logRequests = enabled; | ||
| return logRequests; | ||
| } | ||
| export function getLog() { | ||
| /** | ||
| * Get the log of dictionary requests. | ||
| * @returns the log | ||
| */ | ||
| export function dictionaryCacheGetLog() { | ||
| return log; | ||
| } | ||
| /** | ||
| * Clear the log of dictionary requests. | ||
| */ | ||
| export function dictionaryCacheClearLog() { | ||
| log.length = 0; | ||
| } | ||
| //# sourceMappingURL=CachingDictionary.js.map |
@@ -11,3 +11,3 @@ import type { IterableLike } from '../util/IterableLike.js'; | ||
| */ | ||
| export declare function createSpellingDictionary(wordList: readonly string[] | IterableLike<string>, name: string, source: string, options?: SpellingDictionaryOptions | undefined): SpellingDictionary; | ||
| export declare function createSpellingDictionary(wordList: readonly string[] | IterableLike<string>, name: string, source: string, options?: SpellingDictionaryOptions | undefined, disableSuggestionsHandling?: boolean): SpellingDictionary; | ||
| export interface SpellingDictionaryLoadError extends Error { | ||
@@ -14,0 +14,0 @@ /** The Error Name */ |
| import { fileURLToPath } from 'node:url'; | ||
| import { buildITrieFromWords, parseDictionaryLines } from 'cspell-trie-lib'; | ||
| import { deepEqual } from 'fast-equals'; | ||
| import { measurePerf } from '../util/performance.js'; | ||
| import { AutoWeakCache, SimpleCache } from '../util/simpleCache.js'; | ||
@@ -19,4 +20,10 @@ import { defaultOptions } from './SpellingDictionary.js'; | ||
| */ | ||
| export function createSpellingDictionary(wordList, name, source, options) { | ||
| const params = [wordList, name, source.toString(), options]; | ||
| export function createSpellingDictionary(wordList, name, source, options, disableSuggestionsHandling) { | ||
| const params = [ | ||
| wordList, | ||
| name, | ||
| source.toString(), | ||
| options, | ||
| disableSuggestionsHandling, | ||
| ]; | ||
| if (!Array.isArray(wordList)) { | ||
@@ -38,5 +45,7 @@ return _createSpellingDictionary(params); | ||
| function _createSpellingDictionary(params) { | ||
| const [wordList, name, source, options] = params; | ||
| const n = ''; // ':' + params[1]; // Add name to perf name for easier debugging. | ||
| const endPerf = measurePerf('createSpellingDictionary' + n); | ||
| const [wordList, name, source, options, disableSuggestionHandling = false] = params; | ||
| // console.log(`createSpellingDictionary ${name} ${source}`); | ||
| const parseOptions = { stripCaseAndAccents: options?.supportNonStrictSearches ?? true }; | ||
| const parseOptions = { stripCaseAndAccents: options?.supportNonStrictSearches ?? true, disableSuggestionHandling }; | ||
| const words = parseDictionaryLines(wordList, parseOptions); | ||
@@ -48,3 +57,5 @@ const trie = buildITrieFromWords(words); | ||
| } | ||
| return new SpellingDictionaryFromTrie(trie, name, opts, source); | ||
| const d = new SpellingDictionaryFromTrie(trie, name, opts, source); | ||
| endPerf(); | ||
| return d; | ||
| } | ||
@@ -65,3 +76,3 @@ export function createFailedToLoadDictionary(name, sourceUrl, error, options) { | ||
| suggest: () => [], | ||
| mapWord: (a) => a, | ||
| mapWord: undefined, | ||
| genSuggestions: () => { | ||
@@ -68,0 +79,0 @@ return; |
@@ -1,2 +0,57 @@ | ||
| import type { SpellingDictionary } from './SpellingDictionary.js'; | ||
| import type { CompoundWordsMethod, ITrie, SuggestionResult } from 'cspell-trie-lib'; | ||
| import type { FindResult, HasOptions, IgnoreCaseOption, PreferredSuggestion, SpellingDictionary, SpellingDictionaryOptions } from './SpellingDictionary.js'; | ||
| import { SpellingDictionaryFromTrie } from './SpellingDictionaryFromTrie.js'; | ||
| import type { SuggestOptions } from './SuggestOptions.js'; | ||
| import type { TyposDictionary } from './TyposDictionary.js'; | ||
| export declare class FlagWordsDictionaryTrie extends SpellingDictionaryFromTrie { | ||
| readonly name: string; | ||
| readonly source: string; | ||
| readonly containsNoSuggestWords = false; | ||
| readonly options: SpellingDictionaryOptions; | ||
| constructor(trie: ITrie, name: string, source: string); | ||
| /** | ||
| * A Forbidden word list does not "have" valid words. | ||
| * Therefore it always returns false. | ||
| * @param _word - the word | ||
| * @param _options - options | ||
| * @returns always false | ||
| */ | ||
| has(_word: string, _options?: HasOptions): boolean; | ||
| find(word: string, hasOptions?: HasOptions): FindResult | undefined; | ||
| suggest(word: string, numSuggestions?: number, compoundMethod?: CompoundWordsMethod, numChanges?: number, ignoreCase?: boolean): SuggestionResult[]; | ||
| suggest(word: string, suggestOptions: SuggestOptions): SuggestionResult[]; | ||
| genSuggestions(): void; | ||
| readonly isDictionaryCaseSensitive: boolean; | ||
| terms(): Iterable<string>; | ||
| } | ||
| export declare class FlagWordsDictionary implements SpellingDictionary { | ||
| readonly name: string; | ||
| readonly source: string; | ||
| private dictTypos; | ||
| private dictTrie; | ||
| readonly containsNoSuggestWords = false; | ||
| readonly options: SpellingDictionaryOptions; | ||
| readonly type = "flag-words"; | ||
| readonly mapWord: undefined; | ||
| constructor(name: string, source: string, dictTypos: TyposDictionary, dictTrie: FlagWordsDictionaryTrie | undefined); | ||
| /** | ||
| * A Forbidden word list does not "have" valid words. | ||
| * Therefore it always returns false. | ||
| * @param word - the word | ||
| * @param options - options | ||
| * @returns always false | ||
| */ | ||
| has(word: string, options?: HasOptions): boolean; | ||
| /** A more detailed search for a word, might take longer than `has` */ | ||
| find(word: string, options?: HasOptions): FindResult | undefined; | ||
| isForbidden(word: string, ignoreCaseAndAccents?: IgnoreCaseOption): boolean; | ||
| isNoSuggestWord(word: string, options: HasOptions): boolean; | ||
| suggest(word: string, suggestOptions?: SuggestOptions): SuggestionResult[]; | ||
| getPreferredSuggestions(word: string): PreferredSuggestion[]; | ||
| genSuggestions(): void; | ||
| get size(): number; | ||
| readonly isDictionaryCaseSensitive: boolean; | ||
| getErrors?(): Error[]; | ||
| terms(): Iterable<string>; | ||
| } | ||
| /** | ||
@@ -3,0 +58,0 @@ * Create a dictionary where all words are to be forbidden. |
@@ -1,3 +0,2 @@ | ||
| import { opMap, pipe } from '@cspell/cspell-pipe/sync'; | ||
| import { buildITrieFromWords, parseDictionaryLines } from 'cspell-trie-lib'; | ||
| import { parseDictionary, parseDictionaryLines } from 'cspell-trie-lib'; | ||
| import { createAutoResolveWeakCache } from '../util/AutoResolve.js'; | ||
@@ -8,3 +7,3 @@ import * as Defaults from './defaults.js'; | ||
| import { createTyposDictionary } from './TyposDictionary.js'; | ||
| class FlagWordsDictionaryTrie extends SpellingDictionaryFromTrie { | ||
| export class FlagWordsDictionaryTrie extends SpellingDictionaryFromTrie { | ||
| name; | ||
@@ -42,4 +41,7 @@ source; | ||
| isDictionaryCaseSensitive = true; | ||
| terms() { | ||
| return this.trie.words(); | ||
| } | ||
| } | ||
| class FlagWordsDictionary { | ||
| export class FlagWordsDictionary { | ||
| name; | ||
@@ -52,2 +54,3 @@ source; | ||
| type = 'flag-words'; | ||
| mapWord = undefined; | ||
| constructor(name, source, dictTypos, dictTrie) { | ||
@@ -95,5 +98,2 @@ this.name = name; | ||
| } | ||
| mapWord(word) { | ||
| return word; | ||
| } | ||
| get size() { | ||
@@ -106,2 +106,9 @@ return this.dictTypos.size + (this.dictTrie?.size || 0); | ||
| } | ||
| *terms() { | ||
| if (this.dictTrie) { | ||
| yield* this.dictTrie.terms(); | ||
| return; | ||
| } | ||
| return; | ||
| } | ||
| } | ||
@@ -121,5 +128,6 @@ const createCache = createAutoResolveWeakCache(); | ||
| const { t: specialWords, f: typoWords } = bisect(parseDictionaryLines(wordList, { stripCaseAndAccents: false }), (line) => testSpecialCharacters.test(line)); | ||
| const trieDict = specialWords.size ? buildTrieDict(specialWords, name, source) : undefined; | ||
| const trie = parseDictionary(specialWords, { stripCaseAndAccents: false, makeWordsForbidden: true }); | ||
| const trieDict = new FlagWordsDictionaryTrie(trie, name, source); | ||
| const typosDict = createTyposDictionary(typoWords, name, source); | ||
| if (!trieDict) | ||
| if (!specialWords.size) | ||
| return typosDict; | ||
@@ -129,7 +137,2 @@ return new FlagWordsDictionary(name, source, typosDict, trieDict); | ||
| } | ||
| const regExpCleanIgnore = /^(!!)+/; | ||
| function buildTrieDict(words, name, source) { | ||
| const trie = buildITrieFromWords(pipe(words, opMap((w) => '!' + w), opMap((w) => w.replace(regExpCleanIgnore, '')))); | ||
| return new FlagWordsDictionaryTrie(trie, name, source); | ||
| } | ||
| function bisect(values, predicate) { | ||
@@ -136,0 +139,0 @@ const t = new Set(); |
@@ -15,2 +15,3 @@ import { opFilter, opMap, pipe } from '@cspell/cspell-pipe/sync'; | ||
| type = 'ignore'; | ||
| mapWord = undefined; | ||
| constructor(name, source, words) { | ||
@@ -66,5 +67,2 @@ this.name = name; | ||
| } | ||
| mapWord(word) { | ||
| return word; | ||
| } | ||
| get size() { | ||
@@ -71,0 +69,0 @@ return this.dict.size; |
@@ -6,3 +6,3 @@ export { CachingDictionary, createCachingDictionary } from './CachingDictionary.js'; | ||
| export { createIgnoreWordsDictionary } from './IgnoreWordsDictionary.js'; | ||
| export type { DictionaryDefinitionInline, FindOptions, FindResult, HasOptions, PreferredSuggestion, SearchOptions, SpellingDictionary, SpellingDictionaryOptions, } from './SpellingDictionary.js'; | ||
| export type { DictionaryDefinitionInline, FindOptions, FindResult, HasOptions, PreferredSuggestion, SearchOptions, SpellingDictionary, SpellingDictionaryOptions, Suggestion, } from './SpellingDictionary.js'; | ||
| export { createCollection, SpellingDictionaryCollection } from './SpellingDictionaryCollection.js'; | ||
@@ -9,0 +9,0 @@ export { createSpellingDictionaryFromTrieFile } from './SpellingDictionaryFromTrie.js'; |
@@ -18,3 +18,8 @@ import type { DictionaryInformation, ReplaceMap } from '@cspell/cspell-types'; | ||
| export type SearchOptionsRO = Readonly<SearchOptions>; | ||
| export type FindOptions = SearchOptions; | ||
| export interface FindOptions extends SearchOptions { | ||
| /** | ||
| * Separate compound words using the specified separator. | ||
| */ | ||
| compoundSeparator?: string | undefined; | ||
| } | ||
| export type FindOptionsRO = Readonly<FindOptions>; | ||
@@ -90,2 +95,4 @@ export interface Suggestion { | ||
| } | ||
| export type MapWordSingleFn = (word: string) => string; | ||
| export type MapWordMultipleFn = (word: string) => string[]; | ||
| export interface SpellingDictionary extends DictionaryInfo { | ||
@@ -96,3 +103,3 @@ readonly type: string; | ||
| /** A more detailed search for a word, might take longer than `has` */ | ||
| find(word: string, options?: SearchOptionsRO): FindResult | undefined; | ||
| find(word: string, options?: FindOptionsRO): FindResult | undefined; | ||
| /** | ||
@@ -119,3 +126,3 @@ * Checks if a word is forbidden. | ||
| genSuggestions(collector: SuggestionCollector, suggestOptions: SuggestOptionsRO): void; | ||
| mapWord(word: string): string; | ||
| mapWord?: MapWordSingleFn | undefined; | ||
| /** | ||
@@ -127,8 +134,23 @@ * Generates all possible word combinations by applying `repMap`. | ||
| */ | ||
| remapWord?: (word: string) => string[]; | ||
| remapWord?: MapWordMultipleFn | undefined; | ||
| readonly size: number; | ||
| readonly isDictionaryCaseSensitive: boolean; | ||
| getErrors?(): Error[]; | ||
| /** | ||
| * Get all the terms in the dictionary, they may be formatted according to the dictionary options. | ||
| * @returns the terms in the dictionary. | ||
| */ | ||
| terms?: () => Iterable<string>; | ||
| } | ||
| export interface SuggestDictionary extends SpellingDictionary { | ||
| getPreferredSuggestions: (word: string) => PreferredSuggestion[]; | ||
| /** | ||
| * Determine if the word can appear in a list of suggestions. | ||
| * @param word - word | ||
| * @param ignoreCaseAndAccents - ignore case. | ||
| * @returns true if a word is suggested, otherwise false. | ||
| */ | ||
| isSuggestedWord(word: string, ignoreCaseAndAccents?: IgnoreCaseOption): boolean; | ||
| } | ||
| export declare const defaultOptions: SpellingDictionaryOptions; | ||
| //# sourceMappingURL=SpellingDictionary.d.ts.map |
@@ -5,5 +5,2 @@ import { CASE_INSENSITIVE_PREFIX, CompoundWordsMethod } from 'cspell-trie-lib'; | ||
| import { defaultNumSuggestions, hasOptionToSearchOption, suggestionCollector } from './SpellingDictionaryMethods.js'; | ||
| function identityString(w) { | ||
| return w; | ||
| } | ||
| class SpellingDictionaryCollectionImpl { | ||
@@ -13,3 +10,3 @@ dictionaries; | ||
| options = { weightMap: undefined }; | ||
| mapWord = identityString; | ||
| mapWord = undefined; | ||
| type = 'SpellingDictionaryCollection'; | ||
@@ -16,0 +13,0 @@ source; |
@@ -1,4 +0,4 @@ | ||
| import type { Buffer } from 'node:buffer'; | ||
| import type { ITrie, SuggestionCollector, SuggestionResult } from 'cspell-trie-lib'; | ||
| import type { FindResult, HasOptionsRO, SpellingDictionary, SpellingDictionaryOptionsRO } from './SpellingDictionary.js'; | ||
| import type { RepMapper } from '../util/repMap.js'; | ||
| import type { FindOptionsRO, FindResult, HasOptionsRO, MapWordMultipleFn, MapWordSingleFn, PreferredSuggestion, SpellingDictionary, SpellingDictionaryOptionsRO } from './SpellingDictionary.js'; | ||
| import type { SuggestOptions } from './SuggestOptions.js'; | ||
@@ -14,4 +14,5 @@ export declare class SpellingDictionaryFromTrie implements SpellingDictionary { | ||
| readonly unknownWords: Set<string>; | ||
| readonly mapWord: (word: string) => string; | ||
| readonly remapWord: (word: string) => string[]; | ||
| readonly mapWord: MapWordSingleFn | undefined; | ||
| readonly remapWord: MapWordMultipleFn | undefined; | ||
| readonly repMapper: RepMapper | undefined; | ||
| readonly type = "SpellingDictionaryFromTrie"; | ||
@@ -24,3 +25,3 @@ readonly isDictionaryCaseSensitive: boolean; | ||
| has(word: string, hasOptions?: HasOptionsRO): boolean; | ||
| find(word: string, hasOptions?: HasOptionsRO): FindResult | undefined; | ||
| find(word: string, hasOptions?: FindOptionsRO): FindResult | undefined; | ||
| private resolveOptions; | ||
@@ -35,2 +36,3 @@ private _find; | ||
| genSuggestions(collector: SuggestionCollector, suggestOptions: SuggestOptions): void; | ||
| getPreferredSuggestions(word: string): PreferredSuggestion[]; | ||
| getErrors(): Error[]; | ||
@@ -46,4 +48,4 @@ } | ||
| */ | ||
| export declare function createSpellingDictionaryFromTrieFile(data: string | Buffer, name: string, source: string, options: SpellingDictionaryOptionsRO): SpellingDictionary; | ||
| declare function outerWordForms(word: string, mapWord: (word: string) => string[]): Iterable<string>; | ||
| export declare function createSpellingDictionaryFromTrieFile(data: string | Uint8Array<ArrayBuffer>, name: string, source: string, options: SpellingDictionaryOptionsRO): SpellingDictionary; | ||
| declare function outerWordForms(word: string, repMapper: RepMapper | undefined): Iterable<string>; | ||
| export declare const __testing__: { | ||
@@ -50,0 +52,0 @@ outerWordForms: typeof outerWordForms; |
| import { CompoundWordsMethod, decodeTrie, suggestionCollector } from 'cspell-trie-lib'; | ||
| import { clean } from '../util/clean.js'; | ||
| import { measurePerf } from '../util/performance.js'; | ||
| import { createMapper, createRepMapper } from '../util/repMap.js'; | ||
@@ -16,2 +17,3 @@ import * as Defaults from './defaults.js'; | ||
| remapWord; | ||
| repMapper; | ||
| type = 'SpellingDictionaryFromTrie'; | ||
@@ -29,5 +31,8 @@ isDictionaryCaseSensitive; | ||
| this.source = source; | ||
| this.mapWord = createMapper(options.repMap, options.dictionaryInformation?.ignore); | ||
| this.remapWord = createRepMapper(options.repMap, options.dictionaryInformation?.ignore); | ||
| this.isDictionaryCaseSensitive = options.caseSensitive ?? trie.isCaseAware; | ||
| const mapWord = createMapper(options.repMap, options.dictionaryInformation?.ignore); | ||
| const repMapper = createRepMapper(options.repMap, options.dictionaryInformation?.ignore); | ||
| this.mapWord = mapWord?.fn; | ||
| this.remapWord = repMapper?.fn; | ||
| this.repMapper = repMapper; | ||
| this.isDictionaryCaseSensitive = options.caseSensitive ?? true; | ||
| this.containsNoSuggestWords = options.noSuggest || false; | ||
@@ -60,3 +65,3 @@ this._size = size || 0; | ||
| const { useCompounds, ignoreCase } = this.resolveOptions(hasOptions); | ||
| const r = this._find(word, useCompounds, ignoreCase); | ||
| const r = this._find(word, useCompounds, ignoreCase, undefined); | ||
| return (r && !r.forbidden && !!r.found) || false; | ||
@@ -66,3 +71,3 @@ } | ||
| const { useCompounds, ignoreCase } = this.resolveOptions(hasOptions); | ||
| const r = this._find(word, useCompounds, ignoreCase); | ||
| const r = this._find(word, useCompounds, ignoreCase, hasOptions?.compoundSeparator); | ||
| const { forbidden = this.#isForbidden(word) } = r || {}; | ||
@@ -82,7 +87,7 @@ if (this.#ignoreForbiddenWords && forbidden) { | ||
| } | ||
| _find = (word, useCompounds, ignoreCase) => this.findAnyForm(word, useCompounds, ignoreCase); | ||
| findAnyForm(word, useCompounds, ignoreCase) { | ||
| const outerForms = outerWordForms(word, this.remapWord || ((word) => [this.mapWord(word)])); | ||
| _find = (word, useCompounds, ignoreCase, compoundSeparator) => this.findAnyForm(word, useCompounds, ignoreCase, compoundSeparator); | ||
| findAnyForm(word, useCompounds, ignoreCase, compoundSeparator) { | ||
| const outerForms = outerWordForms(word, this.repMapper); | ||
| for (const form of outerForms) { | ||
| const r = this._findAnyForm(form, useCompounds, ignoreCase); | ||
| const r = this._findAnyForm(form, useCompounds, ignoreCase, compoundSeparator); | ||
| if (r) | ||
@@ -93,6 +98,9 @@ return r; | ||
| } | ||
| _findAnyForm(mWord, useCompounds, ignoreCase) { | ||
| const opts = ignoreCase | ||
| _findAnyForm(mWord, useCompounds, ignoreCase, compoundSeparator) { | ||
| let opts = ignoreCase | ||
| ? this.#findWordOptionsNotCaseSensitive | ||
| : this.#findWordOptionsCaseSensitive; | ||
| if (compoundSeparator) { | ||
| opts = { ...opts, compoundSeparator }; | ||
| } | ||
| const findResult = this.trie.findWord(mWord, opts); | ||
@@ -158,2 +166,8 @@ if (findResult.found !== false) { | ||
| } | ||
| getPreferredSuggestions(word) { | ||
| if (!this.trie.hasPreferredSuggestions) | ||
| return []; | ||
| const sugs = [...this.trie.getPreferredSuggestions(word)]; | ||
| return sugs.map((sug, i) => ({ word: sug, cost: i + 1, isPreferred: true })); | ||
| } | ||
| getErrors() { | ||
@@ -172,6 +186,11 @@ return []; | ||
| export function createSpellingDictionaryFromTrieFile(data, name, source, options) { | ||
| const endPerf = measurePerf('createSpellingDictionaryFromTrieFile'); | ||
| const trie = decodeTrie(data); | ||
| return new SpellingDictionaryFromTrie(trie, name, options, source); | ||
| const d = new SpellingDictionaryFromTrie(trie, name, options, source); | ||
| endPerf(); | ||
| return d; | ||
| } | ||
| function* outerWordForms(word, mapWord) { | ||
| // eslint-disable-next-line no-control-regex | ||
| const isAsciiRange = /^[\u0000-\u007F]*$/; | ||
| function* outerWordForms(word, repMapper) { | ||
| // Only generate the needed forms. | ||
@@ -182,12 +201,31 @@ const sent = new Set(); | ||
| yield w; | ||
| sent.add(w); | ||
| w = word.normalize('NFC'); | ||
| if (w !== ww) { | ||
| yield w; | ||
| // this function is called for every word lookup, so needs to be efficient. | ||
| // Check to see if it is a pure ascii word. | ||
| if (!isAsciiRange.test(w)) { | ||
| sent.add(w); | ||
| w = word.normalize('NFC'); | ||
| if (w !== ww) { | ||
| yield w; | ||
| sent.add(w); | ||
| } | ||
| w = word.normalize('NFD'); | ||
| if (w !== ww && !sent.has(w)) { | ||
| yield w; | ||
| sent.add(w); | ||
| } | ||
| } | ||
| w = word.normalize('NFD'); | ||
| if (w !== ww && !sent.has(w)) { | ||
| yield w; | ||
| sent.add(w); | ||
| if (!repMapper) | ||
| return; | ||
| const mapWord = repMapper.fn; | ||
| // nothing was added to the set, just do the map. | ||
| if (!sent.size) { | ||
| if (!repMapper.test.test(ww)) | ||
| return; | ||
| for (const m of mapWord(ww)) { | ||
| if (m !== ww && !sent.has(m)) { | ||
| yield m; | ||
| sent.add(m); | ||
| } | ||
| } | ||
| return; | ||
| } | ||
@@ -194,0 +232,0 @@ for (const f of sent) { |
@@ -1,12 +0,6 @@ | ||
| import type { IgnoreCaseOption, PreferredSuggestion, SpellingDictionary } from './SpellingDictionary.js'; | ||
| import type { SuggestionResult } from 'cspell-trie-lib'; | ||
| import type { SuggestDictionary } from './SpellingDictionary.js'; | ||
| import { type TypoEntry, type TyposDef } from './Typos/index.js'; | ||
| export interface SuggestDictionary extends SpellingDictionary { | ||
| getPreferredSuggestions: (word: string) => PreferredSuggestion[]; | ||
| /** | ||
| * Determine if the word can appear in a list of suggestions. | ||
| * @param word - word | ||
| * @param ignoreCaseAndAccents - ignore case. | ||
| * @returns true if a word is suggested, otherwise false. | ||
| */ | ||
| isSuggestedWord(word: string, ignoreCaseAndAccents?: IgnoreCaseOption): boolean; | ||
| export interface PreferredSuggestionResult extends SuggestionResult { | ||
| isPreferred: true; | ||
| } | ||
@@ -13,0 +7,0 @@ /** |
@@ -15,2 +15,3 @@ import { pipe } from '@cspell/cspell-pipe/sync'; | ||
| size; | ||
| mapWord = undefined; | ||
| /** | ||
@@ -93,5 +94,2 @@ * Note: ignoreWordsLower is only suggestions with the case and accents removed. | ||
| } | ||
| mapWord(word) { | ||
| return word; | ||
| } | ||
| isDictionaryCaseSensitive = true; | ||
@@ -98,0 +96,0 @@ getErrors() { |
| import type { TypoEntry, TyposDef } from './typos.js'; | ||
| export declare function isSuggestion(v: string): boolean; | ||
| export declare function createTyposDefFromEntries(entries: Iterable<TypoEntry>): TyposDef; | ||
@@ -3,0 +4,0 @@ export declare function sanitizeIntoTypoDef(dirtyDef: TyposDef | Record<string, unknown> | unknown): TyposDef | undefined; |
@@ -1,3 +0,2 @@ | ||
| import assert from 'node:assert'; | ||
| import { appendToDef, createTyposDef } from './util.js'; | ||
| import { appendToDef, assert, createTyposDef } from './util.js'; | ||
| function assertString(v) { | ||
@@ -8,5 +7,9 @@ assert(typeof v === 'string', 'A string was expected.'); | ||
| const suggestionsSeparator = /[,]/; | ||
| const typoSuggestionsSeparator = /:|->/; | ||
| // const typoSuggestionsSeparator = /:|->/; | ||
| const typoEntrySeparator = /[\n;]/; | ||
| const inlineComment = /#.*/gm; | ||
| const sugFormatRegex = /^\s*(?:[!~:])*(?<word>.*?)(?<separator>(->|:([0-9a-f]{1,2}:)?))(?<sugs>.*)$/; | ||
| export function isSuggestion(v) { | ||
| return sugFormatRegex.test(v); | ||
| } | ||
| export function createTyposDefFromEntries(entries) { | ||
@@ -120,7 +123,29 @@ const def = Object.create(null); | ||
| } | ||
| /** | ||
| * Split text into multiple lines | ||
| * @param content - text content | ||
| * @returns | ||
| */ | ||
| function splitIntoLines(content) { | ||
| return trimAndFilter(normalize(content).split(typoEntrySeparator)); | ||
| } | ||
| /** | ||
| * Split a typo entry into key and value | ||
| * Entry format: | ||
| * - `word:suggestion` | ||
| * - `word->suggestion` | ||
| * - `word: first, second, third suggestions` | ||
| * - sequencing values are ignored, e.g.: `:0:`, `:1:`, `:a:` | ||
| * - `word:0:first` | ||
| * - `word:1:second` | ||
| * @param line - the line of text | ||
| * @returns | ||
| */ | ||
| function splitEntry(line) { | ||
| return line.split(typoSuggestionsSeparator, 2); | ||
| // Remove any sequencing values like `:1:` or `:a:` | ||
| const m = line.match(sugFormatRegex); | ||
| if (!m?.groups) { | ||
| return [line.trim(), undefined]; | ||
| } | ||
| return [m.groups.word.trim(), m.groups.sugs.trim()]; | ||
| } | ||
@@ -127,0 +152,0 @@ export function parseTyposFile(content) { |
@@ -31,2 +31,3 @@ import type { TypoEntry, TyposDef, TyposDefKey, TyposDefValue } from './typos.js'; | ||
| export declare function extractIgnoreValues(typosDef: TyposDef, ignorePrefix: string): Set<string>; | ||
| export declare function assert(condition: unknown, message?: string): asserts condition; | ||
| //# sourceMappingURL=util.d.ts.map |
@@ -106,2 +106,7 @@ import { opConcatMap, opFilter, pipe } from '@cspell/cspell-pipe/sync'; | ||
| } | ||
| export function assert(condition, message = 'Assert Failed') { | ||
| if (condition) | ||
| return; | ||
| throw new Error(message); | ||
| } | ||
| //# sourceMappingURL=util.js.map |
@@ -15,2 +15,3 @@ import { opAppend, pipe } from '@cspell/cspell-pipe/sync'; | ||
| size; | ||
| mapWord = undefined; | ||
| ignoreWords; | ||
@@ -126,5 +127,2 @@ /** | ||
| } | ||
| mapWord(word) { | ||
| return word; | ||
| } | ||
| isDictionaryCaseSensitive = true; | ||
@@ -131,0 +129,0 @@ getErrors() { |
| import type { CharacterSet, ReplaceMap } from '@cspell/cspell-types'; | ||
| export type ReplaceMapper = (src: string) => string; | ||
| export declare function createMapper(repMap: ReplaceMap | undefined, ignoreCharset?: string): ReplaceMapper; | ||
| export interface ReplaceMapper { | ||
| test?: RegExp; | ||
| fn: (src: string) => string; | ||
| } | ||
| export declare function createMapper(repMap: ReplaceMap | undefined, ignoreCharset?: string): ReplaceMapper | undefined; | ||
| declare function charsetToRepMapRegEx(charset: CharacterSet | undefined, replaceWith?: string): ReplaceMap | undefined; | ||
@@ -15,3 +18,7 @@ declare function createMapperRegExp(repMap: ReplaceMap): RegExp; | ||
| } | ||
| export declare function createRepMapper(repMap: ReplaceMap | undefined, ignoreCharset?: string): (word: string) => string[]; | ||
| export interface RepMapper { | ||
| test: RegExp; | ||
| fn: (word: string) => string[]; | ||
| } | ||
| export declare function createRepMapper(repMap: ReplaceMap | undefined, ignoreCharset?: string): RepMapper | undefined; | ||
| declare function applyEdits(word: string, edits: Edit[]): string[]; | ||
@@ -18,0 +25,0 @@ declare function calcAllEdits(root: RepTrieNode, word: string): Edit[]; |
+26
-8
@@ -6,3 +6,3 @@ import { expandCharacterSet } from 'cspell-trie-lib'; | ||
| if (!repMap && !ignoreCharset) | ||
| return (a) => a; | ||
| return undefined; | ||
| repMap = repMap || []; | ||
@@ -15,3 +15,3 @@ const charsetMap = charsetToRepMapRegEx(ignoreCharset); | ||
| if (!filteredMap.length) { | ||
| return (a) => a; | ||
| return undefined; | ||
| } | ||
@@ -24,4 +24,8 @@ const regEx = createMapperRegExp(repMap); | ||
| } | ||
| return function (s) { | ||
| function fn(s) { | ||
| return s.replace(regEx, resolve); | ||
| } | ||
| return { | ||
| test: regexpRemoveFlags(regEx, 'gm'), | ||
| fn, | ||
| }; | ||
@@ -74,9 +78,18 @@ } | ||
| export function createRepMapper(repMap, ignoreCharset) { | ||
| if (!repMap && !ignoreCharset) | ||
| return (word) => [word]; | ||
| if (!repMap?.length && !ignoreCharset) | ||
| return undefined; | ||
| let tRepMap = repMap || []; | ||
| const charsetMap = charsetToRepMapRegEx(ignoreCharset); | ||
| if (charsetMap) { | ||
| tRepMap = [...tRepMap, ...charsetMap]; | ||
| } | ||
| const regEx = createMapperRegExp(tRepMap); | ||
| const trie = createTrie(repMap, ignoreCharset); | ||
| // const root = createTrie(repMap, ignoreCharset); | ||
| return (word) => { | ||
| const edits = calcAllEdits(trie, word); | ||
| return applyEdits(word, edits); | ||
| return { | ||
| test: regexpRemoveFlags(regEx, 'gm'), | ||
| fn: (word) => { | ||
| const edits = calcAllEdits(trie, word); | ||
| return applyEdits(word, edits); | ||
| }, | ||
| }; | ||
@@ -150,2 +163,7 @@ } | ||
| } | ||
| function regexpRemoveFlags(re, flagsToRemove) { | ||
| const toRemove = new Set(flagsToRemove); | ||
| const flags = [...re.flags].filter((f) => !toRemove.has(f)).join(''); | ||
| return new RegExp(re.source, flags); | ||
| } | ||
| export const __testing__ = { | ||
@@ -152,0 +170,0 @@ charsetToRepMap: charsetToRepMapRegEx, |
+7
-6
@@ -7,3 +7,3 @@ { | ||
| }, | ||
| "version": "9.4.0", | ||
| "version": "9.6.0", | ||
| "description": "A spelling dictionary library useful for checking words and getting suggestions.", | ||
@@ -58,12 +58,13 @@ "type": "module", | ||
| "dependencies": { | ||
| "@cspell/cspell-pipe": "9.4.0", | ||
| "@cspell/cspell-types": "9.4.0", | ||
| "cspell-trie-lib": "9.4.0", | ||
| "fast-equals": "^5.3.3" | ||
| "@cspell/cspell-pipe": "9.6.0", | ||
| "@cspell/cspell-types": "9.6.0", | ||
| "cspell-trie-lib": "9.6.0", | ||
| "fast-equals": "^6.0.0" | ||
| }, | ||
| "devDependencies": { | ||
| "@cspell/dict-de-de": "^4.1.2", | ||
| "gensequence": "^8.0.8", | ||
| "lorem-ipsum": "^2.0.8" | ||
| }, | ||
| "gitHead": "12dba3d8b880384d1401c765cb2186647f5a266f" | ||
| "gitHead": "163793ddf2a0ad90bc7c90351698a106003297af" | ||
| } |
116879
8.24%75
2.74%3027
8.18%3
50%+ Added
+ Added
+ Added
+ Added
- Removed
- Removed
- Removed
- Removed
- Removed
Updated
Updated
Updated
Updated