@lobehub/ui
Version:
Lobe UI is an open-source UI component library for building AIGC web apps
1 lines • 3.79 kB
Source Map (JSON)
{"version":3,"file":"remarkBr.mjs","names":["parts: string[]","matches: string[]","newNodes: any[]"],"sources":["../../../src/Markdown/plugins/remarkBr.ts"],"sourcesContent":["import { visit } from 'unist-util-visit';\n\n/**\n * Remark plugin to handle <br> and <br/> tags in markdown text\n * This plugin converts <br> and <br/> tags to proper HTML elements\n * without requiring allowHtml to be enabled\n */\nexport const remarkBr = () => {\n return (tree: any) => {\n // First try to process html nodes that might contain ONLY br tags\n visit(tree, 'html', (node, index, parent) => {\n if (!node.value || typeof node.value !== 'string') return;\n\n // Only handle standalone br tags, not complex HTML containing br tags\n const brRegex = /^\\s*<\\s*br\\s*\\/?>\\s*$/gi;\n if (brRegex.test(node.value)) {\n // Replace the html node with a break node\n parent.children.splice(index, 1, { type: 'break' });\n return index;\n }\n });\n\n // Also process text nodes\n visit(tree, 'text', (node, index = 0, parent) => {\n if (!node.value || typeof node.value !== 'string') return;\n\n // Check if the text contains <br> or <br/> tags\n const brRegex = /<\\s*br\\s*\\/?>/gi;\n\n if (!brRegex.test(node.value)) return;\n\n // Reset regex lastIndex for split operation\n brRegex.lastIndex = 0;\n\n // Split the text by br tags, but keep the matched tags\n const parts: string[] = [];\n const matches: string[] = [];\n let lastIndex = 0;\n let match;\n\n while ((match = brRegex.exec(node.value)) !== null) {\n // Add text before the match\n if (match.index > lastIndex) {\n parts.push(node.value.slice(lastIndex, match.index));\n }\n\n // Store the matched br tag\n matches.push(match[0]);\n lastIndex = match.index + match[0].length;\n }\n\n // Add remaining text after the last match\n if (lastIndex < node.value.length) {\n parts.push(node.value.slice(lastIndex));\n }\n\n // Create new nodes\n const newNodes: any[] = [];\n\n for (const [i, part] of parts.entries()) {\n // Add text node if not empty\n if (part) {\n newNodes.push({\n type: 'text',\n value: part,\n });\n }\n\n // Add br element if we have a corresponding match\n if (i < matches.length) {\n newNodes.push({\n type: 'break',\n });\n }\n }\n\n // Replace the original text node with the new nodes\n if (newNodes.length > 0) {\n parent.children.splice(index, 1, ...newNodes);\n return index + newNodes.length - 1; // Skip the newly added nodes\n }\n });\n };\n};\n"],"mappings":";;;;;;;;AAOA,MAAa,iBAAiB;AAC5B,SAAQ,SAAc;AAEpB,QAAM,MAAM,SAAS,MAAM,OAAO,WAAW;AAC3C,OAAI,CAAC,KAAK,SAAS,OAAO,KAAK,UAAU,SAAU;AAInD,OADgB,0BACJ,KAAK,KAAK,MAAM,EAAE;AAE5B,WAAO,SAAS,OAAO,OAAO,GAAG,EAAE,MAAM,SAAS,CAAC;AACnD,WAAO;;IAET;AAGF,QAAM,MAAM,SAAS,MAAM,QAAQ,GAAG,WAAW;AAC/C,OAAI,CAAC,KAAK,SAAS,OAAO,KAAK,UAAU,SAAU;GAGnD,MAAM,UAAU;AAEhB,OAAI,CAAC,QAAQ,KAAK,KAAK,MAAM,CAAE;AAG/B,WAAQ,YAAY;GAGpB,MAAMA,QAAkB,EAAE;GAC1B,MAAMC,UAAoB,EAAE;GAC5B,IAAI,YAAY;GAChB,IAAI;AAEJ,WAAQ,QAAQ,QAAQ,KAAK,KAAK,MAAM,MAAM,MAAM;AAElD,QAAI,MAAM,QAAQ,UAChB,OAAM,KAAK,KAAK,MAAM,MAAM,WAAW,MAAM,MAAM,CAAC;AAItD,YAAQ,KAAK,MAAM,GAAG;AACtB,gBAAY,MAAM,QAAQ,MAAM,GAAG;;AAIrC,OAAI,YAAY,KAAK,MAAM,OACzB,OAAM,KAAK,KAAK,MAAM,MAAM,UAAU,CAAC;GAIzC,MAAMC,WAAkB,EAAE;AAE1B,QAAK,MAAM,CAAC,GAAG,SAAS,MAAM,SAAS,EAAE;AAEvC,QAAI,KACF,UAAS,KAAK;KACZ,MAAM;KACN,OAAO;KACR,CAAC;AAIJ,QAAI,IAAI,QAAQ,OACd,UAAS,KAAK,EACZ,MAAM,SACP,CAAC;;AAKN,OAAI,SAAS,SAAS,GAAG;AACvB,WAAO,SAAS,OAAO,OAAO,GAAG,GAAG,SAAS;AAC7C,WAAO,QAAQ,SAAS,SAAS;;IAEnC"}