src/researches/buildKeywordForms.js
function( keyphrase, language, morphologyData ) {
	if ( isUndefined( keyphrase ) || keyphrase === "" ) {
		return [];
	}

	/*
	 * If the keyphrase is embedded in double quotation marks, return keyword itself, without outer-most quotation marks.
	 * Additionally, provide apostrophe variations.
	 */

	const doubleQuotes = [ "“", "”", "〝", "〞", "〟", "‟", "„", "\"" ];
	if ( includes( doubleQuotes, keyphrase[ 0 ] ) && includes( doubleQuotes, keyphrase[ keyphrase.length - 1 ] ) ) {
		keyphrase = keyphrase.substring( 1, keyphrase.length - 1 );
		return [ unique( [].concat( escapeRegExp( keyphrase ), getVariationsApostrophe( keyphrase ) ) ) ];
	}

	const words = filterFunctionWords( getWords( keyphrase ), language );

	const forms = [];

	const getForms = getFormsForLanguage[ language ];
	/*
	 * Only returns the keyword and the keyword with apostrophe variations if morphological forms cannot be built.
	 * Otherwise additionally returns the morphological forms.
	 */
	if ( morphologyData === false || isUndefined( getForms ) ) {
		words.forEach( function( word ) {
			const wordToLowerCase = escapeRegExp( word.toLocaleLowerCase( language ) );

			forms.push( unique( [].concat( wordToLowerCase, getVariationsApostrophe( wordToLowerCase ) ) ) );
		} );
	} else {
		words.forEach( function( word ) {
			const wordToLowerCase = escapeRegExp( word.toLocaleLowerCase() );
			const formsOfThisWord = language === "de"
				? getForms( wordToLowerCase, morphologyData ).forms : getForms( wordToLowerCase, morphologyData );
			const variationsApostrophes = getVariationsApostropheInArray( formsOfThisWord );
			forms.push( unique( flatten( formsOfThisWord.concat( variationsApostrophes ) ) ).filter( Boolean ) );
		} );
	}

	return forms;
}
function( keyphrase, language, morphologyData ) {
	if ( isUndefined( keyphrase ) || keyphrase === "" ) {
		return [];
	}

	/*
	 * If the keyphrase is embedded in double quotation marks, return keyword itself, without outer-most quotation marks.
	 * Additionally, provide apostrophe variations.
	 */

	const doubleQuotes = [ "“", "”", "〝", "〞", "〟", "‟", "„", "\"" ];
	if ( includes( doubleQuotes, keyphrase[ 0 ] ) && includes( doubleQuotes, keyphrase[ keyphrase.length - 1 ] ) ) {
		keyphrase = keyphrase.substring( 1, keyphrase.length - 1 );
		return [ unique( [].concat( escapeRegExp( keyphrase ), getVariationsApostrophe( keyphrase ) ) ) ];
	}

	const words = filterFunctionWords( getWords( keyphrase ), language );

	const forms = [];

	const getForms = getFormsForLanguage[ language ];
	/*
	 * Only returns the keyword and the keyword with apostrophe variations if morphological forms cannot be built.
	 * Otherwise additionally returns the morphological forms.
	 */
	if ( morphologyData === false || isUndefined( getForms ) ) {
		words.forEach( function( word ) {
			const wordToLowerCase = escapeRegExp( word.toLocaleLowerCase( language ) );

			forms.push( unique( [].concat( wordToLowerCase, getVariationsApostrophe( wordToLowerCase ) ) ) );
		} );
	} else {
		words.forEach( function( word ) {
			const wordToLowerCase = escapeRegExp( word.toLocaleLowerCase() );
			const formsOfThisWord = language === "de"
				? getForms( wordToLowerCase, morphologyData ).forms : getForms( wordToLowerCase, morphologyData );
			const variationsApostrophes = getVariationsApostropheInArray( formsOfThisWord );
			forms.push( unique( flatten( formsOfThisWord.concat( variationsApostrophes ) ) ).filter( Boolean ) );
		} );
	}

	return forms;
}
Analyzes the focus keyword string. Checks if morphology is requested or if the user wants to match exact string.
If morphology is required the module builds all word forms for all words (if no function words list available) or
for all content words (i.e., excluding prepositions, articles, conjunctions, if the function words list is available).

@param {string} keyphrase The keyphrase of the paper (or a synonym phrase) to get forms for.
@param {string} language The language to use for morphological analyzer and for function words.
@param {Object} morphologyData The available morphology data per language (false if unavailable).

@returns {Array} Array of all forms to be searched for keyword-based assessments.