[d24f17c] | 1 | 'use strict';
|
---|
| 2 |
|
---|
| 3 | var identity = require('../nodes/identity.js');
|
---|
| 4 | var Scalar = require('../nodes/Scalar.js');
|
---|
| 5 | var stringify = require('./stringify.js');
|
---|
| 6 | var stringifyComment = require('./stringifyComment.js');
|
---|
| 7 |
|
---|
| 8 | function stringifyPair({ key, value }, ctx, onComment, onChompKeep) {
|
---|
| 9 | const { allNullValues, doc, indent, indentStep, options: { commentString, indentSeq, simpleKeys } } = ctx;
|
---|
| 10 | let keyComment = (identity.isNode(key) && key.comment) || null;
|
---|
| 11 | if (simpleKeys) {
|
---|
| 12 | if (keyComment) {
|
---|
| 13 | throw new Error('With simple keys, key nodes cannot have comments');
|
---|
| 14 | }
|
---|
| 15 | if (identity.isCollection(key)) {
|
---|
| 16 | const msg = 'With simple keys, collection cannot be used as a key value';
|
---|
| 17 | throw new Error(msg);
|
---|
| 18 | }
|
---|
| 19 | }
|
---|
| 20 | let explicitKey = !simpleKeys &&
|
---|
| 21 | (!key ||
|
---|
| 22 | (keyComment && value == null && !ctx.inFlow) ||
|
---|
| 23 | identity.isCollection(key) ||
|
---|
| 24 | (identity.isScalar(key)
|
---|
| 25 | ? key.type === Scalar.Scalar.BLOCK_FOLDED || key.type === Scalar.Scalar.BLOCK_LITERAL
|
---|
| 26 | : typeof key === 'object'));
|
---|
| 27 | ctx = Object.assign({}, ctx, {
|
---|
| 28 | allNullValues: false,
|
---|
| 29 | implicitKey: !explicitKey && (simpleKeys || !allNullValues),
|
---|
| 30 | indent: indent + indentStep
|
---|
| 31 | });
|
---|
| 32 | let keyCommentDone = false;
|
---|
| 33 | let chompKeep = false;
|
---|
| 34 | let str = stringify.stringify(key, ctx, () => (keyCommentDone = true), () => (chompKeep = true));
|
---|
| 35 | if (!explicitKey && !ctx.inFlow && str.length > 1024) {
|
---|
| 36 | if (simpleKeys)
|
---|
| 37 | throw new Error('With simple keys, single line scalar must not span more than 1024 characters');
|
---|
| 38 | explicitKey = true;
|
---|
| 39 | }
|
---|
| 40 | if (ctx.inFlow) {
|
---|
| 41 | if (allNullValues || value == null) {
|
---|
| 42 | if (keyCommentDone && onComment)
|
---|
| 43 | onComment();
|
---|
| 44 | return str === '' ? '?' : explicitKey ? `? ${str}` : str;
|
---|
| 45 | }
|
---|
| 46 | }
|
---|
| 47 | else if ((allNullValues && !simpleKeys) || (value == null && explicitKey)) {
|
---|
| 48 | str = `? ${str}`;
|
---|
| 49 | if (keyComment && !keyCommentDone) {
|
---|
| 50 | str += stringifyComment.lineComment(str, ctx.indent, commentString(keyComment));
|
---|
| 51 | }
|
---|
| 52 | else if (chompKeep && onChompKeep)
|
---|
| 53 | onChompKeep();
|
---|
| 54 | return str;
|
---|
| 55 | }
|
---|
| 56 | if (keyCommentDone)
|
---|
| 57 | keyComment = null;
|
---|
| 58 | if (explicitKey) {
|
---|
| 59 | if (keyComment)
|
---|
| 60 | str += stringifyComment.lineComment(str, ctx.indent, commentString(keyComment));
|
---|
| 61 | str = `? ${str}\n${indent}:`;
|
---|
| 62 | }
|
---|
| 63 | else {
|
---|
| 64 | str = `${str}:`;
|
---|
| 65 | if (keyComment)
|
---|
| 66 | str += stringifyComment.lineComment(str, ctx.indent, commentString(keyComment));
|
---|
| 67 | }
|
---|
| 68 | let vsb, vcb, valueComment;
|
---|
| 69 | if (identity.isNode(value)) {
|
---|
| 70 | vsb = !!value.spaceBefore;
|
---|
| 71 | vcb = value.commentBefore;
|
---|
| 72 | valueComment = value.comment;
|
---|
| 73 | }
|
---|
| 74 | else {
|
---|
| 75 | vsb = false;
|
---|
| 76 | vcb = null;
|
---|
| 77 | valueComment = null;
|
---|
| 78 | if (value && typeof value === 'object')
|
---|
| 79 | value = doc.createNode(value);
|
---|
| 80 | }
|
---|
| 81 | ctx.implicitKey = false;
|
---|
| 82 | if (!explicitKey && !keyComment && identity.isScalar(value))
|
---|
| 83 | ctx.indentAtStart = str.length + 1;
|
---|
| 84 | chompKeep = false;
|
---|
| 85 | if (!indentSeq &&
|
---|
| 86 | indentStep.length >= 2 &&
|
---|
| 87 | !ctx.inFlow &&
|
---|
| 88 | !explicitKey &&
|
---|
| 89 | identity.isSeq(value) &&
|
---|
| 90 | !value.flow &&
|
---|
| 91 | !value.tag &&
|
---|
| 92 | !value.anchor) {
|
---|
| 93 | // If indentSeq === false, consider '- ' as part of indentation where possible
|
---|
| 94 | ctx.indent = ctx.indent.substring(2);
|
---|
| 95 | }
|
---|
| 96 | let valueCommentDone = false;
|
---|
| 97 | const valueStr = stringify.stringify(value, ctx, () => (valueCommentDone = true), () => (chompKeep = true));
|
---|
| 98 | let ws = ' ';
|
---|
| 99 | if (keyComment || vsb || vcb) {
|
---|
| 100 | ws = vsb ? '\n' : '';
|
---|
| 101 | if (vcb) {
|
---|
| 102 | const cs = commentString(vcb);
|
---|
| 103 | ws += `\n${stringifyComment.indentComment(cs, ctx.indent)}`;
|
---|
| 104 | }
|
---|
| 105 | if (valueStr === '' && !ctx.inFlow) {
|
---|
| 106 | if (ws === '\n')
|
---|
| 107 | ws = '\n\n';
|
---|
| 108 | }
|
---|
| 109 | else {
|
---|
| 110 | ws += `\n${ctx.indent}`;
|
---|
| 111 | }
|
---|
| 112 | }
|
---|
| 113 | else if (!explicitKey && identity.isCollection(value)) {
|
---|
| 114 | const vs0 = valueStr[0];
|
---|
| 115 | const nl0 = valueStr.indexOf('\n');
|
---|
| 116 | const hasNewline = nl0 !== -1;
|
---|
| 117 | const flow = ctx.inFlow ?? value.flow ?? value.items.length === 0;
|
---|
| 118 | if (hasNewline || !flow) {
|
---|
| 119 | let hasPropsLine = false;
|
---|
| 120 | if (hasNewline && (vs0 === '&' || vs0 === '!')) {
|
---|
| 121 | let sp0 = valueStr.indexOf(' ');
|
---|
| 122 | if (vs0 === '&' &&
|
---|
| 123 | sp0 !== -1 &&
|
---|
| 124 | sp0 < nl0 &&
|
---|
| 125 | valueStr[sp0 + 1] === '!') {
|
---|
| 126 | sp0 = valueStr.indexOf(' ', sp0 + 1);
|
---|
| 127 | }
|
---|
| 128 | if (sp0 === -1 || nl0 < sp0)
|
---|
| 129 | hasPropsLine = true;
|
---|
| 130 | }
|
---|
| 131 | if (!hasPropsLine)
|
---|
| 132 | ws = `\n${ctx.indent}`;
|
---|
| 133 | }
|
---|
| 134 | }
|
---|
| 135 | else if (valueStr === '' || valueStr[0] === '\n') {
|
---|
| 136 | ws = '';
|
---|
| 137 | }
|
---|
| 138 | str += ws + valueStr;
|
---|
| 139 | if (ctx.inFlow) {
|
---|
| 140 | if (valueCommentDone && onComment)
|
---|
| 141 | onComment();
|
---|
| 142 | }
|
---|
| 143 | else if (valueComment && !valueCommentDone) {
|
---|
| 144 | str += stringifyComment.lineComment(str, ctx.indent, commentString(valueComment));
|
---|
| 145 | }
|
---|
| 146 | else if (chompKeep && onChompKeep) {
|
---|
| 147 | onChompKeep();
|
---|
| 148 | }
|
---|
| 149 | return str;
|
---|
| 150 | }
|
---|
| 151 |
|
---|
| 152 | exports.stringifyPair = stringifyPair;
|
---|