// keywords that should have no default relevance value
const COMMON_KEYWORDS = [
'of',
'and',
'for',
'in',
'not',
'or',
'if',
'then',
'parent', // common variable name
'list', // common variable name
'value' // common variable name
];
const DEFAULT_KEYWORD_SCOPE = "keyword";
/**
* Given raw keywords from a language definition, compile them.
*
* @param {string | Record<string,string|string[]> | Array<string>} rawKeywords
* @param {boolean} caseInsensitive
*/
export function compileKeywords(rawKeywords, caseInsensitive, scopeName = DEFAULT_KEYWORD_SCOPE) {
/** @type KeywordDict */
const compiledKeywords = Object.create(null);
// input can be a string of keywords, an array of keywords, or a object with
// named keys representing scopeName (which can then point to a string or array)
if (typeof rawKeywords === 'string') {
compileList(scopeName, rawKeywords.split(" "));
} else if (Array.isArray(rawKeywords)) {
compileList(scopeName, rawKeywords);
} else {
Object.keys(rawKeywords).forEach(function(scopeName) {
// collapse all our objects back into the parent object
Object.assign(
compiledKeywords,
compileKeywords(rawKeywords[scopeName], caseInsensitive, scopeName)
);
});
}
return compiledKeywords;
// ---
/**
* Compiles an individual list of keywords
*
* Ex: "for if when while|5"
*
* @param {string} scopeName
* @param {Array<string>} keywordList
*/
function compileList(scopeName, keywordList) {
if (caseInsensitive) {
keywordList = keywordList.map(x => x.toLowerCase());
}
keywordList.forEach(function(keyword) {
const pair = keyword.split('|');
compiledKeywords[pair[0]] = [scopeName, scoreForKeyword(pair[0], pair[1])];
});
}
}
/**
* Returns the proper score for a given keyword
*
* Also takes into account comment keywords, which will be scored 0 UNLESS
* another score has been manually assigned.
* @param {string} keyword
* @param {string} [providedScore]
*/
function scoreForKeyword(keyword, providedScore) {
// manual scores always win over common keywords
// so you can force a score of 1 if you really insist
if (providedScore) {
return Number(providedScore);
}
return commonKeyword(keyword) ? 0 : 1;
}
/**
* Determines if a given keyword is common or not
*
* @param {string} keyword */
function commonKeyword(keyword) {
return COMMON_KEYWORDS.includes(keyword.toLowerCase());
}