yaml-unist-parser
Version:
A YAML parser that produces output compatible with unist
66 lines (64 loc) • 2.48 kB
JavaScript
import { tokens } from "../cst.mjs";
import { createDocumentHead } from "../factories/document-head.mjs";
import { transformDirective } from "./directive.mjs";
//#region src/transforms/document-head.ts
function transformDocumentHead(tokensBeforeBody, cstNode, document, context) {
const { directives, endCommentCandidates } = categorizeNodes(tokensBeforeBody, context);
let betweenTokens = [];
let docStart = null;
if (cstNode) for (const token of tokens(cstNode.start)) {
betweenTokens.push(token);
if (!docStart && token.type === "doc-start") {
for (const t of betweenTokens) if (t.type === "comment") {
const comment = context.transformComment(t);
endCommentCandidates.push(comment);
}
betweenTokens = [];
docStart = token;
}
}
const position = getPosition(directives, document, docStart, context);
let trailingComment = null;
if (docStart && betweenTokens.length > 0) {
const lastToken = betweenTokens[0];
if (lastToken.type === "comment") {
if (context.transformOffset(lastToken.offset).line === position.end.line) {
trailingComment = context.transformComment(lastToken);
betweenTokens.shift();
}
}
}
return {
documentHead: createDocumentHead(position, directives, docStart ? endCommentCandidates : [], trailingComment),
docStart,
tokensBeforeBody: betweenTokens
};
}
function categorizeNodes(tokensBeforeBody, context) {
const directives = [];
let endCommentCandidates = [];
let lastDirective = null;
for (const token of tokensBeforeBody) if (token.type === "comment") {
const node = context.transformComment(token);
if (lastDirective && lastDirective.position.end.line === node.position.start.line && !lastDirective.trailingComment) {
lastDirective.trailingComment = node;
lastDirective.position.end = node.position.end;
} else endCommentCandidates.push(node);
} else {
const node = transformDirective(token, context);
directives.push(node);
lastDirective = node;
endCommentCandidates = [];
}
return {
directives,
endCommentCandidates
};
}
function getPosition(directives, document, docStart, context) {
const range = docStart ? [docStart.offset, docStart.offset + docStart.source.length] : document.contents ? [document.contents.range[0], document.contents.range[0]] : [document.range[0], document.range[0]];
if (directives.length !== 0) range[0] = directives[0].position.start.offset;
return context.transformRange(range);
}
//#endregion
export { transformDocumentHead };