123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119 |
- '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);
- };
|