Dashboard sipadu mbip
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

QuoteDouble.js 5.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. exports.default = void 0;
  6. var _errors = require("../errors");
  7. var _Node = _interopRequireDefault(require("./Node"));
  8. var _Range = _interopRequireDefault(require("./Range"));
  9. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  10. class QuoteDouble extends _Node.default {
  11. static endOfQuote(src, offset) {
  12. let ch = src[offset];
  13. while (ch && ch !== '"') {
  14. offset += ch === '\\' ? 2 : 1;
  15. ch = src[offset];
  16. }
  17. return offset + 1;
  18. }
  19. /**
  20. * @returns {string | { str: string, errors: YAMLSyntaxError[] }}
  21. */
  22. get strValue() {
  23. if (!this.valueRange || !this.context) return null;
  24. const errors = [];
  25. const {
  26. start,
  27. end
  28. } = this.valueRange;
  29. const {
  30. indent,
  31. src
  32. } = this.context;
  33. if (src[end - 1] !== '"') errors.push(new _errors.YAMLSyntaxError(this, 'Missing closing "quote')); // Using String#replace is too painful with escaped newlines preceded by
  34. // escaped backslashes; also, this should be faster.
  35. let str = '';
  36. for (let i = start + 1; i < end - 1; ++i) {
  37. const ch = src[i];
  38. if (ch === '\n') {
  39. if (_Node.default.atDocumentBoundary(src, i + 1)) errors.push(new _errors.YAMLSemanticError(this, 'Document boundary indicators are not allowed within string values'));
  40. const {
  41. fold,
  42. offset,
  43. error
  44. } = _Node.default.foldNewline(src, i, indent);
  45. str += fold;
  46. i = offset;
  47. if (error) errors.push(new _errors.YAMLSemanticError(this, 'Multi-line double-quoted string needs to be sufficiently indented'));
  48. } else if (ch === '\\') {
  49. i += 1;
  50. switch (src[i]) {
  51. case '0':
  52. str += '\0';
  53. break;
  54. // null character
  55. case 'a':
  56. str += '\x07';
  57. break;
  58. // bell character
  59. case 'b':
  60. str += '\b';
  61. break;
  62. // backspace
  63. case 'e':
  64. str += '\x1b';
  65. break;
  66. // escape character
  67. case 'f':
  68. str += '\f';
  69. break;
  70. // form feed
  71. case 'n':
  72. str += '\n';
  73. break;
  74. // line feed
  75. case 'r':
  76. str += '\r';
  77. break;
  78. // carriage return
  79. case 't':
  80. str += '\t';
  81. break;
  82. // horizontal tab
  83. case 'v':
  84. str += '\v';
  85. break;
  86. // vertical tab
  87. case 'N':
  88. str += '\u0085';
  89. break;
  90. // Unicode next line
  91. case '_':
  92. str += '\u00a0';
  93. break;
  94. // Unicode non-breaking space
  95. case 'L':
  96. str += '\u2028';
  97. break;
  98. // Unicode line separator
  99. case 'P':
  100. str += '\u2029';
  101. break;
  102. // Unicode paragraph separator
  103. case ' ':
  104. str += ' ';
  105. break;
  106. case '"':
  107. str += '"';
  108. break;
  109. case '/':
  110. str += '/';
  111. break;
  112. case '\\':
  113. str += '\\';
  114. break;
  115. case '\t':
  116. str += '\t';
  117. break;
  118. case 'x':
  119. str += this.parseCharCode(i + 1, 2, errors);
  120. i += 2;
  121. break;
  122. case 'u':
  123. str += this.parseCharCode(i + 1, 4, errors);
  124. i += 4;
  125. break;
  126. case 'U':
  127. str += this.parseCharCode(i + 1, 8, errors);
  128. i += 8;
  129. break;
  130. case '\n':
  131. // skip escaped newlines, but still trim the following line
  132. while (src[i + 1] === ' ' || src[i + 1] === '\t') i += 1;
  133. break;
  134. default:
  135. errors.push(new _errors.YAMLSyntaxError(this, `Invalid escape sequence ${src.substr(i - 1, 2)}`));
  136. str += '\\' + src[i];
  137. }
  138. } else if (ch === ' ' || ch === '\t') {
  139. // trim trailing whitespace
  140. const wsStart = i;
  141. let next = src[i + 1];
  142. while (next === ' ' || next === '\t') {
  143. i += 1;
  144. next = src[i + 1];
  145. }
  146. if (next !== '\n') str += i > wsStart ? src.slice(wsStart, i + 1) : ch;
  147. } else {
  148. str += ch;
  149. }
  150. }
  151. return errors.length > 0 ? {
  152. errors,
  153. str
  154. } : str;
  155. }
  156. parseCharCode(offset, length, errors) {
  157. const {
  158. src
  159. } = this.context;
  160. const cc = src.substr(offset, length);
  161. const ok = cc.length === length && /^[0-9a-fA-F]+$/.test(cc);
  162. const code = ok ? parseInt(cc, 16) : NaN;
  163. if (isNaN(code)) {
  164. errors.push(new _errors.YAMLSyntaxError(this, `Invalid escape sequence ${src.substr(offset - 2, length + 2)}`));
  165. return src.substr(offset - 2, length + 2);
  166. }
  167. return String.fromCodePoint(code);
  168. }
  169. /**
  170. * Parses a "double quoted" value from the source
  171. *
  172. * @param {ParseContext} context
  173. * @param {number} start - Index of first character
  174. * @returns {number} - Index of the character after this scalar
  175. */
  176. parse(context, start) {
  177. this.context = context;
  178. const {
  179. src
  180. } = context;
  181. let offset = QuoteDouble.endOfQuote(src, start + 1);
  182. this.valueRange = new _Range.default(start, offset);
  183. offset = _Node.default.endOfWhiteSpace(src, offset);
  184. offset = this.parseComment(offset);
  185. return offset;
  186. }
  187. }
  188. exports.default = QuoteDouble;