UNPKG

5.45 kBJavaScriptView Raw
1'use strict';
2
3var identity = require('../nodes/identity.js');
4var Scalar = require('../nodes/Scalar.js');
5var stringify = require('./stringify.js');
6var stringifyComment = require('./stringifyComment.js');
7
8function 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) || (!identity.isNode(key) && typeof key === 'object')) {
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
152exports.stringifyPair = stringifyPair;