UNPKG

yaml-unist-parser

Version:

A YAML parser that produces output compatible with unist

75 lines (73 loc) 3.65 kB
import { getPointText } from "../utils/get-point-text.mjs"; import { maybeContentPropertyToken, tokens } from "../cst.mjs"; import { extractComments } from "../utils/extract-comments.mjs"; import { getLast } from "../utils/get-last.mjs"; import { createDocumentBody } from "../factories/document-body.mjs"; import { findCharIndex } from "../utils/find-char-index.mjs"; //#region src/transforms/document-body.ts function transformDocumentBody(docStart, tokensBeforeBody, cstNode, document, tokensAfterBody, docEnd, context) { const { documentTrailingComment, endComments, propTokens } = categorizeNodes(tokensBeforeBody, cstNode, tokensAfterBody, docEnd, context); const hasContent = document.contents && (document.contents.range[0] < document.contents.range[1] || propTokens.some((token) => token.type === "tag" || token.type === "anchor")); const content = hasContent ? context.transformNode(document.contents, { tokens: propTokens }) : null; if (!hasContent) for (const token of extractComments(propTokens, context)) // istanbul ignore next -- @preserve throw new Error(`Unexpected token type in empty document body: ${token.type}`); const { position, documentEndPoint } = getPosition(docStart, document, content, docEnd, context); return { documentBody: createDocumentBody(position, content, endComments), documentEndPoint, documentTrailingComment }; } function categorizeNodes(tokensBeforeBody, cstNode, tokensAfterBody, docEnd, context) { const endComments = []; const documentTrailingComments = []; const propTokens = []; for (const token of tokensBeforeBody) { if (maybeContentPropertyToken(token)) { propTokens.push(token); continue; } // istanbul ignore next -- @preserve throw new Error(`Unexpected token type: ${token.type}`); } for (const token of extractComments(tokensAfterBody, context)) // istanbul ignore next -- @preserve throw new Error(`Unexpected token type: ${token.type}`); const docEndPoint = docEnd ? context.transformOffset(docEnd.offset) : null; if (cstNode) for (const token of tokens(cstNode.end, docEnd === null || docEnd === void 0 ? void 0 : docEnd.end)) { if (token.type === "comment") { const comment = context.transformComment(token); if (docEndPoint) { if (docEndPoint.line === comment.position.start.line) documentTrailingComments.push(comment); else if (comment.position.start.line < docEndPoint.line) endComments.push(comment); } else endComments.push(comment); continue; } // istanbul ignore next -- @preserve throw new Error(`Unexpected token type: ${token.type}`); } // istanbul ignore if -- @preserve if (documentTrailingComments.length > 1) throw new Error(`Unexpected multiple document trailing comments at ${getPointText(documentTrailingComments[1].position.start)}`); return { propTokens, endComments, documentTrailingComment: getLast(documentTrailingComments) || null }; } function getPosition(docStart, document, content, docEnd, context) { let origEnd = docEnd ? Math.max(0, docEnd.offset - 1) : findCharIndex(context.text, document.range[2], /\S/u) ?? context.text.length; if (context.text[origEnd - 1] === "\r") origEnd--; let origStart = content !== null ? content.position.start.offset : origEnd; if (docStart) { const docStartEnd = docStart.offset + docStart.source.length + 1; if (origStart < docStartEnd && docStartEnd <= origEnd) origStart = docStartEnd; } const position = context.transformRange([origStart, origEnd]); return { position, documentEndPoint: docEnd ? context.transformOffset(docEnd.offset + docEnd.source.length) : position.end }; } //#endregion export { transformDocumentBody };