diff --git a/lib/index.js b/lib/index.js index e6e255e..31f13f5 100644 --- a/lib/index.js +++ b/lib/index.js @@ -5,7 +5,14 @@ */ /** - * @callback Dictionary + * @typedef Dictionary + * A hunspell dictionary. + * @property {Uint8Array} aff + * Data for the affix file (defines the language, keyboard, flags, and more). + * @property {Uint8Array} dic + * Data for the dictionary file (contains words and flags applying to those words). + * + * @callback DictionaryCallback * Dictionary function. * @param {DictionaryOnLoad} onload * Callback called when the dictionary is loaded. @@ -18,7 +25,7 @@ * Callback called when the dictionary is loaded. * @param {Error | undefined} error * Error. - * @param {unknown} [result] + * @param {Dictionary} [result] * Dictionary. * @returns {undefined | void} * Nothing. @@ -27,8 +34,8 @@ * * @typedef Options * Configuration. - * @property {Dictionary} dictionary - * Dictionary function (required); + * @property {Dictionary | DictionaryCallback} dictionary + * Dictionary (required); * result of importing one of the dictionaries in `wooorm/dictionaries`. * @property {ReadonlyArray | null | undefined} [ignore] * List of words to ignore (optional). @@ -80,15 +87,17 @@ const emptyIgnore = [] /** * Check spelling. * - * @param {Readonly | Dictionary} options + * @param {Readonly | DictionaryCallback | Dictionary} options * Configuration or dictionary (required). * @returns * Transform. */ export default function retextSpell(options) { const settings = - typeof options === 'function' ? {dictionary: options} : options || {} - const dictionary = settings.dictionary + typeof options === 'function' || + (options && 'aff' in options && 'dic' in options) + ? {dictionary: options} + : options || {} const ignore = settings.ignore || emptyIgnore const ignoreLiteral = typeof settings.ignoreLiteral === 'boolean' ? settings.ignoreLiteral : true @@ -102,7 +111,7 @@ export default function retextSpell(options) { : true const personal = settings.personal - if (typeof dictionary !== 'function') { + if (!settings.dictionary) { throw new TypeError('Missing `dictionary` in options') } @@ -125,7 +134,11 @@ export default function retextSpell(options) { // Callback called when a `dictionary` is loaded or when `load`ing failed. // Flushes the queue when available, and sets the results on the parent scope. - dictionary(onload) + if (typeof settings.dictionary === 'function') { + settings.dictionary(onload) + } else { + onload(undefined, settings.dictionary) + } /** * Transform. diff --git a/package.json b/package.json index efcf912..5cff3f3 100644 --- a/package.json +++ b/package.json @@ -50,6 +50,7 @@ "@types/node": "^20.0.0", "c8": "^8.0.0", "dictionary-en": "^3.0.0", + "dictionary-en-v4": "npm:dictionary-en@^4.0.0", "prettier": "^3.0.0", "remark-cli": "^11.0.0", "remark-preset-wooorm": "^9.0.0", diff --git a/test.js b/test.js index fd62104..28f2bb0 100644 --- a/test.js +++ b/test.js @@ -1,6 +1,7 @@ import assert from 'node:assert/strict' import test from 'node:test' import dictionaryEn from 'dictionary-en' +import dictionaryEnV4 from 'dictionary-en-v4' import {retext} from 'retext' import retextEmoji from 'retext-emoji' import retextSpell from 'retext-spell' @@ -78,6 +79,16 @@ test('retextSpell', async function (t) { ]) }) + await t.test('should work with newer dictionary versions', async function () { + const file = await retext() + .use(retextSpell, dictionaryEnV4) + .process('kolor') + + assert.deepEqual(file.messages.map(String), [ + '1:1-1:6: Unexpected unknown word `kolor`, expected for example `color`, `dolor`' + ]) + }) + await t.test('should work w/ repeated misspellings', async function () { const file = await retext() .use(retextSpell, dictionaryEn)