@eagleoutice/flowr-dev
Version:
Static Dataflow Analyzer and Program Slicer for the R Programming Language
141 lines • 4.63 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.startAndEndsWith = startAndEndsWith;
exports.isSubsequence = isSubsequence;
exports.matchByPrefixOrSubsequence = matchByPrefixOrSubsequence;
exports.withoutWhitespace = withoutWhitespace;
exports.longestCommonPrefix = longestCommonPrefix;
exports.joinWithLast = joinWithLast;
exports.isUrl = isUrl;
exports.fileUrlToPath = fileUrlToPath;
exports.isAbsolutePath = isAbsolutePath;
exports.dropRawStringSurround = dropRawStringSurround;
const path_1 = __importDefault(require("path"));
const url_1 = require("url");
/**
* Check if the given string starts and ends with the given letter
*/
function startAndEndsWith(str, letter) {
return str.startsWith(letter) && str.endsWith(letter);
}
/**
* Whether every character of `needle` appears in `hay` in order (a subsequence / fuzzy match).
*/
function isSubsequence(needle, hay) {
if (needle.length === 0) {
return true;
}
let i = 0;
for (const c of hay) {
if (c === needle[i] && ++i === needle.length) {
return true;
}
}
return false;
}
/**
* The `candidates` that start with `needle`, or -- if none do -- those that contain it as a
* {@link isSubsequence|subsequence} (case-insensitive). `needle` itself is never returned.
*/
function matchByPrefixOrSubsequence(candidates, needle) {
const prefixed = candidates.filter(c => c.startsWith(needle) && c !== needle);
if (prefixed.length > 0) {
return prefixed;
}
const lower = needle.toLowerCase();
return candidates.filter(c => c !== needle && isSubsequence(lower, c.toLowerCase()));
}
/**
* Removes all whitespace in the given string
*/
function withoutWhitespace(output) {
return output.replace(/\s/g, '');
}
/**
* Find the longest common prefix in an array of strings
*/
function longestCommonPrefix(strings) {
if (strings.length === 0) {
return '';
}
let prefix = strings[0];
for (const str of strings) {
if (prefix.length === 0) {
break;
}
let i = 0;
while (i < prefix.length && prefix[i] === str[i]) {
i++;
}
if (i !== prefix.length) {
prefix = prefix.slice(0, i);
}
}
return prefix;
}
/**
* Join a list of strings, but with special handling for the last element/scenarios in which the array contains exactly two elements.
* The goal is to create (partial) sentences like `a, b, and c` or `a and b`.
*/
function joinWithLast(strs, { join = ', ', last = ', and ', joinTwo = ' and ' } = {}) {
if (strs.length <= 1) {
return strs.join('');
}
else if (strs.length === 2) {
return strs.join(joinTwo);
}
return strs.slice(0, -1).join(join) + last + strs[strs.length - 1];
}
const UrlPattern = /^(https?|ftps?|s3|gs):\/\//i;
/** Check if the given string looks like a remote URL (http/https/ftp/ftps/s3/gs). */
function isUrl(p) {
return UrlPattern.test(p);
}
/**
* If `s` is a `file://` URI, return the local filesystem path it refers to.
* Returns `undefined` for any other string.
*/
function fileUrlToPath(s) {
if (!s.startsWith('file://')) {
return undefined;
}
try {
return (0, url_1.fileURLToPath)(s);
}
catch {
return undefined;
}
}
/**
* Check if the given path is an absolute path.
*/
function isAbsolutePath(p, regex) {
return regex?.test(p) || p.startsWith('/') || p.startsWith('\\') ||
/[a-zA-Z]:[\\/]/.test(p) || // Windows absolute path
path_1.default.normalize(p + '/') === path_1.default.normalize(path_1.default.resolve(p) + '/');
}
const CorrespondingClose = {
'(': ')',
'[': ']',
'{': '}'
};
/** collect '-' at the start until '[' or '(' is reached, then drop the same from the end if present otherwise return the value as is */
function dropRawStringSurround(value) {
const dashCount = value.match(/^-*/)?.[0].length ?? 0;
const open = value[dashCount];
if (open === '[' || open === '(' || open === '{') {
// if the value starts with a dash and then a bracket, we drop the dashes at the end
const end = value.endsWith(CorrespondingClose[open] + '-'.repeat(dashCount)) ? dashCount : undefined;
if (end !== undefined) {
return value.slice(dashCount + 1, -end - 1);
}
else {
return value;
}
}
return value;
}
//# sourceMappingURL=strings.js.map