# Markdown PDF 导出器 一个同时提供 Web 与 Windows 桌面端的 Markdown 排版、分页预览和 PDF 导出工具。预览与 PDF 复用同一份安全 HTML、`#write` DOM、主题 CSS 和 分页运行时,适合内网部署,也可以作为不依赖本地服务的桌面应用使用。 当前版本:`v0.5.0`。 ## v0.5.0 主要能力 - 新增“连续”预览模式:不分页、低测量开销,适合编辑时快速刷新;快速 预览继续提供分页近似,精确预览和导出 PDF 保持权威分页; - 分页引擎从 Web 应用抽取为 `@md-to-pdf/preview-engine`,Web、 Playwright PDF 与 Electron PDF 直接复用同一运行时; - 快速预览支持按修改位置复用稳定前缀,只重新分页受影响的后缀; - Web 链接只处理当前文档锚点和 HTTP/HTTPS 外链;外链在新浏览器窗口 打开,本地路径及不支持协议不执行导航; - Desktop 支持 HTTP/HTTPS、系统协议、本地相对或绝对路径和 `file:` URI;Markdown 链接可选择在当前窗口或新窗口打开; - Desktop 支持多窗口和同一文件单例。窗口聚焦时检查磁盘文件变化,并 提示是否重新加载; - 四个内置主题统一命名为 Typora Github、Typora Pixyll、 Typora whitey 和 Typora Clean,默认使用 Typora Github; - 围栏代码块输出 Typora 兼容的 `.md-fences` DOM,并避免内部 `` 重复套用行内代码样式; - 桌面发行链会在每次打包前完整重建内嵌 Web 依赖,避免安装包携带陈旧 前端资源。 ## Web 与桌面端 | 能力 | Web / Docker | Windows Desktop | | --- | --- | --- | | 新建 Markdown | 支持 | 支持 | | 打开 Markdown | 浏览器文件选择 | 原生对话框、文件关联、第二实例转交 | | 保存 Markdown | 浏览器下载 | 原生另存为 | | 相对本地图片 | 默认不支持 | 以 Markdown 所在目录为安全边界 | | 文档内锚点 | 当前预览定位 | 当前预览定位 | | HTTP/HTTPS 链接 | 浏览器新窗口 | 系统默认浏览器 | | 本地文件链接 | 不执行 | 相对、绝对路径及 `file:` URI 均可尝试打开 | | 多文件 | 当前浏览器文档 | 多窗口、同一文件单例 | | 外部文件变化 | 不适用 | 窗口聚焦时提示重新加载 | | 远程图片 | 服务端受限下载并内嵌 | 应用服务受限下载并内嵌 | | 自定义主题 | Compose 只读挂载目录 | “更多 → 打开自定义主题目录” | | PDF 引擎 | 固定版本 Playwright Chromium | Electron 自带 Chromium | Web 端不提供本地素材目录能力。需要包含本地相对资源的文档时,请使用 Desktop;Web 端可使用 Base64/Data URL 或受限公网图片。 ## 渲染架构 ```mermaid flowchart LR A["Markdown 与受限资源"] --> B["Renderer 安全渲染"] B --> C["统一 #write HTML"] D["主题 CSS 与导出配置"] --> C C --> E["共享 Preview Engine"] E --> F["连续预览"] E --> G["快速分页预览"] E --> H["Playwright Chromium"] E --> I["Electron Chromium"] H --> J["Web PDF"] I --> K["Desktop PDF"] ``` 连续预览适合高频编辑;快速预览提供客户端分页反馈;精确预览直接展示 服务端生成的 PDF,是 Web 最终分页的权威结果。桌面 PDF 复用相同分页 载荷和运行时。 ## 项目目录 ```text apps/ web/ React 编辑、设置、快速/精确预览与浏览器文件操作 server/ Fastify API、Playwright PDF 与容器运行入口 desktop/ Electron 主进程、IPC、原生文件和 Windows 打包 packages/ core/ 跨端文档、导出配置和主题协议 renderer/ Markdown 到安全 #write HTML 的渲染管线 application/ 共享渲染、主题注册和图片资源应用服务 markdown-echarts/ ECharts YAML 协议、验证与浏览器 SVG 运行时 preview-engine/ 连续预览、增量分页、媒体适配和 Paged.js 运行时 themes/ 内置主题与主题清单 deploy/ Dockerfile、Compose、Nginx 和部署文档 docs/ 项目进度与主题开发说明 scripts/ 主题导入等维护脚本 logos/ 应用图标源文件 .local/themes/ 本地开发和 Compose 自定义主题目录 ``` 包依赖保持单向:`core` 提供基础协议和链接分类;`markdown-echarts` 提供独立图表能力;`renderer` 消费两者生成安全 HTML;`application` 组合渲染器、主题和资源用例;`preview-engine` 消费渲染结果完成连续或 分页排版;三个 `apps/*` 只负责平台界面、传输、链接动作与 PDF 适配。 各包的目录和用法: - [application](packages/application/README.md) - [core](packages/core/README.md) - [renderer](packages/renderer/README.md) - [markdown-echarts](packages/markdown-echarts/README.md) - [preview-engine](packages/preview-engine/README.md) ## 本地开发 要求 Node.js 22 或更高版本。 ```powershell npm install npm run dev ``` 默认地址: - Web:http://localhost:5173 - API:http://localhost:3001 - 健康检查:http://localhost:3001/api/health 桌面端开发: ```powershell npm run desktop:dev ``` 桌面端目录包和 Windows 安装包: ```powershell npm run desktop:package npm run make -w @md-to-pdf/desktop ``` 桌面 `package` 和 `make` 会先完整重建内嵌 Web 及全部共享依赖,不能 复用陈旧的 `apps/web/dist`。产物位于 `apps/desktop/out/v0.5.0/`。 正式安装包命名为 `md-to-pdf-0.5.0-x86_64-Setup.exe`,同时生成免安装 ZIP;当前发行包 未配置代码签名。 ## 文档与媒体 Markdown 支持 Front Matter、表格、任务列表、脚注、highlight.js、 KaTeX、Mermaid 和安全的 ECharts YAML 围栏。 独立一行的 `![标题](地址)` 会生成带标题的图片块。分页引擎将图片、 Mermaid、ECharts 及其紧邻标题视为不可拆分媒体块,并按文档顺序串行 计算。图片的缩放基准是原图先收缩到内容限宽后的高度;需要回填上一页时 只缩放媒体内容,不缩放标题。这样可利用接近可容纳的页尾空白,同时避免 跨页、重复重排和后续媒体顺序变化。 ECharts 围栏语法、支持系列和安全边界详见 [markdown-echarts 包文档](packages/markdown-echarts/README.md)。 ## 主题 仓库内置 Typora Github、Typora Pixyll、Typora whitey 和 Typora Clean 四套主题,默认使用 Typora Github。主题由版本化 `theme.json` 清单、主体 CSS、可选基础 CSS、打印 CSS 和资源组成。 - 本地开发与 Compose:将主题目录放入 `.local/themes/`; - Desktop:从“更多 → 打开自定义主题目录”打开实际安装目录,再放入主题; - 主题格式、安全限制和资源引用详见[主题开发指南](docs/THEMES.md)。 Compose 会把 `.local/themes` 只读挂载到容器。Typora 主题导入脚本只用于 刷新本地开发副本: ```powershell npm run theme:import-typora ``` ## Docker Compose 部署 ```powershell docker compose -f deploy\compose.yaml up --build -d ``` 默认访问 http://localhost:8080。端口、镜像、主题挂载、PDF 并发和超时 配置详见 [AIO 容器部署说明](deploy/README.md)。 ## 验证 ```powershell npm test npm run typecheck npm run build git diff --check ``` 涉及分页或 PDF 的改动还应使用包含中文、长表格、代码、公式、图片、 Mermaid、ECharts 和分页边界的示例完成 Web、Compose 与 Desktop 端到端 验证,并检查 PDF 页面渲染结果。 ## 安全与隐私 - 不建立 Markdown、图片或 PDF 历史数据库; - 文档和资源只在当前请求或当前桌面会话中处理; - Markdown 原始 HTML 不执行,输出经过白名单过滤; - Mermaid 使用严格安全模式,ECharts 只接受受限纯数据 YAML; - 本地资源阻止路径穿越和符号链接越界; - 远程资源阻止内网地址,并限制数量、单文件大小、总大小和超时; - PDF 页面阻止未授权外部网络访问。 当前实现与交接状态详见 [docs/PROGRESS.md](docs/PROGRESS.md)。