小红书排版自动化:构建本地 Markdown 切图工具
背景
这个博客使用 Astro 构建,文章以 Markdown/MDX 格式书写,通过 Tailwind Typography 渲染为日式文库本风格。但当我试图将文章分享到小红书时,遇到了一个典型的问题:
小红书的图片发布机制与长文章天然矛盾。
平台支持最多 18 张图片,每张图有固定的宽高比限制(竖屏 3:4,即 1080×1440px)。手动截图排版不仅效率低下,而且难以保证每一页的视觉一致性和文字完整性。
于是有了这个需求:一个本地运行的脚本,能自动将 Markdown 文章渲染、分页并导出为高清序列图,直接用于小红书发布。
设计目标
- 画布标准:1080×1440px,四周 80px 安全边距,实际内容区 920px
- 视觉对齐:延续博客的文库本美学——米白底色、衬线字体、宽松行距
- 智能分页:不能简单按高度裁剪,必须保证文字和图片不被截断
- 高清输出:2x 缩放因子,输出 2160×2880px 的 Retina 级别图片
技术方案
核心思路:用 Playwright 无头浏览器渲染 HTML,通过 DOM 遍历实现逐元素分页。
整个工具分为三个模块:
- Markdown 解析 — 将 MD/MDX 解析为结构化 HTML
- 智能分页引擎 — 逐个元素插入虚拟容器,检测溢出后自动换页
- 截图输出 — 对每个分页容器截图,按顺序输出 PNG
智能分页算法
这是整个脚本最关键的部分。不能简单粗暴地每 1440px 切一刀——那会导致文字或图片被拦腰截断。
算法思路如下:
- 创建一个宽 1080px、高 1440px 的虚拟页面容器
- 遍历所有 HTML 元素(段落、标题、图片、引用块)
- 逐个插入元素,实时检测容器 scrollHeight
- 若插入后溢出,撤销插入,封口当前页面
- 创建新页面,将溢出元素放入,继续循环
样式渲染
排版规格与博客保持一致:
- 字体:
Noto Serif CJK SC等系统衬线体 - 行高:1.8–2.0,段落间距 1.5em
- 引用块:左侧浅灰边框 + 背景色卡片
- 图片:max-width 100%,圆角 12px,限制最大高度
对话体识别
文章如包含对话格式(“小松:”、“寺岛:”),脚本会通过正则匹配自动识别,为说话人姓名加粗或使用不同颜色以示区分——这在采访类文章中尤为重要。
目录结构
scripts/xhs-exporter/
├── index.js # 主逻辑入口
├── template.html # HTML 渲染模板
└── package.json # 依赖声明
执行方式:
node scripts/xhs-exporter/index.js ./src/content/posts/article.md
输出:
output/
├── page_01.png
├── page_02.png
├── page_03.png
└── ...
后续方向
目前脚本已覆盖核心分页逻辑,后续可以扩展:
- 模板系统:支持不同社交平台的尺寸预设(微信、微博等)
- 批量处理:一键转换整个 content 目录
- 水印/署名:自动在末页添加出处信息
- 预览模式:本地启动一个 Web 界面实时调整分页