yoastseo
Version:
Yoast client-side content analysis
220 lines (208 loc) • 9.77 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = _default;
var _indices = require("../../word/indices");
var _stripSpaces = _interopRequireDefault(require("../../sanitize/stripSpaces.js"));
var _quotes = require("../../sanitize/quotes.js");
var _getIndicesWithRegex = _interopRequireDefault(require("./getIndicesWithRegex.js"));
var _includesIndex = _interopRequireDefault(require("../../word/includesIndex"));
var _followsIndex = _interopRequireDefault(require("../../word/followsIndex"));
var _lodash = require("lodash");
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
/**
* Gets stop characters to determine sentence breakers.
*
* @param {string} sentence The sentence to get the stop characters from.
* @param {RegExp} stopCharacterRegex Regex to match the stop characters.
*
* @returns {Array} The array with stop characters.
*/
const getStopCharacters = function (sentence, stopCharacterRegex) {
let match;
const matches = [];
stopCharacterRegex.lastIndex = 0;
while ((match = stopCharacterRegex.exec(sentence)) !== null) {
matches.push({
index: match.index,
match: match[0]
});
}
return matches;
};
/**
* Filters auxiliaries preceded by a reflexive pronoun.
*
* @param {string} text The text part in which to check.
* @param {Array} auxiliaryMatches The auxiliary matches for which to check.
* @param {RegExp} directPrecedenceExceptionRegex The regex needed to find the right auxiliaries.
*
* @returns {Array} The filtered list of auxiliary indices.
*/
const auxiliaryPrecedenceExceptionFilter = function (text, auxiliaryMatches, directPrecedenceExceptionRegex) {
const directPrecedenceExceptionMatches = (0, _getIndicesWithRegex.default)(text, directPrecedenceExceptionRegex);
(0, _lodash.forEach)(auxiliaryMatches, function (auxiliaryMatch) {
if ((0, _includesIndex.default)(directPrecedenceExceptionMatches, auxiliaryMatch.index)) {
auxiliaryMatches = auxiliaryMatches.filter(function (auxiliaryObject) {
return auxiliaryObject.index !== auxiliaryMatch.index;
});
}
});
return auxiliaryMatches;
};
/**
* Filters auxiliaries followed by a word on the followingAuxiliaryExceptionWords list.
*
* @param {string} text The text part in which to check.
* @param {Array} auxiliaryMatches The auxiliary matches for which to check.
* @param {RegExp} followingAuxiliaryExceptionRegex The regex needed to find the right auxiliaries.
*
* @returns {Array} The filtered list of auxiliary indices.
*/
const followingAuxiliaryExceptionFilter = function (text, auxiliaryMatches, followingAuxiliaryExceptionRegex) {
const followingAuxiliaryExceptionMatches = (0, _getIndicesWithRegex.default)(text, followingAuxiliaryExceptionRegex);
(0, _lodash.forEach)(auxiliaryMatches, function (auxiliaryMatch) {
if ((0, _followsIndex.default)(followingAuxiliaryExceptionMatches, auxiliaryMatch)) {
auxiliaryMatches = auxiliaryMatches.filter(function (auxiliaryObject) {
return auxiliaryObject.index !== auxiliaryMatch.index;
});
}
});
return auxiliaryMatches;
};
/**
* Filters auxiliaries preceded by an elided word (e.g., s') on the elisionAuxiliaryExceptionWords list.
*
* @param {string} text The text part in which to check.
* @param {Array} auxiliaryMatches The auxiliary matches for which to check.
* @param {RegExp} elisionAuxiliaryExceptionRegex Regex to match the elisionAuxiliary exception.
*
* @returns {Array} The filtered list of auxiliary indices.
*/
const elisionAuxiliaryExceptionFilter = function (text, auxiliaryMatches, elisionAuxiliaryExceptionRegex) {
const elisionAuxiliaryExceptionMatches = (0, _getIndicesWithRegex.default)(text, elisionAuxiliaryExceptionRegex);
(0, _lodash.forEach)(auxiliaryMatches, function (auxiliaryMatch) {
if ((0, _includesIndex.default)(elisionAuxiliaryExceptionMatches, auxiliaryMatch.index, false)) {
auxiliaryMatches = auxiliaryMatches.filter(function (auxiliaryObject) {
return auxiliaryObject.index !== auxiliaryMatch.index;
});
}
});
return auxiliaryMatches;
};
/**
* Gets the indices of sentence breakers (auxiliaries, stopwords and stop characters;
* in English also active verbs) to determine clauses.
* Indices are filtered because there could be duplicate matches, like "even though" and "though".
* In addition, 'having' will be matched both as a -ing verb as well as an auxiliary.
*
* @param {string} sentence The sentence to check for indices of sentence breakers.
* @param {Object} options The language options for which to match the sentence breakers.
*
* @returns {Array} The array with valid indices to use for determining clauses.
*/
const getSentenceBreakers = function (sentence, options) {
sentence = sentence.toLocaleLowerCase();
const {
regexes
} = options;
let auxiliaryIndices = (0, _indices.getIndicesByWordList)(options.auxiliaries, sentence);
const stopCharacterIndices = getStopCharacters(sentence, regexes.stopCharacterRegex);
let stopwordIndices = (0, _indices.getIndicesByWordList)(options.stopwords, sentence);
// Check in options if there are other stopword indices created based on language-specific rules.
if (options.otherStopWordIndices && options.otherStopWordIndices.length > 0) {
stopwordIndices = stopwordIndices.concat(options.otherStopWordIndices);
}
if (typeof regexes.directPrecedenceExceptionRegex !== "undefined") {
// Filters auxiliaries matched in the sentence based on a precedence exception filter.
auxiliaryIndices = auxiliaryPrecedenceExceptionFilter(sentence, auxiliaryIndices, regexes.directPrecedenceExceptionRegex);
}
if (typeof regexes.elisionAuxiliaryExceptionRegex !== "undefined") {
// Filters auxiliaries matched in the sentence based on a elision exception filter.
auxiliaryIndices = elisionAuxiliaryExceptionFilter(sentence, auxiliaryIndices, regexes.elisionAuxiliaryExceptionRegex);
}
let totalIndices = auxiliaryIndices.concat(stopwordIndices, stopCharacterIndices);
totalIndices = (0, _indices.filterIndices)(totalIndices);
return (0, _indices.sortIndices)(totalIndices);
};
/**
* Gets the auxiliaries from a sentence.
*
* @param {string} sentencePart The part of the sentence to match for auxiliaries.
* @param {object} regexes The regexes needed to find the auxiliaries.
*
* @returns {Array} All formatted matches from the sentence part.
*/
const getAuxiliaryMatches = function (sentencePart, regexes) {
const {
auxiliaryRegex,
directPrecedenceExceptionRegex,
followingAuxiliaryExceptionRegex
} = regexes;
let auxiliaryMatches = sentencePart.match(auxiliaryRegex) || [];
if (typeof directPrecedenceExceptionRegex !== "undefined" || typeof followingAuxiliaryExceptionRegex !== "undefined") {
// An array with the matched auxiliaries and their indices.
let auxiliaryMatchIndices = (0, _indices.getIndicesByWordList)(auxiliaryMatches, sentencePart);
if (typeof directPrecedenceExceptionRegex !== "undefined") {
// Filters auxiliaries matched in the sentence part based on a precedence exception filter.
auxiliaryMatchIndices = auxiliaryPrecedenceExceptionFilter(sentencePart, auxiliaryMatchIndices, directPrecedenceExceptionRegex);
}
// Filters auxiliaries matched in the sentence part based on a exception filter for words following the auxiliary.
auxiliaryMatchIndices = followingAuxiliaryExceptionFilter(sentencePart, auxiliaryMatchIndices, followingAuxiliaryExceptionRegex);
// An array with the matched auxiliary verbs (without indices).
auxiliaryMatches = [];
(0, _lodash.forEach)(auxiliaryMatchIndices, function (auxiliaryMatchIndex) {
auxiliaryMatches.push(auxiliaryMatchIndex.match);
});
}
return (0, _lodash.map)(auxiliaryMatches, function (auxiliaryMatch) {
return (0, _stripSpaces.default)(auxiliaryMatch);
});
};
/**
* Gets the clauses from a sentence by determining sentence breakers.
*
* @param {string} sentence The sentence to split up into clauses.
* @param {object} options The language options for which to get the clauses.
*
* @returns {Array} The array with all clauses that have an auxiliary.
*/
const getClauses = function (sentence, options) {
const clauses = [];
const auxiliaryRegex = options.regexes.auxiliaryRegex;
sentence = (0, _quotes.normalizeSingle)(sentence);
// First check if there is an auxiliary in the sentence.
if (sentence.match(auxiliaryRegex) === null) {
return clauses;
}
const indices = getSentenceBreakers(sentence, options);
// Get the words after the found auxiliary.
for (let i = 0; i < indices.length; i++) {
let endIndex = sentence.length;
if (!(0, _lodash.isUndefined)(indices[i + 1])) {
endIndex = indices[i + 1].index;
}
// Cut the sentence from the current index to the endIndex (start of next breaker, of end of sentence).
const clause = (0, _stripSpaces.default)(sentence.substring(indices[i].index, endIndex));
const auxiliaryMatches = getAuxiliaryMatches(clause, options.regexes);
// If a clause doesn't have an auxiliary, we don't need it, so it can be filtered out.
if (auxiliaryMatches.length !== 0) {
const foundClause = new options.Clause(clause, auxiliaryMatches);
clauses.push(foundClause);
}
}
return clauses;
};
/**
* Split the sentence into clauses based on auxiliaries.
*
* @param {string} sentence The sentence to split in parts.
* @param {Object} options The language options for which to get the clauses.
*
* @returns {Array} A list with clauses.
*/
function _default(sentence, options) {
return getClauses(sentence, options);
}
//# sourceMappingURL=getClauses.js.map