import { unified } from 'unified'; import { visit } from 'unist-util-visit'; import remarkParse from 'remark-parse'; import remarkGfm from 'remark-gfm'; import remarkRehype from 'remark-rehype'; import remarkBreaks from 'remark-breaks'; import remarkMath from 'remark-math'; import rehypeKatex from 'rehype-katex'; function remarkSplitBlocks() { return (tree: any) => { visit(tree, 'paragraph', (node, index, parent) => { if (parent == null || index == null) { return; } const breakIndex = node.children.findIndex((child: any) => child.type === 'break'); if (breakIndex === -1) { return; } const beforeBreak = node.children.slice(0, breakIndex); const afterBreak = node.children.slice(breakIndex + 1); // Keep content before the break in the current paragraph. node.children = beforeBreak; // Insert content after the break as the next sibling of this // paragraph in its actual parent (root, listItem, blockquote, etc.). // Previously this only spliced into tree.children and dropped // nested content when the parent wasn't a direct root child. if (afterBreak.length > 0) { const newParagraph = { type: 'paragraph', children: afterBreak, }; parent.children.splice(index + 1, 0, newParagraph); // Continue at the newly inserted paragraph so further // hard breaks inside it are split as well. return index + 1; } }); }; } export default defineNuxtPlugin((nuxtApp) => { const remark = unified() .use(remarkParse) .use(remarkGfm) .use(remarkMath) .use(remarkBreaks) .use(remarkSplitBlocks) .use(remarkRehype, { allowDangerousHtml: true }) .use(rehypeKatex, { output: 'mathml' }); return { provide: { remark, } } })