cm-tarnation
Version:
An alternative parser for CodeMirror 6
76 lines • 2.66 kB
JavaScript
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
import { pointsMatch, toPoints } from "../../util";
/** Matcher that takes a string pattern, and matches that against an input. */
export class StringMatcher {
/**
* @param str - The source string.
* @param ignoreCase - If `true`, matches will be case-insensitive.
* @param variables - A variable table to use when expanding variables.
*/
constructor(str, ignoreCase = false, variables) {
if (variables)
str = expandVariables(str, variables);
if (ignoreCase)
str = str.toLowerCase();
this.cased = ignoreCase && str.toLowerCase() !== str.toUpperCase();
this.length = str.length;
this.points = toPoints(str);
}
/**
* Tests to see if this pattern matches the given string.
*
* @param str - The string to match.
* @param pos - The position to start matching at.
*/
test(str, pos) {
if (this.length > str.length)
return false;
if (pointsMatch(this.points, str, pos))
return true;
// less optimized code path due to lowercasing requirement
if (this.cased) {
const lowered = str.slice(pos, pos + this.length).toLowerCase();
return pointsMatch(this.points, lowered, 0);
}
return false;
}
/**
* Returns the results of attempting to match a string against this pattern.
*
* @param str - The string to match.
* @param pos - The position to start matching at.
*/
match(str, pos) {
if (this.test(str, pos)) {
return {
total: str.slice(pos, pos + this.length),
captures: null,
length: this.length
};
}
return null;
}
}
/**
* Expands the variables in a pattern source using a variable table.
*
* @param src - The source to expand.
* @param variables - The variable table to use.
*/
function expandVariables(src, variables) {
let depth = 0;
while (/@\w/.test(src) && depth < 5) {
depth++;
src = src.replace(/@(\w+)/g, (_, ident) => {
const value = variables[ident];
if (typeof value !== "string") {
throw new Error(`Variable ${ident} is not a string`);
}
return value;
});
}
return src;
}
//# sourceMappingURL=string.js.map