@js-data-tools/js-helpers
Version:
A set of JavaScript / TypeScript helper functions for parsing, converting, transforming and formatting data.
71 lines (70 loc) • 2.59 kB
JavaScript
export const CHAR_CODE_OPEN_PAREN = 40;
export const CHAR_CODE_CLOSE_PAREN = 41;
export const CHAR_CODE_OPEN_BRACKET = 91;
export const CHAR_CODE_CLOSE_BRACKET = 93;
export const CHAR_CODE_OPEN_BRACE = 123;
export const CHAR_CODE_CLOSE_BRACE = 125;
export const CHAR_CODE_QUOTE = 34;
export const CHAR_CODE_APOSTROPHE = 39;
export const CHAR_CODE_BACKTICK = 96;
export function skipUntilClosingQuote(text, start, quote) {
for (let i = start; i < text.length; ++i) {
const current = text.charCodeAt(i);
if (current === quote) {
return i;
}
if (current == 92) {
i++;
}
}
return text.length;
}
export function skipPairsUntil(text, start, match, throwOnMismatch) {
const stack = [];
if (typeof (match) === "string") {
match = match.charCodeAt(0);
}
const matchSymbol = typeof (match) === "number" ? ((x) => x === match) : match;
for (let i = start; i < text.length; ++i) {
const current = text.charCodeAt(i);
if (matchSymbol(current) && !stack.length) {
return i;
}
switch (current) {
case CHAR_CODE_OPEN_PAREN:
stack.push(CHAR_CODE_CLOSE_PAREN);
break;
case CHAR_CODE_OPEN_BRACKET:
stack.push(CHAR_CODE_CLOSE_BRACKET);
break;
case CHAR_CODE_OPEN_BRACE:
stack.push(CHAR_CODE_CLOSE_BRACE);
break;
case CHAR_CODE_CLOSE_PAREN:
case CHAR_CODE_CLOSE_BRACKET:
case CHAR_CODE_CLOSE_BRACE:
{
const pending = stack.pop();
if (pending != current) {
if (throwOnMismatch !== false) {
throw new Error(`Unexpected '${String.fromCharCode(current)}' at offset ${i}. Expected '${pending ? String.fromCharCode(pending) : "(none)"}'`);
}
return text.length;
}
}
break;
case CHAR_CODE_QUOTE:
case CHAR_CODE_APOSTROPHE:
case CHAR_CODE_BACKTICK:
i = skipUntilClosingQuote(text, i + 1, current);
if (i === text.length) {
return i;
}
break;
}
}
if (throwOnMismatch !== false && stack.length) {
throw new Error(`There are ${stack.length} unclosed groups: '${stack.map(x => String.fromCharCode(x)).join("','")}'`);
}
return text.length;
}