Files
MorphDoc/docs/PROGRESS.md
T

987 lines
56 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Markdown PDF 导出器进度
最后更新:2026-07-30
## 1. 当前概况
项目目录:
```text
C:\Projects\md-to-pdf
```
当前分支:
```text
main
```
已有提交:
```text
b459def fix: 修复预览与 PDF 渲染边界问题
d93728b feat: 完善 Mermaid 配置与预览缩放
d1b5880 feat: 实现 Chromium PDF 导出与精确预览
d625523 fix: 修复长文档分页与滚动同步
1d93f31 feat: 实现真实分页预览
52cf816 feat: 完善导出设置与打印预览
ec14f79 feat: 扩展本地主题兼容能力
fa07472 feat: 实现网页实时预览
7224dfd feat: 实现 Markdown 渲染核心
ec48bce chore: 初始化项目骨架
```
`v0.4.1` 图片资源阶段已经完成:Web 素材目录、Desktop 同目录资源、
受限公网图片下载、可见图片标题、图片整块分页与超高图片单页适配均复用
统一渲染链路。Electron 安装包和 Docker Compose 发布候选均已通过验证。
`v0.4.2` 为仅面向桌面端的维护版本:移除 Windows 原生应用菜单栏;
Web/Compose 发布仍保持 `v0.4.1`
`v0.4.3` 将桌面发行包迁移为标准 NSIS 安装向导,并使用全英文、无空格、
包含版本与平台的安装包文件名;Web/Compose 发布仍保持 `v0.4.1`
`v0.4.4` 仅精简 Electron 桌面发行包的语言资源,保留简体中文和英文;
Web/Compose 发布仍保持 `v0.4.1`
`v0.4.5` 同步更新 Web 与 Desktop:新增新建/保存 Markdown、桌面文件
关联、窗口状态恢复、自定义主题目录和收纳式“更多”菜单;Web 明确取消
本地素材目录。图片、Mermaid 与 ECharts 的分页算法统一为按文档顺序
串行计算的媒体块回填,每个媒体元素至多重排一次,标题保持原尺寸。
`v0.5.0` 完成渲染架构和桌面文档工作流升级:分页与连续预览抽取为共享
`packages/preview-engine`,快速预览支持从修改位置复用稳定前缀;Web
增加连续预览和受控外链,Desktop 支持多窗口、同文件单例、本地链接及
聚焦时外部文件变化提示。四套主题统一命名,并修复围栏代码块的 Typora
DOM 兼容和桌面发行包复用陈旧 Web 产物的问题。
`v0.5.1` 正式版新增 10 套政企与标书主题、规范页边距和页面装饰、
结构化公文 Front Matter、内置中文字体、教程及 14 份主题示例;同时
重组“更多”菜单,补齐桌面文件快捷键、未保存确认和跟随新路径的另存为,
并修复红头标题居中、代码块自动换行、左侧内容留白和跨页分页。Windows
安装包、Docker Compose、本机安装与发布验证均已完成。
`v0.6.0` 已完成开发立项,核心范围冻结为 DOCX 导出与 Markdown
工具栏。DOCX 采用 Node.js 编排、固定版本 Pandoc、动态
`reference.docx` 和 Chromium/Electron 高分辨率 PNG 媒体管线,不引入
Python;左侧编辑器计划升级为 CodeMirror 6,并通过项目自有命令注册层
支持基础工具栏及后续 Front Matter、ECharts YAML 工具扩展。完整设计与
验收门禁见 [v0.6.0 设计文档](V0.6.0_DESIGN.md)。
`v0.6.0` 阶段 2 已完成 Pandoc 运行时探查:固定 `3.9.0.2`,官方
Windows ZIP 和 Linux amd64 tarball 的 SHA-256 均已核验;Linux 静态程序
可直接运行于 `node:22-bookworm-slim`。Desktop 安装包预计增加约
39.34 MiB,解压目录增加约 220.35 MiB;Docker 压缩层预计增加约
32.92 MiB,运行内容增加约 154.13 MiB。项目当前采用公司内部专属许可,
未来公开 GitHub 时计划重新评估并切换到 Apache License 2.0。三套 Typora
复制主题允许继续用于公司内部源码共享、部署和安装包分发,但不受项目
许可证重新授权;公开 GitHub 前必须移除、替换或取得公开分发授权。
## 2. 已完成
### 2.1 项目骨架
- 建立 npm workspaces。
- 建立 React + Vite 前端。
- 建立 Fastify 后端。
- 建立 `packages/core` 共享包。
- 建立主题、测试和 Docker 目录。
- 初始化本地 Git 仓库。
### 2.2 导出配置模型
`packages/core/src/export-config.ts` 已包含:
- 版本 3 配置模型;
- A3、A4、A5、Letter、Legal、Tabloid 和自定义纸张;
- 横向、纵向;
- 四边页边距;
- 页眉和页脚左右中区域;
- 页码位置和格式;
- PDF 元数据;
- 打印背景、缩放和一级标题分页选项;
- Mermaid 布局、主题、外观和字体;
- Zod 数据校验;
- 默认 A4 技术文档预设。
### 2.3 主题接口
`packages/core/src/theme.ts``themes/typora-like` 和动态主题注册器已包含:
- 版本化主题清单;
- 主题 ID、名称、版本、作者、许可证;
- DOM 预设;
- 支持能力声明;
- 可选基础 CSS、主体 CSS 和打印 CSS
- 自制 Typora 风格主题;
- `#write` 兼容文档结构;
- 内置主题和 `.local/themes` 本地主题动态扫描;
- 按基础 CSS、主体 CSS、打印 CSS 的固定顺序组合;
- 主题内相对 CSS `@import` 安全展开;
- 主题 CSS 相对资源重写与受限资源接口;
- 目录匹配、真实路径包含关系和外部 URL 安全检查。
内置主题包含项目自有的 Typora 风格主题,以及按公司内部私有项目决策
复制的 GitHub、Pixyll 和 Whitey 三套 Typora 默认主题。三套复制主题的
来源和内部使用边界记录在 `themes/INTERNAL_THEME_NOTICE.md`;如未来公开、
商用或向公司外部分发,必须重新完成许可证审查。
### 2.4 Markdown 渲染核心
提交 `7224dfd` 已完成:
- `packages/renderer` 独立工作区;
- Front Matter 解析;
- Markdown 到安全 HTML
- 标题锚点;
- 表格;
- 任务列表;
- 脚注;
- highlight.js 代码高亮;
- KaTeX 数学公式;
- Mermaid 安全占位;
- sanitize-html 安全过滤;
- 元数据规范化;
- 功能检测;
- 统一 `<article id="write">` 输出;
- 5 项渲染单元测试。
### 2.5 网页实时预览
提交 `fa07472` 已完成:
- 可测试的 Fastify `buildApp()`
- `POST /api/render` 服务端统一 Markdown 渲染;
- 动态主题清单、CSS 和资源 API;
- Markdown 编辑及本地 `.md` 文件读取;
- 250ms 防抖 A4 实时预览;
- iframe 隔离主题 CSS
- KaTeX、highlight.js 和按需加载的 Mermaid
- 桌面双栏与移动端上下布局;
- 5 项渲染器测试和 4 项后端测试。
### 2.6 主题兼容增强
提交 `ec14f79` 已完成:
- 主题清单可选基础 CSS
- 基础 CSS、主体 CSS、打印 CSS 固定组合顺序;
- 安全的相对 CSS `@import` 展开和资源 URL 重写;
- CSS 导入深度、循环、外部 URL 和越界路径检查;
- GitHub、Pixyll 和 Whitey 三套本地 Typora 白色主题导入;
- 可恢复替换和默认防覆盖;
- 主题开发指南;
- 后端测试增至 6 项。
### 2.7 导出设置与打印预览
提交 `52cf816` 已完成:
- 导出配置升级到版本 3,并兼容迁移版本 2 浏览器缓存;
- 纸张收敛为 A3、A4、A5、US-Letter 和 US-Legal
- 默认 A4 纵向和 16mm 四边页边距;
- 统一 96 CSS px/in、72 PDF pt/in 和 25.4mm/in 的物理单位换算;
- 响应式导出设置抽屉;
- 纸张、方向、页边距、页眉、页码和主题的版本化浏览器缓存;
- 页眉左中右内容和变量;
- 五种页码样式、对齐和起始页码;
- Mermaid 官方配置 frontmatter、默认主题与错误隔离;
- Mermaid 全局 Dagre/ELK 布局、官方主题、外观和字体设置;
- Markdown 表格对齐属性保留和自适应列宽;
- 纸张尺寸和页边距实时预览。
## 3. Chromium PDF 导出与精确预览
### 3.1 Chromium PDF 导出
- 引入固定版本 Playwright Chromium。
- 新增 `POST /api/pdf`,复用服务端 Markdown 渲染结果、`#write` DOM、主题 CSS、打印 CSS 和统一分页运行时。
- PDF 文本可搜索,支持中文、长表格、KaTeX、Mermaid、页眉、页脚和页码。
- Chromium 浏览器实例复用,每个请求使用独立 BrowserContext。
- 支持浏览器预热、并发门控、排队上限、超时和关闭清理。
- 仅允许同源、`data:``blob:``about:` 资源,阻止 PDF 页面访问外部网络。
- PDF 响应提供安全的 UTF-8 文件名、页数、Mermaid 错误数和 `Server-Timing`
- 前端“导出 PDF”按钮已启用,生成完成后直接下载。
### 3.2 快速预览与精确预览
- 快速预览继续使用 Paged.js,适合编辑时即时反馈。
- 精确预览直接复用 `/api/pdf` 结果,确保显示页数和最终下载一致。
- 快速与精确模式可以切换,PDF 缓存按 Markdown、主题和导出配置失效。
- PDF.js 使用集中渲染队列,当前可见页优先,滚动方向上的相邻页次优先。
- 远离视口的 Canvas 延迟释放,避免 65 页长文档持续占用大尺寸位图内存。
- 未完成渲染的页面显示白色占位,Canvas 完成后才显示,消除快速滚动时的黑影。
- 编辑区和两种预览模式支持按滚动比例同步定位。
### 3.3 Mermaid 分页性能优化
- Mermaid 仍使用官方渲染器、配置 frontmatter、严格安全模式、默认主题和 classic 样式。
- 渲染完成后记录 SVG 与容器的实际小数宽高,将 SVG 转为内嵌 Data URL 图片再交给 Paged.js 分页。
- 静态 SVG 仍由 Chromium 以矢量和可搜索文字输出,不发生位图化。
- 快速预览和 PDF 默认使用相同的静态 SVG;`mermaid-output=inline-svg` 仅保留为内部诊断开关。
- 65 页、67 个 Mermaid 的附件中,分页耗时约从 2.60 秒降至 1.29 秒,总生成耗时约降低 12.7%。
- A/B PDF 均为 65 页,逐页 61,102 个非空白字符和 11,762 个文本项完全一致。
### 3.4 PDF 性能观测
- 记录排队、浏览器、上下文、导航、文档渲染、Mermaid、资源等待、分页、PDF 打印和总耗时。
- `Server-Timing` 已暴露上述关键阶段,包括 `mermaid-conversion`
- 65 页附件的主要耗时来自 Mermaid 渲染、Paged.js 分页和 Chromium PDF 打印。
- PDF 缓冲区直接返回,避免无意义的二次 `Buffer` 复制。
### 3.5 AIO 容器部署
- 使用多阶段 Dockerfile 构建前端、后端和共享包。
- 基于 Node.js 22 Debian 构建运行镜像,并由项目锁定的 Playwright
`1.62.0` 安装精确匹配的 Chromium 与系统依赖。
- 单容器内由 Nginx 提供前端并代理 Fastify API。
- Playwright 通过同一 Nginx 地址加载精确预览运行时。
- 容器以非 root `pwuser` 运行并提供 1 GiB 共享内存。
- Compose 支持端口、只读主题目录、PDF 并发、队列和超时配置。
- 增加容器健康检查和统一进程退出处理。
- Nginx 显式以 JavaScript MIME 类型提供 PDF.js `.mjs` Worker。
### 3.6 Mermaid 配置与预览缩放
- Mermaid 固定为 `11.16.0`ELK 使用官方
`@mermaid-js/layout-elk@0.2.2` 并按需加载核心布局代码。
- 全局导出设置支持 Dagre、ELK、官方主题、Classic、Hand-drawn、Neo
外观和自定义本地字体。
- 单图 `config` Front Matter 可以覆盖全局布局、主题、外观、字体、
`themeVariables` 和图表专属配置。
- `style``classDef``linkStyle` 保持 Mermaid 原生语义。
- `themeCSS`、严格安全模式和资源限制不能由 Markdown 覆盖。
- Mermaid 与 Paged.js 计算期间隐藏分页 iframe,避免显示官方渲染器的
临时测量节点。
- 快速预览和精确预览共用 50%~400% 显示缩放,支持滑块、手动输入、
100% 重置和独立浏览器缓存。
- 缩放不进入导出配置,不改变分页或 PDF;精确预览会按显示宽度重绘
邻近 Canvas,保持文字清晰。
### 3.7 渲染边界修复与复用重构
- PDF 总超时覆盖 Chromium 启动、上下文创建、页面渲染和有界清理,
浏览器预热也受同一超时约束。
- 当前预览模式的重复点击不再触发无意义的状态重置和 PDF 请求。
- Mermaid 分页测量使用实际主题、字体和盒模型,静态 SVG 图片锁定实际
小数尺寸,避免测量容器宽度与真实纸张不一致。
- 非法 Front Matter 在预览和 PDF API 中统一返回 400;无效本地主题
会被隔离并记录警告,不影响其他主题。
- `packages/core` 统一维护 Markdown 文档、分页载荷、分页结果和耗时类型,
前端快速预览与后端 PDF 使用同一个载荷构造函数。
- 前端 Markdown 防抖渲染与主题清单/CSS 加载已从 `App.tsx` 抽取为独立
Hook,保留原有取消请求和错误隔离行为。
- 主题注册表增加 1 秒目录扫描缓存和主动失效接口,减少同一请求链路中
重复遍历主题目录,同时兼顾本地主题热更新。
- CSS 像素与 PDF 点数换算只使用 core 中的共享常量;删除已经不参与协议
或逻辑的 `contentHeight` 字段。
### 3.8 Windows 显示缩放与快速预览分页差异
- 此前 65 页长文档在快速预览中生成 64 页、在精确预览和最终 PDF 中
生成 65 页;该差异并非由 Chromium 版本不同导致。
- 出现差异时,笔记本内屏使用 Windows 150% 系统显示缩放。切换到使用
100% 显示缩放的外接显示器后,快速预览与精确预览的分页结果基本一致。
- 当前定位是:Windows 显示缩放改变浏览器的 `devicePixelRatio`,并可能
影响字体栅格化和 CSS 布局中的子像素取整;单处差异很小,但会在长文档
分页过程中累计,最终造成页数差异。
- 精确预览直接展示服务端 Chromium 生成的 PDF,最终下载也复用同一结果,
因此精确预览和最终 PDF 继续作为权威分页结果;快速预览定位为编辑期间的
客户端近似分页,不承诺在所有显示缩放环境下与 PDF 页数完全一致。
- 后续优化快速预览时,应重点检查 `devicePixelRatio`、浏览器页面缩放、
字体度量和逐页高度取整;分页测量不得依赖物理像素,视觉缩放不得参与
文档排版和分页计算,并避免逐页取整造成累计误差。
- 后续分页回归应覆盖 Windows 100%、125% 和 150% 系统显示缩放,分别
记录快速预览、精确预览和最终 PDF 的页数及分页边界。
### 3.9 Markdown ECharts 图表
- 新增可独立复用的 `packages/markdown-echarts` 工作区,为 Markdown-it
提供安全的 `echarts` YAML 围栏。
- 围栏支持版本、固定高度或宽高比、主题、图注和 ECharts `option`
高度默认 80mm,主题默认跟随文档。
- 当前支持 line、bar、scatter、pie、radar、heatmap、boxplot 和
candlestick 系列,并校验各系列的数据结构和必要坐标系。
- 每个系列必须使用非空 `series[].data``dataset.source` 或具有有效
上游数据的内置 transform;缺少数据等错误会显示包含配置路径的局部
占位,不中断整篇 Markdown。
- YAML 会转换为安全纯数据对象;禁止函数、自定义标签、锚点和别名、
外部 URL、HTML formatter、原型污染属性及 `custom` 系列。
- 浏览器按需加载 ECharts 模块,以 SVG 渲染,并可冻结为内联 SVG 或
SVG Data URL 图片;快速预览与 PDF 使用同一套运行时。
- 分页遵循 Mermaid 的不可拆分规则:当前页空间足够时原位放置,不足时
移到下一页,超高图表等比例缩放到单页内,不跨页切割。
- PDF 输出等待 ECharts、Mermaid、字体和图片全部完成后再分页,并分别
返回 ECharts 与 Mermaid 错误数量。
- 包内 README 已记录围栏语法、默认值、验证规则、错误行为、安全边界、
Markdown-it 接入和浏览器渲染方式。
### 3.10 工作区布局与页码导航
- 默认 Markdown 示例新增 ECharts 柱状图,打开网页即可验证 YAML 围栏、
SVG 渲染和分页。
- 文件名及渲染、分页、导出错误状态从源文本标题栏迁移到顶部应用标题
旁,长文件名支持省略和完整悬停提示。
- 源文本区域支持收起和展开;桌面端收起为 48px 左侧窄栏,预览区扩展
到剩余宽度并保持纸张居中,窄屏收起为 44px 顶部横条。
- 折叠内容使用真实 `display:none`,不会残留可聚焦文本框或进入无障碍
树;按钮提供 `aria-controls``aria-expanded`
- 当前页从预览标题行移到缩放工具栏左侧,显示为
`第 [n] / 总页数 页`,避免重复信息。
- 页码输入支持 Enter 和失焦提交,自动限制到 1~总页数;空值和非法
小数恢复当前页。
- 快速预览直接定位 iframe 内 `.pagedjs_page`;精确预览定位
`.precise-pdf-page`。滚动预览时输入框同步当前页。
- 精确预览会动态识别桌面内部滚动容器或窄屏主窗口滚动容器,目标页顶端
与实际可视滚动区域对齐。
- 快速预览 iframe 只负责生成分页内容并回传自然高度,滚动统一交给外层
`.preview-scroll`;滚动条因此与精确预览一样贴在右侧预览容器边缘,
不再贴着居中的纸张右边缘。
- 快速预览的页码识别和跳转会合并外层滚动位置、iframe 位置、内部分页
位置与显示缩放比例,50%~400% 视觉缩放不会破坏页码同步。
### 3.11 ECharts 第二阶段图表
- ECharts 系列支持从首版 8 种扩展到 17 种,新增 `tree``treemap`
`sunburst``graph``sankey``chord``funnel``gauge`
`pictorialBar`
- 当前使用 ECharts 6.1.0`chord` 直接采用 ECharts 6 官方和弦图及
`ChordChart` 按需模块,不引入第三方扩展。
- `tree``treemap``sunburst` 校验递归层级结构;矩形树图和旭日图
的叶节点必须提供有限数值。
- `graph``sankey``chord` 校验节点、关系边、端点引用与边权重;
Graph 未指定布局时,有完整坐标则使用 `none`,否则默认使用 `force`
- `funnel``gauge` 校验有限数值数据;`pictorialBar` 复用柱图的数据和
坐标轴规则,并允许不加载外部资源的 `path://` 内嵌矢量路径。
- 安全策略新增层级节点、关系节点和关系边数量限制,继续禁止外部图片、
跳转链接、函数、HTML formatter 和原型污染属性。
- 默认 Markdown 现在包含基础柱状图及九种第二阶段图表,每种均使用独立
YAML 围栏,可直接编辑和观察 SVG、分页及错误占位行为。
- Treemap 默认示例关闭节点下钻和面包屑,显式启用父级与叶节点标签,并
增加白色分隔边框,避免扁平数据区域缺少辨识信息或底部控件占用空间。
- Markdown/PDF 属于确定性的静态输出场景,浏览器引擎会在全局和系列级
强制关闭 ECharts 动画、动画延迟和持续时间,不允许 YAML 动画参数使
预览或 PDF 停留在动画中间帧。
### 3.12 v0.4.0 Electron 桌面端
- 新增 `apps/desktop` Electron 43.2.0 工作区,使用 Electron Forge
7.11.2 打包。
- 根项目版本升级为 `0.4.0`Vite 从根 `package.json` 注入统一版本,
工具标题右侧显示 `v0.4.0` 徽标。
- 应用窗口和 PDF 窗口均关闭 Node Integration,启用 Context Isolation
和 Chromium Sandbox,并使用不同 preload 暴露窄 IPC 接口。
- 桌面端 PDF 直接接收 Web 端已经构造的共享分页载荷,复用现有
`PagedDocumentRuntime`、主题 CSS、Mermaid 和 ECharts 运行时。
- 隐藏 PDF 窗口使用 Electron 自带 Chromium 的
`webContents.printToPDF()`,桌面发行包不携带 Playwright Chromium。
- Paged.js 的帧队列在纯隐藏窗口中不会推进;桌面 PDF 任务期间使用
计时器调度分页队列,分页完成后恢复原生 `requestAnimationFrame`
- Chromium 打印前将透明、不可聚焦、不进入任务栏的 PDF 窗口短暂放到
屏幕外,使复杂分页页面拥有可打印的窗口表面,用户不会看到该窗口。
- PDF Buffer 通过受控 IPC 返回 Web 界面,桌面端使用系统“另存为”对话框
写入文件;Web 版继续使用浏览器下载行为。
- 生产页面通过 `mdpdf://bundle/` 自定义安全协议加载,不使用权限过宽的
`file://`PDF Session 只允许同源、`data:``blob:``about:`
资源。
- Windows x64 未签名目录包、Squirrel `Setup.exe` 和 ZIP 已由 Forge
成功生成;`app.asar` 只包含
编译后的主进程、preload 和清单,Web 静态资源作为只读资源单独打包。
- 新增 `packages/application`,统一封装 Markdown 渲染、主题清单、主题
CSS 和主题资源读取;Fastify 仅作为 HTTP 适配器。
- Web 端通过应用后端抽象选择 HTTP 或 Electron IPC;桌面端通过受限 IPC
直接调用共享服务,不启动 Fastify,不占用本地 HTTP 端口。
- 主题资源通过 `mdpdf://theme/` 安全协议提供,应用窗口与独立 PDF
Session 均完成协议注册和来源限制。
- 修复 Electron 主进程 ESM Bundle 中 YAML 依赖动态加载 `process`
失败的问题,构建时注入 Node `createRequire`
- `logos/` 作为统一品牌源:Web 使用 favicon、Apple Touch Icon 和
Web ManifestElectron 使用 ICO、ICNS、窗口图标和安装器图标。
- Forge 输出目录包含版本号,正式内部交付使用 Squirrel `Setup.exe`
ZIP 作为免安装辅助包;当前未签名。
### 3.13 v0.4.0 内置主题与发布产物
- `.local/themes` 中 GitHub、Pixyll 和 Whitey 三套主题已复制到
`themes/`,从 v0.4.0 起随 Web 容器和桌面安装包内置。
- 内置主题注册优先于相同 ID 的本地主题,避免 Compose 默认挂载旧副本
覆盖发布版本,并记录可诊断警告。
- Windows 正式安装包为
`Markdown PDF 导出器-0.4.0 Setup.exe`,约 137.48 MiBSHA-256 为
`9C12F9A007E102BDB5213ABC5246F4480083FCA5D67DCD45354728BCFDB54220`
- 中文产品名、窗口标题、安装包和开始菜单名称保持不变,Windows 主程序
与进程文件固定为 `md-to-pdf.exe`;目录包和 Squirrel NUPKG 均已验证。
- 本地镜像为 `yixiong/md-to-pdf:v0.4.0`Compose 容器保持健康运行并
监听 `http://localhost:8080`
- Dockerfile 默认保留完整 Playwright Chromium 安装路径,同时支持通过
构建参数复用本机已验证的旧版本运行层,适合内网软件源较慢的环境。
### 3.14 v0.4.1 图片资源与标题分页
- `packages/application` 统一提取 Markdown 图片引用,将验证后的本地或
远程图片转换为 Data URL,再交给 Web 预览、Playwright PDF 和 Electron
PDF 共用的 HTML。
- Web 增加素材目录选择,支持把 Markdown 的关联图片作为受限 Base64
资源随渲染和 PDF 请求提交;请求体上限同步提高到 24 MiB。
- Desktop 增加原生“打开 Markdown”,主进程记录文档目录并直接读取相对
图片,不启动 Server,也不允许读取文档目录之外的文件。
- 相对路径支持中文、空格和百分号编码;拒绝绝对路径、`..` 穿越和符号
链接越界。
- 远程图片支持 HTTP/HTTPS、逐跳重定向校验、10 秒超时、格式嗅探与
5 分钟缓存;阻止 localhost、私网和链路本地目标,并兼容企业代理常用
的域名 Fake-IP 网段。
- 每篇文档最多 50 个图片引用,单图不超过 8 MiB,总图片不超过 15 MiB
支持 PNG、JPEG、GIF、WebP、AVIF 和受限 SVG。
- 独立图片使用 `figure + img + figcaption``[]` 中的文本显示为图片
标题;行内混排图片继续保持普通段落语义。
- 图片与标题整块分页。超高图先扣除标题区实际高度,再等比例缩放到单页,
与 Mermaid 和 ECharts 遵循相同的不可跨页规则。
- 默认示例增加 NASA 中等尺寸图与 Unsplash 超高竖图,直接覆盖正常图片
和超高图片分页场景。
### 3.15 v0.4.2 桌面窗口精简
- Electron 主进程不再创建默认应用菜单,移除窗口顶部的
`File / Edit / View / Window` 原生菜单栏。
- 应用窗口同时启用菜单栏自动隐藏,避免 Windows 恢复默认菜单。
- 该维护版本只重新生成桌面安装包和免安装 ZIP;Web/Compose 镜像继续
使用已验证的 `v0.4.1`
### 3.16 v0.4.3 标准 Windows 安装向导
- 桌面发行链路由 Electron Forge Squirrel 迁移到 electron-builder
26.15.3 的 NSIS assisted installer。
- 安装向导提供当前用户/所有用户安装选项、安装目录选择、安装进度和完成
页面;主程序继续使用 `md-to-pdf.exe`
- 正式安装包固定命名为
`md-to-pdf-0.4.3-x86_64-Setup.exe`,免安装包命名为
`md-to-pdf-0.4.3-x86_64.zip`
- 项目自有 `build/installer.nsh` 显式创建桌面和开始菜单快捷方式,
安装完成后直接启动主程序,不依赖 `.lnk`
- 卸载时显式清理桌面快捷方式、开始菜单快捷方式及其目录。
- 安装包和校验文件作为 Gitea `v0.4.3` Release 附件发布,不写入 Git
历史。
### 3.17 v0.4.4 桌面语言包精简
- Electron 发行包只保留 `zh-CN``en-US` 两种 Chromium 语言资源。
- 不裁剪 ICU、ANGLE、Direct3D、Dawn、SwiftShader 或其他 Chromium
运行时组件,保证桌面预览与 PDF 导出在不同图形环境下的可靠性。
- 本版本只重新生成桌面安装包和免安装 ZIP;Web/Compose 发布继续保持
`v0.4.1`
### 3.18 v0.4.5 文档工作流与媒体分页
- Web 与 Desktop 均支持新建 Markdown;未保存时使用“未命名文档”状态,
不显示伪造源文件名,并允许直接导出 PDF。
- Web 保存使用浏览器下载;Desktop 使用原生另存为。默认文件名优先取
第一个一级标题,没有一级标题时取首行可见文本,并清理 Windows 非法
字符、保留名和末尾空格或句点。
- “打开 Markdown”继续作为顶部独立强操作;新建、保存及桌面自定义主题
目录收纳到“更多”菜单,Web 不再显示本地素材目录入口。
- Windows 安装包注册 `.md``.markdown` 文件关联;系统打开文件会
转交给现有单实例窗口并自动加载。
- Desktop 监听窗口位置、尺寸和最大化变化,延迟写入完整状态;退出前
刷新待写状态。下次启动按当前显示器工作区限制尺寸并修正坐标,避免
多显示器断开后窗口落在屏幕外。
- Desktop 会建立自定义主题目录,“更多”菜单可直接在资源管理器打开;
目录允许留空,放入合法主题后由共享主题注册器读取。
- 图片、Mermaid 和 ECharts 统一视为带标题的媒体块。分页按 DOM 文档
顺序串行处理,每个媒体元素只允许一次回填或缩放重排。
- 图片基准高度按原尺寸先收缩到内容限宽后计算;媒体块只有在上一页空白
与所需空间比例达到阈值时才尝试回填。缩放只作用于图片或图表内容,
标题保持原字号和自然高度。
- ECharts 在分页前冻结为 SVG 图片,三类媒体共享回填决策与边界检查;
无法安全回填时仍移至下一页,保证顺序、不跨页且不覆盖后续内容。
- 默认示例仅保留一张网络图片,并新增有效 Base64 横图、不同尺寸图片、
Mermaid 和 ECharts,用于观察媒体分页、标题配对和渲染效果。
- 根 README、Desktop README、四个工作区包 README、进度文档和发布
规范随版本同步更新。
### 3.19 v0.5.0 共享预览引擎与桌面多窗口
- 新增 `packages/preview-engine`,从 `apps/web` 抽取 Paged.js 运行时、
Mermaid、ECharts、图片尺寸适配、媒体回填、跨页表格和共享页面 CSS。
- Web 快速预览、服务端 Playwright PDF 与 Electron PDF 直接使用同一个
Preview EngineMarkdown 解析仍由 `packages/renderer` 的 markdown-it
管线负责,应用服务继续统一主题与图片资源。
- 新增“连续”预览模式,不创建纸张和分页节点,适合高频编辑;快速预览
保留分页反馈,精确预览与最终 PDF 继续作为权威结果。
- 增量分页根据源块稳定身份识别最早修改位置,复用此前稳定分页前缀,并
串行重算受影响后缀;最终 PDF 不依赖客户端缓存。
- Web 只处理当前文档锚点和 HTTP/HTTPS 外链,外链使用浏览器新窗口;
本地路径及不支持协议不会替换预览 iframe。
- Desktop 支持 HTTP/HTTPS、系统协议、相对或绝对本地路径及 `file:`
URI;Markdown 链接提示在当前窗口或新窗口打开。
- Desktop 改为多窗口,并按规范化文件路径保持同一文件单例;窗口聚焦时
比较磁盘修改时间,检测到外部变化后提示是否重新加载。
- 主窗口关闭后会选取仍存活的最新窗口作为状态持久化主窗口;窗口位置、
尺寸和最大化状态仍按约 2 秒防抖写入并在启动时修正到可见工作区。
- Core 新增跨端文档链接分类与 PDF 本地链接编码协议;精确 PDF 使用
`mdpdf.local.invalid` 暂存本地链接,PDF.js 注释层解码后交给平台。
- 内置主题名称统一为 Typora Github、Typora Pixyll、Typora whitey 和
Typora Clean,默认主题为 Typora Github;删除强制覆盖主题链接样式的
`!important`,保留主题自身设计。
- markdown-it 普通围栏输出 `pre.md-fences` 和可选 `lang`Preview
Engine 仅重置内部语义 `code` 的重复行内盒模型,代码块与行内代码均
保持主题预期,Mermaid/ECharts 专用围栏不受影响。
- 根级 `build:web-runtime` 统一内嵌 Web 的六个工作区构建顺序;Desktop
`package``make` 强制先调用该脚本,防止安装包复制陈旧
`apps/web/dist`
### 3.20 v0.5.1 正式文档主题与桌面文件工作流
- 围栏代码按正文宽度自动换行,长单词允许安全断行;代码内容统一保留
`8px` 左侧内边距,并保留代码块外框、语法高亮和 Typora 兼容 DOM。
- 多行代码块按至少两行一组生成可分页分片,当前页能容纳一组时不再将
整块代码推到下一页;跨页分片保持连续边框和完整文本。
- 新增政企标准红头、函件红头、企业简版红头、简报红头 4 套红头主题,
正式制度、正式报告、可研报告 3 套正式文档主题,以及经典标书、商务蓝
标书、暗标 3 套标书主题。
- 主题清单新增分类、文档结构预设、推荐导出设置和页面装饰;没有主题推荐
时保持 16mm 默认页边距,正式主题自动采用规范页边距、页眉页脚和页码。
- Renderer 根据结构化 Front Matter 生成红头、文号、签发人、密级、
主送、正文、附件、落款、抄送和印发信息,也支持项目报告与标书封面。
- 红头标题使用居中网格布局,签发人不再挤压发文机关;正文、红头标题、
页眉页脚使用主题内置 Fandol 中文字体,降低跨机器显示差异。
- `samples/tutorials` 内置 ECharts 和公文主题教程,包含 YAML 示例、
字段说明、图表标题和图例渲染;公文教程保持 Typora Github 阅读主题。
- `samples/themes` 为全部 14 套主题提供示例;Desktop 发行配置将教程、
示例和字体随应用复制,打开主题示例时自动切换相应主题。
- 移除顶部加号入口,将文件操作、教程与示例、主题管理整合为三个菜单
分区;文件操作统一命名为“新建文件”“保存文件”“另存为文件”。
- Desktop 支持 `Ctrl+N``Ctrl+W``Ctrl+S``Ctrl+Shift+S`,新建和
关闭时对未保存内容进行确认;另存为成功后当前窗口追踪新文件路径,
Web 端不显示或拦截“另存为”。
## 4. 已执行验证
2026-07-29 对 v0.5.1 完整工作区及最终代码块修复执行:
```text
npm test
npm run typecheck
npm run build
git diff --check
```
- 最终修复前的完整工作区共 65 个测试文件、286 项测试全部通过;将
左侧内边距调整到共享分页规则后,Preview Engine 18 项和 Application
9 项定向测试再次通过;
- Markdown ECharts、Core、Renderer、Application、Preview Engine、
Web、Server 和 Desktop 类型检查全部通过;
- Web 生产资源、Server 和 Desktop 主进程/Preload 构建通过,生产资源
中的应用版本为 `0.5.1`
- 保留的手动验收服务继续运行:Web 与主题 API 均返回 HTTP 200
Electron 应用及其 GPU、网络、渲染进程正常存活;
- `git diff --check` 通过,仅有 Git 对 Windows 工作区换行转换的提示。
- v0.5.1 Windows 目录版、NSIS 和 ZIP 经完整内嵌 Web 重建后生成;
目录版主程序文件版本为 `0.5.1`、产品版本为 `0.5.1.0`,启动后正常
响应,并保留独立验收窗口。
- 目录版包含 14 套主题、14 份主题示例、2 份教程、5 个 Fandol WOFF2
中文字体及其许可文件,语言包仅保留 `zh-CN``en-US`ZIP 中同样
检出主题、示例和字体资源。
- NSIS 安装包 `md-to-pdf-0.5.1-x86_64-Setup.exe` 为 114,688,014
字节,SHA-256 为
`676CCE73D782B0B15AC6BC68F253CFBC4740383583E4DAA98F746EDF9999C5CC`
- 免安装包 `md-to-pdf-0.5.1-x86_64.zip` 为 152,183,607 字节,
SHA-256 为
`82BF6ADF1200604F145CC86FA3ED193955CF6741EBEE3DF8953483515CFF621F`
- 主程序与安装包 Authenticode 状态均为未签名,与当前发行说明一致。
- 正式镜像 `yixiong/md-to-pdf:v0.5.1` 内容 ID 为
`sha256:72f519a69bfd6cb2f6df30c2be938e58ceb6f20e4748a32551874de3d436b276`
Compose 强制替换后健康运行在 `http://localhost:8080`
- 容器确认包含 14 套主题和 17 份 Markdown 教程/示例;生产 Bundle
同时包含代码自动换行、任意长单词断行和 `8px` 左侧内边距。
- 容器代码块回归 PDF 返回 HTTP 200,共 2 页、64,721 字节,
Mermaid/ECharts 错误数均为 0;视觉检查确认长 SQL 正确换行、跨页
连续、24 个字段完整且没有右侧越界。
- 本机 NSIS 安装项版本为 `0.5.1`,发布者为 `YIXIONG Tech.ltd`
用户完成安装和桌面端手动验收,未发现发布阻塞问题。
2026-07-28 在当前完整工作区成功执行:
```text
npm test
npm run typecheck
npm run build
git diff --check
```
结果:
- ECharts 围栏测试:36 项通过;
- Core 共享协议测试:15 项通过;
- 渲染器测试:14 项通过;
- 应用服务测试:11 项通过;
- Preview Engine 测试:53 项通过;
- 前端测试:54 项通过;
- 后端测试:29 项通过;
- 桌面端测试:26 项通过;
- 全项目共 238 项测试通过;
- 全项目类型检查通过;
- 生产构建通过;
- `git diff --check` 通过。
`v0.5.0` 双端与发行验收结果:
- 正式镜像 `yixiong/md-to-pdf:v0.5.0` 内容 ID 为
`sha256:13a0955f3629e4e96d7af9d38230ead5ff6b8b70be2b35d5f8da9fdeb1f66474`
大小 640,294,504 字节;Compose 使用该内容 ID 健康运行在
`http://localhost:8080`
- Web 快速、连续和精确预览完成真实浏览器验证:连续模式只有外层滚动,
ECharts 使用完整内容宽度和配置高度;快速预览后缀编辑保留稳定前缀。
- Web 外链样式、受控新窗口和本地链接禁用通过;精确 PDF 注释层保留
HTTP/HTTPS 与锚点,并能将 `.invalid` 地址解码为原始本地路径。
- Desktop 多窗口、同一文件单例、主窗口关闭后的状态接管、最大化防抖
写入和重启恢复通过;本机安装版已升级至 v0.5.0。
- 围栏代码块在 Typora Github 中显示完整外框且内部不再逐行出现行内
代码方框;Web 与最终 Desktop 安装版均由用户确认,ECharts 围栏未受
普通代码块兼容样式影响。
- 正式 NSIS 为 `md-to-pdf-0.5.0-x86_64-Setup.exe`95,004,759
字节,SHA-256 为
`60992D1FDCA513F46346C78478537EB4159D8C0E76B41ECF3CDC25BE77707D92`
- 正式 ZIP 为 `md-to-pdf-0.5.0-x86_64.zip`132,485,574 字节,
SHA-256 为
`D74F82293FB67126E583546CBA894569EFC9A0B1B6343FAC648CCC95F1D188D8`
- 安装版内嵌 `paged-preview` Bundle 与本地最新 Web Bundle 的
SHA-256 均为
`BD29762A2E3CF1A2AAC4DD055D623B42C754DF46A3E773DD99B01CDFDAE36CE5`
`.md``.markdown` OpenWithProgids 注册正常。
`v0.4.5` 双端与媒体分页验收结果:
- 正式镜像 `yixiong/md-to-pdf:v0.4.5` 已完成多阶段构建,镜像内容 ID
`sha256:0703c3762cd0e4e551ce44732b064a938c2095eb331a22e28861a148fe520354`
Compose 已强制替换为正式镜像并健康运行在 `http://localhost:8080`
- 正式镜像 PDF 冒烟请求返回 HTTP 200,生成 1 页、96,661 字节 PDF
Mermaid 与 ECharts 错误数均为 0。
- 默认示例在 Web 快速预览与精确预览中均为 10 页;12 个媒体块均只
出现一次,全部标题正确配对,无重叠、越界、解码或图表错误。
- 容器生成 `output/pdf/v0.4.5-media-pagination-rc.pdf`,共 10 页、
928,803 字节;Mermaid 与 ECharts 错误数均为 0,逐页视觉检查通过。
- Desktop 新建、输入、默认标题文件名保存、原生 PDF 导出均通过;
`output/桌面保存验收.md` 内容正确,Desktop README 导出 PDF 为 5 页。
- 从第二实例系统打开 `README.md` 时保持单窗口并自动加载;自定义主题
目录能够打开且可识别已有主题。
- 窗口最大化变化约 2 秒后写入状态;重启恢复最大化。窗口位置与尺寸
测试覆盖屏幕越界修正、最小尺寸、原子写入和损坏状态回退。
- 正式 NSIS 安装包为 `md-to-pdf-0.4.5-x86_64-Setup.exe`
94,998,489 字节,SHA-256 为
`9CBD6362E15AA745185805E753D5A7749434E0E142E6CE0F66463E6A19468F1D`
- 免安装包为 `md-to-pdf-0.4.5-x86_64.zip`132,477,245 字节,
SHA-256 为
`97B2D44E72F626A3396E5AB5B330FFB7F9BECAF945A1707808C876940A82E850`
- 正式目录版主程序版本为 `0.4.5`,只包含 `zh-CN``en-US` 语言包,
Authenticode 状态为未签名,启动后应用与渲染进程均正常响应。
- 本机当前用户安装已从 `0.4.3` 原位升级到 `0.4.5`;卸载注册信息、
桌面与开始菜单快捷方式、`.md``.markdown` 打开注册均验证通过,
安装版应用启动正常。
Electron 桌面端第一阶段验证结果:
- Electron 43.2.0 应用窗口成功加载现有 React/Vite 界面,标题旁正确显示
`v0.4.0`
- 最小 Markdown 通过隐藏 Electron Chromium 生成 1 页、52,308 字节
PDF,文字可搜索,并通过桌面原生保存通道落盘。
- 默认示例通过桌面端生成 4 页、439,501 字节 A4 PDFMermaid 和
10 个 ECharts 图表错误数均为 0。
- 将默认示例全部 4 页渲染为 PNG 后逐页检查,Tree、Treemap、Sunburst、
Graph、Sankey、Chord、Funnel、Gauge 和 PictorialBar 均完整显示,
未发现空白页、黑块、跨页切割或明显裁切。
- PDF.js 可以从 4 页中提取 670 个非空白字符,各页均包含可搜索文字。
- Forge 成功生成 Windows x64 未签名目录包,生产窗口通过
`mdpdf://bundle/index.html` 加载,版本徽标和界面静态资源正常。
- 精简后的 `app.asar` 约 554 KiB,Web 静态资源共 134 个文件、约
9.0 MiB;运行目录只包含 Electron 自带的一套 Chromium。
已使用浏览器插件完成视觉验证:
- 默认示例中的 ECharts 柱状图生成 1 个内联 SVG,无错误占位;
- 顶栏文件名、分页状态与操作按钮在桌面和窄屏均无重叠;
- 桌面端源文本收起后宽度从 576px 降为 48px,预览区从 864px 扩展
到 1392px;窄屏折叠条为 44px
- 快速预览输入第 2 页后目标页顶端对齐 iframe 视口,滚动回首页和第二页
时输入框分别同步为 1 和 2
- 页码输入 0 和 99 时分别限制到 1 和总页数;
- 精确预览输入第 2 页后,目标页与桌面滚动容器顶部误差为 0;
- 快速预览改用外层滚动容器后,右侧容器边界为 1440px,纸张边界约为
1400px,滚动条稳定贴在容器最右侧而非纸张边缘;
- 快速预览输入第 1 页后目标页与外层可视区域顶部误差为 0,外层滚动到
第 2 页时页码输入框同步更新为 2;
- 快速预览在 50% 和 150% 下的可滚动高度分别随内容显示高度缩放,
iframe 自身保持无滚动;切换精确/快速模式后仍使用同一右侧滚动条;
- 桌面端收起源文本后,预览滚动容器从 48px 延伸至窗口右边缘,纸张仍
在扩展后的预览区域内居中;
- 窄屏精确预览自动使用主窗口滚动,并正确跳转到第 2 页;
- 页码控件在窄屏独占首行,缩放控件在下一行铺满,没有与预览模式或主题
选择器重叠;
- 当前默认 Markdown 和主题资源加载正常,快速预览生成 2 页;
- 编辑 Markdown 后标题、表格、Mermaid 和分页状态均完成防抖重绘;
- 从本地 GitHub 主题切换到内置 Typora 风格主题后 iframe 正常重建;
- 本轮浏览器回归期间控制台无警告或错误;
- 预览缩放在 50%、100%、150% 和 400% 下均按比例显示,快速与精确
预览的分页结果不受缩放影响;
- 包含 ELK、Base 主题、Hand-drawn 外观、自定义字体、
`themeVariables``style``classDef` 的 Mermaid 样例在快速预览
与精确预览中均成功渲染;
- 在 Windows 150% 系统显示缩放的笔记本内屏上,65 页附件的快速预览
生成 64 页,67 个 Mermaid 全部使用静态 SVG
- 同一附件的精确预览和最终 PDF 均为 65 页;
- 切换到 Windows 100% 系统显示缩放的外接显示器后,快速预览与精确预览
的分页结果基本一致,进一步排除了 Chromium 版本差异这一判断方向;
- 精确预览快速跳转至第 46、47、65 页,无黑色 Canvas、空白页或渲染错误;
- PDF.js 同时只保留视口邻近页面的 Canvas,远端页面资源可以释放;
- Mermaid A/B PDF 页数、逐页文字和抽样视觉结果一致;
- 抽查第 2、6、27、53、65 页,Mermaid 尺寸、分页位置和末页内容正常。
ECharts 第二阶段浏览器与 PDF 验证结果:
- 默认示例生成 10 个 ECharts SVG,包含原柱状图和九种新增系列,错误
占位数为 0,浏览器控制台无警告或错误;
- 快速预览生成 6 页,第 2~6 页各放置两张完整图表,所有图表边界均位于
当前页内容区内,没有跨页切割;
- 精确预览同样生成 6 页,逐页跳转正常;Chord、Funnel、Gauge 和
PictorialBar 的 PDF Canvas 视觉检查通过;
- 使用默认导出配置调用 PDF API 生成 4 页 PDF,响应中的 ECharts 和
Mermaid 错误数均为 0
- PDF 中九种新增图表的标题均可搜索;将全部页面渲染为 PNG 后,Tree、
Treemap、Sunburst、Graph、Sankey、Chord、Funnel、Gauge 和
PictorialBar 均显示完整,未发现裁切、重叠、黑块或空白图表。
- 修正 Treemap 示例后再次检查快速与精确预览:底部下钻面包屑已隐藏,
五个叶节点边界清晰;SVG 中父级和叶节点共 7 个标签均处于可见状态。
- 进一步确认此前 Treemap 标签虽存在于 SVG,但被冻结在入场动画初始帧,
`fill-opacity` 约为 `0.000014`,肉眼近似完全透明;全局关闭动画后,
快速预览和精确 PDF 中的 2 个父级及 5 个叶节点标签均清晰可见。
2026-07-27 已重新构建并启动本地发布候选镜像:
- 使用完整多阶段 `deploy/Dockerfile` 构建
`yixiong/md-to-pdf:v0.3.0`,镜像大小约 612 MB
- Compose 强制重建后容器健康检查通过,服务继续监听
`http://localhost:8080`
- 首页返回 200`POST /api/render` 的 ECharts 冒烟请求返回
`code``echarts` 功能标识和 `md-echarts` 安全占位;
- 容器内 `@md-to-pdf/markdown-echarts` 工作区包可正常加载;
- 当前镜像已通过发布前手动验收,并作为 `v0.3.0` 发布镜像保留运行。
此前主题阶段已使用浏览器插件完成视觉验证:
- 导入并打开 `tmp/数据中台项目周报_2026_W30.md`
- 参考 `tmp/数据中台项目周报_2026_W30.pdf` 的 Typora 输出;
- GitHub、Pixyll 和 Whitey 三套保留的本地主题均可正常切换;
- 三套主题中的表格均为 `border-collapse: collapse`、单元格间距为 0,并铺满 `#write` 内容宽度;
- GitHub 表格边框颜色与主题定义的 `#dfe2e5` 一致;
- Open Sans、PT Serif 和 Merriweather 字体资源均成功加载;
- KaTeX、代码高亮和 Mermaid 正常显示;
- 浏览器控制台无警告或错误。
2026-07-26 已在 Docker Desktop 完成 AIO 容器验证:
- Docker Compose 配置展开、镜像构建、启动、健康检查和重启恢复通过;
- 运行镜像约 611 MBNode.js、Nginx、Fastify 和 Chromium 均以非
root UID 999 运行;
- Nginx 首页、分页运行页、API、主题 CSS 和 PDF.js Worker 均正常;
- 默认只读挂载识别 1 个内置主题和 3 个本地主题;
- 周报通过容器导出为 4 页,附件通过容器导出为 65 页,Mermaid
错误数均为 0
- 两份 PDF 的所有页面均包含可搜索文字,附件共提取 68,434 个字符;
- 抽查周报第 1、4 页和附件第 1、33、65 页,未发现裁切、重叠、
黑块或空白页;
- 浏览器快速预览、主题切换、精确 PDF.js 预览和导出交互通过;
- 修复 Nginx 缺少 `.mjs` MIME 映射导致精确预览 Worker 加载失败的问题。
`v0.3.0` 发布验收完成后,已停止并删除本项目 Compose 容器及网络以释放
本地资源;`yixiong/md-to-pdf:v0.3.0` 镜像继续保留。
2026-07-27 已构建并启动 `v0.3.1` 发布候选:
- 使用完整多阶段 Dockerfile 构建 `yixiong/md-to-pdf:v0.3.1`,镜像
大小约 612 MB
- Compose 容器使用该镜像运行并通过健康检查,服务监听
`http://localhost:8080`
- 容器首页返回 200,默认 Markdown 解析出 10 个 ECharts 围栏,
错误占位和渲染警告均为 0
- 容器生成的默认配置 PDF 为 4 页、约 521 KiBECharts 和 Mermaid
渲染错误数均为 0
- ECharts 已编译进按需加载的前端浏览器 Bundle,生产运行时不需要保留
独立的 `echarts` Node.js 包;
- 当前容器保留运行,等待 `v0.3.1` 发布前手动验收。
2026-07-27 已完成 `v0.4.0` 最终发布候选验证:
- 生成本地镜像 `yixiong/md-to-pdf:v0.4.0`,镜像内容 ID 为
`sha256:1bf4a136e9b822fa0925070cd522ea2adbad8b388d8e039d6509024d466666b3`
- Compose 强制替换为 v0.4.0 后健康检查通过,首页返回 200,健康接口
返回 `ok`,主题接口返回 4 个 `bundled` 主题;
- 容器 Chromium 生成中文、表格、KaTeX、代码和 Mermaid 验收 PDF
HTTP 200、1 页、147,374 字节,Mermaid/ECharts 错误数均为 0
- PDF 渲染为 PNG 后检查通过,中文、公式、表格、代码、图表、页边距和
页码均正常,无裁切、重叠、黑块或空白;
- Compose 网页真实加载后标题旁显示 `v0.4.0`,主题选择器包含 4 个内置
主题,多页预览和图表正常,浏览器控制台无错误;
- Forge Squirrel 安装包、NUPKG 和 ZIP 均已生成,安装包约 137.48 MiB,
当前 Authenticode 状态为未签名。
2026-07-27 已完成 `v0.4.1` 图片资源发布候选验证:
- 用户提供的 `tmp/数据工程规划.md` 成功解析 2 张本地 PNG,生成约
5.0 MB 内嵌 HTML,图片自然宽度均为 8192px,零资源告警。
- Web 真实选择 Markdown 与 `.assets` 目录后生成 4 页快速预览,两张
本地图片均完整位于各自页面内容区。
- Wikimedia SVG、NASA JPEG 和 Unsplash JPEG 三种公网图片均完成下载、
格式识别、Data URL 内嵌和自然尺寸解码。
- 1200×1800 超高网络图在扣除标题高度后缩放;最终图片约 977px 高,
图加标题约 1001px 高,完整位于同一页且未复制、裁切或跨页。
- 默认示例的快速预览和精确预览均为 7 页,两个图片标题可见;容器
Playwright PDF 的精确预览同样为 7 页。
- Electron 目录版显示 `v0.4.1`,使用 Electron 内置 Chromium 成功渲染
两张默认网络图片;Windows 主程序仍为 `md-to-pdf.exe`
- 最终 Squirrel 安装包为
`Markdown PDF 导出器-0.4.1 Setup.exe`144,166,400 字节,SHA-256
`FC6687494255EE21224B65C1CA2D520316D568CCE8EB99A608A0DEF160611F4E`
Authenticode 状态为未签名。
- 本地镜像 `yixiong/md-to-pdf:v0.4.1` 内容 ID 为
`sha256:1ded8a8a11ecb8b69eaa116bb9129dd4ec039e9918b047169fe5f8add2af3a80`
Compose 容器健康运行在 `http://localhost:8080`
2026-07-27 已完成 `v0.4.2` 桌面维护版本验证:
- 仅重新构建桌面端及其内嵌 Web 静态资源,没有重新构建或替换
Web/Compose 发布镜像。
- Windows 目录版视觉检查通过:默认原生菜单栏已经移除,应用内容直接
位于系统标题栏下方,版本徽标显示 `v0.4.2`
- Windows 主程序继续使用英文文件名 `md-to-pdf.exe`
- Squirrel 安装包为 `Markdown PDF 导出器-0.4.2 Setup.exe`
144,166,400 字节,SHA-256 为
`59DA57522C99EB6B16A9591AFDEC349B785BF9B76950504B314273520152D41B`
Authenticode 状态为未签名。
2026-07-27 已完成 `v0.4.3` 标准安装向导验证:
- NSIS 中文辅助安装向导正确显示安装范围和安装目录选择,版本显示为
`0.4.3`
- 当前用户安装成功,安装目录为
`%LOCALAPPDATA%\Programs\md-to-pdf`,卸载项版本为 `0.4.3`
- 桌面和开始菜单快捷方式均存在,实际目标均为安装目录中的
`md-to-pdf.exe`;从开始菜单快捷方式启动成功。
- 静默卸载返回 0,安装目录、桌面快捷方式和开始菜单目录全部清理;
随后重新安装成功,最终本机保持已安装状态。
- 正式安装包为 `md-to-pdf-0.4.3-x86_64-Setup.exe`
103,346,230 字节,SHA-256 为
`C027B4AC604889C7E7E00BA3CE08A12616312BC9250268775B1B7B578A7C4817`
Authenticode 状态为未签名。
- 免安装包为 `md-to-pdf-0.4.3-x86_64.zip`143,784,617 字节,
SHA-256 为
`91BED88A7CB623B98383408D5553D80A6135FB94F7FE2D77A5FCED339CCF5BC6`
2026-07-27 已完成 `v0.4.4` 桌面语言包精简验证:
- 目录版只包含 `zh-CN.pak``en-US.pak`,语言资源从 55 个、
48,911,653 字节降为 2 个、1,137,843 字节。
- 目录版总大小从 378,084,454 字节降为 330,310,644 字节,减少
47,773,810 字节;Chromium 图形与软件渲染后备组件均保持完整。
- Windows 主程序版本为 `0.4.4`,目录版成功启动并保持应用、GPU、
渲染器等 4 个 Electron 进程正常运行。
- 正式安装包为 `md-to-pdf-0.4.4-x86_64-Setup.exe`94,991,759 字节,
SHA-256 为
`0827FD87A8EEC8B034DF738909CB6A20231245B507AE4A0BAA579AFA03A942DE`
Authenticode 状态为未签名。
- 免安装包为 `md-to-pdf-0.4.4-x86_64.zip`132,470,241 字节,
SHA-256 为
`D6CDB8DAE30676BAB6B2A037567164476AD294588B102A6FBBE9458ABCE5CCC0`
## 5. 当前注意事项
- `output/` 可能包含本地 PDF 验证产物,已被 Git 忽略,不得提交。
- `apps/web/src/App.tsx` 负责分页 iframe 生命周期和父页面消息处理。
- `apps/web/src/use-markdown-render.ts` 负责 Markdown 防抖请求、取消和
渲染错误状态。
- `apps/web/src/use-theme-resources.ts` 负责主题清单、主题 CSS 和请求取消。
- `apps/web/src/paged-preview-frame.ts` 负责 iframe 消息协议和运行目标选择。
- `packages/preview-engine/src/paged-document-runtime.ts` 是连续预览、
快速预览和 PDF 共用的媒体渲染、资源等待和 Paged.js 运行时。
- `packages/preview-engine/src/continuous-preview.ts`
`incremental-pagination.ts` 分别负责无分页 DOM 更新和后缀分页缓存。
- `packages/preview-engine/src/paged-preview.ts` 负责分页协议、共享文档
CSS、页眉页码和 Typora 代码围栏结构兼容。
- Mermaid、ECharts、图片适配、媒体回填及跨页表格实现均位于
`packages/preview-engine/src/`,不得在 Web 或 Desktop 复制第二套。
- `apps/web/src/PrecisePdfPreview.tsx``pdf-render-queue.ts` 负责 PDF.js 精确预览和 Canvas 生命周期。
- `apps/web/src/document-link.ts``pdf-annotation-links.ts` 负责 Web
链接动作和精确 PDF 注释层适配。
- `apps/web/src/PreviewPageControl.tsx``preview-page.ts` 负责当前页输入、
页码边界、滚动页识别和快速跳转。
- `apps/web/src/preview-zoom.ts``PreviewZoomControl.tsx` 负责预览缩放缓存、边界和控制界面。
- `packages/markdown-echarts` 负责 ECharts YAML 协议、验证、安全过滤、
Markdown-it 插件、浏览器 SVG 渲染和分页样式。
- `apps/server/src/pdf-engine.ts` 负责 Chromium 生命周期、并发、网络限制、分页调用和 PDF 输出。
- `apps/web/src/ExportSettingsDrawer.tsx` 是导出设置界面。
- `apps/web/src/export-settings.ts` 负责版本化浏览器缓存。
- `packages/core/src/export-config.ts` 是纸张、页边距、页眉页脚和页码的共享模型。
- `packages/core/src/document.ts` 是渲染文档、分页载荷、运行结果和耗时的
共享模型。
- `apps/server/src/app.ts` 是新增的可测试 Fastify 应用。
- `packages/application` 负责共享 Markdown 渲染和主题应用服务;
`apps/server``apps/desktop` 分别提供 HTTP 和 IPC 适配。
- `apps/desktop/src/desktop-application-controller.ts` 负责 Electron
多窗口、同文件单例、文件变化检测和平台链接动作;`main.ts` 负责启动
组装、协议和生命周期。
- `apps/desktop/src/desktop-document-link.ts` 负责本地链接解析和
Markdown 目标识别。
- `apps/desktop/src/electron-pdf-generator.ts` 负责隐藏 PDF 窗口、分页
调度、网络限制、打印和窗口复用。
- `apps/desktop/src/app-preload.ts``pdf-preload.ts` 分别定义应用
窗口和 PDF 运行窗口的最小 IPC 能力。
- `.local/themes/` 只用于外挂自定义主题;四套发布主题已经内置,无需
重复挂载。历史副本保存在 `.local/theme-backups`,均被 Git 忽略。
- Typora 复制主题按公司内部私有项目决策内置,不面向外部公开或商用;
未来改变分发范围前必须重新完成许可证审查。
- 快速预览会受到客户端 Windows 显示缩放、浏览器缩放和设备像素比影响;
对页数和分页边界有严格要求时,以精确预览和最终 PDF 为准。
- 图片资源不落盘:Web 使用当前请求内 Base64 资源,Desktop 从受限文档
目录读取;远程图片仅保留有界内存缓存。
- 桌面端已通过进程内共享服务实现离线 Markdown 渲染、主题读取和 PDF
导出,不依赖 Fastify 或本地 HTTP Server。
- `v0.5.0` AIO 正式镜像已经通过 Docker Desktop 构建、PDF 冒烟和
Compose 健康检查,当前 Compose 容器保持运行。
- Desktop `package``make` 必须经过 `build:embedded-web`;禁止直接
调用 electron-builder 复制未经本轮编译的 `apps/web/dist`
## 6. 推荐接手顺序
### 阶段一:v0.6.0 分阶段开发
- 阶段 1:已冻结架构、能力边界和 Word/WPS 验收门禁;
- 阶段 2:已冻结 Pandoc `3.9.0.2`、许可证、Docker 与 Desktop
分发方式;
- 阶段 3:实现 DOCX 共享模型和跨端导出协议;
- 阶段 4:实现 CodeMirror 6 与可扩展基础 Markdown 工具栏;
- 阶段 5~8:依次实现资源预处理、动态 reference.docx、Pandoc 转换服务
以及 Web/Desktop 导出交互;
- 阶段 910:完成自动化和 Word/WPS 互操作验收,再构建正式发布产物。
每个阶段验收通过后创建一个独立提交,再进入下一阶段。当前阶段不得混入
后续阶段的功能实现。
### 阶段二:后续版本扩展
- Front Matter 可视化编辑工具;
- ECharts YAML 可视化配置工具;
- 更完整的自定义主题 DOCX 显式样式清单;
- 浏览器本地配置预设及配置 JSON 导入和导出。
## 7. 首版验收目标
- 可以选择或粘贴 Markdown
- 网页正确预览常用 Markdown、公式、Mermaid 和 ECharts
- 可以下载真实 PDF
- PDF 文本可搜索;
- 预览与 PDF 基本一致;
- 支持 A4、Letter、方向和边距;
- 支持基础页眉、页脚和页码;
- 支持主题切换扩展;
- 相对图片可用;
- 转换后不保留用户文档;
- Docker Compose 可在内网启动。