esthesaurus
Version:
Tesauro de castellano
144 lines (124 loc) • 3.71 kB
JavaScript
const fs = require('fs');
/**
* @module Thesaurus loads partialThesaurus based on the given word.
* Exposes some methods, basically includes.
*/
/** @todo Class */
let Thesaurus = { words: {} };
/**
* Normalizes the word and gets the possible words to check. If the partials dicts haven't been
* loaded, loads it into Thesaurus.
* @param {String} word
* @returns Normalized word and beggining.
*/
function _initWord (word) {
return word.normalize('NFD').replace(/[\u0300-\u036f]/g, "").toLowerCase().trim();
}
/** Loads the file with the given word beggining */
function _getPartialDict (word) {
let beggining = word.length > 1
? word.slice(0,2)
: word.slice(0,1);
const path = `./words/${beggining}.js`;
if (!Thesaurus.words[beggining]) {
try {
Thesaurus.words[beggining] = require(path);
} catch (err) {
return false;
}
}
return Thesaurus.words[beggining];
}
/**
* Checks if a word is included in the Thesaurus.
*/
Thesaurus.includes = (w) => {
let word = _initWord(w);
let toCheck = _getWordsToCheck(word);
if (!toCheck.length) {
throw "Unexpected error. Not word to check";
}
return Boolean(toCheck.some(w => {
let partial = _getPartialDict(w);
return partial && partial.includes(w);
}));
}
/**
* Chechs if the word is plural, femenin or has a prefix.
* @param {string} word
* @returns array of words to check
*/
function _getWordsToCheck (word) {
let toCheck = [..._removePrefix(word), word];
toCheck.unshift(..._getSingulars(toCheck));
/** May induce false positives */
toCheck.unshift(..._getMasculin(toCheck));
return toCheck;
}
/**
* Gets an array with all the prefixes.
* @param update Boolean; reads all files in Thesaurus and updates the prefixes file.
* This is so not to be checjing all words every time this function is called.
*/
Thesaurus.getPrefixes = (update = false) => {
let prefixesPath = './src/prefixes.js';
if (update) {
let all = Thesaurus.all();
Thesaurus.prefixes = all.filter(el => /.*[-]$/.test(el)).map(el => el.slice(0, -1));
let data = 'module.exports = ' + JSON.stringify(Thesaurus.prefixes);
fs.writeFileSync(prefixesPath, data);
} else if (!Thesaurus.prefixes) {
Thesaurus.prefixes = require('./prefixes.js');
}
return Thesaurus.prefixes;
}
/** Loads all the data in the Thesaurus */
Thesaurus.loadAll = () => {
fs.readdirSync('src/words').forEach(f => _getPartialDict(f.replace('.js', '')));
}
/** Returns all the words in the Thesaurs as a single array */
Thesaurus.all = () => {
Thesaurus.loadAll();
let all = [];
Object.values(Thesaurus.words).forEach(w => all.push(...w));
return all;
}
function _removePrefix(w) {
let result = [];
let reg = (p) => `^${p}(.*)`;
Thesaurus.getPrefixes().forEach(prefix => {
let match = w.match(reg(prefix));
// console.log('testing', prefix, 'against', w)
match && result.push(match[1]);
});
return result;
}
/**
* If the word it's a plural, checks its singular form.
* @param {string} word
* @param {object} partialDict
* @example 'bueyes' -> first checks buey;
* if not included checks bueye
* and if not included then bueyes
*/
function _getSingulars (words){
let sing = [];
words.forEach(word => {
let letters = word.split('');
letters.pop() === 's' && sing.unshift(letters.join(''));
letters.pop() === 'e' && sing.unshift(letters.join(''));
});
return sing;
}
function _getMasculin(words) {
let ret = [];
words.forEach(word => {
let letters = word.split('');
if (letters.pop() === 'a') {
letters.push('o');
ret.push( letters.join(''))
}
});
return ret;
}
module.exports = Thesaurus;