UNPKG

@dcoffey/espells

Version:

Pure JS/TS spellchecker, using Hunspell dictionaries. Based on Spylls.

147 lines 5.62 kB
/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ import { iterate } from "iterare"; import { CapType, CONSTANTS as C } from "../constants.js"; import { any, includes } from "../util.js"; import { affixForms as affixes } from "./affixes.js"; import { compoundForms as compounds } from "./compounds.js"; import { breakWord } from "./decompose.js"; import { LKWord } from "./lk-word.js"; /** Class that facilitaties lookups for a spellchecker. */ export class Lookup { /** * @param aff - The affix data to use. * @param dic - The dictionary data to use. */ constructor(aff, dic) { this.aff = aff; this.dic = dic; } /** * Checks if a word is spelled correctly. * * @param word - The word to check. * @param caps - If true, checking will be case sensitive. Defaults to true. * @param allowNoSuggest - If false, words which are in the dictionary, * but are flagged with the `NOSUGGEST` flag (if provided), will not be * considered correct. Defaults to true. */ check(word, caps = true, allowNoSuggest = true) { let forbidden = this.isForbidden(word); let warn = this.isWarn(word); if (forbidden) return { correct: false, forbidden, warn }; if (this.aff.ICONV) word = this.aff.ICONV.match(word); word = this.aff.ignore(word); if (C.NUMBER_REGEX.test(word)) return { correct: true, forbidden, warn }; for (const words of breakWord(this.aff, word)) { if (words.every(word => this.correct(word, { caps, allowNoSuggest }))) { return { correct: true, forbidden, warn }; } } return { correct: false, forbidden, warn }; } /** * Yields *correct* combinations of stems and affixes for a word, * specifically instances of {@link AffixForm} or {@link CompoundForm}. If * this function does actually yield a form, that means that it can be * considered as spelled correctly. * * @param word - The word to yield the forms of. * @see {@link LKC} */ *forms(word, { caps = true, allowNoSuggest = true, affixForms = true, compoundForms = true } = {}) { let captype, variants; if (caps) { ; [captype, ...variants] = this.aff.casing.variants(word); } else { captype = this.aff.casing.guess(word); variants = [word]; } const lkword = new LKWord(this.aff, this.dic, word, captype); for (const variant of variants) { const word = lkword.to(variant); if (affixForms) { for (const form of affixes(word, allowNoSuggest)) { if (form.inDictionary && captype === CapType.ALL && includes(this.aff.KEEPCASE, form.flags) && this.aff.isSharps(form.inDictionary.stem) && this.aff.isSharps(lkword.word)) { continue; } yield form; } } if (compoundForms) yield* compounds(word, allowNoSuggest); } } // -- UTILITY /** * Checks if a word is spelled correctly. Performs no processing on the * word, such as handling `aff.IGNORE` characters. * * @param word - The word to check. * @see {@link LKC} */ correct(word, { caps, allowNoSuggest, affixForms, compoundForms } = {}) { return any(this.forms(word, { caps, allowNoSuggest, affixForms, compoundForms })); } /** * Yields the stems of a word. If no stems are returned, the word was incorrect. * * @param word - The word to yield the stems of. * @see {@link LKC} */ *stems(word, { caps, allowNoSuggest, affixForms, compoundForms } = {}) { if (this.aff.ICONV) word = this.aff.ICONV.match(word); word = this.aff.ignore(word); const iter = this.forms(word, { caps, allowNoSuggest, affixForms, compoundForms }); for (const form of iter) { if (Array.isArray(form)) yield* iterate(form).map(form => form.stem); else yield form.stem; } } /** * Yields a list of a data maps associated with the homonyms of the given stem. * * @param stem - The stem to get the data of. * @param caps - If true, checking will be case sensitive. Defaults to true. */ *data(stem, caps = true) { for (const homonym of this.dic.homonyms(stem, !caps)) { if (!homonym.data) continue; yield homonym.data; } } /** * Determines if a stem is marked with the `WARN` flag. * * @param stem - The stem to check. */ isWarn(stem) { return this.dic.hasFlag(stem, this.aff.WARN, true); } /** * Determines if a stem is marked as forbidden, either through the * `FORBIDDENWORD` flag *or* the the combination of the stem having the * `WARN` flag and the `FORBIDWARN` directive being true. * * @param stem - The word to check. */ isForbidden(stem) { return (this.dic.hasFlag(stem, this.aff.FORBIDDENWORD, true) || (this.aff.FORBIDWARN && this.dic.hasFlag(stem, this.aff.WARN, true))); } } //# sourceMappingURL=index.js.map