Inline.js 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485
  1. // Generated by CoffeeScript 1.12.4
  2. var DumpException, Escaper, Inline, ParseException, ParseMore, Pattern, Unescaper, Utils,
  3. indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
  4. Pattern = require('./Pattern');
  5. Unescaper = require('./Unescaper');
  6. Escaper = require('./Escaper');
  7. Utils = require('./Utils');
  8. ParseException = require('./Exception/ParseException');
  9. ParseMore = require('./Exception/ParseMore');
  10. DumpException = require('./Exception/DumpException');
  11. Inline = (function() {
  12. function Inline() {}
  13. Inline.REGEX_QUOTED_STRING = '(?:"(?:[^"\\\\]*(?:\\\\.[^"\\\\]*)*)"|\'(?:[^\']*(?:\'\'[^\']*)*)\')';
  14. Inline.PATTERN_TRAILING_COMMENTS = new Pattern('^\\s*#.*$');
  15. Inline.PATTERN_QUOTED_SCALAR = new Pattern('^' + Inline.REGEX_QUOTED_STRING);
  16. Inline.PATTERN_THOUSAND_NUMERIC_SCALAR = new Pattern('^(-|\\+)?[0-9,]+(\\.[0-9]+)?$');
  17. Inline.PATTERN_SCALAR_BY_DELIMITERS = {};
  18. Inline.settings = {};
  19. Inline.configure = function(exceptionOnInvalidType, objectDecoder) {
  20. if (exceptionOnInvalidType == null) {
  21. exceptionOnInvalidType = null;
  22. }
  23. if (objectDecoder == null) {
  24. objectDecoder = null;
  25. }
  26. this.settings.exceptionOnInvalidType = exceptionOnInvalidType;
  27. this.settings.objectDecoder = objectDecoder;
  28. };
  29. Inline.parse = function(value, exceptionOnInvalidType, objectDecoder) {
  30. var context, result;
  31. if (exceptionOnInvalidType == null) {
  32. exceptionOnInvalidType = false;
  33. }
  34. if (objectDecoder == null) {
  35. objectDecoder = null;
  36. }
  37. this.settings.exceptionOnInvalidType = exceptionOnInvalidType;
  38. this.settings.objectDecoder = objectDecoder;
  39. if (value == null) {
  40. return '';
  41. }
  42. value = Utils.trim(value);
  43. if (0 === value.length) {
  44. return '';
  45. }
  46. context = {
  47. exceptionOnInvalidType: exceptionOnInvalidType,
  48. objectDecoder: objectDecoder,
  49. i: 0
  50. };
  51. switch (value.charAt(0)) {
  52. case '[':
  53. result = this.parseSequence(value, context);
  54. ++context.i;
  55. break;
  56. case '{':
  57. result = this.parseMapping(value, context);
  58. ++context.i;
  59. break;
  60. default:
  61. result = this.parseScalar(value, null, ['"', "'"], context);
  62. }
  63. if (this.PATTERN_TRAILING_COMMENTS.replace(value.slice(context.i), '') !== '') {
  64. throw new ParseException('Unexpected characters near "' + value.slice(context.i) + '".');
  65. }
  66. return result;
  67. };
  68. Inline.dump = function(value, exceptionOnInvalidType, objectEncoder) {
  69. var ref, result, type;
  70. if (exceptionOnInvalidType == null) {
  71. exceptionOnInvalidType = false;
  72. }
  73. if (objectEncoder == null) {
  74. objectEncoder = null;
  75. }
  76. if (value == null) {
  77. return 'null';
  78. }
  79. type = typeof value;
  80. if (type === 'object') {
  81. if (value instanceof Date) {
  82. return value.toISOString();
  83. } else if (objectEncoder != null) {
  84. result = objectEncoder(value);
  85. if (typeof result === 'string' || (result != null)) {
  86. return result;
  87. }
  88. }
  89. return this.dumpObject(value);
  90. }
  91. if (type === 'boolean') {
  92. return (value ? 'true' : 'false');
  93. }
  94. if (Utils.isDigits(value)) {
  95. return (type === 'string' ? "'" + value + "'" : String(parseInt(value)));
  96. }
  97. if (Utils.isNumeric(value)) {
  98. return (type === 'string' ? "'" + value + "'" : String(parseFloat(value)));
  99. }
  100. if (type === 'number') {
  101. return (value === 2e308 ? '.Inf' : (value === -2e308 ? '-.Inf' : (isNaN(value) ? '.NaN' : value)));
  102. }
  103. if (Escaper.requiresDoubleQuoting(value)) {
  104. return Escaper.escapeWithDoubleQuotes(value);
  105. }
  106. if (Escaper.requiresSingleQuoting(value)) {
  107. return Escaper.escapeWithSingleQuotes(value);
  108. }
  109. if ('' === value) {
  110. return '""';
  111. }
  112. if (Utils.PATTERN_DATE.test(value)) {
  113. return "'" + value + "'";
  114. }
  115. if ((ref = value.toLowerCase()) === 'null' || ref === '~' || ref === 'true' || ref === 'false') {
  116. return "'" + value + "'";
  117. }
  118. return value;
  119. };
  120. Inline.dumpObject = function(value, exceptionOnInvalidType, objectSupport) {
  121. var j, key, len1, output, val;
  122. if (objectSupport == null) {
  123. objectSupport = null;
  124. }
  125. if (value instanceof Array) {
  126. output = [];
  127. for (j = 0, len1 = value.length; j < len1; j++) {
  128. val = value[j];
  129. output.push(this.dump(val));
  130. }
  131. return '[' + output.join(', ') + ']';
  132. } else {
  133. output = [];
  134. for (key in value) {
  135. val = value[key];
  136. output.push(this.dump(key) + ': ' + this.dump(val));
  137. }
  138. return '{' + output.join(', ') + '}';
  139. }
  140. };
  141. Inline.parseScalar = function(scalar, delimiters, stringDelimiters, context, evaluate) {
  142. var i, joinedDelimiters, match, output, pattern, ref, ref1, strpos, tmp;
  143. if (delimiters == null) {
  144. delimiters = null;
  145. }
  146. if (stringDelimiters == null) {
  147. stringDelimiters = ['"', "'"];
  148. }
  149. if (context == null) {
  150. context = null;
  151. }
  152. if (evaluate == null) {
  153. evaluate = true;
  154. }
  155. if (context == null) {
  156. context = {
  157. exceptionOnInvalidType: this.settings.exceptionOnInvalidType,
  158. objectDecoder: this.settings.objectDecoder,
  159. i: 0
  160. };
  161. }
  162. i = context.i;
  163. if (ref = scalar.charAt(i), indexOf.call(stringDelimiters, ref) >= 0) {
  164. output = this.parseQuotedScalar(scalar, context);
  165. i = context.i;
  166. if (delimiters != null) {
  167. tmp = Utils.ltrim(scalar.slice(i), ' ');
  168. if (!(ref1 = tmp.charAt(0), indexOf.call(delimiters, ref1) >= 0)) {
  169. throw new ParseException('Unexpected characters (' + scalar.slice(i) + ').');
  170. }
  171. }
  172. } else {
  173. if (!delimiters) {
  174. output = scalar.slice(i);
  175. i += output.length;
  176. strpos = output.indexOf(' #');
  177. if (strpos !== -1) {
  178. output = Utils.rtrim(output.slice(0, strpos));
  179. }
  180. } else {
  181. joinedDelimiters = delimiters.join('|');
  182. pattern = this.PATTERN_SCALAR_BY_DELIMITERS[joinedDelimiters];
  183. if (pattern == null) {
  184. pattern = new Pattern('^(.+?)(' + joinedDelimiters + ')');
  185. this.PATTERN_SCALAR_BY_DELIMITERS[joinedDelimiters] = pattern;
  186. }
  187. if (match = pattern.exec(scalar.slice(i))) {
  188. output = match[1];
  189. i += output.length;
  190. } else {
  191. throw new ParseException('Malformed inline YAML string (' + scalar + ').');
  192. }
  193. }
  194. if (evaluate) {
  195. output = this.evaluateScalar(output, context);
  196. }
  197. }
  198. context.i = i;
  199. return output;
  200. };
  201. Inline.parseQuotedScalar = function(scalar, context) {
  202. var i, match, output;
  203. i = context.i;
  204. if (!(match = this.PATTERN_QUOTED_SCALAR.exec(scalar.slice(i)))) {
  205. throw new ParseMore('Malformed inline YAML string (' + scalar.slice(i) + ').');
  206. }
  207. output = match[0].substr(1, match[0].length - 2);
  208. if ('"' === scalar.charAt(i)) {
  209. output = Unescaper.unescapeDoubleQuotedString(output);
  210. } else {
  211. output = Unescaper.unescapeSingleQuotedString(output);
  212. }
  213. i += match[0].length;
  214. context.i = i;
  215. return output;
  216. };
  217. Inline.parseSequence = function(sequence, context) {
  218. var e, i, isQuoted, len, output, ref, value;
  219. output = [];
  220. len = sequence.length;
  221. i = context.i;
  222. i += 1;
  223. while (i < len) {
  224. context.i = i;
  225. switch (sequence.charAt(i)) {
  226. case '[':
  227. output.push(this.parseSequence(sequence, context));
  228. i = context.i;
  229. break;
  230. case '{':
  231. output.push(this.parseMapping(sequence, context));
  232. i = context.i;
  233. break;
  234. case ']':
  235. return output;
  236. case ',':
  237. case ' ':
  238. case "\n":
  239. break;
  240. default:
  241. isQuoted = ((ref = sequence.charAt(i)) === '"' || ref === "'");
  242. value = this.parseScalar(sequence, [',', ']'], ['"', "'"], context);
  243. i = context.i;
  244. if (!isQuoted && typeof value === 'string' && (value.indexOf(': ') !== -1 || value.indexOf(":\n") !== -1)) {
  245. try {
  246. value = this.parseMapping('{' + value + '}');
  247. } catch (error) {
  248. e = error;
  249. }
  250. }
  251. output.push(value);
  252. --i;
  253. }
  254. ++i;
  255. }
  256. throw new ParseMore('Malformed inline YAML string ' + sequence);
  257. };
  258. Inline.parseMapping = function(mapping, context) {
  259. var done, i, key, len, output, shouldContinueWhileLoop, value;
  260. output = {};
  261. len = mapping.length;
  262. i = context.i;
  263. i += 1;
  264. shouldContinueWhileLoop = false;
  265. while (i < len) {
  266. context.i = i;
  267. switch (mapping.charAt(i)) {
  268. case ' ':
  269. case ',':
  270. case "\n":
  271. ++i;
  272. context.i = i;
  273. shouldContinueWhileLoop = true;
  274. break;
  275. case '}':
  276. return output;
  277. }
  278. if (shouldContinueWhileLoop) {
  279. shouldContinueWhileLoop = false;
  280. continue;
  281. }
  282. key = this.parseScalar(mapping, [':', ' ', "\n"], ['"', "'"], context, false);
  283. i = context.i;
  284. done = false;
  285. while (i < len) {
  286. context.i = i;
  287. switch (mapping.charAt(i)) {
  288. case '[':
  289. value = this.parseSequence(mapping, context);
  290. i = context.i;
  291. if (output[key] === void 0) {
  292. output[key] = value;
  293. }
  294. done = true;
  295. break;
  296. case '{':
  297. value = this.parseMapping(mapping, context);
  298. i = context.i;
  299. if (output[key] === void 0) {
  300. output[key] = value;
  301. }
  302. done = true;
  303. break;
  304. case ':':
  305. case ' ':
  306. case "\n":
  307. break;
  308. default:
  309. value = this.parseScalar(mapping, [',', '}'], ['"', "'"], context);
  310. i = context.i;
  311. if (output[key] === void 0) {
  312. output[key] = value;
  313. }
  314. done = true;
  315. --i;
  316. }
  317. ++i;
  318. if (done) {
  319. break;
  320. }
  321. }
  322. }
  323. throw new ParseMore('Malformed inline YAML string ' + mapping);
  324. };
  325. Inline.evaluateScalar = function(scalar, context) {
  326. var cast, date, exceptionOnInvalidType, firstChar, firstSpace, firstWord, objectDecoder, raw, scalarLower, subValue, trimmedScalar;
  327. scalar = Utils.trim(scalar);
  328. scalarLower = scalar.toLowerCase();
  329. switch (scalarLower) {
  330. case 'null':
  331. case '':
  332. case '~':
  333. return null;
  334. case 'true':
  335. return true;
  336. case 'false':
  337. return false;
  338. case '.inf':
  339. return 2e308;
  340. case '.nan':
  341. return 0/0;
  342. case '-.inf':
  343. return 2e308;
  344. default:
  345. firstChar = scalarLower.charAt(0);
  346. switch (firstChar) {
  347. case '!':
  348. firstSpace = scalar.indexOf(' ');
  349. if (firstSpace === -1) {
  350. firstWord = scalarLower;
  351. } else {
  352. firstWord = scalarLower.slice(0, firstSpace);
  353. }
  354. switch (firstWord) {
  355. case '!':
  356. if (firstSpace !== -1) {
  357. return parseInt(this.parseScalar(scalar.slice(2)));
  358. }
  359. return null;
  360. case '!str':
  361. return Utils.ltrim(scalar.slice(4));
  362. case '!!str':
  363. return Utils.ltrim(scalar.slice(5));
  364. case '!!int':
  365. return parseInt(this.parseScalar(scalar.slice(5)));
  366. case '!!bool':
  367. return Utils.parseBoolean(this.parseScalar(scalar.slice(6)), false);
  368. case '!!float':
  369. return parseFloat(this.parseScalar(scalar.slice(7)));
  370. case '!!timestamp':
  371. return Utils.stringToDate(Utils.ltrim(scalar.slice(11)));
  372. default:
  373. if (context == null) {
  374. context = {
  375. exceptionOnInvalidType: this.settings.exceptionOnInvalidType,
  376. objectDecoder: this.settings.objectDecoder,
  377. i: 0
  378. };
  379. }
  380. objectDecoder = context.objectDecoder, exceptionOnInvalidType = context.exceptionOnInvalidType;
  381. if (objectDecoder) {
  382. trimmedScalar = Utils.rtrim(scalar);
  383. firstSpace = trimmedScalar.indexOf(' ');
  384. if (firstSpace === -1) {
  385. return objectDecoder(trimmedScalar, null);
  386. } else {
  387. subValue = Utils.ltrim(trimmedScalar.slice(firstSpace + 1));
  388. if (!(subValue.length > 0)) {
  389. subValue = null;
  390. }
  391. return objectDecoder(trimmedScalar.slice(0, firstSpace), subValue);
  392. }
  393. }
  394. if (exceptionOnInvalidType) {
  395. throw new ParseException('Custom object support when parsing a YAML file has been disabled.');
  396. }
  397. return null;
  398. }
  399. break;
  400. case '0':
  401. if ('0x' === scalar.slice(0, 2)) {
  402. return Utils.hexDec(scalar);
  403. } else if (Utils.isDigits(scalar)) {
  404. return Utils.octDec(scalar);
  405. } else if (Utils.isNumeric(scalar)) {
  406. return parseFloat(scalar);
  407. } else {
  408. return scalar;
  409. }
  410. break;
  411. case '+':
  412. if (Utils.isDigits(scalar)) {
  413. raw = scalar;
  414. cast = parseInt(raw);
  415. if (raw === String(cast)) {
  416. return cast;
  417. } else {
  418. return raw;
  419. }
  420. } else if (Utils.isNumeric(scalar)) {
  421. return parseFloat(scalar);
  422. } else if (this.PATTERN_THOUSAND_NUMERIC_SCALAR.test(scalar)) {
  423. return parseFloat(scalar.replace(',', ''));
  424. }
  425. return scalar;
  426. case '-':
  427. if (Utils.isDigits(scalar.slice(1))) {
  428. if ('0' === scalar.charAt(1)) {
  429. return -Utils.octDec(scalar.slice(1));
  430. } else {
  431. raw = scalar.slice(1);
  432. cast = parseInt(raw);
  433. if (raw === String(cast)) {
  434. return -cast;
  435. } else {
  436. return -raw;
  437. }
  438. }
  439. } else if (Utils.isNumeric(scalar)) {
  440. return parseFloat(scalar);
  441. } else if (this.PATTERN_THOUSAND_NUMERIC_SCALAR.test(scalar)) {
  442. return parseFloat(scalar.replace(',', ''));
  443. }
  444. return scalar;
  445. default:
  446. if (date = Utils.stringToDate(scalar)) {
  447. return date;
  448. } else if (Utils.isNumeric(scalar)) {
  449. return parseFloat(scalar);
  450. } else if (this.PATTERN_THOUSAND_NUMERIC_SCALAR.test(scalar)) {
  451. return parseFloat(scalar.replace(',', ''));
  452. }
  453. return scalar;
  454. }
  455. }
  456. };
  457. return Inline;
  458. })();
  459. module.exports = Inline;