Spaces:
Runtime error
Runtime error
import rehypeRaw from 'rehype-raw'; | |
import remarkGfm from 'remark-gfm'; | |
import type { PluggableList, Plugin } from 'unified'; | |
import rehypeSanitize, { defaultSchema, type Options as RehypeSanitizeOptions } from 'rehype-sanitize'; | |
import { SKIP, visit } from 'unist-util-visit'; | |
import type { UnistNode, UnistParent } from 'node_modules/unist-util-visit/lib'; | |
export const allowedHTMLElements = [ | |
'a', | |
'b', | |
'blockquote', | |
'br', | |
'code', | |
'dd', | |
'del', | |
'details', | |
'div', | |
'dl', | |
'dt', | |
'em', | |
'h1', | |
'h2', | |
'h3', | |
'h4', | |
'h5', | |
'h6', | |
'hr', | |
'i', | |
'ins', | |
'kbd', | |
'li', | |
'ol', | |
'p', | |
'pre', | |
'q', | |
'rp', | |
'rt', | |
'ruby', | |
's', | |
'samp', | |
'source', | |
'span', | |
'strike', | |
'strong', | |
'sub', | |
'summary', | |
'sup', | |
'table', | |
'tbody', | |
'td', | |
'tfoot', | |
'th', | |
'thead', | |
'tr', | |
'ul', | |
'var', | |
]; | |
const rehypeSanitizeOptions: RehypeSanitizeOptions = { | |
...defaultSchema, | |
tagNames: allowedHTMLElements, | |
attributes: { | |
...defaultSchema.attributes, | |
div: [...(defaultSchema.attributes?.div ?? []), 'data*', ['className', '__boltArtifact__']], | |
}, | |
strip: [], | |
}; | |
export function remarkPlugins(limitedMarkdown: boolean) { | |
const plugins: PluggableList = [remarkGfm]; | |
if (limitedMarkdown) { | |
plugins.unshift(limitedMarkdownPlugin); | |
} | |
return plugins; | |
} | |
export function rehypePlugins(html: boolean) { | |
const plugins: PluggableList = []; | |
if (html) { | |
plugins.push(rehypeRaw, [rehypeSanitize, rehypeSanitizeOptions]); | |
} | |
return plugins; | |
} | |
const limitedMarkdownPlugin: Plugin = () => { | |
return (tree, file) => { | |
const contents = file.toString(); | |
visit(tree, (node: UnistNode, index, parent: UnistParent) => { | |
if ( | |
index == null || | |
['paragraph', 'text', 'inlineCode', 'code', 'strong', 'emphasis'].includes(node.type) || | |
!node.position | |
) { | |
return true; | |
} | |
let value = contents.slice(node.position.start.offset, node.position.end.offset); | |
if (node.type === 'heading') { | |
value = `\n${value}`; | |
} | |
parent.children[index] = { | |
type: 'text', | |
value, | |
} as any; | |
return [SKIP, index] as const; | |
}); | |
}; | |
}; | |