/** * marked HTML 后处理:为代码块/内联 code/链接/表格注入 inline style(P1-G)。 * * 为什么后处理而非 marked 自定义 renderer: * - mp-weixin rich-text 不链接页面 CSS class,仅认节点 inline style → 必须把样式写进 HTML 属性。 * - 纯字符串后处理规避 marked renderer 版本签名差异(v5 前 (text,info) / v5+ Token 对象), * 版本无关,build 不依赖 renderer TS 签名。 * * mp-weixin rich-text 限制(已核官方文档,非臆测): * - 节点事件屏蔽,无法 bindtap 跳转 → 链接仅展示 + 长按复制(rich-text selectable=true); * 跳转需第三方 mp-html(本次不做,记后续)。 * - rich-text 非滚动容器,overflow-y:auto/max-height 不创建滚动区 → 长代码靠 * white-space:pre-wrap + word-break:break-all 换行防撑爆,不限高滚动。 */ /** 给指定标签注入 inline style(已有 style 则合并,无则新增)。 */ function styleTag(html: string, tag: string, style: string): string { const re = new RegExp(`<${tag}(\\s[^>]*)?>`, 'g') return html.replace(re, (m, attrs: string) => { if (attrs && /\sstyle\s*=/.test(attrs)) { // 已有 style:追加(在现有 style 值末尾加分号 + 新 style) return m.replace(/style\s*=\s*"([^"]*)"/, (_full, prev: string) => { const merged = prev.endsWith(';') ? prev : `${prev};` return `style="${merged}${style}"` }) } return `<${tag}${attrs || ''} style="${style}">` }) } /** * 对 marked.parse 产出的 HTML 注入 inline style。 * * 设计取舍:pre(块代码)给深色背景; 不给背景(透明),仅等宽+橙色 —— 避免块代码内层 code * 与 pre 背景冲突的双层色块(块代码内 code 透明继承 pre 深底,内联 code 橙色等宽在消息底上也可读)。 */ export function styleMarkdown(html: string): string { let out = html // 块代码
:深色背景 + 等宽 + 圆角 + pre-wrap 换行防撑爆
  out = styleTag(
    out,
    'pre',
    'display:block;background-color:#1a1a1a;color:#d4d4d4;padding:10px;border-radius:6px;white-space:pre-wrap;word-break:break-all;font-family:monospace;font-size:12px;margin:6px 0',
  )
  // code(块内 + 内联):等宽橙色,透明背景(避与 pre 双层色块)
  out = styleTag(
    out,
    'code',
    'font-family:monospace;color:#e0a070;background-color:transparent;font-size:12px',
  )
  // 链接:蓝下划线(rich-text 不可点击,仅展示 + selectable 长按复制)
  out = styleTag(out, 'a', 'color:#4a9eff;text-decoration:underline')
  // 表格:border + 块级 + 横向溢出处理(rich-text 非滚动,靠 word-break 兜底;border 提升可读)
  out = styleTag(
    out,
    'table',
    'display:block;border-collapse:collapse;width:100%;font-size:12px;word-break:break-all',
  )
  out = styleTag(out, 'th', 'border:1px solid #333;padding:4px 6px;background-color:#1a1a1a')
  out = styleTag(out, 'td', 'border:1px solid #333;padding:4px 6px')
  return out
}