@cspell/cspell-tools
Version:
Tools to assist with the development of cSpell
108 lines • 3.86 kB
JavaScript
import { parseDictionary } from 'cspell-trie-lib';
import { createReader } from './Reader.js';
import { defaultAllowedSplitWords, defaultExcludeWordsCollection } from './WordsCollection.js';
class AllowedSplitWordsImpl {
collection;
size;
constructor(collection) {
this.collection = collection;
this.size = collection.size;
}
has(word, caseSensitive) {
return !this.size || this.collection.has(word, caseSensitive);
}
}
export async function createAllowedSplitWordsFromFiles(files) {
if (!files || !files.length)
return defaultAllowedSplitWords;
const collection = await createWordsCollectionFromFiles(files);
return new AllowedSplitWordsImpl(collection);
}
export function createAllowedSplitWords(words) {
if (!words)
return defaultAllowedSplitWords;
return new AllowedSplitWordsImpl(createWordsCollection(words));
}
function buildHasFn(dict) {
function has(word, caseSensitive) {
const r = dict.hasWord(word, true);
if (r || caseSensitive)
return r;
const lc = word.toLowerCase();
if (lc == word)
return false;
return dict.hasWord(lc, true);
}
return has;
}
async function readFile(filename) {
return await createReader(filename, {});
}
function readersToCollection(readers) {
const dictReaders = readers.filter(isDictionaryReader).map(dictReaderToCollection);
const nonDictCollection = lineReadersToCollection(readers.filter((a) => !isDictionaryReader(a)));
const collections = [...dictReaders, nonDictCollection];
const collection = {
size: collections.reduce((s, a) => s + a.size, 0),
has: (word, caseSensitive) => collections.some((a) => a.has(word, caseSensitive)),
};
return collection;
}
const cache = new WeakMap();
export async function createWordsCollectionFromFiles(files) {
files = Array.isArray(files) ? files : [files];
const cached = cache.get(files);
if (cached)
return cached;
const sources = await Promise.all(files.map((file) => readFile(file)));
const collection = readersToCollection(sources);
cache.set(files, collection);
return collection;
}
export function createWordsCollection(words) {
if (words instanceof Set)
return words;
const arrWords = (Array.isArray(words) ? words : [...words])
.map((a) => a.trim())
.filter((a) => !!a)
.filter((a) => !a.startsWith('#'));
const setOfWords = new Set(arrWords);
const has = buildHasFn({ hasWord: (word) => setOfWords.has(word) });
return { size: setOfWords.size, has };
}
class ExcludeWordsCollectionImpl {
collection;
size;
constructor(collection) {
this.collection = collection;
this.size = collection.size;
}
has(word, caseSensitive) {
return this.collection.has(word, caseSensitive);
}
}
export async function createExcludeWordsCollectionFromFiles(files) {
if (!files || !files.length)
return defaultExcludeWordsCollection;
const collection = await createWordsCollectionFromFiles(files);
return new ExcludeWordsCollectionImpl(collection);
}
export function createExcludeWordsCollection(words) {
return new ExcludeWordsCollectionImpl(words ? createWordsCollection(words) : new Set());
}
function isDictionaryReader(reader) {
return 'hasWord' in reader && !!reader.hasWord;
}
function dictReaderToCollection(reader) {
return { size: reader.size, has: buildHasFn(reader) };
}
function lineReadersToCollection(readers) {
function* words() {
for (const reader of readers) {
yield* reader.lines;
}
}
const dict = parseDictionary(words(), { stripCaseAndAccents: false });
return { size: dict.size, has: buildHasFn(dict) };
}
//# sourceMappingURL=createWordsCollection.js.map