| import { isNode, isPair } from '../nodes/identity.js'; | |
| import { stringify } from './stringify.js'; | |
| import { lineComment, indentComment } from './stringifyComment.js'; | |
| function stringifyCollection(collection, ctx, options) { | |
| const flow = ctx.inFlow ?? collection.flow; | |
| const stringify = flow ? stringifyFlowCollection : stringifyBlockCollection; | |
| return stringify(collection, ctx, options); | |
| } | |
| function stringifyBlockCollection({ comment, items }, ctx, { blockItemPrefix, flowChars, itemIndent, onChompKeep, onComment }) { | |
| const { indent, options: { commentString } } = ctx; | |
| const itemCtx = Object.assign({}, ctx, { indent: itemIndent, type: null }); | |
| let chompKeep = false; // flag for the preceding node's status | |
| const lines = []; | |
| for (let i = 0; i < items.length; ++i) { | |
| const item = items[i]; | |
| let comment = null; | |
| if (isNode(item)) { | |
| if (!chompKeep && item.spaceBefore) | |
| lines.push(''); | |
| addCommentBefore(ctx, lines, item.commentBefore, chompKeep); | |
| if (item.comment) | |
| comment = item.comment; | |
| } | |
| else if (isPair(item)) { | |
| const ik = isNode(item.key) ? item.key : null; | |
| if (ik) { | |
| if (!chompKeep && ik.spaceBefore) | |
| lines.push(''); | |
| addCommentBefore(ctx, lines, ik.commentBefore, chompKeep); | |
| } | |
| } | |
| chompKeep = false; | |
| let str = stringify(item, itemCtx, () => (comment = null), () => (chompKeep = true)); | |
| if (comment) | |
| str += lineComment(str, itemIndent, commentString(comment)); | |
| if (chompKeep && comment) | |
| chompKeep = false; | |
| lines.push(blockItemPrefix + str); | |
| } | |
| let str; | |
| if (lines.length === 0) { | |
| str = flowChars.start + flowChars.end; | |
| } | |
| else { | |
| str = lines[0]; | |
| for (let i = 1; i < lines.length; ++i) { | |
| const line = lines[i]; | |
| str += line ? `\n${indent}${line}` : '\n'; | |
| } | |
| } | |
| if (comment) { | |
| str += '\n' + indentComment(commentString(comment), indent); | |
| if (onComment) | |
| onComment(); | |
| } | |
| else if (chompKeep && onChompKeep) | |
| onChompKeep(); | |
| return str; | |
| } | |
| function stringifyFlowCollection({ items }, ctx, { flowChars, itemIndent }) { | |
| const { indent, indentStep, flowCollectionPadding: fcPadding, options: { commentString } } = ctx; | |
| itemIndent += indentStep; | |
| const itemCtx = Object.assign({}, ctx, { | |
| indent: itemIndent, | |
| inFlow: true, | |
| type: null | |
| }); | |
| let reqNewline = false; | |
| let linesAtValue = 0; | |
| const lines = []; | |
| for (let i = 0; i < items.length; ++i) { | |
| const item = items[i]; | |
| let comment = null; | |
| if (isNode(item)) { | |
| if (item.spaceBefore) | |
| lines.push(''); | |
| addCommentBefore(ctx, lines, item.commentBefore, false); | |
| if (item.comment) | |
| comment = item.comment; | |
| } | |
| else if (isPair(item)) { | |
| const ik = isNode(item.key) ? item.key : null; | |
| if (ik) { | |
| if (ik.spaceBefore) | |
| lines.push(''); | |
| addCommentBefore(ctx, lines, ik.commentBefore, false); | |
| if (ik.comment) | |
| reqNewline = true; | |
| } | |
| const iv = isNode(item.value) ? item.value : null; | |
| if (iv) { | |
| if (iv.comment) | |
| comment = iv.comment; | |
| if (iv.commentBefore) | |
| reqNewline = true; | |
| } | |
| else if (item.value == null && ik?.comment) { | |
| comment = ik.comment; | |
| } | |
| } | |
| if (comment) | |
| reqNewline = true; | |
| let str = stringify(item, itemCtx, () => (comment = null)); | |
| reqNewline || (reqNewline = lines.length > linesAtValue || str.includes('\n')); | |
| if (i < items.length - 1) { | |
| str += ','; | |
| } | |
| else if (ctx.options.trailingComma) { | |
| if (ctx.options.lineWidth > 0) { | |
| reqNewline || (reqNewline = lines.reduce((sum, line) => sum + line.length + 2, 2) + | |
| (str.length + 2) > | |
| ctx.options.lineWidth); | |
| } | |
| if (reqNewline) { | |
| str += ','; | |
| } | |
| } | |
| if (comment) | |
| str += lineComment(str, itemIndent, commentString(comment)); | |
| lines.push(str); | |
| linesAtValue = lines.length; | |
| } | |
| const { start, end } = flowChars; | |
| if (lines.length === 0) { | |
| return start + end; | |
| } | |
| else { | |
| if (!reqNewline) { | |
| const len = lines.reduce((sum, line) => sum + line.length + 2, 2); | |
| reqNewline = ctx.options.lineWidth > 0 && len > ctx.options.lineWidth; | |
| } | |
| if (reqNewline) { | |
| let str = start; | |
| for (const line of lines) | |
| str += line ? `\n${indentStep}${indent}${line}` : '\n'; | |
| return `${str}\n${indent}${end}`; | |
| } | |
| else { | |
| return `${start}${fcPadding}${lines.join(' ')}${fcPadding}${end}`; | |
| } | |
| } | |
| } | |
| function addCommentBefore({ indent, options: { commentString } }, lines, comment, chompKeep) { | |
| if (comment && chompKeep) | |
| comment = comment.replace(/^\n+/, ''); | |
| if (comment) { | |
| const ic = indentComment(commentString(comment), indent); | |
| lines.push(ic.trimStart()); // Avoid double indent on first line | |
| } | |
| } | |
| export { stringifyCollection }; | |
Xet Storage Details
- Size:
- 5.55 kB
- Xet hash:
- ad2a296735dfd31d56348ade08a306aba308d78b64d12bb4e0b49992540596fb
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.