release: 发布 v0.4.5
新增能力:Web 与 Desktop 支持新建和保存 Markdown;桌面端注册 .md/.markdown 打开程序,支持单实例文件转交、自定义主题目录以及窗口位置、尺寸和最大化状态的延迟原子持久化与屏幕越界修正。 界面与兼容性:保留打开 Markdown 为独立主操作,将新建、保存和主题目录收纳到更多菜单;Web 移除本地素材目录入口并明确默认不支持本地素材;新文档默认使用一级标题或首行合法化生成文件名,可不保存直接导出 PDF。 渲染修复:图片、Mermaid 和 ECharts 按文档顺序串行执行媒体分页回填,每个媒体元素至多重排一次;图片以限宽后的高度作为缩放基准,只缩放媒体主体并保持标题尺寸;ECharts 冻结为 SVG 图片后参与统一分页。 示例与文档:默认示例仅保留一张网络图片,增加有效 Base64 横图、竖图、边界图片及多尺寸 Mermaid/ECharts;更新根 README、Desktop README、部署文档、四个 packages README、PROGRESS 和 AGENTS 发布规范;登记 v0.4.6 超链接导航问题。 部署与验证:构建并运行 yixiong/md-to-pdf:v0.4.5 正式镜像,Compose 健康且 PDF 冒烟无 Mermaid/ECharts 错误;生成 NSIS 安装包和免安装 ZIP,本机已升级到 NSIS v0.4.5 并清理旧 Squirrel 安装;202 项测试、类型检查、生产构建和 git diff --check 全部通过。 发布产物:Setup.exe SHA-256 9CBD6362E15AA745185805E753D5A7749434E0E142E6CE0F66463E6A19468F1D;ZIP SHA-256 97B2D44E72F626A3396E5AB5B330FFB7F9BECAF945A1707808C876940A82E850;当前 Windows 产物未配置代码签名。
This commit is contained in:
@@ -1,26 +1,90 @@
|
||||
# Markdown PDF 导出器
|
||||
|
||||
一个面向内网部署的 Markdown 排版与 PDF 导出工具。项目目标是使用同一份 HTML 和 CSS 完成网页预览与 Chromium PDF 渲染,并提供纸张、页边距、页眉页脚、页码及主题扩展能力。
|
||||
一个同时提供 Web 与 Windows 桌面端的 Markdown 排版、分页预览和 PDF
|
||||
导出工具。预览与 PDF 复用同一份安全 HTML、`#write` DOM、主题 CSS 和
|
||||
分页运行时,适合内网部署,也可以作为不依赖本地服务的桌面应用使用。
|
||||
|
||||
## 当前状态
|
||||
当前版本:`v0.4.5`。
|
||||
|
||||
已经实现:
|
||||
## v0.4.5 主要能力
|
||||
|
||||
- React Markdown 编辑与本地文件读取;
|
||||
- Fastify 预览接口;
|
||||
- 共享导出配置模型;
|
||||
- 动态主题清单、CSS 和静态资源接口;
|
||||
- Markdown、Front Matter、安全过滤和扩展语法渲染核心;
|
||||
- 表格、任务列表、脚注、代码高亮、KaTeX 和 Mermaid;
|
||||
- iframe 隔离的真实分页预览、双向滚动同步与主题切换;
|
||||
- Chromium PDF 下载、精确 PDF.js 预览与导出性能观测;
|
||||
- 五种纸张、页边距、页眉、页码、Mermaid 风格和浏览器配置缓存;
|
||||
- 快速预览与精确预览共用的 50%~400% 显示缩放;
|
||||
- 内置 Typora 风格、GitHub、Pixyll 和 Whitey 四套主题;
|
||||
- Web 素材目录上传、桌面同目录相对图片和受限公网图片下载;
|
||||
- 图片标题、整块分页及超高图片单页等比例适配;
|
||||
- 无本地 Server 的 Electron 桌面端与 Windows 安装包;
|
||||
- 前端、Fastify、Nginx 和 Playwright Chromium 的 AIO 容器部署。
|
||||
- 新建、打开和保存 Markdown;新文档可直接导出 PDF;
|
||||
- Windows 注册 `.md`、`.markdown` 文件关联,系统打开文件时自动加载;
|
||||
- 桌面窗口位置、尺寸和最大化状态延迟持久化,并在多显示器变化后自动
|
||||
修正到可见工作区;
|
||||
- “打开 Markdown”保留为独立主按钮,新建、保存和主题目录收纳在“更多”
|
||||
菜单;
|
||||
- 桌面端提供可直接放置自定义主题的本地目录;
|
||||
- 图片、Mermaid 和 ECharts 采用串行媒体分页:每个媒体块至多重排一次,
|
||||
严格保持文档顺序;
|
||||
- 媒体先按内容限宽计算基准高度。当上一页空白接近媒体所需空间时,允许
|
||||
将媒体内容等比例缩小回填;图片标题或图表标题保持原字号且与媒体成块;
|
||||
- 示例文档覆盖横图、竖图、Base64 图片、Mermaid、ECharts 以及不同尺寸
|
||||
的分页边界。
|
||||
|
||||
## Web 与桌面端
|
||||
|
||||
| 能力 | Web / Docker | Windows Desktop |
|
||||
| --- | --- | --- |
|
||||
| 新建 Markdown | 支持 | 支持 |
|
||||
| 打开 Markdown | 浏览器文件选择 | 原生对话框、文件关联、第二实例转交 |
|
||||
| 保存 Markdown | 浏览器下载 | 原生另存为 |
|
||||
| 相对本地图片 | 默认不支持 | 以 Markdown 所在目录为安全边界 |
|
||||
| 远程图片 | 服务端受限下载并内嵌 | 应用服务受限下载并内嵌 |
|
||||
| 自定义主题 | 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["共享分页运行时"]
|
||||
E --> F["Web 快速预览"]
|
||||
E --> G["Playwright Chromium"]
|
||||
E --> H["Electron Chromium"]
|
||||
G --> I["Web PDF"]
|
||||
H --> J["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 运行时
|
||||
themes/ 内置主题与主题清单
|
||||
deploy/ Dockerfile、Compose、Nginx 和部署文档
|
||||
docs/ 项目进度与主题开发说明
|
||||
scripts/ 主题导入等维护脚本
|
||||
logos/ 应用图标源文件
|
||||
.local/themes/ 本地开发和 Compose 自定义主题目录
|
||||
```
|
||||
|
||||
包依赖保持单向:`core` 提供基础协议;`markdown-echarts` 提供独立图表
|
||||
能力;`renderer` 消费两者生成安全 HTML;`application` 组合渲染器、主题
|
||||
和资源用例;三个 `apps/*` 只负责各自平台的界面、传输与 PDF 适配。
|
||||
|
||||
各包的目录和用法:
|
||||
|
||||
- [application](packages/application/README.md)
|
||||
- [core](packages/core/README.md)
|
||||
- [renderer](packages/renderer/README.md)
|
||||
- [markdown-echarts](packages/markdown-echarts/README.md)
|
||||
|
||||
## 本地开发
|
||||
|
||||
@@ -33,118 +97,67 @@ npm run dev
|
||||
|
||||
默认地址:
|
||||
|
||||
- 前端:http://localhost:5173
|
||||
- 后端:http://localhost:3001
|
||||
- Web:http://localhost:5173
|
||||
- API:http://localhost:3001
|
||||
- 健康检查:http://localhost:3001/api/health
|
||||
|
||||
页面支持直接编辑 Markdown,或选择本地 `.md` 文件。若 Markdown 使用
|
||||
相对图片路径,再选择对应的素材目录即可;文件与图片只进入当前渲染请求,
|
||||
不写入数据库。桌面端使用原生“打开 Markdown”对话框,并自动从 Markdown
|
||||
所在目录安全解析相对图片。
|
||||
桌面端开发:
|
||||
|
||||
独立一行的 `` 会显示图片标题。图片与标题作为一个整体
|
||||
参与分页;超出单页内容区时,图片会在预留标题高度后等比例缩放,不跨页
|
||||
切割。远程图片会先由应用服务受限下载并内嵌,失败时显示可诊断占位。
|
||||
|
||||
编辑区和分页预览使用双向比例滚动同步。在任意一侧滚动时,另一侧会跟随到相同的全文阅读进度,方便定位并修改较长文档。
|
||||
|
||||
预览工具栏支持滑块和手动百分比输入。缩放比例只改变浏览器显示,不改变纸张尺寸、分页结果或最终 PDF,并会单独保存在浏览器中。
|
||||
|
||||
## Mermaid 配置与样式
|
||||
|
||||
导出设置可以统一控制整篇文档的 Mermaid 布局、主题、外观和字体:
|
||||
|
||||
- 布局:Dagre、ELK;
|
||||
- 主题:Mermaid 11.16.0 提供的 Default、Base、Dark、Forest、Neutral、Neo 和 Redux 系列;
|
||||
- 外观:Classic、Hand-drawn、Neo;
|
||||
- 字体:任意本地 CSS 字体族。
|
||||
|
||||
未设置时使用 `dagre + default + classic`。单个 Mermaid 区块的 `config` Front Matter 优先于全局导出设置:
|
||||
|
||||
````markdown
|
||||
```mermaid
|
||||
---
|
||||
config:
|
||||
layout: elk
|
||||
theme: base
|
||||
look: handDrawn
|
||||
fontFamily: Microsoft YaHei
|
||||
themeVariables:
|
||||
primaryColor: "#dbeafe"
|
||||
primaryBorderColor: "#2563eb"
|
||||
flowchart:
|
||||
wrappingWidth: 360
|
||||
---
|
||||
flowchart TB
|
||||
classDef important fill:#fee2e2,stroke:#dc2626
|
||||
A["较长的节点名称<br/>第二行说明"] --> B["下一个节点"]
|
||||
style A fill:#dcfce7,stroke:#16a34a
|
||||
class B important
|
||||
```powershell
|
||||
npm run desktop:dev
|
||||
```
|
||||
````
|
||||
|
||||
`style`、`classDef`、`linkStyle`、`themeVariables` 和图表专属配置均由 Mermaid 官方渲染器处理。原始 `themeCSS`、`securityLevel` 和资源限制属于安全配置,不能由 Markdown 代码块覆盖。
|
||||
桌面端目录包和 Windows 安装包:
|
||||
|
||||
ELK 使用官方 `@mermaid-js/layout-elk`,只有图表实际请求 ELK 时才加载核心布局代码。
|
||||
|
||||
### Mermaid 长标签
|
||||
|
||||
流程图节点标签的默认最大宽度为 320px,可以通过上例中的 `flowchart.wrappingWidth` 调整。
|
||||
|
||||
需要自动换行时可以使用 Mermaid Markdown String:
|
||||
|
||||
````markdown
|
||||
```mermaid
|
||||
flowchart LR
|
||||
A["`这是一段可以由 Mermaid 自动换行的较长节点文字`"]
|
||||
```powershell
|
||||
npm run desktop:package
|
||||
npm run make -w @md-to-pdf/desktop
|
||||
```
|
||||
````
|
||||
|
||||
个别节点仍需缩小字体时,优先使用 Mermaid 自带的 `classDef`:
|
||||
产物位于 `apps/desktop/out/v0.4.5/`。正式安装包命名为
|
||||
`md-to-pdf-0.4.5-x86_64-Setup.exe`,同时生成免安装 ZIP;当前发行包
|
||||
未配置代码签名。
|
||||
|
||||
````markdown
|
||||
```mermaid
|
||||
flowchart LR
|
||||
A["较长节点"] --> B["普通节点"]
|
||||
classDef compact font-size:12px;
|
||||
class A compact;
|
||||
```
|
||||
````
|
||||
## 文档与媒体
|
||||
|
||||
## 内置与本地 Typora 主题
|
||||
Markdown 支持 Front Matter、表格、任务列表、脚注、highlight.js、
|
||||
KaTeX、Mermaid 和安全的 ECharts YAML 围栏。
|
||||
|
||||
公司内部版本已经内置 GitHub、Pixyll 和 Whitey 三套适合打印的白色
|
||||
Typora 默认主题。如需从本机 Typora 安装目录刷新本地开发副本,可以运行:
|
||||
独立一行的 `` 会生成带标题的图片块。分页引擎将图片、
|
||||
Mermaid、ECharts 及其紧邻标题视为不可拆分媒体块,并按文档顺序串行
|
||||
计算。图片的缩放基准是原图先收缩到内容限宽后的高度;需要回填上一页时
|
||||
只缩放媒体内容,不缩放标题。这样可利用接近可容纳的页尾空白,同时避免
|
||||
跨页、重复重排和后续媒体顺序变化。
|
||||
|
||||
ECharts 围栏语法、支持系列和安全边界详见
|
||||
[markdown-echarts 包文档](packages/markdown-echarts/README.md)。
|
||||
|
||||
## 主题
|
||||
|
||||
仓库内置 Typora 风格、GitHub、Pixyll 和 Whitey 四套主题。主题由
|
||||
版本化 `theme.json` 清单、主体 CSS、可选基础 CSS、打印 CSS 和资源组成。
|
||||
|
||||
- 本地开发与 Compose:将主题目录放入 `.local/themes/`;
|
||||
- Desktop:从“更多 → 打开自定义主题目录”打开实际安装目录,再放入主题;
|
||||
- 主题格式、安全限制和资源引用详见[主题开发指南](docs/THEMES.md)。
|
||||
|
||||
Compose 会把 `.local/themes` 只读挂载到容器。Typora 主题导入脚本只用于
|
||||
刷新本地开发副本:
|
||||
|
||||
```powershell
|
||||
npm run theme:import-typora
|
||||
```
|
||||
|
||||
默认从 Typora 安装目录的 `resources\style` 读取基础 CSS、主题和资源,写入 `.local\themes\typora-*`。启动开发服务后,这些主题会出现在预览页面的主题选择器中。
|
||||
|
||||
导入工具不会默认覆盖已存在的目标。确认替换本地副本时使用:
|
||||
|
||||
```powershell
|
||||
npm run theme:import-typora -- --replace
|
||||
```
|
||||
|
||||
旧副本会移动到 `.local\theme-backups`。
|
||||
|
||||
本地主题由动态主题注册器加载,CSS 中的相对字体和图片会通过受限资源接口提供。外部 URL、越界路径和符号链接逃逸会被拒绝。
|
||||
|
||||
自定义主题目录、`theme.json`、CSS 组合顺序、资源引用和安全限制详见 [主题开发指南](docs/THEMES.md)。
|
||||
|
||||
## Docker Desktop 部署
|
||||
## Docker Compose 部署
|
||||
|
||||
```powershell
|
||||
docker compose -f deploy\compose.yaml up --build -d
|
||||
```
|
||||
|
||||
默认访问地址为 http://localhost:8080。Compose 会将 `.local/themes`
|
||||
作为只读主题目录挂载;端口、主题目录和 PDF 并发参数的配置方式详见
|
||||
[AIO 容器部署说明](deploy/README.md)。
|
||||
默认访问 http://localhost:8080。端口、镜像、主题挂载、PDF 并发和超时
|
||||
配置详见 [AIO 容器部署说明](deploy/README.md)。
|
||||
|
||||
## 测试与构建
|
||||
## 验证
|
||||
|
||||
```powershell
|
||||
npm test
|
||||
@@ -153,8 +166,18 @@ 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)。
|
||||
|
||||
Reference in New Issue
Block a user