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.

stringify.js 10KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337
  1. "use strict";
  2. var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard");
  3. Object.defineProperty(exports, "__esModule", {
  4. value: true
  5. });
  6. exports.stringifyNumber = stringifyNumber;
  7. exports.stringifyString = stringifyString;
  8. var _addComment = require("./addComment");
  9. var _constants = require("./constants");
  10. var _foldFlowLines = _interopRequireWildcard(require("./foldFlowLines"));
  11. var _options = require("./tags/options");
  12. function stringifyNumber(_ref) {
  13. var format = _ref.format,
  14. minFractionDigits = _ref.minFractionDigits,
  15. tag = _ref.tag,
  16. value = _ref.value;
  17. if (!isFinite(value)) return isNaN(value) ? '.nan' : value < 0 ? '-.inf' : '.inf';
  18. var n = JSON.stringify(value);
  19. if (!format && minFractionDigits && (!tag || tag === 'tag:yaml.org,2002:float') && /^\d/.test(n)) {
  20. var i = n.indexOf('.');
  21. if (i < 0) {
  22. i = n.length;
  23. n += '.';
  24. }
  25. var d = minFractionDigits - (n.length - i - 1);
  26. while (d-- > 0) {
  27. n += '0';
  28. }
  29. }
  30. return n;
  31. }
  32. function lineLengthOverLimit(str, limit) {
  33. var strLen = str.length;
  34. if (strLen <= limit) return false;
  35. for (var i = 0, start = 0; i < strLen; ++i) {
  36. if (str[i] === '\n') {
  37. if (i - start > limit) return true;
  38. start = i + 1;
  39. if (strLen - start <= limit) return false;
  40. }
  41. }
  42. return true;
  43. }
  44. function doubleQuotedString(value, _ref2) {
  45. var implicitKey = _ref2.implicitKey,
  46. indent = _ref2.indent;
  47. var _strOptions$doubleQuo = _options.strOptions.doubleQuoted,
  48. jsonEncoding = _strOptions$doubleQuo.jsonEncoding,
  49. minMultiLineLength = _strOptions$doubleQuo.minMultiLineLength;
  50. var json = JSON.stringify(value);
  51. if (jsonEncoding) return json;
  52. var str = '';
  53. var start = 0;
  54. for (var i = 0, ch = json[i]; ch; ch = json[++i]) {
  55. if (ch === ' ' && json[i + 1] === '\\' && json[i + 2] === 'n') {
  56. // space before newline needs to be escaped to not be folded
  57. str += json.slice(start, i) + '\\ ';
  58. i += 1;
  59. start = i;
  60. ch = '\\';
  61. }
  62. if (ch === '\\') switch (json[i + 1]) {
  63. case 'u':
  64. {
  65. str += json.slice(start, i);
  66. var code = json.substr(i + 2, 4);
  67. switch (code) {
  68. case '0000':
  69. str += '\\0';
  70. break;
  71. case '0007':
  72. str += '\\a';
  73. break;
  74. case '000b':
  75. str += '\\v';
  76. break;
  77. case '001b':
  78. str += '\\e';
  79. break;
  80. case '0085':
  81. str += '\\N';
  82. break;
  83. case '00a0':
  84. str += '\\_';
  85. break;
  86. case '2028':
  87. str += '\\L';
  88. break;
  89. case '2029':
  90. str += '\\P';
  91. break;
  92. default:
  93. if (code.substr(0, 2) === '00') str += '\\x' + code.substr(2);else str += json.substr(i, 6);
  94. }
  95. i += 5;
  96. start = i + 1;
  97. }
  98. break;
  99. case 'n':
  100. if (implicitKey || json[i + 2] === '"' || json.length < minMultiLineLength) {
  101. i += 1;
  102. } else {
  103. // folding will eat first newline
  104. str += json.slice(start, i) + '\n\n';
  105. while (json[i + 2] === '\\' && json[i + 3] === 'n' && json[i + 4] !== '"') {
  106. str += '\n';
  107. i += 2;
  108. }
  109. str += indent; // space after newline needs to be escaped to not be folded
  110. if (json[i + 2] === ' ') str += '\\';
  111. i += 1;
  112. start = i + 1;
  113. }
  114. break;
  115. default:
  116. i += 1;
  117. }
  118. }
  119. str = start ? str + json.slice(start) : json;
  120. return implicitKey ? str : (0, _foldFlowLines.default)(str, indent, _foldFlowLines.FOLD_QUOTED, _options.strOptions.fold);
  121. }
  122. function singleQuotedString(value, ctx) {
  123. var indent = ctx.indent,
  124. implicitKey = ctx.implicitKey;
  125. if (implicitKey) {
  126. if (/\n/.test(value)) return doubleQuotedString(value, ctx);
  127. } else {
  128. // single quoted string can't have leading or trailing whitespace around newline
  129. if (/[ \t]\n|\n[ \t]/.test(value)) return doubleQuotedString(value, ctx);
  130. }
  131. var res = "'" + value.replace(/'/g, "''").replace(/\n+/g, "$&\n".concat(indent)) + "'";
  132. return implicitKey ? res : (0, _foldFlowLines.default)(res, indent, _foldFlowLines.FOLD_FLOW, _options.strOptions.fold);
  133. }
  134. function blockString(_ref3, ctx, onComment, onChompKeep) {
  135. var comment = _ref3.comment,
  136. type = _ref3.type,
  137. value = _ref3.value;
  138. // 1. Block can't end in whitespace unless the last line is non-empty.
  139. // 2. Strings consisting of only whitespace are best rendered explicitly.
  140. if (/\n[\t ]+$/.test(value) || /^\s*$/.test(value)) {
  141. return doubleQuotedString(value, ctx);
  142. }
  143. var indent = ctx.indent || (ctx.forceBlockIndent ? ' ' : '');
  144. var indentSize = indent ? '2' : '1'; // root is at -1
  145. var literal = type === _constants.Type.BLOCK_FOLDED ? false : type === _constants.Type.BLOCK_LITERAL ? true : !lineLengthOverLimit(value, _options.strOptions.fold.lineWidth - indent.length);
  146. var header = literal ? '|' : '>';
  147. if (!value) return header + '\n';
  148. var wsStart = '';
  149. var wsEnd = '';
  150. value = value.replace(/[\n\t ]*$/, function (ws) {
  151. var n = ws.indexOf('\n');
  152. if (n === -1) {
  153. header += '-'; // strip
  154. } else if (value === ws || n !== ws.length - 1) {
  155. header += '+'; // keep
  156. if (onChompKeep) onChompKeep();
  157. }
  158. wsEnd = ws.replace(/\n$/, '');
  159. return '';
  160. }).replace(/^[\n ]*/, function (ws) {
  161. if (ws.indexOf(' ') !== -1) header += indentSize;
  162. var m = ws.match(/ +$/);
  163. if (m) {
  164. wsStart = ws.slice(0, -m[0].length);
  165. return m[0];
  166. } else {
  167. wsStart = ws;
  168. return '';
  169. }
  170. });
  171. if (wsEnd) wsEnd = wsEnd.replace(/\n+(?!\n|$)/g, "$&".concat(indent));
  172. if (wsStart) wsStart = wsStart.replace(/\n+/g, "$&".concat(indent));
  173. if (comment) {
  174. header += ' #' + comment.replace(/ ?[\r\n]+/g, ' ');
  175. if (onComment) onComment();
  176. }
  177. if (!value) return "".concat(header).concat(indentSize, "\n").concat(indent).concat(wsEnd);
  178. if (literal) {
  179. value = value.replace(/\n+/g, "$&".concat(indent));
  180. return "".concat(header, "\n").concat(indent).concat(wsStart).concat(value).concat(wsEnd);
  181. }
  182. value = value.replace(/\n+/g, '\n$&').replace(/(?:^|\n)([\t ].*)(?:([\n\t ]*)\n(?![\n\t ]))?/g, '$1$2') // more-indented lines aren't folded
  183. // ^ ind.line ^ empty ^ capture next empty lines only at end of indent
  184. .replace(/\n+/g, "$&".concat(indent));
  185. var body = (0, _foldFlowLines.default)("".concat(wsStart).concat(value).concat(wsEnd), indent, _foldFlowLines.FOLD_BLOCK, _options.strOptions.fold);
  186. return "".concat(header, "\n").concat(indent).concat(body);
  187. }
  188. function plainString(item, ctx, onComment, onChompKeep) {
  189. var comment = item.comment,
  190. type = item.type,
  191. value = item.value;
  192. var actualString = ctx.actualString,
  193. implicitKey = ctx.implicitKey,
  194. indent = ctx.indent,
  195. inFlow = ctx.inFlow,
  196. tags = ctx.tags;
  197. if (implicitKey && /[\n[\]{},]/.test(value) || inFlow && /[[\]{},]/.test(value)) {
  198. return doubleQuotedString(value, ctx);
  199. }
  200. if (!value || /^[\n\t ,[\]{}#&*!|>'"%@`]|^[?-]$|^[?-][ \t]|[\n:][ \t]|[ \t]\n|[\n\t ]#|[\n\t :]$/.test(value)) {
  201. // not allowed:
  202. // - empty string, '-' or '?'
  203. // - start with an indicator character (except [?:-]) or /[?-] /
  204. // - '\n ', ': ' or ' \n' anywhere
  205. // - '#' not preceded by a non-space char
  206. // - end with ' ' or ':'
  207. return implicitKey || inFlow || value.indexOf('\n') === -1 ? value.indexOf('"') !== -1 && value.indexOf("'") === -1 ? singleQuotedString(value, ctx) : doubleQuotedString(value, ctx) : blockString(item, ctx, onComment, onChompKeep);
  208. }
  209. if (!implicitKey && !inFlow && type !== _constants.Type.PLAIN && value.indexOf('\n') !== -1) {
  210. // Where allowed & type not set explicitly, prefer block style for multiline strings
  211. return blockString(item, ctx, onComment, onChompKeep);
  212. }
  213. var str = value.replace(/\n+/g, "$&\n".concat(indent)); // Verify that output will be parsed as a string, as e.g. plain numbers and
  214. // booleans get parsed with those types in v1.2 (e.g. '42', 'true' & '0.9e-3'),
  215. // and others in v1.1.
  216. if (actualString && typeof tags.resolveScalar(str).value !== 'string') {
  217. return doubleQuotedString(value, ctx);
  218. }
  219. var body = implicitKey ? str : (0, _foldFlowLines.default)(str, indent, _foldFlowLines.FOLD_FLOW, _options.strOptions.fold);
  220. if (comment && !inFlow && (body.indexOf('\n') !== -1 || comment.indexOf('\n') !== -1)) {
  221. if (onComment) onComment();
  222. return (0, _addComment.addCommentBefore)(body, indent, comment);
  223. }
  224. return body;
  225. }
  226. function stringifyString(item, ctx, onComment, onChompKeep) {
  227. var defaultType = _options.strOptions.defaultType;
  228. var implicitKey = ctx.implicitKey,
  229. inFlow = ctx.inFlow;
  230. var _item = item,
  231. type = _item.type,
  232. value = _item.value;
  233. if (typeof value !== 'string') {
  234. value = String(value);
  235. item = Object.assign({}, item, {
  236. value: value
  237. });
  238. }
  239. var _stringify = function _stringify(_type) {
  240. switch (_type) {
  241. case _constants.Type.BLOCK_FOLDED:
  242. case _constants.Type.BLOCK_LITERAL:
  243. return blockString(item, ctx, onComment, onChompKeep);
  244. case _constants.Type.QUOTE_DOUBLE:
  245. return doubleQuotedString(value, ctx);
  246. case _constants.Type.QUOTE_SINGLE:
  247. return singleQuotedString(value, ctx);
  248. case _constants.Type.PLAIN:
  249. return plainString(item, ctx, onComment, onChompKeep);
  250. default:
  251. return null;
  252. }
  253. };
  254. if (type !== _constants.Type.QUOTE_DOUBLE && /[\x00-\x08\x0b-\x1f\x7f-\x9f]/.test(value)) {
  255. // force double quotes on control characters
  256. type = _constants.Type.QUOTE_DOUBLE;
  257. } else if ((implicitKey || inFlow) && (type === _constants.Type.BLOCK_FOLDED || type === _constants.Type.BLOCK_LITERAL)) {
  258. // should not happen; blocks are not valid inside flow containers
  259. type = _constants.Type.QUOTE_DOUBLE;
  260. }
  261. var res = _stringify(type);
  262. if (res === null) {
  263. res = _stringify(defaultType);
  264. if (res === null) throw new Error("Unsupported default string type ".concat(defaultType));
  265. }
  266. return res;
  267. }