// 一个小型且安全的 Markdown -> HTML 解析器(支持标题、段落、链接、粗体、斜体、行内代码)
function escapeHtml(str) {
return str.replace(/&/g, '&').replace(//g, '>')
}
function parseInline(md) {
// code
md = md.replace(/`([^`]+)`/g, '$1')
// bold **text** or __text__
md = md.replace(/\*\*([^*]+)\*\*/g, '$1')
md = md.replace(/__([^_]+)__/g, '$1')
// italic *text* or _text_
md = md.replace(/\*([^*]+)\*/g, '$1')
md = md.replace(/_([^_]+)_/g, '$1')
// links [text](url)
md = md.replace(/\[([^\]]+)\]\(([^)]+)\)/g, (m, text, url) => {
const safeUrl = url.replace(/\"/g, '%22')
return `${text}`
})
return md
}
function parsedHeaderHtml(headerMarkdown){
const raw = headerMarkdown || ''
// split into lines and paragraphs
const blocks = raw.split(/\n{2,}/g)
const html = blocks.map(block => {
const line = block.trim()
if (!line) return ''
// heading
const hMatch = line.match(/^(#{1,6})\s+(.*)$/)
if (hMatch) {
const level = Math.min(6, hMatch[1].length)
const content = parseInline(escapeHtml(hMatch[2]))
// 增加块间距(mb-2)以扩大行之间的视觉间隔
return `
${parseInline(escapeHtml(line))}
` }).join('\n') return html } export { parsedHeaderHtml }