'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); /** * Methods for consuming quoted values */ const SINGLE_QUOTE = 39; // ' const DOUBLE_QUOTE = 34; // " const defaultOptions = { escape: 92, // \ character throws: false }; /** * Consumes 'single' or "double"-quoted string from given string, if possible * @param {StreamReader} stream * @param {Number} options.escape A character code of quote-escape symbol * @param {Boolean} options.throws Throw error if quotes string can’t be properly consumed * @return {Boolean} `true` if quoted string was consumed. The contents * of quoted string will be availabe as `stream.current()` */ var eatQuoted = function(stream, options) { options = options ? Object.assign({}, defaultOptions, options) : defaultOptions; const start = stream.pos; const quote = stream.peek(); if (stream.eat(isQuote)) { while (!stream.eof()) { switch (stream.next()) { case quote: stream.start = start; return true; case options.escape: stream.next(); break; } } // If we’re here then stream wasn’t properly consumed. // Revert stream and decide what to do stream.pos = start; if (options.throws) { throw stream.error('Unable to consume quoted string'); } } return false; }; function isQuote(code) { return code === SINGLE_QUOTE || code === DOUBLE_QUOTE; } /** * Check if given code is a number * @param {Number} code * @return {Boolean} */ function isNumber(code) { return code > 47 && code < 58; } /** * Check if given character code is alpha code (letter through A to Z) * @param {Number} code * @param {Number} [from] * @param {Number} [to] * @return {Boolean} */ function isAlpha(code, from, to) { from = from || 65; // A to = to || 90; // Z code &= ~32; // quick hack to convert any char code to uppercase char code return code >= from && code <= to; } /** * Check if given character code is alpha-numeric (letter through A to Z or number) * @param {Number} code * @return {Boolean} */ function isAlphaNumeric(code) { return isNumber(code) || isAlpha(code); } function isWhiteSpace(code) { return code === 32 /* space */ || code === 9 /* tab */ || code === 160; /* non-breaking space */ } /** * Check if given character code is a space * @param {Number} code * @return {Boolean} */ function isSpace(code) { return isWhiteSpace(code) || code === 10 /* LF */ || code === 13; /* CR */ } const defaultOptions$1 = { escape: 92, // \ character throws: false }; /** * Eats paired characters substring, for example `(foo)` or `[bar]` * @param {StreamReader} stream * @param {Number} open Character code of pair openinig * @param {Number} close Character code of pair closing * @param {Object} [options] * @return {Boolean} Returns `true` if chacarter pair was successfully * consumed, it’s content will be available as `stream.current()` */ function eatPair(stream, open, close, options) { options = options ? Object.assign({}, defaultOptions$1, options) : defaultOptions$1; const start = stream.pos; if (stream.eat(open)) { let stack = 1, ch; while (!stream.eof()) { if (eatQuoted(stream, options)) { continue; } ch = stream.next(); if (ch === open) { stack++; } else if (ch === close) { stack--; if (!stack) { stream.start = start; return true; } } else if (ch === options.escape) { stream.next(); } } // If we’re here then paired character can’t be consumed stream.pos = start; if (options.throws) { throw stream.error(`Unable to find matching pair for ${String.fromCharCode(open)}`); } } return false; } exports.eatQuoted = eatQuoted; exports.isQuote = isQuote; exports.isAlpha = isAlpha; exports.isNumber = isNumber; exports.isAlphaNumeric = isAlphaNumeric; exports.isSpace = isSpace; exports.isWhiteSpace = isWhiteSpace; exports.eatPair = eatPair;