UNPKG

mystjs

Version:
172 lines 7.29 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.transform = exports.convertHtmlToMdast = exports.ensureCaptionIsParagraph = exports.propagateTargets = exports.liftChildren = exports.addContainerCaptionNumbers = exports.addAdmonitionHeaders = void 0; const unified_1 = require("unified"); const rehype_parse_1 = __importDefault(require("rehype-parse")); const rehype_remark_1 = __importDefault(require("rehype-remark")); const hast_util_to_mdast_1 = require("hast-util-to-mdast"); const unist_util_visit_1 = require("unist-util-visit"); const unist_util_select_1 = require("unist-util-select"); const unist_util_find_after_1 = require("unist-util-find-after"); const unist_util_remove_1 = require("unist-util-remove"); const unist_util_map_1 = require("unist-util-map"); const types_1 = require("./types"); const utils_1 = require("./utils"); const state_1 = require("./state"); const defaultOptions = { addAdmonitionHeaders: true, addContainerCaptionNumbers: true, disableHeadingEnumeration: false, disableContainerEnumeration: false, disableEquationEnumeration: false, }; const defaultHtmlToMdastOptions = { keepBreaks: true, htmlHandlers: { table(h, node) { return h(node, 'table', (0, hast_util_to_mdast_1.all)(h, node)); }, th(h, node) { const result = h(node, 'tableCell', (0, hast_util_to_mdast_1.all)(h, node)); result.header = true; return result; }, _brKeep(h, node) { return h(node, '_break'); }, }, }; // Visit all admonitions and add headers if necessary function addAdmonitionHeaders(tree) { (0, unist_util_visit_1.visit)(tree, 'admonition', (node) => { var _a; if (!node.kind || node.kind === types_1.AdmonitionKind.admonition) return; node.children = [ { type: 'admonitionTitle', children: [{ type: 'text', value: (0, utils_1.admonitionKindToTitle)(node.kind) }], }, ...((_a = node.children) !== null && _a !== void 0 ? _a : []), ]; }); } exports.addAdmonitionHeaders = addAdmonitionHeaders; // Visit all containers and add captions function addContainerCaptionNumbers(tree, state) { (0, unist_util_select_1.selectAll)('container', tree) .filter((container) => container.enumerator !== false) .forEach((container) => { var _a, _b; const enumerator = (_a = state.getTarget(container.identifier)) === null || _a === void 0 ? void 0 : _a.node.enumerator; const para = (0, unist_util_select_1.select)('caption > paragraph', container); if (enumerator && para) { para.children = [ { type: 'captionNumber', kind: container.kind, value: enumerator }, ...((_b = para === null || para === void 0 ? void 0 : para.children) !== null && _b !== void 0 ? _b : []), ]; } }); } exports.addContainerCaptionNumbers = addContainerCaptionNumbers; /** @deprecated use myst-common */ function liftChildren(tree, nodeType) { (0, unist_util_map_1.map)(tree, (node) => { var _a, _b; const children = (_b = (_a = node.children) === null || _a === void 0 ? void 0 : _a.map((child) => { if (child.type === nodeType && child.children) return child.children; return child; })) === null || _b === void 0 ? void 0 : _b.flat(); if (children !== undefined) node.children = children; return node; }); } exports.liftChildren = liftChildren; /** * Propagate target identifier/value to subsequent node * * Note: While this propagation happens regardless of the * subsequent node type, references are only resolved to * the TargetKind nodes enumerated in state.ts. For example: * * (paragraph-target)= * Just a normal paragraph * * will add identifier/label to paragraph node, but the node * will still not be targetable. */ function propagateTargets(tree) { (0, unist_util_visit_1.visit)(tree, 'mystTarget', (node, index) => { const nextNode = (0, unist_util_find_after_1.findAfter)(tree, index); const normalized = (0, utils_1.normalizeLabel)(node.label); if (nextNode && normalized) { nextNode.identifier = normalized.identifier; nextNode.label = normalized.label; } }); (0, unist_util_remove_1.remove)(tree, 'mystTarget'); } exports.propagateTargets = propagateTargets; /** * Ensure caption content is nested in a paragraph. * * This function is idempotent! */ function ensureCaptionIsParagraph(tree) { (0, unist_util_visit_1.visit)(tree, 'caption', (node) => { if (node.children && node.children[0].type !== 'paragraph') { node.children = [{ type: 'paragraph', children: node.children }]; } }); } exports.ensureCaptionIsParagraph = ensureCaptionIsParagraph; function convertHtmlToMdast(tree, opts) { const handlers = Object.assign(Object.assign({}, defaultHtmlToMdastOptions.htmlHandlers), opts === null || opts === void 0 ? void 0 : opts.htmlHandlers); const otherOptions = Object.assign(Object.assign({}, defaultHtmlToMdastOptions), opts); const htmlNodes = (0, unist_util_select_1.selectAll)('html', tree); htmlNodes.forEach((node) => { const hast = (0, unified_1.unified)() .use(rehype_parse_1.default, { fragment: true }) .parse(node.value); // hast-util-to-mdast removes breaks if they are the first/last children // and nests standalone breaks in paragraphs. // However, since HTML nodes may just be fragments in the middle of markdown text, // there is an option to `keepBreaks` which will simply convert `<br />` // tags to `break` nodes, without the special hast-util-to-mdast behavior. if (otherOptions.keepBreaks) { (0, unist_util_select_1.selectAll)('[tagName=br]', hast).forEach((n) => { n.tagName = '_brKeep'; }); } const mdast = (0, unified_1.unified)().use(rehype_remark_1.default, { handlers }).runSync(hast); node.type = 'htmlParsed'; node.children = mdast.children; (0, unist_util_visit_1.visit)(node, (n) => delete n.position); }); liftChildren(tree, 'htmlParsed'); (0, unist_util_select_1.selectAll)('_break', tree).forEach((n) => { n.type = 'break'; }); return tree; } exports.convertHtmlToMdast = convertHtmlToMdast; const transform = (state, o) => (tree) => { const opts = Object.assign(Object.assign({}, defaultOptions), o); ensureCaptionIsParagraph(tree); propagateTargets(tree); (0, state_1.enumerateTargets)(state, tree, opts); (0, state_1.resolveReferences)(state, tree); liftChildren(tree, 'mystDirective'); liftChildren(tree, 'mystRole'); if (opts.addAdmonitionHeaders) addAdmonitionHeaders(tree); if (opts.addContainerCaptionNumbers) addContainerCaptionNumbers(tree, state); }; exports.transform = transform; //# sourceMappingURL=transforms.js.map