UNPKG

@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
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; }