UNPKG

yoastseo

Version:

Yoast client-side content analysis

194 lines (183 loc) 8.3 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.arraysDifference = arraysDifference; exports.arraysOverlap = arraysOverlap; exports.combinations = combinations; exports.getIndicesOfCharacter = getIndicesOfCharacter; exports.getIndicesOfWords = getIndicesOfWords; exports.replaceTurkishIs = replaceTurkishIs; exports.replaceTurkishIsMemoized = void 0; var _lodash = require("lodash"); var _getWords = _interopRequireDefault(require("../word/getWords")); function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; } /** * Gets positions of the first character of a word in the input text. * * @param {string} text The original text, for which the indices of word beginnings need to be determined. * * @returns {Array} indices The array of indices in the text at which words start. */ function getIndicesOfWords(text) { const indices = []; const words = (0, _getWords.default)(text); let startSearchFrom = 0; words.forEach(function (word) { const currentIndex = text.indexOf(word, startSearchFrom); indices.push(currentIndex); startSearchFrom = currentIndex + word.length; }); return indices; } /** * Gets indices of a specific character in the input text. * * @param {string} text The original text, for which the indices of specific characters have to be determined. * @param {string} characterToFind The character that needs to be found in the text. * * @returns {Array} indices The array of indices in the text at which the characterToFind occurs. */ function getIndicesOfCharacter(text, characterToFind) { const indices = []; if (text.indexOf(characterToFind) > -1) { for (let i = 0; i < text.length; i++) { if (text[i] === characterToFind) { indices.push(i); } } } return indices; } /** * Compares two arrays of which the second array is the sub-array of the first array. * Returns the array of elements of the first array which are not in the second array. * * @param {Array} bigArray The array with all elements. * @param {Array} subarray The array with some elements from the bigArray. * * @returns {Array} difference An array of all elements of bigArray which are not in subarray. */ function arraysDifference(bigArray, subarray) { return (0, _lodash.filter)(bigArray, function (element) { return !(0, _lodash.includes)(subarray, element); }); } /** * Compares two arrays and returns the array of elements that occur in both arrays. * * @param {Array} firstArray The first array with elements to compare. * @param {Array} secondArray The second array with elements to compare. * * @returns {Array} overlap An array of all elements of firstArray which are also in secondArray. */ function arraysOverlap(firstArray, secondArray) { return (0, _lodash.filter)(firstArray, function (element) { return (0, _lodash.includes)(secondArray, element); }); } /** * Generates all possible combinations of the elements of an array (treated as unique). * https://gist.github.com/jpillora/4435759 * * @param {Array} collection The array with elements that should be combined. * * @returns {Array} result An array of all possible combinations of elements of the original array. */ function combinations(collection) { /** * A recursive function that iterates through all elements of an array to produce its combinations. * * @param {Array} xs The array to start accumulating with. * @param {Array} array The array with elements that should be combined. * * @returns {Array} result An array of all possible combinations of elements of the original array. */ function acc(xs, array) { const x = xs[0]; if (typeof x === "undefined") { return array; } for (let i = 0, l = array.length; i < l; ++i) { array.push(array[i].concat(x)); } return acc(xs.slice(1), array); } return acc(collection, [[]]).slice(1).concat([[]]); } /** * Replaces characters on specified indices in the input text. * * @param {string} text The original text, for which the characters have to be substituted. * @param {Array} indices The array of indices that have to be substituted. * @param {string} substitute The character that is used to substitute in the text. * * @returns {string} result The string of the original text with the characters on specified indices are substituted with the substitute character. */ function replaceCharactersByIndex(text, indices, substitute) { const modifiedTextSplitByLetter = text.split(""); indices.forEach(function (index) { modifiedTextSplitByLetter.splice(index, 1, substitute); }); return modifiedTextSplitByLetter.join(""); } /** * Generates upper and lower case for Turkish strings that contain characters İ or ı, which appear to not be processed correctly by regexes. * * @param {string} text The text to build possible upper and lower case alternatives. * * @returns {Array} An array of strings that contains all possible upper and lower case alternatives of the original string */ function replaceTurkishIs(text) { // Get indices of all occurrences of İ, I, i, or ı. const indicesOfAllIs = getIndicesOfCharacter(text, "İ").concat(getIndicesOfCharacter(text, "I"), getIndicesOfCharacter(text, "i"), getIndicesOfCharacter(text, "ı")); indicesOfAllIs.sort(); // If there are no Is return the text if (indicesOfAllIs.length === 0) { return [text]; } const indicesOfIsInWordBeginnings = arraysOverlap(getIndicesOfWords(text), indicesOfAllIs); const results = []; // First round of creating combinations: assign which indices will be replaced by İ const combinationsDottedI = combinations(indicesOfIsInWordBeginnings); combinationsDottedI.forEach(function (oneCombinationDottedI) { // If the combination is full array, just add it to results immediately without going through the rest of iterations. if ((0, _lodash.isEqual)(oneCombinationDottedI, indicesOfIsInWordBeginnings)) { results.push([oneCombinationDottedI, [], [], []]); } else { const indicesNotDottedI = arraysDifference(indicesOfIsInWordBeginnings, oneCombinationDottedI); // Second round of creating combinations: assign which indices will be replaced by I const combinationsDotlessI = combinations(indicesNotDottedI); combinationsDotlessI.forEach(function (oneCombinationDotlessI) { // If the combination is full array, just add it to results immediately without going through the rest of iterations. if ((0, _lodash.isEqual)(oneCombinationDotlessI, indicesNotDottedI)) { results.push([oneCombinationDottedI, oneCombinationDotlessI, [], []]); } else { const indicesSmalli = arraysDifference(indicesNotDottedI, oneCombinationDotlessI); // Third round of creating combinations: assign which indices will be replaced by i const combinationsDottedi = combinations(indicesSmalli); combinationsDottedi.forEach(function (oneCombinationDottedi) { // If the combination is full array, just add it to results immediately without going through the rest of iterations. if ((0, _lodash.isEqual)(oneCombinationDottedi, indicesSmalli)) { results.push([oneCombinationDottedI, oneCombinationDotlessI, oneCombinationDottedi, []]); } else { const oneCombinationDotlessi = arraysDifference(indicesSmalli, oneCombinationDottedi); results.push([oneCombinationDottedI, oneCombinationDotlessI, oneCombinationDottedi, oneCombinationDotlessi]); } }); } }); } }); const textAlternations = []; results.forEach(function (result) { const toDottedI = replaceCharactersByIndex(text, result[0], "İ"); const toDotlessI = replaceCharactersByIndex(toDottedI, result[1], "I"); const toDottedi = replaceCharactersByIndex(toDotlessI, result[2], "i"); const toDotlessi = replaceCharactersByIndex(toDottedi, result[3], "ı"); textAlternations.push(toDotlessi); }); return textAlternations; } const replaceTurkishIsMemoized = exports.replaceTurkishIsMemoized = (0, _lodash.memoize)(replaceTurkishIs); //# sourceMappingURL=specialCharacterMappings.js.map