UNPKG

@mintlify/common

Version:

Commonly shared code within Mintlify

90 lines (89 loc) 4.08 kB
import remarkStringify from 'remark-stringify'; import { unified } from 'unified'; import { visit } from 'unist-util-visit'; import { coreRemarkMdxPlugins } from '../../remark.js'; export const remarkExtractMultiView = (mdxExtracts) => { return (tree) => { const multiViews = []; const sanitizeNode = (node) => { const sanitized = Object.assign({}, node); if ('attributes' in sanitized && Array.isArray(sanitized.attributes)) { sanitized.attributes = sanitized.attributes.map((attr) => { if (attr.value != null && typeof attr.value !== 'string') { return Object.assign(Object.assign({}, attr), { value: String(attr.value) }); } return attr; }); } if ('children' in sanitized && Array.isArray(sanitized.children)) { sanitized.children = sanitized.children.map(sanitizeNode); } return sanitized; }; const stringifyNode = (node) => { try { return unified() .use(coreRemarkMdxPlugins) .use(remarkStringify) .stringify(sanitizeNode(node)); } catch (error) { console.error('Error converting MDX content to markdown:', error); return ''; } }; const getStringValue = (attribute) => { if (!(attribute === null || attribute === void 0 ? void 0 : attribute.value)) { return undefined; } if (typeof attribute.value === 'string') { return attribute.value; } if (typeof attribute.value === 'object' && 'value' in attribute.value) { return String(attribute.value.value); } return undefined; }; visit(tree, 'mdxJsxFlowElement', (node) => { if (node.name === 'View') { const title = getStringValue(node.attributes.find((attr) => attr.type === 'mdxJsxAttribute' && attr.name === 'title')); const icon = getStringValue(node.attributes.find((attr) => attr.type === 'mdxJsxAttribute' && attr.name === 'icon')); const iconType = getStringValue(node.attributes.find((attr) => attr.type === 'mdxJsxAttribute' && attr.name === 'iconType')); const content = stringifyNode({ type: 'root', children: node.children, }); if (title) { const existingView = multiViews.find((view) => view.title === title); if (existingView) { console.warn(`\n⚠️ Duplicate View title: "${title}"\n` + ` Use one View component per title per page. Duplicate Views are ignored.\n` + ` Learn more: https://www.mintlify.com/docs/components/view\n`); return; } // Extract the id attribute (set by remarkComponentIds or explicit) so the // client can match URL hashes back to the correct view for shareable links. const id = getStringValue(node.attributes.find((attr) => attr.type === 'mdxJsxAttribute' && attr.name === 'id')); const viewItem = { title, content, }; if (icon) { viewItem.icon = icon; } if (iconType) { viewItem.iconType = iconType; } if (id) { viewItem.id = id; } multiViews.push(viewItem); } } }); if (mdxExtracts && multiViews.length) { mdxExtracts.multiViewItems = multiViews; } return tree; }; };