Created
March 22, 2021 14:26
-
-
Save andreidmt/2481723ca58c081ca7d02ee8446720d9 to your computer and use it in GitHub Desktop.
Functional'ish autocorrect using http://spellchecker.glitch.me
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| const axios = require("axios") | |
| const { map, pipe, pipeP, reduce, sortWith, read } = require("@asd14/m") // replace with ramda or underscore | |
| const CORRECTIONS_URL = "https://spellchecker.glitch.me/corrections" | |
| const CHECKSPELLING_URL = "https://spellchecker.glitch.me/checkspelling" | |
| /** | |
| * Given a string, return a list of misspelled words and their positions | |
| * | |
| * @param {string} source | |
| * | |
| * @returns {Promise<{wrong: string, start: number, end: number}>} | |
| * | |
| * @example | |
| * await detectMisspelledWords("helllo world!") | |
| * // => [{ | |
| * // wrong: "helllo", | |
| * // start: 0, | |
| * // end: 6 | |
| * // }] | |
| */ | |
| const detectMisspelledWords = async source => { | |
| const wrongWords = await axios.post(CHECKSPELLING_URL, { corpus: source }) | |
| return pipe( | |
| read(["data", "misspellings"], []), | |
| map(({ start, end }) => ({ | |
| wrong: source.slice(start, end), | |
| start, | |
| end, | |
| })) | |
| )(wrongWords) | |
| } | |
| /** | |
| * Given a word, return the first most likely correction | |
| * | |
| * @param {string} source | |
| * | |
| * @returns {Promise<string>} | |
| * | |
| * @example | |
| * await findCorrection("helllo") | |
| * // => "hello" | |
| */ | |
| const findCorrection = source => | |
| axios | |
| .get(`${CORRECTIONS_URL}?word=${source}`) | |
| .then(read(["data", "corrections", 0])) | |
| /** | |
| * Given a list of misspelled words, find the first suggested correction | |
| * | |
| * @param {{wrong: string, start: number, end: number}[]} source | |
| * | |
| * @returns {Promise<{wrong: string, correct: string, start: number, end: number}>} | |
| * | |
| * @example | |
| * await updateWithCorrectWords([{wrong: "helllo", start: 0, end: 6}]) | |
| * // => [{ | |
| * // wrong: "helllo", | |
| * // correct: "hello", | |
| * // start: 0, | |
| * // end: 6 | |
| * // }] | |
| */ | |
| const updateWithCorrectWords = source => | |
| pipeP( | |
| map(async ({ wrong, ...rest }) => { | |
| const correct = await findCorrection(wrong) | |
| return { wrong, correct, ...rest } | |
| }), | |
| queries => Promise.all(queries) | |
| )(source) | |
| /** | |
| * Given a string, find and replace all misspelled words | |
| * | |
| * @param {string} source | |
| * | |
| * @returns {Promise<string>} | |
| * | |
| * @example | |
| * await fixAllWords("helllo worldi!") | |
| * // => "hello world!" | |
| */ | |
| const fixAllWords = source => | |
| pipeP( | |
| detectMisspelledWords, | |
| updateWithCorrectWords, | |
| sortWith("start"), | |
| reduce( | |
| ({ result, offset }, { correct, start, end }) => { | |
| const wrong = result.slice(start + offset, end + offset) | |
| return { | |
| result: result.replace(wrong, correct), | |
| offset: offset + correct.length - wrong.length, | |
| } | |
| }, | |
| { | |
| result: source, | |
| offset: 0, | |
| } | |
| ), | |
| read("result") | |
| )(source) | |
| // | |
| const corpus = "helllo asd worldi!" | |
| fixAllWords(corpus).then(result => { | |
| console.log({ | |
| input: corpus, | |
| output: result, | |
| }) | |
| // => { | |
| // input: 'helllo asd worldi!', | |
| // output: 'hello acid world!' | |
| // } | |
| }) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment