@mintlify/common
Version:
Commonly shared code within Mintlify
90 lines (89 loc) • 4.08 kB
JavaScript
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;
};
};