package.internals.string-parse.js Maven / Gradle / Ivy
The newest version!
'use strict';
// adapted from https://github.com/jridgewell/string-dedent
var getBuiltIn = require('../internals/get-built-in');
var uncurryThis = require('../internals/function-uncurry-this');
var fromCharCode = String.fromCharCode;
var fromCodePoint = getBuiltIn('String', 'fromCodePoint');
var charAt = uncurryThis(''.charAt);
var charCodeAt = uncurryThis(''.charCodeAt);
var stringIndexOf = uncurryThis(''.indexOf);
var stringSlice = uncurryThis(''.slice);
var ZERO_CODE = 48;
var NINE_CODE = 57;
var LOWER_A_CODE = 97;
var LOWER_F_CODE = 102;
var UPPER_A_CODE = 65;
var UPPER_F_CODE = 70;
var isDigit = function (str, index) {
var c = charCodeAt(str, index);
return c >= ZERO_CODE && c <= NINE_CODE;
};
var parseHex = function (str, index, end) {
if (end >= str.length) return -1;
var n = 0;
for (; index < end; index++) {
var c = hexToInt(charCodeAt(str, index));
if (c === -1) return -1;
n = n * 16 + c;
}
return n;
};
var hexToInt = function (c) {
if (c >= ZERO_CODE && c <= NINE_CODE) return c - ZERO_CODE;
if (c >= LOWER_A_CODE && c <= LOWER_F_CODE) return c - LOWER_A_CODE + 10;
if (c >= UPPER_A_CODE && c <= UPPER_F_CODE) return c - UPPER_A_CODE + 10;
return -1;
};
module.exports = function (raw) {
var out = '';
var start = 0;
// We need to find every backslash escape sequence, and cook the escape into a real char.
var i = 0;
var n;
while ((i = stringIndexOf(raw, '\\', i)) > -1) {
out += stringSlice(raw, start, i);
// If the backslash is the last char of the string, then it was an invalid sequence.
// This can't actually happen in a tagged template literal, but could happen if you manually
// invoked the tag with an array.
if (++i === raw.length) return;
var next = charAt(raw, i++);
switch (next) {
// Escaped control codes need to be individually processed.
case 'b':
out += '\b';
break;
case 't':
out += '\t';
break;
case 'n':
out += '\n';
break;
case 'v':
out += '\v';
break;
case 'f':
out += '\f';
break;
case 'r':
out += '\r';
break;
// Escaped line terminators just skip the char.
case '\r':
// Treat `\r\n` as a single terminator.
if (i < raw.length && charAt(raw, i) === '\n') ++i;
// break omitted
case '\n':
case '\u2028':
case '\u2029':
break;
// `\0` is a null control char, but `\0` followed by another digit is an illegal octal escape.
case '0':
if (isDigit(raw, i)) return;
out += '\0';
break;
// Hex escapes must contain 2 hex chars.
case 'x':
n = parseHex(raw, i, i + 2);
if (n === -1) return;
i += 2;
out += fromCharCode(n);
break;
// Unicode escapes contain either 4 chars, or an unlimited number between `{` and `}`.
// The hex value must not overflow 0x10FFFF.
case 'u':
if (i < raw.length && charAt(raw, i) === '{') {
var end = stringIndexOf(raw, '}', ++i);
if (end === -1) return;
n = parseHex(raw, i, end);
i = end + 1;
} else {
n = parseHex(raw, i, i + 4);
i += 4;
}
if (n === -1 || n > 0x10FFFF) return;
out += fromCodePoint(n);
break;
default:
if (isDigit(next, 0)) return;
out += next;
}
start = i;
}
return out + stringSlice(raw, start);
};
© 2015 - 2024 Weber Informatics LLC | Privacy Policy