Parser.js 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603
  1. // Generated by CoffeeScript 1.12.4
  2. var Inline, ParseException, ParseMore, Parser, Pattern, Utils;
  3. Inline = require('./Inline');
  4. Pattern = require('./Pattern');
  5. Utils = require('./Utils');
  6. ParseException = require('./Exception/ParseException');
  7. ParseMore = require('./Exception/ParseMore');
  8. Parser = (function() {
  9. Parser.prototype.PATTERN_FOLDED_SCALAR_ALL = new Pattern('^(?:(?<type>![^\\|>]*)\\s+)?(?<separator>\\||>)(?<modifiers>\\+|\\-|\\d+|\\+\\d+|\\-\\d+|\\d+\\+|\\d+\\-)?(?<comments> +#.*)?$');
  10. Parser.prototype.PATTERN_FOLDED_SCALAR_END = new Pattern('(?<separator>\\||>)(?<modifiers>\\+|\\-|\\d+|\\+\\d+|\\-\\d+|\\d+\\+|\\d+\\-)?(?<comments> +#.*)?$');
  11. Parser.prototype.PATTERN_SEQUENCE_ITEM = new Pattern('^\\-((?<leadspaces>\\s+)(?<value>.+?))?\\s*$');
  12. Parser.prototype.PATTERN_ANCHOR_VALUE = new Pattern('^&(?<ref>[^ ]+) *(?<value>.*)');
  13. Parser.prototype.PATTERN_COMPACT_NOTATION = new Pattern('^(?<key>' + Inline.REGEX_QUOTED_STRING + '|[^ \'"\\{\\[].*?) *\\:(\\s+(?<value>.+?))?\\s*$');
  14. Parser.prototype.PATTERN_MAPPING_ITEM = new Pattern('^(?<key>' + Inline.REGEX_QUOTED_STRING + '|[^ \'"\\[\\{].*?) *\\:(\\s+(?<value>.+?))?\\s*$');
  15. Parser.prototype.PATTERN_DECIMAL = new Pattern('\\d+');
  16. Parser.prototype.PATTERN_INDENT_SPACES = new Pattern('^ +');
  17. Parser.prototype.PATTERN_TRAILING_LINES = new Pattern('(\n*)$');
  18. Parser.prototype.PATTERN_YAML_HEADER = new Pattern('^\\%YAML[: ][\\d\\.]+.*\n', 'm');
  19. Parser.prototype.PATTERN_LEADING_COMMENTS = new Pattern('^(\\#.*?\n)+', 'm');
  20. Parser.prototype.PATTERN_DOCUMENT_MARKER_START = new Pattern('^\\-\\-\\-.*?\n', 'm');
  21. Parser.prototype.PATTERN_DOCUMENT_MARKER_END = new Pattern('^\\.\\.\\.\\s*$', 'm');
  22. Parser.prototype.PATTERN_FOLDED_SCALAR_BY_INDENTATION = {};
  23. Parser.prototype.CONTEXT_NONE = 0;
  24. Parser.prototype.CONTEXT_SEQUENCE = 1;
  25. Parser.prototype.CONTEXT_MAPPING = 2;
  26. function Parser(offset) {
  27. this.offset = offset != null ? offset : 0;
  28. this.lines = [];
  29. this.currentLineNb = -1;
  30. this.currentLine = '';
  31. this.refs = {};
  32. }
  33. Parser.prototype.parse = function(value, exceptionOnInvalidType, objectDecoder) {
  34. var alias, allowOverwrite, block, c, context, data, e, first, i, indent, isRef, j, k, key, l, lastKey, len, len1, len2, len3, lineCount, m, matches, mergeNode, n, name, parsed, parsedItem, parser, ref, ref1, ref2, refName, refValue, val, values;
  35. if (exceptionOnInvalidType == null) {
  36. exceptionOnInvalidType = false;
  37. }
  38. if (objectDecoder == null) {
  39. objectDecoder = null;
  40. }
  41. this.currentLineNb = -1;
  42. this.currentLine = '';
  43. this.lines = this.cleanup(value).split("\n");
  44. data = null;
  45. context = this.CONTEXT_NONE;
  46. allowOverwrite = false;
  47. while (this.moveToNextLine()) {
  48. if (this.isCurrentLineEmpty()) {
  49. continue;
  50. }
  51. if ("\t" === this.currentLine[0]) {
  52. throw new ParseException('A YAML file cannot contain tabs as indentation.', this.getRealCurrentLineNb() + 1, this.currentLine);
  53. }
  54. isRef = mergeNode = false;
  55. if (values = this.PATTERN_SEQUENCE_ITEM.exec(this.currentLine)) {
  56. if (this.CONTEXT_MAPPING === context) {
  57. throw new ParseException('You cannot define a sequence item when in a mapping');
  58. }
  59. context = this.CONTEXT_SEQUENCE;
  60. if (data == null) {
  61. data = [];
  62. }
  63. if ((values.value != null) && (matches = this.PATTERN_ANCHOR_VALUE.exec(values.value))) {
  64. isRef = matches.ref;
  65. values.value = matches.value;
  66. }
  67. if (!(values.value != null) || '' === Utils.trim(values.value, ' ') || Utils.ltrim(values.value, ' ').indexOf('#') === 0) {
  68. if (this.currentLineNb < this.lines.length - 1 && !this.isNextLineUnIndentedCollection()) {
  69. c = this.getRealCurrentLineNb() + 1;
  70. parser = new Parser(c);
  71. parser.refs = this.refs;
  72. data.push(parser.parse(this.getNextEmbedBlock(null, true), exceptionOnInvalidType, objectDecoder));
  73. } else {
  74. data.push(null);
  75. }
  76. } else {
  77. if (((ref = values.leadspaces) != null ? ref.length : void 0) && (matches = this.PATTERN_COMPACT_NOTATION.exec(values.value))) {
  78. c = this.getRealCurrentLineNb();
  79. parser = new Parser(c);
  80. parser.refs = this.refs;
  81. block = values.value;
  82. indent = this.getCurrentLineIndentation();
  83. if (this.isNextLineIndented(false)) {
  84. block += "\n" + this.getNextEmbedBlock(indent + values.leadspaces.length + 1, true);
  85. }
  86. data.push(parser.parse(block, exceptionOnInvalidType, objectDecoder));
  87. } else {
  88. data.push(this.parseValue(values.value, exceptionOnInvalidType, objectDecoder));
  89. }
  90. }
  91. } else if ((values = this.PATTERN_MAPPING_ITEM.exec(this.currentLine)) && values.key.indexOf(' #') === -1) {
  92. if (this.CONTEXT_SEQUENCE === context) {
  93. throw new ParseException('You cannot define a mapping item when in a sequence');
  94. }
  95. context = this.CONTEXT_MAPPING;
  96. if (data == null) {
  97. data = {};
  98. }
  99. Inline.configure(exceptionOnInvalidType, objectDecoder);
  100. try {
  101. key = Inline.parseScalar(values.key);
  102. } catch (error) {
  103. e = error;
  104. e.parsedLine = this.getRealCurrentLineNb() + 1;
  105. e.snippet = this.currentLine;
  106. throw e;
  107. }
  108. if ('<<' === key) {
  109. mergeNode = true;
  110. allowOverwrite = true;
  111. if (((ref1 = values.value) != null ? ref1.indexOf('*') : void 0) === 0) {
  112. refName = values.value.slice(1);
  113. if (this.refs[refName] == null) {
  114. throw new ParseException('Reference "' + refName + '" does not exist.', this.getRealCurrentLineNb() + 1, this.currentLine);
  115. }
  116. refValue = this.refs[refName];
  117. if (typeof refValue !== 'object') {
  118. throw new ParseException('YAML merge keys used with a scalar value instead of an object.', this.getRealCurrentLineNb() + 1, this.currentLine);
  119. }
  120. if (refValue instanceof Array) {
  121. for (i = j = 0, len = refValue.length; j < len; i = ++j) {
  122. value = refValue[i];
  123. if (data[name = String(i)] == null) {
  124. data[name] = value;
  125. }
  126. }
  127. } else {
  128. for (key in refValue) {
  129. value = refValue[key];
  130. if (data[key] == null) {
  131. data[key] = value;
  132. }
  133. }
  134. }
  135. } else {
  136. if ((values.value != null) && values.value !== '') {
  137. value = values.value;
  138. } else {
  139. value = this.getNextEmbedBlock();
  140. }
  141. c = this.getRealCurrentLineNb() + 1;
  142. parser = new Parser(c);
  143. parser.refs = this.refs;
  144. parsed = parser.parse(value, exceptionOnInvalidType);
  145. if (typeof parsed !== 'object') {
  146. throw new ParseException('YAML merge keys used with a scalar value instead of an object.', this.getRealCurrentLineNb() + 1, this.currentLine);
  147. }
  148. if (parsed instanceof Array) {
  149. for (l = 0, len1 = parsed.length; l < len1; l++) {
  150. parsedItem = parsed[l];
  151. if (typeof parsedItem !== 'object') {
  152. throw new ParseException('Merge items must be objects.', this.getRealCurrentLineNb() + 1, parsedItem);
  153. }
  154. if (parsedItem instanceof Array) {
  155. for (i = m = 0, len2 = parsedItem.length; m < len2; i = ++m) {
  156. value = parsedItem[i];
  157. k = String(i);
  158. if (!data.hasOwnProperty(k)) {
  159. data[k] = value;
  160. }
  161. }
  162. } else {
  163. for (key in parsedItem) {
  164. value = parsedItem[key];
  165. if (!data.hasOwnProperty(key)) {
  166. data[key] = value;
  167. }
  168. }
  169. }
  170. }
  171. } else {
  172. for (key in parsed) {
  173. value = parsed[key];
  174. if (!data.hasOwnProperty(key)) {
  175. data[key] = value;
  176. }
  177. }
  178. }
  179. }
  180. } else if ((values.value != null) && (matches = this.PATTERN_ANCHOR_VALUE.exec(values.value))) {
  181. isRef = matches.ref;
  182. values.value = matches.value;
  183. }
  184. if (mergeNode) {
  185. } else if (!(values.value != null) || '' === Utils.trim(values.value, ' ') || Utils.ltrim(values.value, ' ').indexOf('#') === 0) {
  186. if (!(this.isNextLineIndented()) && !(this.isNextLineUnIndentedCollection())) {
  187. if (allowOverwrite || data[key] === void 0) {
  188. data[key] = null;
  189. }
  190. } else {
  191. c = this.getRealCurrentLineNb() + 1;
  192. parser = new Parser(c);
  193. parser.refs = this.refs;
  194. val = parser.parse(this.getNextEmbedBlock(), exceptionOnInvalidType, objectDecoder);
  195. if (allowOverwrite || data[key] === void 0) {
  196. data[key] = val;
  197. }
  198. }
  199. } else {
  200. val = this.parseValue(values.value, exceptionOnInvalidType, objectDecoder);
  201. if (allowOverwrite || data[key] === void 0) {
  202. data[key] = val;
  203. }
  204. }
  205. } else {
  206. lineCount = this.lines.length;
  207. if (1 === lineCount || (2 === lineCount && Utils.isEmpty(this.lines[1]))) {
  208. try {
  209. value = Inline.parse(this.lines[0], exceptionOnInvalidType, objectDecoder);
  210. } catch (error) {
  211. e = error;
  212. e.parsedLine = this.getRealCurrentLineNb() + 1;
  213. e.snippet = this.currentLine;
  214. throw e;
  215. }
  216. if (typeof value === 'object') {
  217. if (value instanceof Array) {
  218. first = value[0];
  219. } else {
  220. for (key in value) {
  221. first = value[key];
  222. break;
  223. }
  224. }
  225. if (typeof first === 'string' && first.indexOf('*') === 0) {
  226. data = [];
  227. for (n = 0, len3 = value.length; n < len3; n++) {
  228. alias = value[n];
  229. data.push(this.refs[alias.slice(1)]);
  230. }
  231. value = data;
  232. }
  233. }
  234. return value;
  235. } else if ((ref2 = Utils.ltrim(value).charAt(0)) === '[' || ref2 === '{') {
  236. try {
  237. return Inline.parse(value, exceptionOnInvalidType, objectDecoder);
  238. } catch (error) {
  239. e = error;
  240. e.parsedLine = this.getRealCurrentLineNb() + 1;
  241. e.snippet = this.currentLine;
  242. throw e;
  243. }
  244. }
  245. throw new ParseException('Unable to parse.', this.getRealCurrentLineNb() + 1, this.currentLine);
  246. }
  247. if (isRef) {
  248. if (data instanceof Array) {
  249. this.refs[isRef] = data[data.length - 1];
  250. } else {
  251. lastKey = null;
  252. for (key in data) {
  253. lastKey = key;
  254. }
  255. this.refs[isRef] = data[lastKey];
  256. }
  257. }
  258. }
  259. if (Utils.isEmpty(data)) {
  260. return null;
  261. } else {
  262. return data;
  263. }
  264. };
  265. Parser.prototype.getRealCurrentLineNb = function() {
  266. return this.currentLineNb + this.offset;
  267. };
  268. Parser.prototype.getCurrentLineIndentation = function() {
  269. return this.currentLine.length - Utils.ltrim(this.currentLine, ' ').length;
  270. };
  271. Parser.prototype.getNextEmbedBlock = function(indentation, includeUnindentedCollection) {
  272. var data, indent, isItUnindentedCollection, newIndent, removeComments, removeCommentsPattern, unindentedEmbedBlock;
  273. if (indentation == null) {
  274. indentation = null;
  275. }
  276. if (includeUnindentedCollection == null) {
  277. includeUnindentedCollection = false;
  278. }
  279. this.moveToNextLine();
  280. if (indentation == null) {
  281. newIndent = this.getCurrentLineIndentation();
  282. unindentedEmbedBlock = this.isStringUnIndentedCollectionItem(this.currentLine);
  283. if (!(this.isCurrentLineEmpty()) && 0 === newIndent && !unindentedEmbedBlock) {
  284. throw new ParseException('Indentation problem.', this.getRealCurrentLineNb() + 1, this.currentLine);
  285. }
  286. } else {
  287. newIndent = indentation;
  288. }
  289. data = [this.currentLine.slice(newIndent)];
  290. if (!includeUnindentedCollection) {
  291. isItUnindentedCollection = this.isStringUnIndentedCollectionItem(this.currentLine);
  292. }
  293. removeCommentsPattern = this.PATTERN_FOLDED_SCALAR_END;
  294. removeComments = !removeCommentsPattern.test(this.currentLine);
  295. while (this.moveToNextLine()) {
  296. indent = this.getCurrentLineIndentation();
  297. if (indent === newIndent) {
  298. removeComments = !removeCommentsPattern.test(this.currentLine);
  299. }
  300. if (removeComments && this.isCurrentLineComment()) {
  301. continue;
  302. }
  303. if (this.isCurrentLineBlank()) {
  304. data.push(this.currentLine.slice(newIndent));
  305. continue;
  306. }
  307. if (isItUnindentedCollection && !this.isStringUnIndentedCollectionItem(this.currentLine) && indent === newIndent) {
  308. this.moveToPreviousLine();
  309. break;
  310. }
  311. if (indent >= newIndent) {
  312. data.push(this.currentLine.slice(newIndent));
  313. } else if (Utils.ltrim(this.currentLine).charAt(0) === '#') {
  314. } else if (0 === indent) {
  315. this.moveToPreviousLine();
  316. break;
  317. } else {
  318. throw new ParseException('Indentation problem.', this.getRealCurrentLineNb() + 1, this.currentLine);
  319. }
  320. }
  321. return data.join("\n");
  322. };
  323. Parser.prototype.moveToNextLine = function() {
  324. if (this.currentLineNb >= this.lines.length - 1) {
  325. return false;
  326. }
  327. this.currentLine = this.lines[++this.currentLineNb];
  328. return true;
  329. };
  330. Parser.prototype.moveToPreviousLine = function() {
  331. this.currentLine = this.lines[--this.currentLineNb];
  332. };
  333. Parser.prototype.parseValue = function(value, exceptionOnInvalidType, objectDecoder) {
  334. var e, foldedIndent, matches, modifiers, pos, ref, ref1, val;
  335. if (0 === value.indexOf('*')) {
  336. pos = value.indexOf('#');
  337. if (pos !== -1) {
  338. value = value.substr(1, pos - 2);
  339. } else {
  340. value = value.slice(1);
  341. }
  342. if (this.refs[value] === void 0) {
  343. throw new ParseException('Reference "' + value + '" does not exist.', this.currentLine);
  344. }
  345. return this.refs[value];
  346. }
  347. if (matches = this.PATTERN_FOLDED_SCALAR_ALL.exec(value)) {
  348. modifiers = (ref = matches.modifiers) != null ? ref : '';
  349. foldedIndent = Math.abs(parseInt(modifiers));
  350. if (isNaN(foldedIndent)) {
  351. foldedIndent = 0;
  352. }
  353. val = this.parseFoldedScalar(matches.separator, this.PATTERN_DECIMAL.replace(modifiers, ''), foldedIndent);
  354. if (matches.type != null) {
  355. Inline.configure(exceptionOnInvalidType, objectDecoder);
  356. return Inline.parseScalar(matches.type + ' ' + val);
  357. } else {
  358. return val;
  359. }
  360. }
  361. if ((ref1 = value.charAt(0)) === '[' || ref1 === '{' || ref1 === '"' || ref1 === "'") {
  362. while (true) {
  363. try {
  364. return Inline.parse(value, exceptionOnInvalidType, objectDecoder);
  365. } catch (error) {
  366. e = error;
  367. if (e instanceof ParseMore && this.moveToNextLine()) {
  368. value += "\n" + Utils.trim(this.currentLine, ' ');
  369. } else {
  370. e.parsedLine = this.getRealCurrentLineNb() + 1;
  371. e.snippet = this.currentLine;
  372. throw e;
  373. }
  374. }
  375. }
  376. } else {
  377. if (this.isNextLineIndented()) {
  378. value += "\n" + this.getNextEmbedBlock();
  379. }
  380. return Inline.parse(value, exceptionOnInvalidType, objectDecoder);
  381. }
  382. };
  383. Parser.prototype.parseFoldedScalar = function(separator, indicator, indentation) {
  384. var isCurrentLineBlank, j, len, line, matches, newText, notEOF, pattern, ref, text;
  385. if (indicator == null) {
  386. indicator = '';
  387. }
  388. if (indentation == null) {
  389. indentation = 0;
  390. }
  391. notEOF = this.moveToNextLine();
  392. if (!notEOF) {
  393. return '';
  394. }
  395. isCurrentLineBlank = this.isCurrentLineBlank();
  396. text = '';
  397. while (notEOF && isCurrentLineBlank) {
  398. if (notEOF = this.moveToNextLine()) {
  399. text += "\n";
  400. isCurrentLineBlank = this.isCurrentLineBlank();
  401. }
  402. }
  403. if (0 === indentation) {
  404. if (matches = this.PATTERN_INDENT_SPACES.exec(this.currentLine)) {
  405. indentation = matches[0].length;
  406. }
  407. }
  408. if (indentation > 0) {
  409. pattern = this.PATTERN_FOLDED_SCALAR_BY_INDENTATION[indentation];
  410. if (pattern == null) {
  411. pattern = new Pattern('^ {' + indentation + '}(.*)$');
  412. Parser.prototype.PATTERN_FOLDED_SCALAR_BY_INDENTATION[indentation] = pattern;
  413. }
  414. while (notEOF && (isCurrentLineBlank || (matches = pattern.exec(this.currentLine)))) {
  415. if (isCurrentLineBlank) {
  416. text += this.currentLine.slice(indentation);
  417. } else {
  418. text += matches[1];
  419. }
  420. if (notEOF = this.moveToNextLine()) {
  421. text += "\n";
  422. isCurrentLineBlank = this.isCurrentLineBlank();
  423. }
  424. }
  425. } else if (notEOF) {
  426. text += "\n";
  427. }
  428. if (notEOF) {
  429. this.moveToPreviousLine();
  430. }
  431. if ('>' === separator) {
  432. newText = '';
  433. ref = text.split("\n");
  434. for (j = 0, len = ref.length; j < len; j++) {
  435. line = ref[j];
  436. if (line.length === 0 || line.charAt(0) === ' ') {
  437. newText = Utils.rtrim(newText, ' ') + line + "\n";
  438. } else {
  439. newText += line + ' ';
  440. }
  441. }
  442. text = newText;
  443. }
  444. if ('+' !== indicator) {
  445. text = Utils.rtrim(text);
  446. }
  447. if ('' === indicator) {
  448. text = this.PATTERN_TRAILING_LINES.replace(text, "\n");
  449. } else if ('-' === indicator) {
  450. text = this.PATTERN_TRAILING_LINES.replace(text, '');
  451. }
  452. return text;
  453. };
  454. Parser.prototype.isNextLineIndented = function(ignoreComments) {
  455. var EOF, currentIndentation, ret;
  456. if (ignoreComments == null) {
  457. ignoreComments = true;
  458. }
  459. currentIndentation = this.getCurrentLineIndentation();
  460. EOF = !this.moveToNextLine();
  461. if (ignoreComments) {
  462. while (!EOF && this.isCurrentLineEmpty()) {
  463. EOF = !this.moveToNextLine();
  464. }
  465. } else {
  466. while (!EOF && this.isCurrentLineBlank()) {
  467. EOF = !this.moveToNextLine();
  468. }
  469. }
  470. if (EOF) {
  471. return false;
  472. }
  473. ret = false;
  474. if (this.getCurrentLineIndentation() > currentIndentation) {
  475. ret = true;
  476. }
  477. this.moveToPreviousLine();
  478. return ret;
  479. };
  480. Parser.prototype.isCurrentLineEmpty = function() {
  481. var trimmedLine;
  482. trimmedLine = Utils.trim(this.currentLine, ' ');
  483. return trimmedLine.length === 0 || trimmedLine.charAt(0) === '#';
  484. };
  485. Parser.prototype.isCurrentLineBlank = function() {
  486. return '' === Utils.trim(this.currentLine, ' ');
  487. };
  488. Parser.prototype.isCurrentLineComment = function() {
  489. var ltrimmedLine;
  490. ltrimmedLine = Utils.ltrim(this.currentLine, ' ');
  491. return ltrimmedLine.charAt(0) === '#';
  492. };
  493. Parser.prototype.cleanup = function(value) {
  494. var count, i, indent, j, l, len, len1, line, lines, ref, ref1, ref2, smallestIndent, trimmedValue;
  495. if (value.indexOf("\r") !== -1) {
  496. value = value.split("\r\n").join("\n").split("\r").join("\n");
  497. }
  498. count = 0;
  499. ref = this.PATTERN_YAML_HEADER.replaceAll(value, ''), value = ref[0], count = ref[1];
  500. this.offset += count;
  501. ref1 = this.PATTERN_LEADING_COMMENTS.replaceAll(value, '', 1), trimmedValue = ref1[0], count = ref1[1];
  502. if (count === 1) {
  503. this.offset += Utils.subStrCount(value, "\n") - Utils.subStrCount(trimmedValue, "\n");
  504. value = trimmedValue;
  505. }
  506. ref2 = this.PATTERN_DOCUMENT_MARKER_START.replaceAll(value, '', 1), trimmedValue = ref2[0], count = ref2[1];
  507. if (count === 1) {
  508. this.offset += Utils.subStrCount(value, "\n") - Utils.subStrCount(trimmedValue, "\n");
  509. value = trimmedValue;
  510. value = this.PATTERN_DOCUMENT_MARKER_END.replace(value, '');
  511. }
  512. lines = value.split("\n");
  513. smallestIndent = -1;
  514. for (j = 0, len = lines.length; j < len; j++) {
  515. line = lines[j];
  516. if (Utils.trim(line, ' ').length === 0) {
  517. continue;
  518. }
  519. indent = line.length - Utils.ltrim(line).length;
  520. if (smallestIndent === -1 || indent < smallestIndent) {
  521. smallestIndent = indent;
  522. }
  523. }
  524. if (smallestIndent > 0) {
  525. for (i = l = 0, len1 = lines.length; l < len1; i = ++l) {
  526. line = lines[i];
  527. lines[i] = line.slice(smallestIndent);
  528. }
  529. value = lines.join("\n");
  530. }
  531. return value;
  532. };
  533. Parser.prototype.isNextLineUnIndentedCollection = function(currentIndentation) {
  534. var notEOF, ret;
  535. if (currentIndentation == null) {
  536. currentIndentation = null;
  537. }
  538. if (currentIndentation == null) {
  539. currentIndentation = this.getCurrentLineIndentation();
  540. }
  541. notEOF = this.moveToNextLine();
  542. while (notEOF && this.isCurrentLineEmpty()) {
  543. notEOF = this.moveToNextLine();
  544. }
  545. if (false === notEOF) {
  546. return false;
  547. }
  548. ret = false;
  549. if (this.getCurrentLineIndentation() === currentIndentation && this.isStringUnIndentedCollectionItem(this.currentLine)) {
  550. ret = true;
  551. }
  552. this.moveToPreviousLine();
  553. return ret;
  554. };
  555. Parser.prototype.isStringUnIndentedCollectionItem = function() {
  556. return this.currentLine === '-' || this.currentLine.slice(0, 2) === '- ';
  557. };
  558. return Parser;
  559. })();
  560. module.exports = Parser;