PlainValue-ec8e588e.js 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876
  1. 'use strict';
  2. const Char = {
  3. ANCHOR: '&',
  4. COMMENT: '#',
  5. TAG: '!',
  6. DIRECTIVES_END: '-',
  7. DOCUMENT_END: '.'
  8. };
  9. const Type = {
  10. ALIAS: 'ALIAS',
  11. BLANK_LINE: 'BLANK_LINE',
  12. BLOCK_FOLDED: 'BLOCK_FOLDED',
  13. BLOCK_LITERAL: 'BLOCK_LITERAL',
  14. COMMENT: 'COMMENT',
  15. DIRECTIVE: 'DIRECTIVE',
  16. DOCUMENT: 'DOCUMENT',
  17. FLOW_MAP: 'FLOW_MAP',
  18. FLOW_SEQ: 'FLOW_SEQ',
  19. MAP: 'MAP',
  20. MAP_KEY: 'MAP_KEY',
  21. MAP_VALUE: 'MAP_VALUE',
  22. PLAIN: 'PLAIN',
  23. QUOTE_DOUBLE: 'QUOTE_DOUBLE',
  24. QUOTE_SINGLE: 'QUOTE_SINGLE',
  25. SEQ: 'SEQ',
  26. SEQ_ITEM: 'SEQ_ITEM'
  27. };
  28. const defaultTagPrefix = 'tag:yaml.org,2002:';
  29. const defaultTags = {
  30. MAP: 'tag:yaml.org,2002:map',
  31. SEQ: 'tag:yaml.org,2002:seq',
  32. STR: 'tag:yaml.org,2002:str'
  33. };
  34. function findLineStarts(src) {
  35. const ls = [0];
  36. let offset = src.indexOf('\n');
  37. while (offset !== -1) {
  38. offset += 1;
  39. ls.push(offset);
  40. offset = src.indexOf('\n', offset);
  41. }
  42. return ls;
  43. }
  44. function getSrcInfo(cst) {
  45. let lineStarts, src;
  46. if (typeof cst === 'string') {
  47. lineStarts = findLineStarts(cst);
  48. src = cst;
  49. } else {
  50. if (Array.isArray(cst)) cst = cst[0];
  51. if (cst && cst.context) {
  52. if (!cst.lineStarts) cst.lineStarts = findLineStarts(cst.context.src);
  53. lineStarts = cst.lineStarts;
  54. src = cst.context.src;
  55. }
  56. }
  57. return {
  58. lineStarts,
  59. src
  60. };
  61. }
  62. /**
  63. * @typedef {Object} LinePos - One-indexed position in the source
  64. * @property {number} line
  65. * @property {number} col
  66. */
  67. /**
  68. * Determine the line/col position matching a character offset.
  69. *
  70. * Accepts a source string or a CST document as the second parameter. With
  71. * the latter, starting indices for lines are cached in the document as
  72. * `lineStarts: number[]`.
  73. *
  74. * Returns a one-indexed `{ line, col }` location if found, or
  75. * `undefined` otherwise.
  76. *
  77. * @param {number} offset
  78. * @param {string|Document|Document[]} cst
  79. * @returns {?LinePos}
  80. */
  81. function getLinePos(offset, cst) {
  82. if (typeof offset !== 'number' || offset < 0) return null;
  83. const {
  84. lineStarts,
  85. src
  86. } = getSrcInfo(cst);
  87. if (!lineStarts || !src || offset > src.length) return null;
  88. for (let i = 0; i < lineStarts.length; ++i) {
  89. const start = lineStarts[i];
  90. if (offset < start) {
  91. return {
  92. line: i,
  93. col: offset - lineStarts[i - 1] + 1
  94. };
  95. }
  96. if (offset === start) return {
  97. line: i + 1,
  98. col: 1
  99. };
  100. }
  101. const line = lineStarts.length;
  102. return {
  103. line,
  104. col: offset - lineStarts[line - 1] + 1
  105. };
  106. }
  107. /**
  108. * Get a specified line from the source.
  109. *
  110. * Accepts a source string or a CST document as the second parameter. With
  111. * the latter, starting indices for lines are cached in the document as
  112. * `lineStarts: number[]`.
  113. *
  114. * Returns the line as a string if found, or `null` otherwise.
  115. *
  116. * @param {number} line One-indexed line number
  117. * @param {string|Document|Document[]} cst
  118. * @returns {?string}
  119. */
  120. function getLine(line, cst) {
  121. const {
  122. lineStarts,
  123. src
  124. } = getSrcInfo(cst);
  125. if (!lineStarts || !(line >= 1) || line > lineStarts.length) return null;
  126. const start = lineStarts[line - 1];
  127. let end = lineStarts[line]; // undefined for last line; that's ok for slice()
  128. while (end && end > start && src[end - 1] === '\n') --end;
  129. return src.slice(start, end);
  130. }
  131. /**
  132. * Pretty-print the starting line from the source indicated by the range `pos`
  133. *
  134. * Trims output to `maxWidth` chars while keeping the starting column visible,
  135. * using `…` at either end to indicate dropped characters.
  136. *
  137. * Returns a two-line string (or `null`) with `\n` as separator; the second line
  138. * will hold appropriately indented `^` marks indicating the column range.
  139. *
  140. * @param {Object} pos
  141. * @param {LinePos} pos.start
  142. * @param {LinePos} [pos.end]
  143. * @param {string|Document|Document[]*} cst
  144. * @param {number} [maxWidth=80]
  145. * @returns {?string}
  146. */
  147. function getPrettyContext({
  148. start,
  149. end
  150. }, cst, maxWidth = 80) {
  151. let src = getLine(start.line, cst);
  152. if (!src) return null;
  153. let {
  154. col
  155. } = start;
  156. if (src.length > maxWidth) {
  157. if (col <= maxWidth - 10) {
  158. src = src.substr(0, maxWidth - 1) + '…';
  159. } else {
  160. const halfWidth = Math.round(maxWidth / 2);
  161. if (src.length > col + halfWidth) src = src.substr(0, col + halfWidth - 1) + '…';
  162. col -= src.length - maxWidth;
  163. src = '…' + src.substr(1 - maxWidth);
  164. }
  165. }
  166. let errLen = 1;
  167. let errEnd = '';
  168. if (end) {
  169. if (end.line === start.line && col + (end.col - start.col) <= maxWidth + 1) {
  170. errLen = end.col - start.col;
  171. } else {
  172. errLen = Math.min(src.length + 1, maxWidth) - col;
  173. errEnd = '…';
  174. }
  175. }
  176. const offset = col > 1 ? ' '.repeat(col - 1) : '';
  177. const err = '^'.repeat(errLen);
  178. return `${src}\n${offset}${err}${errEnd}`;
  179. }
  180. class Range {
  181. static copy(orig) {
  182. return new Range(orig.start, orig.end);
  183. }
  184. constructor(start, end) {
  185. this.start = start;
  186. this.end = end || start;
  187. }
  188. isEmpty() {
  189. return typeof this.start !== 'number' || !this.end || this.end <= this.start;
  190. }
  191. /**
  192. * Set `origStart` and `origEnd` to point to the original source range for
  193. * this node, which may differ due to dropped CR characters.
  194. *
  195. * @param {number[]} cr - Positions of dropped CR characters
  196. * @param {number} offset - Starting index of `cr` from the last call
  197. * @returns {number} - The next offset, matching the one found for `origStart`
  198. */
  199. setOrigRange(cr, offset) {
  200. const {
  201. start,
  202. end
  203. } = this;
  204. if (cr.length === 0 || end <= cr[0]) {
  205. this.origStart = start;
  206. this.origEnd = end;
  207. return offset;
  208. }
  209. let i = offset;
  210. while (i < cr.length) {
  211. if (cr[i] > start) break;else ++i;
  212. }
  213. this.origStart = start + i;
  214. const nextOffset = i;
  215. while (i < cr.length) {
  216. // if end was at \n, it should now be at \r
  217. if (cr[i] >= end) break;else ++i;
  218. }
  219. this.origEnd = end + i;
  220. return nextOffset;
  221. }
  222. }
  223. /** Root class of all nodes */
  224. class Node {
  225. static addStringTerminator(src, offset, str) {
  226. if (str[str.length - 1] === '\n') return str;
  227. const next = Node.endOfWhiteSpace(src, offset);
  228. return next >= src.length || src[next] === '\n' ? str + '\n' : str;
  229. } // ^(---|...)
  230. static atDocumentBoundary(src, offset, sep) {
  231. const ch0 = src[offset];
  232. if (!ch0) return true;
  233. const prev = src[offset - 1];
  234. if (prev && prev !== '\n') return false;
  235. if (sep) {
  236. if (ch0 !== sep) return false;
  237. } else {
  238. if (ch0 !== Char.DIRECTIVES_END && ch0 !== Char.DOCUMENT_END) return false;
  239. }
  240. const ch1 = src[offset + 1];
  241. const ch2 = src[offset + 2];
  242. if (ch1 !== ch0 || ch2 !== ch0) return false;
  243. const ch3 = src[offset + 3];
  244. return !ch3 || ch3 === '\n' || ch3 === '\t' || ch3 === ' ';
  245. }
  246. static endOfIdentifier(src, offset) {
  247. let ch = src[offset];
  248. const isVerbatim = ch === '<';
  249. const notOk = isVerbatim ? ['\n', '\t', ' ', '>'] : ['\n', '\t', ' ', '[', ']', '{', '}', ','];
  250. while (ch && notOk.indexOf(ch) === -1) ch = src[offset += 1];
  251. if (isVerbatim && ch === '>') offset += 1;
  252. return offset;
  253. }
  254. static endOfIndent(src, offset) {
  255. let ch = src[offset];
  256. while (ch === ' ') ch = src[offset += 1];
  257. return offset;
  258. }
  259. static endOfLine(src, offset) {
  260. let ch = src[offset];
  261. while (ch && ch !== '\n') ch = src[offset += 1];
  262. return offset;
  263. }
  264. static endOfWhiteSpace(src, offset) {
  265. let ch = src[offset];
  266. while (ch === '\t' || ch === ' ') ch = src[offset += 1];
  267. return offset;
  268. }
  269. static startOfLine(src, offset) {
  270. let ch = src[offset - 1];
  271. if (ch === '\n') return offset;
  272. while (ch && ch !== '\n') ch = src[offset -= 1];
  273. return offset + 1;
  274. }
  275. /**
  276. * End of indentation, or null if the line's indent level is not more
  277. * than `indent`
  278. *
  279. * @param {string} src
  280. * @param {number} indent
  281. * @param {number} lineStart
  282. * @returns {?number}
  283. */
  284. static endOfBlockIndent(src, indent, lineStart) {
  285. const inEnd = Node.endOfIndent(src, lineStart);
  286. if (inEnd > lineStart + indent) {
  287. return inEnd;
  288. } else {
  289. const wsEnd = Node.endOfWhiteSpace(src, inEnd);
  290. const ch = src[wsEnd];
  291. if (!ch || ch === '\n') return wsEnd;
  292. }
  293. return null;
  294. }
  295. static atBlank(src, offset, endAsBlank) {
  296. const ch = src[offset];
  297. return ch === '\n' || ch === '\t' || ch === ' ' || endAsBlank && !ch;
  298. }
  299. static nextNodeIsIndented(ch, indentDiff, indicatorAsIndent) {
  300. if (!ch || indentDiff < 0) return false;
  301. if (indentDiff > 0) return true;
  302. return indicatorAsIndent && ch === '-';
  303. } // should be at line or string end, or at next non-whitespace char
  304. static normalizeOffset(src, offset) {
  305. const ch = src[offset];
  306. return !ch ? offset : ch !== '\n' && src[offset - 1] === '\n' ? offset - 1 : Node.endOfWhiteSpace(src, offset);
  307. } // fold single newline into space, multiple newlines to N - 1 newlines
  308. // presumes src[offset] === '\n'
  309. static foldNewline(src, offset, indent) {
  310. let inCount = 0;
  311. let error = false;
  312. let fold = '';
  313. let ch = src[offset + 1];
  314. while (ch === ' ' || ch === '\t' || ch === '\n') {
  315. switch (ch) {
  316. case '\n':
  317. inCount = 0;
  318. offset += 1;
  319. fold += '\n';
  320. break;
  321. case '\t':
  322. if (inCount <= indent) error = true;
  323. offset = Node.endOfWhiteSpace(src, offset + 2) - 1;
  324. break;
  325. case ' ':
  326. inCount += 1;
  327. offset += 1;
  328. break;
  329. }
  330. ch = src[offset + 1];
  331. }
  332. if (!fold) fold = ' ';
  333. if (ch && inCount <= indent) error = true;
  334. return {
  335. fold,
  336. offset,
  337. error
  338. };
  339. }
  340. constructor(type, props, context) {
  341. Object.defineProperty(this, 'context', {
  342. value: context || null,
  343. writable: true
  344. });
  345. this.error = null;
  346. this.range = null;
  347. this.valueRange = null;
  348. this.props = props || [];
  349. this.type = type;
  350. this.value = null;
  351. }
  352. getPropValue(idx, key, skipKey) {
  353. if (!this.context) return null;
  354. const {
  355. src
  356. } = this.context;
  357. const prop = this.props[idx];
  358. return prop && src[prop.start] === key ? src.slice(prop.start + (skipKey ? 1 : 0), prop.end) : null;
  359. }
  360. get anchor() {
  361. for (let i = 0; i < this.props.length; ++i) {
  362. const anchor = this.getPropValue(i, Char.ANCHOR, true);
  363. if (anchor != null) return anchor;
  364. }
  365. return null;
  366. }
  367. get comment() {
  368. const comments = [];
  369. for (let i = 0; i < this.props.length; ++i) {
  370. const comment = this.getPropValue(i, Char.COMMENT, true);
  371. if (comment != null) comments.push(comment);
  372. }
  373. return comments.length > 0 ? comments.join('\n') : null;
  374. }
  375. commentHasRequiredWhitespace(start) {
  376. const {
  377. src
  378. } = this.context;
  379. if (this.header && start === this.header.end) return false;
  380. if (!this.valueRange) return false;
  381. const {
  382. end
  383. } = this.valueRange;
  384. return start !== end || Node.atBlank(src, end - 1);
  385. }
  386. get hasComment() {
  387. if (this.context) {
  388. const {
  389. src
  390. } = this.context;
  391. for (let i = 0; i < this.props.length; ++i) {
  392. if (src[this.props[i].start] === Char.COMMENT) return true;
  393. }
  394. }
  395. return false;
  396. }
  397. get hasProps() {
  398. if (this.context) {
  399. const {
  400. src
  401. } = this.context;
  402. for (let i = 0; i < this.props.length; ++i) {
  403. if (src[this.props[i].start] !== Char.COMMENT) return true;
  404. }
  405. }
  406. return false;
  407. }
  408. get includesTrailingLines() {
  409. return false;
  410. }
  411. get jsonLike() {
  412. const jsonLikeTypes = [Type.FLOW_MAP, Type.FLOW_SEQ, Type.QUOTE_DOUBLE, Type.QUOTE_SINGLE];
  413. return jsonLikeTypes.indexOf(this.type) !== -1;
  414. }
  415. get rangeAsLinePos() {
  416. if (!this.range || !this.context) return undefined;
  417. const start = getLinePos(this.range.start, this.context.root);
  418. if (!start) return undefined;
  419. const end = getLinePos(this.range.end, this.context.root);
  420. return {
  421. start,
  422. end
  423. };
  424. }
  425. get rawValue() {
  426. if (!this.valueRange || !this.context) return null;
  427. const {
  428. start,
  429. end
  430. } = this.valueRange;
  431. return this.context.src.slice(start, end);
  432. }
  433. get tag() {
  434. for (let i = 0; i < this.props.length; ++i) {
  435. const tag = this.getPropValue(i, Char.TAG, false);
  436. if (tag != null) {
  437. if (tag[1] === '<') {
  438. return {
  439. verbatim: tag.slice(2, -1)
  440. };
  441. } else {
  442. // eslint-disable-next-line no-unused-vars
  443. const [_, handle, suffix] = tag.match(/^(.*!)([^!]*)$/);
  444. return {
  445. handle,
  446. suffix
  447. };
  448. }
  449. }
  450. }
  451. return null;
  452. }
  453. get valueRangeContainsNewline() {
  454. if (!this.valueRange || !this.context) return false;
  455. const {
  456. start,
  457. end
  458. } = this.valueRange;
  459. const {
  460. src
  461. } = this.context;
  462. for (let i = start; i < end; ++i) {
  463. if (src[i] === '\n') return true;
  464. }
  465. return false;
  466. }
  467. parseComment(start) {
  468. const {
  469. src
  470. } = this.context;
  471. if (src[start] === Char.COMMENT) {
  472. const end = Node.endOfLine(src, start + 1);
  473. const commentRange = new Range(start, end);
  474. this.props.push(commentRange);
  475. return end;
  476. }
  477. return start;
  478. }
  479. /**
  480. * Populates the `origStart` and `origEnd` values of all ranges for this
  481. * node. Extended by child classes to handle descendant nodes.
  482. *
  483. * @param {number[]} cr - Positions of dropped CR characters
  484. * @param {number} offset - Starting index of `cr` from the last call
  485. * @returns {number} - The next offset, matching the one found for `origStart`
  486. */
  487. setOrigRanges(cr, offset) {
  488. if (this.range) offset = this.range.setOrigRange(cr, offset);
  489. if (this.valueRange) this.valueRange.setOrigRange(cr, offset);
  490. this.props.forEach(prop => prop.setOrigRange(cr, offset));
  491. return offset;
  492. }
  493. toString() {
  494. const {
  495. context: {
  496. src
  497. },
  498. range,
  499. value
  500. } = this;
  501. if (value != null) return value;
  502. const str = src.slice(range.start, range.end);
  503. return Node.addStringTerminator(src, range.end, str);
  504. }
  505. }
  506. class YAMLError extends Error {
  507. constructor(name, source, message) {
  508. if (!message || !(source instanceof Node)) throw new Error(`Invalid arguments for new ${name}`);
  509. super();
  510. this.name = name;
  511. this.message = message;
  512. this.source = source;
  513. }
  514. makePretty() {
  515. if (!this.source) return;
  516. this.nodeType = this.source.type;
  517. const cst = this.source.context && this.source.context.root;
  518. if (typeof this.offset === 'number') {
  519. this.range = new Range(this.offset, this.offset + 1);
  520. const start = cst && getLinePos(this.offset, cst);
  521. if (start) {
  522. const end = {
  523. line: start.line,
  524. col: start.col + 1
  525. };
  526. this.linePos = {
  527. start,
  528. end
  529. };
  530. }
  531. delete this.offset;
  532. } else {
  533. this.range = this.source.range;
  534. this.linePos = this.source.rangeAsLinePos;
  535. }
  536. if (this.linePos) {
  537. const {
  538. line,
  539. col
  540. } = this.linePos.start;
  541. this.message += ` at line ${line}, column ${col}`;
  542. const ctx = cst && getPrettyContext(this.linePos, cst);
  543. if (ctx) this.message += `:\n\n${ctx}\n`;
  544. }
  545. delete this.source;
  546. }
  547. }
  548. class YAMLReferenceError extends YAMLError {
  549. constructor(source, message) {
  550. super('YAMLReferenceError', source, message);
  551. }
  552. }
  553. class YAMLSemanticError extends YAMLError {
  554. constructor(source, message) {
  555. super('YAMLSemanticError', source, message);
  556. }
  557. }
  558. class YAMLSyntaxError extends YAMLError {
  559. constructor(source, message) {
  560. super('YAMLSyntaxError', source, message);
  561. }
  562. }
  563. class YAMLWarning extends YAMLError {
  564. constructor(source, message) {
  565. super('YAMLWarning', source, message);
  566. }
  567. }
  568. function _defineProperty(obj, key, value) {
  569. if (key in obj) {
  570. Object.defineProperty(obj, key, {
  571. value: value,
  572. enumerable: true,
  573. configurable: true,
  574. writable: true
  575. });
  576. } else {
  577. obj[key] = value;
  578. }
  579. return obj;
  580. }
  581. class PlainValue extends Node {
  582. static endOfLine(src, start, inFlow) {
  583. let ch = src[start];
  584. let offset = start;
  585. while (ch && ch !== '\n') {
  586. if (inFlow && (ch === '[' || ch === ']' || ch === '{' || ch === '}' || ch === ',')) break;
  587. const next = src[offset + 1];
  588. if (ch === ':' && (!next || next === '\n' || next === '\t' || next === ' ' || inFlow && next === ',')) break;
  589. if ((ch === ' ' || ch === '\t') && next === '#') break;
  590. offset += 1;
  591. ch = next;
  592. }
  593. return offset;
  594. }
  595. get strValue() {
  596. if (!this.valueRange || !this.context) return null;
  597. let {
  598. start,
  599. end
  600. } = this.valueRange;
  601. const {
  602. src
  603. } = this.context;
  604. let ch = src[end - 1];
  605. while (start < end && (ch === '\n' || ch === '\t' || ch === ' ')) ch = src[--end - 1];
  606. let str = '';
  607. for (let i = start; i < end; ++i) {
  608. const ch = src[i];
  609. if (ch === '\n') {
  610. const {
  611. fold,
  612. offset
  613. } = Node.foldNewline(src, i, -1);
  614. str += fold;
  615. i = offset;
  616. } else if (ch === ' ' || ch === '\t') {
  617. // trim trailing whitespace
  618. const wsStart = i;
  619. let next = src[i + 1];
  620. while (i < end && (next === ' ' || next === '\t')) {
  621. i += 1;
  622. next = src[i + 1];
  623. }
  624. if (next !== '\n') str += i > wsStart ? src.slice(wsStart, i + 1) : ch;
  625. } else {
  626. str += ch;
  627. }
  628. }
  629. const ch0 = src[start];
  630. switch (ch0) {
  631. case '\t':
  632. {
  633. const msg = 'Plain value cannot start with a tab character';
  634. const errors = [new YAMLSemanticError(this, msg)];
  635. return {
  636. errors,
  637. str
  638. };
  639. }
  640. case '@':
  641. case '`':
  642. {
  643. const msg = `Plain value cannot start with reserved character ${ch0}`;
  644. const errors = [new YAMLSemanticError(this, msg)];
  645. return {
  646. errors,
  647. str
  648. };
  649. }
  650. default:
  651. return str;
  652. }
  653. }
  654. parseBlockValue(start) {
  655. const {
  656. indent,
  657. inFlow,
  658. src
  659. } = this.context;
  660. let offset = start;
  661. let valueEnd = start;
  662. for (let ch = src[offset]; ch === '\n'; ch = src[offset]) {
  663. if (Node.atDocumentBoundary(src, offset + 1)) break;
  664. const end = Node.endOfBlockIndent(src, indent, offset + 1);
  665. if (end === null || src[end] === '#') break;
  666. if (src[end] === '\n') {
  667. offset = end;
  668. } else {
  669. valueEnd = PlainValue.endOfLine(src, end, inFlow);
  670. offset = valueEnd;
  671. }
  672. }
  673. if (this.valueRange.isEmpty()) this.valueRange.start = start;
  674. this.valueRange.end = valueEnd;
  675. return valueEnd;
  676. }
  677. /**
  678. * Parses a plain value from the source
  679. *
  680. * Accepted forms are:
  681. * ```
  682. * #comment
  683. *
  684. * first line
  685. *
  686. * first line #comment
  687. *
  688. * first line
  689. * block
  690. * lines
  691. *
  692. * #comment
  693. * block
  694. * lines
  695. * ```
  696. * where block lines are empty or have an indent level greater than `indent`.
  697. *
  698. * @param {ParseContext} context
  699. * @param {number} start - Index of first character
  700. * @returns {number} - Index of the character after this scalar, may be `\n`
  701. */
  702. parse(context, start) {
  703. this.context = context;
  704. const {
  705. inFlow,
  706. src
  707. } = context;
  708. let offset = start;
  709. const ch = src[offset];
  710. if (ch && ch !== '#' && ch !== '\n') {
  711. offset = PlainValue.endOfLine(src, start, inFlow);
  712. }
  713. this.valueRange = new Range(start, offset);
  714. offset = Node.endOfWhiteSpace(src, offset);
  715. offset = this.parseComment(offset);
  716. if (!this.hasComment || this.valueRange.isEmpty()) {
  717. offset = this.parseBlockValue(offset);
  718. }
  719. return offset;
  720. }
  721. }
  722. exports.Char = Char;
  723. exports.Node = Node;
  724. exports.PlainValue = PlainValue;
  725. exports.Range = Range;
  726. exports.Type = Type;
  727. exports.YAMLError = YAMLError;
  728. exports.YAMLReferenceError = YAMLReferenceError;
  729. exports.YAMLSemanticError = YAMLSemanticError;
  730. exports.YAMLSyntaxError = YAMLSyntaxError;
  731. exports.YAMLWarning = YAMLWarning;
  732. exports._defineProperty = _defineProperty;
  733. exports.defaultTagPrefix = defaultTagPrefix;
  734. exports.defaultTags = defaultTags;