UNPKG

yoastseo

Version:

Yoast client-side content analysis

162 lines (154 loc) 7.64 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.tokenizeKeyphraseFormsForExactMatching = exports.default = void 0; var _matchTextWithTransliteration = _interopRequireDefault(require("./matchTextWithTransliteration")); var _splitIntoTokens = _interopRequireDefault(require("../word/splitIntoTokens")); function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; } /** * Tokenizes the word form of the keyphrase for exact matching. This function gets the word form and tokenizes it. * This function assumes that if a keyphrase needs to be matched exactly, there will be only one word form. * This is the result of how the focus keyphrase is processed in buildTopicStems.js in the buildStems function. * * @param {(string[])} wordForms The word forms to tokenize. * @param {function} customSplitIntoTokensHelper A custom helper to split sentences into tokens. * * @returns {string[]} The tokenized word forms. */ const tokenizeKeyphraseFormsForExactMatching = (wordForms, customSplitIntoTokensHelper) => { // Tokenize word form of the keyphrase. const wordFormText = wordForms[0]; return customSplitIntoTokensHelper ? customSplitIntoTokensHelper(wordFormText) : (0, _splitIntoTokens.default)(wordFormText); }; /** * Gets the exact matches of the keyphrase. * Exact matching happens when the user puts the keyphrase in double quotes. * * @param {Sentence} sentence The sentence to match the word forms with. * @param {string[]} wordForms The word forms to match. * @param {string} locale The locale used in the analysis. * @param {function} customSplitIntoTokensHelper A custom helper to split sentences into tokens. * * @returns {{count: number, matches: Token[]}} Object containing the number of the exact matches and the matched tokens. */ exports.tokenizeKeyphraseFormsForExactMatching = tokenizeKeyphraseFormsForExactMatching; const findExactMatchKeyphraseInSentence = (sentence, wordForms, locale, customSplitIntoTokensHelper) => { const result = { count: 0, matches: [] }; // Tokenize word forms of the keyphrase. const keyphraseTokens = tokenizeKeyphraseFormsForExactMatching(wordForms, customSplitIntoTokensHelper); const sentenceTokens = sentence.tokens; // Initialize the index of the word token of the keyphrase. let indexOfWordInKeyphrase = 0; // Initialize the index of the word token of the sentence. let indexOfWordInSentence = 0; let currentMatch = []; // Check if the tokenized word forms occur in the same order in the sentence tokens. while (indexOfWordInSentence < sentenceTokens.length) { // If the current sentence token matches the current word token of the keyphrase, add it to the current match. const sentenceTokenText = sentenceTokens[indexOfWordInSentence].text; const keyphraseTokenText = keyphraseTokens[indexOfWordInKeyphrase]; const foundMatches = (0, _matchTextWithTransliteration.default)(sentenceTokenText.toLowerCase(), keyphraseTokenText.toLowerCase(), locale); if (foundMatches.length > 0) { currentMatch.push(sentenceTokens[indexOfWordInSentence]); indexOfWordInKeyphrase++; } else { indexOfWordInKeyphrase = 0; currentMatch = []; } /* * If the current match has the same length as the keyphrase tokens, the keyphrase forms have been matched. * Add the current match to the matches array and reset the index of the word in keyphrase and the current match. */ if (currentMatch.length === keyphraseTokens.length) { result.matches.push(...currentMatch); result.count++; indexOfWordInKeyphrase = 0; currentMatch = []; } indexOfWordInSentence++; } return result; }; /** * Matches a word form of the keyphrase with the tokens from the sentence. * * With this approach, we transliterate the word form of the keyphrase before matching it with the sentence tokens. * However, we don't do the transliteration step for the sentence tokens. * As a result, for example, the word form "acción" from the keyphrase will match the word "accion" in the sentence. * But, the word form "accion" from the keyphrase will NOT match the word "acción" in the sentence. * * @param {Token[]} tokens The array of tokens to check. * @param {string} wordForm The word form of the keyphrase. * @param {string} locale The locale used in the analysis. * * @returns {Token[]} The array of the matched tokens. */ const matchWordFormInTokens = (tokens, wordForm, locale) => { let matches = []; tokens.forEach(token => { const occurrence = (0, _matchTextWithTransliteration.default)(token.text, wordForm, locale); if (occurrence.length > 0) { matches = matches.concat(token); } }); return matches; }; /** * Finds keyphrase forms in a sentence. * * @param {Sentence|string} sentence The sentence to check. * @param {string[]} wordForms The word forms of the keyphrase to check. * @param {string} locale The locale used in the analysis. * @param {function} matchWordCustomHelper Custom function to match a word form with sentence. * * @returns {{count: number, matches: (Token|string)[]}} Object containing the number of the matches and the matched tokens. */ const matchWordFormsInSentence = (sentence, wordForms, locale, matchWordCustomHelper) => { const result = { count: 0, matches: [] }; wordForms.forEach(wordForm => { let occurrences = []; if (matchWordCustomHelper) { occurrences = matchWordCustomHelper(sentence, wordForm); } else { const tokens = sentence.tokens.slice(); occurrences = matchWordFormInTokens(tokens, wordForm, locale); } result.count += occurrences.length; result.matches = result.matches.concat(occurrences); }); return result; }; /** * Matches the word forms of a keyphrase with a sentence object from the html parser. * * @param {Sentence|string} sentence The sentence to match against the word forms of a keyphrase. * @param {string[]} wordForms The array of word forms of the keyphrase. * E.g. If the keyphrase is "key word", then (if Premium is activated) this will be [ "key", "keys" ] OR [ "word", "words" ] * The forms are retrieved higher up (among others in keywordCount.js) with researcher.getResearch( "morphology" ). * @param {string} locale The locale used for transliteration. * @param {function} matchWordCustomHelper Custom function to match a word form with sentence. * @param {boolean} useExactMatching Whether to match the keyphrase forms exactly or not. * Exact match is used when the keyphrase is enclosed in double quotes. * @param {function} customSplitIntoTokensHelper A custom helper to split sentences into tokens. * * @returns {{count: number, matches: (Token|string)[]}} Object containing the number of the matches and the matched tokens. */ const matchWordFormsWithSentence = (sentence, wordForms, locale, matchWordCustomHelper, useExactMatching = false, customSplitIntoTokensHelper) => { /* * Only use `findExactMatchKeyphraseInSentence` when the custom helper is not available. * When the custom helper is available, the step for the exact matching happens in the helper. */ if (useExactMatching && !matchWordCustomHelper) { return findExactMatchKeyphraseInSentence(sentence, wordForms, locale, customSplitIntoTokensHelper); } return matchWordFormsInSentence(sentence, wordForms, locale, matchWordCustomHelper); }; var _default = exports.default = matchWordFormsWithSentence; //# sourceMappingURL=matchWordFormsWithSentence.js.map