ReactMarkdown白名单HTML标签放行方案咨询及轻量实现代码求助
方案选择与代码示例
如果你想保留原Markdown里的<kbd>CTRL</kbd>写法,优先选rehype插件,不用修改原内容,直接在HTML处理阶段还原被转义的标签;要是愿意用更简洁的自定义Markdown语法(比如[kbd CTRL]),可以选remark插件,在解析阶段直接生成对应节点。
方案一:Rehype插件(保留原生标签写法)
ReactMarkdown会把<kbd>转义成<kbd>,这个插件会遍历AST,把转义后的文本替换成真实的<kbd>节点:
import ReactMarkdown from 'react-markdown'; import { visit } from 'unist-util-visit'; // 自定义rehype插件:还原<kbd>标签 const rehypeAllowKbd = () => { return (tree) => { visit(tree, 'text', (node, index, parent) => { const text = node.value; const kbdRegex = /<kbd>([^&]+)<\/kbd>/g; if (!kbdRegex.test(text)) return; const nodes = []; let lastIndex = 0; let match; while ((match = kbdRegex.exec(text)) !== null) { if (match.index > lastIndex) { nodes.push({ type: 'text', value: text.slice(lastIndex, match.index) }); } nodes.push({ type: 'element', tagName: 'kbd', properties: {}, children: [{ type: 'text', value: match[1] }] }); lastIndex = match.index + match[0].length; } if (lastIndex < text.length) { nodes.push({ type: 'text', value: text.slice(lastIndex) }); } parent.children.splice(index, 1, ...nodes); }); }; }; // 使用示例 const App = () => { const markdown = `Please press key <kbd>CTRL</kbd>`; return ( <ReactMarkdown rehypePlugins={[rehypeAllowKbd]}> {markdown} </ReactMarkdown> ); }; export default App;
方案二:Remark插件(自定义Markdown语法)
自定义[CTRL](kbd)这样的语法(也可以改成[kbd CTRL],调整插件逻辑即可),在Markdown解析阶段直接生成<kbd>节点:
import ReactMarkdown from 'react-markdown'; import { visit } from 'unist-util-visit'; // 自定义remark插件:解析[内容](kbd)语法 const remarkKbd = () => { return (tree) => { visit(tree, 'link', (node, index, parent) => { if (node.url === 'kbd') { const kbdNode = { type: 'element', tagName: 'kbd', properties: {}, children: node.children }; parent.children.splice(index, 1, kbdNode); } }); }; }; // 使用示例 const App = () => { const markdown = `Please press key [CTRL](kbd)`; return ( <ReactMarkdown remarkPlugins={[remarkKbd]}> {markdown} </ReactMarkdown> ); }; export default App;
如果要改成[kbd CTRL]的写法,把插件里的visit目标改成text,用正则匹配拆分文本即可,逻辑和rehype方案类似。
内容的提问来源于stack exchange,提问作者Antoine Trouve
相关产品推荐
相关产品推荐

