UNPKG

yoastseo

Version:

Yoast client-side content analysis

160 lines (149 loc) 6.93 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; exports.determineIrregularStem = determineIrregularStem; exports.determineIrregularVerbStem = determineIrregularVerbStem; exports.determineRegularStem = determineRegularStem; exports.determineStem = determineStem; exports.findShortestAndAlphabeticallyFirst = findShortestAndAlphabeticallyFirst; var _lodash = require("lodash"); var _yoastseo = require("yoastseo"); var _getAdjectiveStem = _interopRequireDefault(require("./getAdjectiveStem")); var _getVerbStem = require("./getVerbStem.js"); function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; } const { buildFormRule, createRulesFromArrays } = _yoastseo.languageProcessing; /** * Gets the shortest of the alphabetically ordered strings from an array. * * @param {string[]} array The array of strings. * * @returns {string|undefined} The shortest of the alphabetically ordered strings from the input array; * undefined if the input array is empty. */ function findShortestAndAlphabeticallyFirst(array) { const strings = (0, _lodash.flatten)(array); let result = strings.pop(); strings.forEach(str => { const lengthDifference = str.length - result.length; if (lengthDifference === 0) { if (str.localeCompare(result) < 0) { result = str; } } else if (lengthDifference < 0) { result = str; } }); return result; } /** * Checks if the input word occurs in the list of exceptions and if so returns the first form of the paradigm, which is * always the base. * * @param {string} word The word for which to determine its base. * @param {string[]} irregulars An array of irregular nouns and adjectives. * * @returns {string|null} The base form of the irregular word; null if no irregular stem was found. */ function determineIrregularStem(word, irregulars) { for (const paradigm of irregulars) { if (paradigm.includes(word)) { return paradigm[0]; } } return null; } /** * Checks if the input word occurs in the list of exception verbs and if so returns the first form * of the paradigm, which is always the base. Contrary to nouns and adjectives, irregular verbs can have different prefixes * which are not included in the list of exceptions and have to be processed separately. * * @param {string} word The word for which to determine its base. * @param {Object} verbMorphology Regexes and irregulars for verb morphology, False if verb rules should not be applied. * * @returns {string|null} The base form of the irregular word; null if no irregular stem was found. */ function determineIrregularVerbStem(word, verbMorphology) { const paradigmIfIrregularVerb = (0, _getVerbStem.checkIrregulars)(word, verbMorphology.irregularVerbs, verbMorphology.regexVerb.verbPrefixes); if (!(0, _lodash.isUndefined)(paradigmIfIrregularVerb)) { return paradigmIfIrregularVerb[0]; } return null; } /** * Gets possible stems as a regular noun, adjective and verb. * * @param {string} word The word for which to determine its base. * @param {Object} morphologyData The morphology data for the language. * * @returns {string} The shortest and the alphabetically-first of possible noun-like, verb-like and adjective-like bases. */ function determineRegularStem(word, morphologyData) { // Try to singularize as a noun. const regexVerb = morphologyData.verbs.regexVerb; const baseIfPluralNoun = buildFormRule(word, createRulesFromArrays(morphologyData.nouns.regexNoun.singularize)); if (!(0, _lodash.isUndefined)(baseIfPluralNoun)) { // Bring ing-nouns to base forms ("blessings" -> "bless"). if ((0, _getVerbStem.endsWithIng)(baseIfPluralNoun)) { return buildFormRule(baseIfPluralNoun, createRulesFromArrays(regexVerb.ingFormToInfinitive)); } return baseIfPluralNoun; } // Check if the word ends with "ic", "ical" or "ically". Return the "ical" form for consistency. const regexAdjective = morphologyData.adjectives.regexAdjective; const baseIfIcally = buildFormRule(word, createRulesFromArrays(regexAdjective.icallyToBase)); if (!(0, _lodash.isUndefined)(baseIfIcally)) { return baseIfIcally; } // No more quick guesses, we have to determine a verbal infinitive and an adjectival base. const possibleRegularBases = []; // Verbal infinitive. const baseIfVerb = (0, _getVerbStem.getInfinitive)(word, regexVerb).infinitive; possibleRegularBases.push(baseIfVerb); // Adjectival base. const stopAdjectives = morphologyData.adjectives.stopAdjectives; /* The following list of words are the stem of adjectives that have two syllables or more that receive -er and -est in their comparative and superlative forms, e.g 'shallow'. Please note that if the adjective ends in -y and -e, the ending is removed, e.g. 'acute' -> 'acut'. The list is not exhaustive and can be expanded if needed. Oxford dictionary was used to check if the forms indeed exist, e.g. "acuter". */ const multiSyllableAdjWithSuffixes = morphologyData.adjectives.multiSyllableAdjectives ? morphologyData.adjectives.multiSyllableAdjectives.list : []; const baseIfAdjective = (0, _getAdjectiveStem.default)(word, regexAdjective, stopAdjectives, multiSyllableAdjWithSuffixes).base; possibleRegularBases.push(baseIfAdjective); return findShortestAndAlphabeticallyFirst(possibleRegularBases); } /** * Returns the stem of the input word using the morphologyData (language-specific). * * @param {string} word The word to get the stem for. * @param {Object} morphologyData The available morphology data per language (false if unavailable). * * @returns {string} Stemmed (or base) form of the word. */ function determineStem(word, morphologyData) { const nounMorphology = morphologyData.nouns; const baseIfPossessive = buildFormRule(word, createRulesFromArrays(nounMorphology.regexNoun.possessiveToBase)); let stem, irregular; // Determine if this is an irregular noun, adjective or verb. if ((0, _lodash.isUndefined)(baseIfPossessive)) { stem = word; // Word can be a noun, adjective or verb. irregular = determineIrregularStem(word, nounMorphology.irregularNouns) || determineIrregularStem(word, morphologyData.adjectives.irregularAdjectives) || determineIrregularVerbStem(word, morphologyData.verbs); } else { stem = baseIfPossessive; // The word is a possessive, it can only be a noun or an ing-noun; irregular = determineIrregularStem(baseIfPossessive, nounMorphology.irregularNouns); } if (irregular) { // Found the stem of an irregular word! Return it. return irregular; } // Treat the word as a regular noun, adjective or verb. return determineRegularStem(stem, morphologyData); } var _default = exports.default = determineStem; //# sourceMappingURL=determineStem.js.map