stringifyDocument.js 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. 'use strict';
  2. var identity = require('../nodes/identity.js');
  3. var stringify = require('./stringify.js');
  4. var stringifyComment = require('./stringifyComment.js');
  5. function stringifyDocument(doc, options) {
  6. const lines = [];
  7. let hasDirectives = options.directives === true;
  8. if (options.directives !== false && doc.directives) {
  9. const dir = doc.directives.toString(doc);
  10. if (dir) {
  11. lines.push(dir);
  12. hasDirectives = true;
  13. }
  14. else if (doc.directives.docStart)
  15. hasDirectives = true;
  16. }
  17. if (hasDirectives)
  18. lines.push('---');
  19. const ctx = stringify.createStringifyContext(doc, options);
  20. const { commentString } = ctx.options;
  21. if (doc.commentBefore) {
  22. if (lines.length !== 1)
  23. lines.unshift('');
  24. const cs = commentString(doc.commentBefore);
  25. lines.unshift(stringifyComment.indentComment(cs, ''));
  26. }
  27. let chompKeep = false;
  28. let contentComment = null;
  29. if (doc.contents) {
  30. if (identity.isNode(doc.contents)) {
  31. if (doc.contents.spaceBefore && hasDirectives)
  32. lines.push('');
  33. if (doc.contents.commentBefore) {
  34. const cs = commentString(doc.contents.commentBefore);
  35. lines.push(stringifyComment.indentComment(cs, ''));
  36. }
  37. // top-level block scalars need to be indented if followed by a comment
  38. ctx.forceBlockIndent = !!doc.comment;
  39. contentComment = doc.contents.comment;
  40. }
  41. const onChompKeep = contentComment ? undefined : () => (chompKeep = true);
  42. let body = stringify.stringify(doc.contents, ctx, () => (contentComment = null), onChompKeep);
  43. if (contentComment)
  44. body += stringifyComment.lineComment(body, '', commentString(contentComment));
  45. if ((body[0] === '|' || body[0] === '>') &&
  46. lines[lines.length - 1] === '---') {
  47. // Top-level block scalars with a preceding doc marker ought to use the
  48. // same line for their header.
  49. lines[lines.length - 1] = `--- ${body}`;
  50. }
  51. else
  52. lines.push(body);
  53. }
  54. else {
  55. lines.push(stringify.stringify(doc.contents, ctx));
  56. }
  57. if (doc.directives?.docEnd) {
  58. if (doc.comment) {
  59. const cs = commentString(doc.comment);
  60. if (cs.includes('\n')) {
  61. lines.push('...');
  62. lines.push(stringifyComment.indentComment(cs, ''));
  63. }
  64. else {
  65. lines.push(`... ${cs}`);
  66. }
  67. }
  68. else {
  69. lines.push('...');
  70. }
  71. }
  72. else {
  73. let dc = doc.comment;
  74. if (dc && chompKeep)
  75. dc = dc.replace(/^\n+/, '');
  76. if (dc) {
  77. if ((!chompKeep || contentComment) && lines[lines.length - 1] !== '')
  78. lines.push('');
  79. lines.push(stringifyComment.indentComment(commentString(dc), ''));
  80. }
  81. }
  82. return lines.join('\n') + '\n';
  83. }
  84. exports.stringifyDocument = stringifyDocument;