iKode Blog icon iKode Blog
返回文章列表

Article

Markdown 排版实验台:让预览和正式文章共用一套渲染器

技术笔记2026年6月19日 09:051 min

真正可靠的 Markdown 预览,不是长得差不多,而是和正式文章走过完全相同的渲染路径。

Markdown 排版实验台最重要的目标,不是做一个功能很多的编辑器,而是回答一个更具体的问题:我现在看到的预览,发布后还会不会是这个样子?

如果浏览器预览和服务端文章各自维护一套 Markdown 规则,标题、链接、原始 HTML 和排版细节迟早会出现差异。因此实验台没有在前端重新创建渲染器,而是把草稿发送到 Lab API,再调用正式内容页使用的 renderMarkdown

/** Render Markdown through the same safe server renderer used by content pages. */
async function renderPreview(content: string) {
  const response = await $fetch<ApiResponse<{ html: string }>>(
    '/api/lab/markdown-preview',
    { method: 'POST', body: { content } }
  )

  previewHtml.value = response.data.html
}

服务端入口只做两件事:用 Zod 限制输入,再交给共享渲染函数。当前渲染器关闭原始 HTML,同时保留自动链接和排版优化,因此 Lab 与公开文章天然保持一致。

return apiSuccess(event, {
  html: renderMarkdown(parsed.data.content)
})

除了 HTML 预览,工具还会即时计算字符、段落、代码块和阅读时间。统计逻辑保持为纯函数,不依赖 DOM,也不需要等待网络请求。这样编辑时的反馈是即时的,真正的 HTML 渲染则继续由服务端负责。

export function getMarkdownStats(content: string) {
  const trimmed = content.trim()
  const text = plainMarkdownText(trimmed)
  const readableUnits = readableUnitCount(text)

  return {
    characters: text.length,
    paragraphs: trimmed ? trimmed.split(/\n\s*\n/).filter(Boolean).length : 0,
    readingMinutes: readableUnits ? Math.max(1, Math.ceil(readableUnits / 450)) : 0
  }
}

这种拆分让界面保持轻快,也守住了发布一致性。前端负责输入、状态和快速统计;服务端负责验证和可信渲染。它不复杂,但很适合一个会长期写文章的网站。

可以在 Markdown 排版实验台 直接试写。

Comments

留言

需要 GitHub 登录。新评论会先进入待审核,别急,它只是先坐到门口等一会儿。

使用 GitHub 登录后可以评论。

已通过评论

0

还没有通过审核的评论。桌子很安静,第一杯茶还没端上来。