Skip to content

Instantly share code, notes, and snippets.

@andreidmt
Created March 22, 2021 14:26
Show Gist options
  • Select an option

  • Save andreidmt/2481723ca58c081ca7d02ee8446720d9 to your computer and use it in GitHub Desktop.

Select an option

Save andreidmt/2481723ca58c081ca7d02ee8446720d9 to your computer and use it in GitHub Desktop.
Functional'ish autocorrect using http://spellchecker.glitch.me
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