| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182 |
- /**
- * Markdown 转 HTML(优先使用 marked,缺省时使用简化解析)
- * 所有代码注释使用中文
- */
- // 简单的 HTML 转义
- function escapeHtml(input) {
- if (!input) return '';
- return input
- .replace(/&/g, '&')
- .replace(/</g, '<')
- .replace(/>/g, '>')
- .replace(/"/g, '"')
- .replace(/'/g, ''');
- }
- // 简化版 Markdown 解析(支持标题、加粗、斜体、行内代码、代码块、换行)
- function simpleMarkdown(input) {
- if (!input) return '';
- // 提前提取 ```code``` 代码块,避免被后续规则影响
- const codeBlocks = [];
- let text = input.replace(/```([\s\S]*?)```/g, (m, g1) => {
- const placeholder = `__CODE_BLOCK_${codeBlocks.length}__`;
- codeBlocks.push(`<pre><code>${escapeHtml(g1)}</code></pre>`);
- return placeholder;
- });
- // 转义剩余文本
- text = escapeHtml(text);
- // 标题(支持 # 到 ######)
- text = text.replace(/^######\s+(.*)$/gm, '<h6>$1</h6>')
- .replace(/^#####\s+(.*)$/gm, '<h5>$1</h5>')
- .replace(/^####\s+(.*)$/gm, '<h4>$1</h4>')
- .replace(/^###\s+(.*)$/gm, '<h3>$1</h3>')
- .replace(/^##\s+(.*)$/gm, '<h2>$1</h2>')
- .replace(/^#\s+(.*)$/gm, '<h1>$1</h1>');
- // 加粗与斜体
- text = text.replace(/\*\*(.+?)\*\*/g, '<strong>$1</strong>')
- .replace(/\*(.+?)\*/g, '<em>$1</em>');
- // 行内代码
- text = text.replace(/`([^`]+?)`/g, (m, g1) => `<code>${g1}</code>`);
- // 换行
- text = text.replace(/\n/g, '<br/>');
- // 还原代码块占位符
- codeBlocks.forEach((html, idx) => {
- const placeholder = new RegExp(`__CODE_BLOCK_${idx}__`, 'g');
- text = text.replace(placeholder, html);
- });
- return text;
- }
- // 尝试使用 marked
- export function markdownToHtml(input) {
- if (!input) return '';
- try {
- // 某些运行环境可能不支持 require,这里用可选方案
- let markedLib = null;
- if (typeof require !== 'undefined') {
- try { markedLib = require('marked'); } catch (e) { markedLib = null; }
- }
- if (markedLib && markedLib.parse) {
- return markedLib.parse(input);
- }
- } catch (e) {
- // 忽略,使用简化解析
- }
- return simpleMarkdown(input);
- }
- export default {
- markdownToHtml
- };
|