markdown.js 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. /**
  2. * Markdown 转 HTML(优先使用 marked,缺省时使用简化解析)
  3. * 所有代码注释使用中文
  4. */
  5. // 简单的 HTML 转义
  6. function escapeHtml(input) {
  7. if (!input) return '';
  8. return input
  9. .replace(/&/g, '&')
  10. .replace(/</g, '&lt;')
  11. .replace(/>/g, '&gt;')
  12. .replace(/"/g, '&quot;')
  13. .replace(/'/g, '&#39;');
  14. }
  15. // 简化版 Markdown 解析(支持标题、加粗、斜体、行内代码、代码块、换行)
  16. function simpleMarkdown(input) {
  17. if (!input) return '';
  18. // 提前提取 ```code``` 代码块,避免被后续规则影响
  19. const codeBlocks = [];
  20. let text = input.replace(/```([\s\S]*?)```/g, (m, g1) => {
  21. const placeholder = `__CODE_BLOCK_${codeBlocks.length}__`;
  22. codeBlocks.push(`<pre><code>${escapeHtml(g1)}</code></pre>`);
  23. return placeholder;
  24. });
  25. // 转义剩余文本
  26. text = escapeHtml(text);
  27. // 标题(支持 # 到 ######)
  28. text = text.replace(/^######\s+(.*)$/gm, '<h6>$1</h6>')
  29. .replace(/^#####\s+(.*)$/gm, '<h5>$1</h5>')
  30. .replace(/^####\s+(.*)$/gm, '<h4>$1</h4>')
  31. .replace(/^###\s+(.*)$/gm, '<h3>$1</h3>')
  32. .replace(/^##\s+(.*)$/gm, '<h2>$1</h2>')
  33. .replace(/^#\s+(.*)$/gm, '<h1>$1</h1>');
  34. // 加粗与斜体
  35. text = text.replace(/\*\*(.+?)\*\*/g, '<strong>$1</strong>')
  36. .replace(/\*(.+?)\*/g, '<em>$1</em>');
  37. // 行内代码
  38. text = text.replace(/`([^`]+?)`/g, (m, g1) => `<code>${g1}</code>`);
  39. // 换行
  40. text = text.replace(/\n/g, '<br/>');
  41. // 还原代码块占位符
  42. codeBlocks.forEach((html, idx) => {
  43. const placeholder = new RegExp(`__CODE_BLOCK_${idx}__`, 'g');
  44. text = text.replace(placeholder, html);
  45. });
  46. return text;
  47. }
  48. // 尝试使用 marked
  49. export function markdownToHtml(input) {
  50. if (!input) return '';
  51. try {
  52. // 某些运行环境可能不支持 require,这里用可选方案
  53. let markedLib = null;
  54. if (typeof require !== 'undefined') {
  55. try { markedLib = require('marked'); } catch (e) { markedLib = null; }
  56. }
  57. if (markedLib && markedLib.parse) {
  58. return markedLib.parse(input);
  59. }
  60. } catch (e) {
  61. // 忽略,使用简化解析
  62. }
  63. return simpleMarkdown(input);
  64. }
  65. export default {
  66. markdownToHtml
  67. };