完善前端 Markdown 渲染:排版样式、代码高亮、标题锚点、图片灯箱、复制按钮 #1

Merged
kevin merged 1 commits from dsh/go_blog:feat/markdown-rendering into main 2026-08-18 18:12:12 +08:00
Contributor

概述

完善前端 Markdown 渲染能力:文章正文、评论、后台评论列表、编辑器预览统一走一套增强渲染管线(marked + DOMPurify + highlight.js),并补齐了缺失的排版样式。

主要改动

新增共享渲染器 static/js/markdown.js(全局 BlogMD):

  • GFM 支持(表格、任务列表、删除线、自动链接),输出始终经过 DOMPurify 消毒
  • 标题锚点:marked v4+ 已不再默认生成 heading id,新增 CJK 友好的 slugger 重新生成 id,标题悬停显示 # 锚点链接
  • 代码块:highlight.js 语法高亮(声明语言时)、语言徽标、一键复制按钮(含无 Clipboard API 时的降级方案)
  • 图片:懒加载 + 点击灯箱预览(Esc / 点击关闭)
  • 外链自动加 target="_blank" rel="noopener noreferrer"
  • 表格在小屏下横向滚动(外层包裹)

新增排版样式 static/css/markdown.css.md-body 作用域下的完整文章排版(标题层级、表格、列表、任务列表、引用块、行内/块级代码、图片、分割线等)。此前页面大量使用 prose 类,但项目用的是 Tailwind Play CDN,并未加载 typography 插件,导致文章/评论实际没有任何排版样式。

修复的问题

  • marked.setOptions({ mangle, headerIds })parse 之后调用且这两个选项在 marked v4+ 已被移除,属于无效代码 —— 已移除,改为 marked.use() 正确配置
  • CDN 未锁版本(marked/marked.min.js 实际解析到 v15.0.12,v16+ 已不再提供该 UMD 文件,不锁版本会随时失效)—— 统一固定 marked@15.0.12 / dompurify@3.4.13 / highlight.js@11.12.0

编辑器:管理后台与作者的文章编辑器(EasyMDE)的预览 / 分屏预览接入 BlogMD,预览效果与发布后一致。

其他main.go 新增 /static 静态路由;install_linux.sh 部署时同步安装 static/ 目录。

验证

  • go build ./... / go vet ./... 通过
  • 本地起服务 + 注入含表格/任务列表/多语言代码块/引用块/图片的测试文章,Headless Chrome 实测 25 项断言全部通过:标题锚点(含中文 id)、悬停显示、代码高亮、复制按钮(复制内容与代码块完全一致)、语言徽标、表格包裹、任务列表、懒加载图片、灯箱开关、外链 rel、评论渲染、编辑器预览、XSS 消毒(<script>/iframe/onerror/javascript: 均被剥离)
## 概述 完善前端 Markdown 渲染能力:文章正文、评论、后台评论列表、编辑器预览统一走一套增强渲染管线(marked + DOMPurify + highlight.js),并补齐了缺失的排版样式。 ## 主要改动 **新增共享渲染器** `static/js/markdown.js`(全局 `BlogMD`): - GFM 支持(表格、任务列表、删除线、自动链接),输出始终经过 DOMPurify 消毒 - 标题锚点:marked v4+ 已不再默认生成 heading id,新增 CJK 友好的 slugger 重新生成 id,标题悬停显示 `#` 锚点链接 - 代码块:highlight.js 语法高亮(声明语言时)、语言徽标、一键复制按钮(含无 Clipboard API 时的降级方案) - 图片:懒加载 + 点击灯箱预览(Esc / 点击关闭) - 外链自动加 `target="_blank" rel="noopener noreferrer"` - 表格在小屏下横向滚动(外层包裹) **新增排版样式** `static/css/markdown.css`:`.md-body` 作用域下的完整文章排版(标题层级、表格、列表、任务列表、引用块、行内/块级代码、图片、分割线等)。此前页面大量使用 `prose` 类,但项目用的是 Tailwind Play CDN,并未加载 typography 插件,导致文章/评论实际没有任何排版样式。 **修复的问题**: - `marked.setOptions({ mangle, headerIds })` 在 `parse` 之后调用且这两个选项在 marked v4+ 已被移除,属于无效代码 —— 已移除,改为 `marked.use()` 正确配置 - CDN 未锁版本(`marked/marked.min.js` 实际解析到 v15.0.12,v16+ 已不再提供该 UMD 文件,不锁版本会随时失效)—— 统一固定 marked@15.0.12 / dompurify@3.4.13 / highlight.js@11.12.0 **编辑器**:管理后台与作者的文章编辑器(EasyMDE)的预览 / 分屏预览接入 `BlogMD`,预览效果与发布后一致。 **其他**:`main.go` 新增 `/static` 静态路由;`install_linux.sh` 部署时同步安装 `static/` 目录。 ## 验证 - `go build ./...` / `go vet ./...` 通过 - 本地起服务 + 注入含表格/任务列表/多语言代码块/引用块/图片的测试文章,Headless Chrome 实测 25 项断言全部通过:标题锚点(含中文 id)、悬停显示、代码高亮、复制按钮(复制内容与代码块完全一致)、语言徽标、表格包裹、任务列表、懒加载图片、灯箱开关、外链 rel、评论渲染、编辑器预览、XSS 消毒(`<script>`/`iframe`/`onerror`/`javascript:` 均被剥离)
dsh added 1 commit 2026-08-18 18:06:09 +08:00
- Add shared BlogMD renderer (static/js/markdown.js): marked + DOMPurify
  + highlight.js pipeline with GFM support, heading id slugger with
  CJK-aware anchors, syntax highlighting, per-block copy button and
  language badge, lazy images with lightbox, external links opened
  safely in new tabs, tables wrapped for small screens.
- Add .md-body typography styles (static/css/markdown.css) so articles,
  comments and editor previews render with proper headings, tables,
  lists, blockquotes and code blocks (previously the prose classes had
  no effect because the Tailwind typography plugin is not loaded).
- Fix marked options that were set after parsing and removed from
  marked v4+ (mangle/headerIds no-ops).
- Pin CDN versions (marked 15.0.12, dompurify 3.4.13, highlight.js
  11.12.0) instead of floating 'latest' URLs.
- Wire EasyMDE preview/side-by-side to BlogMD in admin and user
  article editors; use BlogMD for comment bodies on the article page,
  admin comment list and comment preview.
- Serve /static in main.go and deploy it in install_linux.sh.
kevin merged commit 5f21c73044 into main 2026-08-18 18:12:12 +08:00
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: kevin/go_blog#1