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.
128 lines
4.5 KiB
128 lines
4.5 KiB
2 years ago
|
'use strict';
|
||
|
|
||
|
var Node = require('../nodes/Node.js');
|
||
|
var Scalar = require('../nodes/Scalar.js');
|
||
|
var stringify = require('./stringify.js');
|
||
|
var stringifyComment = require('./stringifyComment.js');
|
||
|
|
||
|
function stringifyPair({ key, value }, ctx, onComment, onChompKeep) {
|
||
|
const { allNullValues, doc, indent, indentStep, options: { commentString, indentSeq, simpleKeys } } = ctx;
|
||
|
let keyComment = (Node.isNode(key) && key.comment) || null;
|
||
|
if (simpleKeys) {
|
||
|
if (keyComment) {
|
||
|
throw new Error('With simple keys, key nodes cannot have comments');
|
||
|
}
|
||
|
if (Node.isCollection(key)) {
|
||
|
const msg = 'With simple keys, collection cannot be used as a key value';
|
||
|
throw new Error(msg);
|
||
|
}
|
||
|
}
|
||
|
let explicitKey = !simpleKeys &&
|
||
|
(!key ||
|
||
|
(keyComment && value == null && !ctx.inFlow) ||
|
||
|
Node.isCollection(key) ||
|
||
|
(Node.isScalar(key)
|
||
|
? key.type === Scalar.Scalar.BLOCK_FOLDED || key.type === Scalar.Scalar.BLOCK_LITERAL
|
||
|
: typeof key === 'object'));
|
||
|
ctx = Object.assign({}, ctx, {
|
||
|
allNullValues: false,
|
||
|
implicitKey: !explicitKey && (simpleKeys || !allNullValues),
|
||
|
indent: indent + indentStep
|
||
|
});
|
||
|
let keyCommentDone = false;
|
||
|
let chompKeep = false;
|
||
|
let str = stringify.stringify(key, ctx, () => (keyCommentDone = true), () => (chompKeep = true));
|
||
|
if (!explicitKey && !ctx.inFlow && str.length > 1024) {
|
||
|
if (simpleKeys)
|
||
|
throw new Error('With simple keys, single line scalar must not span more than 1024 characters');
|
||
|
explicitKey = true;
|
||
|
}
|
||
|
if (ctx.inFlow) {
|
||
|
if (allNullValues || value == null) {
|
||
|
if (keyCommentDone && onComment)
|
||
|
onComment();
|
||
|
return str === '' ? '?' : explicitKey ? `? ${str}` : str;
|
||
|
}
|
||
|
}
|
||
|
else if ((allNullValues && !simpleKeys) || (value == null && explicitKey)) {
|
||
|
str = `? ${str}`;
|
||
|
if (keyComment && !keyCommentDone) {
|
||
|
str += stringifyComment.lineComment(str, ctx.indent, commentString(keyComment));
|
||
|
}
|
||
|
else if (chompKeep && onChompKeep)
|
||
|
onChompKeep();
|
||
|
return str;
|
||
|
}
|
||
|
if (keyCommentDone)
|
||
|
keyComment = null;
|
||
|
if (explicitKey) {
|
||
|
if (keyComment)
|
||
|
str += stringifyComment.lineComment(str, ctx.indent, commentString(keyComment));
|
||
|
str = `? ${str}\n${indent}:`;
|
||
|
}
|
||
|
else {
|
||
|
str = `${str}:`;
|
||
|
if (keyComment)
|
||
|
str += stringifyComment.lineComment(str, ctx.indent, commentString(keyComment));
|
||
|
}
|
||
|
let vcb = '';
|
||
|
let valueComment = null;
|
||
|
if (Node.isNode(value)) {
|
||
|
if (value.spaceBefore)
|
||
|
vcb = '\n';
|
||
|
if (value.commentBefore) {
|
||
|
const cs = commentString(value.commentBefore);
|
||
|
vcb += `\n${stringifyComment.indentComment(cs, ctx.indent)}`;
|
||
|
}
|
||
|
valueComment = value.comment;
|
||
|
}
|
||
|
else if (value && typeof value === 'object') {
|
||
|
value = doc.createNode(value);
|
||
|
}
|
||
|
ctx.implicitKey = false;
|
||
|
if (!explicitKey && !keyComment && Node.isScalar(value))
|
||
|
ctx.indentAtStart = str.length + 1;
|
||
|
chompKeep = false;
|
||
|
if (!indentSeq &&
|
||
|
indentStep.length >= 2 &&
|
||
|
!ctx.inFlow &&
|
||
|
!explicitKey &&
|
||
|
Node.isSeq(value) &&
|
||
|
!value.flow &&
|
||
|
!value.tag &&
|
||
|
!value.anchor) {
|
||
|
// If indentSeq === false, consider '- ' as part of indentation where possible
|
||
|
ctx.indent = ctx.indent.substr(2);
|
||
|
}
|
||
|
let valueCommentDone = false;
|
||
|
const valueStr = stringify.stringify(value, ctx, () => (valueCommentDone = true), () => (chompKeep = true));
|
||
|
let ws = ' ';
|
||
|
if (vcb || keyComment) {
|
||
|
if (valueStr === '' && !ctx.inFlow)
|
||
|
ws = vcb === '\n' ? '\n\n' : vcb;
|
||
|
else
|
||
|
ws = `${vcb}\n${ctx.indent}`;
|
||
|
}
|
||
|
else if (!explicitKey && Node.isCollection(value)) {
|
||
|
const flow = valueStr[0] === '[' || valueStr[0] === '{';
|
||
|
if (!flow || valueStr.includes('\n'))
|
||
|
ws = `\n${ctx.indent}`;
|
||
|
}
|
||
|
else if (valueStr === '' || valueStr[0] === '\n')
|
||
|
ws = '';
|
||
|
str += ws + valueStr;
|
||
|
if (ctx.inFlow) {
|
||
|
if (valueCommentDone && onComment)
|
||
|
onComment();
|
||
|
}
|
||
|
else if (valueComment && !valueCommentDone) {
|
||
|
str += stringifyComment.lineComment(str, ctx.indent, commentString(valueComment));
|
||
|
}
|
||
|
else if (chompKeep && onChompKeep) {
|
||
|
onChompKeep();
|
||
|
}
|
||
|
return str;
|
||
|
}
|
||
|
|
||
|
exports.stringifyPair = stringifyPair;
|