UNPKG

yoastseo

Version:

Yoast client-side content analysis

135 lines (128 loc) 5.53 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = stem; /* * Copyright (c) 2001, Dr Martin Porter * Copyright (c) 2002, Richard Boulton. * All rights reserved. * * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that * the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and * the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and * the following disclaimer in the documentation and/or other materials provided with the distribution. * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse * or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * Determines the start index of the R1 region. * R1 is the region after the first non-vowel following a vowel. It should include at least 3 letters. * * @param {string} word The word for which to determine the R1 region. * * @returns {number} The start index of the R1 region. */ const determineR1 = function (word) { // Start with matching first vowel and non-vowel. let r1Index = word.search(/[aeiouyøåæ][^aeiouyøåæ]/); // Then add 2 since the R1 index is the index after the first vowel & non-vowel matched with the regex. if (r1Index !== -1) { r1Index += 2; } // Adjust R1 so that the region preceding it includes at least 3 letters. if (r1Index !== -1 && r1Index < 3) { r1Index = 3; } return r1Index; }; /** * Searches and stems these suffixes if in R1: hetene, hetens, hetens, heten, heter, endes, ande, ende, edes, enes, ede, * ane, ene, ens, ers, ets, het, ast, en, ar, er, as, es, et, a, e. After stemming the suffix, it checks if the word * ends in -ert, if it is stem -t. * Searches and stems suffix -s if in R1 and if preceded by a valid precedence: b, c, d, f, g, h, j, l, m, n, o, p, r, t, v, y, z, * or k not preceded by a vowel. * * @param {string} word The word to check. * @param {number} r1Index The start index of the R1. * @param {Object} morphologyData The morphology data file. * * @returns {string} The stemmed word. */ const removeSuffixesStep1 = function (word, r1Index, morphologyData) { const suffixes1aIndex = word.search(new RegExp(morphologyData.externalStemmer.regexSuffixes1a)); if (suffixes1aIndex >= r1Index && r1Index !== -1) { let wordAfterStemming = word.substring(0, suffixes1aIndex); if (/ert$/i.test(wordAfterStemming)) { wordAfterStemming = wordAfterStemming.slice(0, -1); } return wordAfterStemming; } const suffixSIndex = word.search(/s$/); const suffixes1bIndex = word.search(new RegExp(morphologyData.externalStemmer.regexSuffixes1b)); if (suffixSIndex >= r1Index && suffixes1bIndex !== -1 && r1Index !== -1) { return word.slice(0, -1); } return word; }; /** * Searches for suffixes -ert/-dt/-vt and stems -t if the suffix is in R1. * * @param {string} word The word to check. * @param {number} r1Index The start index of the R1. * @param {Object} morphologyData The morphology data file. * * @returns {string} The stemmed word. */ const removeSuffixesStep2 = function (word, r1Index, morphologyData) { const suffixes2Index = word.search(new RegExp(morphologyData.externalStemmer.regexSuffixes2)); if (suffixes2Index >= r1Index && r1Index !== -1) { word = word.slice(0, -1); } return word; }; /** * Searches and stems these suffixes if in R1: hetslov, eleg, elig, elov, slov, leg, eig, lig, els, lov, ig. * * @param {string} word The word to check. * @param {number} r1Index The start index of the R1. * @param {Object} morphologyData The morphology data file. * * @returns {string} The stemmed word. */ const removeSuffixesStep3 = function (word, r1Index, morphologyData) { const suffixes3Index = word.search(new RegExp(morphologyData.externalStemmer.regexSuffixes3)); if (suffixes3Index >= r1Index && r1Index !== -1) { word = word.substring(0, suffixes3Index); } return word; }; /** * Stems Norwegian words. * * @param {string} word The word to check. * @param {Object} morphologyData The morphology data file. * * @returns {string} The stemmed word. */ function stem(word, morphologyData) { let r1Index = -1; for (const step of [removeSuffixesStep1, removeSuffixesStep2, removeSuffixesStep3]) { r1Index = determineR1(word); word = step(word, r1Index, morphologyData); } return word; } //# sourceMappingURL=stem.js.map