UNPKG

talisman

Version:

Straightforward fuzzy matching, information retrieval and NLP building blocks for JavaScript.

312 lines (260 loc) 8.94 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: false }); exports.minimal = minimal; exports.complex = complex; /** * Talisman stemmers/french/unine * =============================== * * The UniNE (University of Neuchâtel) stemmers for the French language. * * [Reference]: * http://members.unine.ch/jacques.savoy/clef/ * * [Articles]: * Savoy, J. (1993). Stemming of French words based on grammatical category. * Journal of the American Society for Information Science, 44(1), 1-9. * * Savoy, J. (1999). A stemming procedure and stopword list for general French * corpora. Journal of the American Society for Information Science, 50(10), * 944-952. * * [Note]: * It should be possible to fix some bug relevant to SOLR's implementation. */ /** * Function replacing the character at the given index in the target string. * * @param {string} string - The target string. * @param {number} index - Index of the character to substitute. * @param {string} char - The replacing character. * @return {string} - The resulting string. */ function replaceAt(string, index, char) { return string.substr(0, index) + char + string.substr(index + char.length); } /** * Function deleting the character at the given index in the target string. * * @param {string} string - The target string. * @param {number} index - Index of the character to substitute. * @return {string} - The resulting string. */ function deleteAt(string, index) { return string.substr(0, index) + string.substr(index + 1); } /** * Function checking whether the string has the given suffix. * * @param {string} string - The target string. * @param {number} length - Length offset. * @param {string} suffix - The considered suffix. * @return {boolean} */ function endsWith(string, length, suffix) { if (suffix.length > length) return false; return string.slice(0, length).slice(-suffix.length) === suffix; } /** * Function stemming the given world using the minimal UniNE algorithm for the * French language. * * @param {string} word - The word to stem. * @return {string} - The resulting stem. */ function minimal(word) { if (word.length < 6) return word; var length = word.length; if (word[length - 1] === 'x') { if (word[length - 3] === 'a' && word[length - 2] === 'u') return word.slice(0, -2) + 'l'; return word.slice(0, -1); } if (word[length - 1] === 's') length--; if (word[length - 1] === 'r') length--; if (word[length - 1] === 'e') length--; if (word[length - 1] === 'é') length--; if (word[length - 1] === word[length - 2]) length--; return word.slice(0, length); } exports.default = minimal; /** * Function stemming the given world using the complex UniNE algorithm for the * French language. * * @param {string} word - The word to stem. * @return {string} - The resulting stem. */ function normalize(stem, length) { if (length > 4) { for (var i = 0; i < length; i++) { switch (stem[i]) { case 'à': case 'á': case 'â': stem = replaceAt(stem, i, 'a'); break; case 'ô': stem = replaceAt(stem, i, 'o'); break; case 'è': case 'é': case 'ê': stem = replaceAt(stem, i, 'e'); break; case 'ù': case 'û': stem = replaceAt(stem, i, 'u'); break; case 'î': stem = replaceAt(stem, i, 'i'); break; case 'ç': stem = replaceAt(stem, i, 'c'); break; default: } } var character = stem[0]; for (var _i = 1; _i < length; _i++) { if (stem[_i] === character && /[^\W\d]/.test(character)) { stem = deleteAt(stem, _i--); length--; } else { character = stem[_i]; } } } if (length > 4 && endsWith(stem, length, 'ie')) length -= 2; if (length > 4) { if (stem[length - 1] === 'r') length--; if (stem[length - 1] === 'e') length--; if (stem[length - 1] === 'e') length--; if (stem[length - 1] === stem[length - 2] && /[^\W\d]/.test(stem[length - 1])) length--; } return stem.slice(0, length); } function complex(word) { var length = word.length, stem = word; if (length > 5 && stem[length - 1] === 'x') { if (stem[length - 3] === 'a' && stem[length - 2] === 'u' && stem[length - 4] !== 'e') { stem = replaceAt(stem, length - 2, 'l'); } length--; } if (length > 3 && stem[length - 1] === 'x') length--; if (length > 3 && stem[length - 1] === 's') length--; if (length > 9 && endsWith(stem, length, 'issement')) { length -= 6; stem = replaceAt(stem, length - 1, 'r'); return normalize(stem, length); } if (length > 8 && endsWith(stem, length, 'issant')) { length -= 4; stem = replaceAt(stem, length - 1, 'r'); return normalize(stem, length); } if (length > 6 && endsWith(stem, length, 'ement')) { length -= 4; if (length > 3 && endsWith(stem, length, 'ive')) { length--; stem = replaceAt(stem, length - 1, 'f'); } return normalize(stem, length); } if (length > 11 && endsWith(stem, length, 'ficatrice')) { length -= 5; stem = replaceAt(stem, length - 2, 'e'); stem = replaceAt(stem, length - 1, 'r'); return normalize(stem, length); } if (length > 10 && endsWith(stem, length, 'ficateur')) { length -= 4; stem = replaceAt(stem, length - 2, 'e'); stem = replaceAt(stem, length - 1, 'r'); return normalize(stem, length); } if (length > 9 && endsWith(stem, length, 'catrice')) { length -= 3; stem = replaceAt(stem, length - 4, 'q'); stem = replaceAt(stem, length - 3, 'u'); stem = replaceAt(stem, length - 2, 'e'); return normalize(stem, length); } if (length > 8 && endsWith(stem, length, 'cateur')) { length -= 2; stem = replaceAt(stem, length - 4, 'q'); stem = replaceAt(stem, length - 3, 'u'); stem = replaceAt(stem, length - 2, 'e'); stem = replaceAt(stem, length - 1, 'r'); return normalize(stem, length); } if (length > 8 && endsWith(stem, length, 'atrice')) { length -= 4; stem = replaceAt(stem, length - 2, 'e'); stem = replaceAt(stem, length - 1, 'r'); return normalize(stem, length); } if (length > 7 && endsWith(stem, length, 'ateur')) { length -= 3; stem = replaceAt(stem, length - 2, 'e'); stem = replaceAt(stem, length - 1, 'r'); return normalize(stem, length); } if (length > 6 && endsWith(stem, length, 'trice')) { length--; stem = replaceAt(stem, length - 3, 'e'); stem = replaceAt(stem, length - 2, 'u'); stem = replaceAt(stem, length - 1, 'r'); } if (length > 5 && endsWith(stem, length, 'ième')) return normalize(stem, length - 4); if (length > 7 && endsWith(stem, length, 'teuse')) { length -= 2; stem = replaceAt(stem, length - 1, 'r'); return normalize(stem, length); } if (length > 6 && endsWith(stem, length, 'teur')) { length--; stem = replaceAt(stem, length - 1, 'r'); return normalize(stem, length); } if (length > 5 && endsWith(stem, length, 'euse')) return normalize(stem, length - 2); if (length > 8 && endsWith(stem, length, 'ère')) { length--; stem = replaceAt(stem, length - 2, 'e'); return normalize(stem, length); } if (length > 7 && endsWith(stem, length, 'ive')) { length--; stem = replaceAt(stem, length - 1, 'f'); return normalize(stem, length); } if (length > 4 && (endsWith(stem, length, 'folle') || endsWith(stem, length, 'molle'))) { length -= 2; stem = replaceAt(stem, length - 1, 'u'); return normalize(stem, length); } if (length > 9 && endsWith(stem, length, 'nnelle')) return normalize(stem, length - 5); if (length > 9 && endsWith(stem, length, 'nnel')) return normalize(stem, length - 3); if (length > 4 && endsWith(stem, length, 'ète')) { length--; stem = replaceAt(stem, length - 2, 'e'); } if (length > 8 && endsWith(stem, length, 'ique')) length -= 4; if (length > 8 && endsWith(stem, length, 'esse')) return normalize(stem, length - 3); if (length > 7 && endsWith(stem, length, 'inage')) return normalize(stem, length - 3); if (length > 9 && endsWith(stem, length, 'isation')) { length -= 7; if (length > 5 && endsWith(stem, length, 'ual')) stem = replaceAt(stem, length - 2, 'e'); return normalize(stem, length); } if (length > 9 && endsWith(stem, length, 'isateur')) return normalize(stem, length - 7); if (length > 8 && endsWith(stem, length, 'ation')) return normalize(stem, length - 5); if (length > 8 && endsWith(stem, length, 'ition')) return normalize(stem, length - 5); return normalize(stem, length); } module.exports = exports['default']; exports['default'].minimal = exports.minimal; exports['default'].complex = exports.complex;