UNPKG

myst-parser

Version:
73 lines (72 loc) 2.84 kB
import { RuleId, fileError, fileWarn } from 'myst-common'; import { selectAll } from 'unist-util-select'; import { contentFromNode } from './utils.js'; import { parseOptions } from './inlineAttributes.js'; export function applyRoles(tree, specs, vfile) { const specLookup = {}; specs.forEach((spec) => { const names = [spec.name]; if (spec.alias) { names.push(...(typeof spec.alias === 'string' ? [spec.alias] : spec.alias)); } names.forEach((name) => { if (specLookup[name]) { fileWarn(vfile, `duplicate roles registered with name: ${name}`, { ruleId: RuleId.roleRegistered, }); } else { specLookup[name] = spec; } }); }); const nodes = selectAll('mystRole[processed=false]', tree); nodes.forEach((node) => { var _a; delete node.processed; // Indicate that the role has been processed const { name } = node; const spec = specLookup[name]; if (!spec) { fileError(vfile, `unknown role: ${name}`, { node, ruleId: RuleId.roleKnown }); // We probably want to do something better than just delete the children delete node.children; return; } const { body, options: optionsSpec, validate, run } = spec; let data = { name, node: node, options: {} }; const { valid: validOptions, options } = parseOptions(name, node, vfile, optionsSpec); let validationError = validOptions; data.options = options; // Only look to the direct children const bodyNode = (_a = node.children) === null || _a === void 0 ? void 0 : _a.find((n) => n.type === 'mystRoleBody'); if (body) { if (body.required && !bodyNode) { fileError(vfile, `required body not provided for role: ${name}`, { node, ruleId: RuleId.roleBodyCorrect, }); node.type = 'mystRoleError'; delete node.children; validationError = true; } else { data.body = contentFromNode(bodyNode, body, vfile, `body of role: ${name}`, RuleId.roleBodyCorrect); if (body.required && data.body == null) { validationError = true; } } } else if (bodyNode) { fileWarn(vfile, `unexpected body provided for role: ${name}`, { node: bodyNode, ruleId: RuleId.roleBodyCorrect, }); } if (validationError) return; if (validate) { data = validate(data, vfile); } node.children = run(data, vfile); }); }