Inline.js 15 KB

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