UNPKG

yoastseo

Version:

Yoast client-side content analysis

131 lines (121 loc) 5.99 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = wordComplexity; var _lodash = require("lodash"); var _getSentences = _interopRequireDefault(require("../helpers/sentence/getSentences")); var _getWords = _interopRequireDefault(require("../helpers/word/getWords")); var _htmlParser = _interopRequireDefault(require("../helpers/html/htmlParser")); var _helpers = require("../helpers"); var _findKeywordFormsInString = require("../helpers/match/findKeywordFormsInString"); function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; } /** * An object containing the results of the complex words research for a single sentence. * * The structure of the data is: * @example * { * complexWords: ["word1", "word2", "word3" ], * sentence: "the sentence" * } * * @typedef {Object} ComplexWordsResult * @property {string[]} complexWords The complex words in the sentence. * @property {string} sentence The sentence. */ /** * Retrieves all complex words in a sentence. * * @param {string} currentSentence The current sentence. * @param {Researcher} researcher The researcher object. * @param {Object} topicForms The object with word forms of all (content) words from the keyphrase and eventually synonyms, * comes in a shape { * keyphraseForms: [[ form1, form2, ... ], [ form1, form2, ... ]], * synonymsForms: [ * [[ form1, form2, ... ], [ form1, form2, ... ]], * [[ form1, form2, ... ], [ form1, form2, ... ]], * [[ form1, form2, ... ], [ form1, form2, ... ]], * ], * } * * @returns {ComplexWordsResult} An object containing all complex words in a given sentence. */ const getComplexWords = function (currentSentence, researcher, topicForms) { const language = researcher.getConfig("language"); const checkIfWordIsComplex = researcher.getHelper("checkIfWordIsComplex"); const functionWords = researcher.getConfig("functionWords"); const wordComplexityConfig = researcher.getConfig("wordComplexity"); const checkIfWordIsFunction = researcher.getHelper("checkIfWordIsFunction"); const premiumData = (0, _lodash.get)(researcher.getData("morphology"), language, false); // Retrieve all words from the sentence. let words = (0, _getWords.default)(currentSentence); // Filters out keyphrase forms (but not synonyms) because we consider them not to be complex. const matchWordCustomHelper = researcher.getHelper("matchWordCustomHelper"); const foundTopicForms = (0, _findKeywordFormsInString.findTopicFormsInString)(topicForms, currentSentence, false, researcher.paper.getLocale(), matchWordCustomHelper); words = words.filter(word => !foundTopicForms.matches.includes(word)); // Filters out function words because function words are not complex. // Words are converted to lowercase before processing to avoid excluding function words that start with a capital letter. words = words.filter(word => !(checkIfWordIsFunction ? checkIfWordIsFunction(word) : functionWords.includes(word))); const result = { complexWords: [], sentence: currentSentence }; if (!premiumData) { return result; } words.forEach(word => { if (checkIfWordIsComplex(wordComplexityConfig, word, premiumData)) { result.complexWords.push(word); } }); return result; }; /** * Calculates the percentage of the complex words compared to the total words in the text. * * @param {ComplexWordsResult[]} complexWordsResults The array of complex words results. * @param {string[]} words The array of words retrieved from the text. * * @returns {number} The percentage of the complex words compared to the total words in the text. */ const calculateComplexWordsPercentage = function (complexWordsResults, words) { if (words.length === 0) { return 0; } const totalComplexWords = (0, _lodash.flatMap)(complexWordsResults, result => result.complexWords); const percentage = totalComplexWords.length / words.length * 100; // If the number is a decimal, round it to two numbers after the period, e.g. 5.12345 -> 5.12. // This approach is inspired from this thread: https://stackoverflow.com/questions/11832914/how-to-round-to-at-most-2-decimal-places-if-necessary. return +percentage.toFixed(2); }; /** * Gets the complex words from the sentences and calculates the percentage of complex words compared to the total words in the text. * This is a research for the Word Complexity assessment. As such, this research is not part of the AbstractResearcher, and not bundled in Yoast SEO. * * @param {Paper} paper The Paper object to get the text from. * @param {Researcher} researcher The researcher object. * * @returns {{complexWords: ComplexWordsResult[], percentage: number}} * The complex words found and their percentage compared to the total words in the text. */ function wordComplexity(paper, researcher) { const memoizedTokenizer = researcher.getHelper("memoizedTokenizer"); let text = paper.getText(); text = (0, _htmlParser.default)(text); text = (0, _helpers.filterShortcodesFromHTML)(text, paper._attributes && paper._attributes.shortcodes); const sentences = (0, _getSentences.default)(text, memoizedTokenizer); const topicForms = researcher.getResearch("morphology"); // Find the complex words in each sentence. let results = sentences.map(sentence => getComplexWords(sentence, researcher, topicForms)); // Remove sentences without complex words. results = results.filter(result => result.complexWords.length !== 0); // Calculate the percentage of complex words in the text as a whole. const words = (0, _getWords.default)(text); const percentage = calculateComplexWordsPercentage(results, words); return { complexWords: results, percentage: percentage }; } //# sourceMappingURL=wordComplexity.js.map