@v1hz/md2docx 2.7.0 → 2.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +50 -56
- package/dist/index.js +26 -9
- package/dist-electron/main.js +28 -16
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -23,35 +23,12 @@
|
|
|
23
23
|
- **表格与图片题注** — "表 1"、"图 1:标题"
|
|
24
24
|
- **图片尺寸限制** — 等比缩小超限图片
|
|
25
25
|
- **Mermaid 渲染** — beautiful-mermaid + resvg-wasm → 高 DPI PNG
|
|
26
|
-
- **Word 样式** —
|
|
26
|
+
- **Word 样式** — 语义化配置 / 完整底层样式 / 从 DOCX 提取
|
|
27
27
|
- **预设系统** — 可切换、可继承默认值的配置与样式预设
|
|
28
28
|
- **Markdown 格式化** — 只运行预处理流水线
|
|
29
|
+
- **桌面图形界面** — Electron + Vue 3,支持文件拖放、批量转换、预设编辑、转换历史、自动更新
|
|
29
30
|
- **集中缓存** — `~/.md2docx/`,工作目录保持干净
|
|
30
|
-
- **双构建** — npm CLI + Windows 单文件 EXE
|
|
31
|
-
|
|
32
|
-
---
|
|
33
|
-
|
|
34
|
-
## 桌面应用
|
|
35
|
-
|
|
36
|
-
仓库包含基于 Electron + Vue 3 + Vite + Tailwind CSS 的桌面端(早期开发阶段)。应用图标以立体 Markdown 卡片、转换箭头和 Word 文档构成,在标题栏小尺寸与桌面大图标下保持一致识别。标题栏使用 `titleBarStyle: "hidden"` 自定义内容区域并在各平台保留原生窗口控制按钮。系统拖入的文件通过 preload 中的 `webUtils.getPathForFile()` 解析本地路径。桌面转换复用完整 CLI 流水线与预设,支持源文件目录、指定文件夹或每次询问三种输出位置,以及覆盖、自动重命名或每次询问三种同名文件策略。成功文件会从队列收入标题栏转换记录;点击记录按钮后,每个文件都可独立打开、定位或重新加入文件列表,之后按当前转换设置再次转换。设置以居中模态窗口展示,可检测 Pandoc,并通过可视化编辑器调整转换规则、图片与图表行为和语义化 Word 样式;打开时弹窗以短暂的淡入、上移动画进入,标题栏设置按钮同时显示蓝色激活状态,并遵守系统的“减少动态效果”偏好。内置 `default` 只读,自定义时保存为新的用户预设,用户预设可直接编辑。设置中的选择器使用应用内统一菜单,支持鼠标和完整键盘操作,不依赖平台原生网页下拉样式。Windows 安装版启动后会静默检查 GitHub Release 更新;发现版本时显示非阻塞通知条,下载期间可继续工作,完成后由用户选择重新启动。设置页也可手动检查;便携版不会尝试自动安装。复制、重命名和删除位于更多菜单,未保存的编辑在离开前会确认。偏好与记录仅保存在本机。旧版扁平桌面设置会继续生效,并在下次保存时迁移到共享格式。转换记录最多保留 30 条;`Ctrl/⌘ + Enter` 可直接开始转换。
|
|
37
|
-
|
|
38
|
-
主界面右侧始终提供转换设置侧边栏,即使文件列表为空也可提前调整。它与预设编辑器使用同一套字段和视觉样式;选择预设会重置侧边栏并同步默认预设,随后直接调整只影响桌面转换,不会改写预设。主界面右上角的固定侧边栏按钮或 `Ctrl+Alt+B` 可显示/隐藏它;按钮不会随侧边栏展开移动,设置与显示状态会自动保存在本机,并作为配置快照应用于下一批文件。开发模式为每次 `bun run dev` 使用独立的 Chromium 会话缓存,避免残留开发实例争用缓存目录。
|
|
39
|
-
|
|
40
|
-
主界面右上角另有纯图标编辑按钮,可在文件列表与 Markdown 文本编辑器之间切换。用户可直接粘贴文本、设置文档名称并使用当前侧边栏配置转换;文本由主进程安全物化为应用私有目录中的临时 Markdown 文件,再进入与文件转换相同的完整流水线。编辑按钮属于文件工作区,会在侧边栏展开时随工作区边缘左移,而侧边栏按钮保持固定。输出位置设置为“源文件目录”时,文本编辑器转换会弹出 DOCX 保存位置选择;从转换记录重新加入源文件时会自动返回文件列表。
|
|
41
|
-
|
|
42
|
-
```bash
|
|
43
|
-
bun run build:electron # 构建主进程与 preload
|
|
44
|
-
bun run electron # 构建 Electron 与前端并启动
|
|
45
|
-
bun run dev # 启动前端开发服务器与 Electron
|
|
46
|
-
bun run pack # 构建支持自动更新的 Windows 安装版
|
|
47
|
-
bun run pack:portable # 构建不自动安装更新的便携版
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
开发模式会自动显示一次更新通知预览;关闭后可在设置底部点“预览更新”再次查看。预览下载仅模拟进度,不访问更新服务器,也不会退出或安装。
|
|
51
|
-
|
|
52
|
-
## AI 辅助
|
|
53
|
-
|
|
54
|
-
[`SKILL.md`](SKILL.md) 供 AI 代码助手引用,使其正确使用 md2docx CLI。
|
|
31
|
+
- **双构建** — npm CLI + Windows 单文件 EXE + 桌面安装包
|
|
55
32
|
|
|
56
33
|
---
|
|
57
34
|
|
|
@@ -65,18 +42,22 @@ npm install -g @v1hz/md2docx
|
|
|
65
42
|
npx @v1hz/md2docx report.md
|
|
66
43
|
```
|
|
67
44
|
|
|
45
|
+
Windows 桌面用户也可下载安装版或便携版(见 [Releases](https://github.com/WXY-V1hZ/md2docx/releases))。
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
68
49
|
## 快速开始
|
|
69
50
|
|
|
70
51
|
```bash
|
|
71
|
-
md2docx report.md #
|
|
52
|
+
md2docx report.md # 仅路径,默认输出 ./report.docx
|
|
72
53
|
md2docx -f report.md -o output.docx # 带选项(必须有 --file)
|
|
73
54
|
md2docx -f report.md -c config.json --style-raw raw.json --style-config style-config.json
|
|
74
55
|
md2docx preset save --name academic --config config.json
|
|
75
56
|
md2docx preset use academic
|
|
76
57
|
md2docx format -f report.md # 只格式化
|
|
77
|
-
md2docx export config #
|
|
58
|
+
md2docx export config # 导出默认配置
|
|
78
59
|
md2docx export style-raw -f template.docx # 从 DOCX 提取样式
|
|
79
|
-
md2docx clean #
|
|
60
|
+
md2docx clean # 清除预处理/资源/样式缓存
|
|
80
61
|
```
|
|
81
62
|
|
|
82
63
|
所有写文件命令默认覆盖已有输出。
|
|
@@ -94,8 +75,6 @@ md2docx preset list|use <name>|save --name <name> [选项]
|
|
|
94
75
|
md2docx clean
|
|
95
76
|
```
|
|
96
77
|
|
|
97
|
-
### 转换选项
|
|
98
|
-
|
|
99
78
|
| 参数 | 说明 |
|
|
100
79
|
| ----------------------- | ---------------------------- |
|
|
101
80
|
| `<markdown>` | 位置参数,仅无其他选项时可用 |
|
|
@@ -104,11 +83,11 @@ md2docx clean
|
|
|
104
83
|
| `-c, --config <path>` | 配置 JSON |
|
|
105
84
|
| `--style-raw <path>` | 底层 Word 样式 JSON |
|
|
106
85
|
| `--style-config <path>` | 语义化样式配置 JSON |
|
|
107
|
-
| `-o, --output <path>` | DOCX
|
|
86
|
+
| `-o, --output <path>` | DOCX 输出(format 为 `.md`) |
|
|
108
87
|
|
|
109
|
-
位置参数不能与 `--file` 或其他选项混用。`format
|
|
88
|
+
位置参数不能与 `--file` 或其他选项混用。`format` 必须提供 `--file`,不接受样式参数,不调用 Pandoc。
|
|
110
89
|
|
|
111
|
-
###
|
|
90
|
+
### 默认输出路径
|
|
112
91
|
|
|
113
92
|
```text
|
|
114
93
|
report.md → ./report.docx
|
|
@@ -121,23 +100,29 @@ export style-config → ./style-config.json
|
|
|
121
100
|
|
|
122
101
|
---
|
|
123
102
|
|
|
124
|
-
##
|
|
103
|
+
## 桌面应用
|
|
125
104
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
105
|
+
仓库包含 Electron 桌面端(Windows 安装版支持自动更新)。主要功能:
|
|
106
|
+
|
|
107
|
+
- **文件管理**:拖入 `.md` 文件或粘贴 Markdown 文本进行转换,支持批量
|
|
108
|
+
- **转换侧边栏**(`Ctrl+Alt+B`):实时调整输出目录、命名策略、样式等配置
|
|
109
|
+
- **预设可视化编辑**:创建、编辑、管理预设,内置 `default` 只读,自定义时自动保存为新预设
|
|
110
|
+
- **转换记录**:最多 30 条,可打开输出、定位文件或重新转换
|
|
111
|
+
- **设置面板**:Pandoc 检测、输出设置、更新检查
|
|
133
112
|
|
|
134
|
-
|
|
113
|
+
```bash
|
|
114
|
+
bun run build:electron # 构建主进程与 preload
|
|
115
|
+
bun run electron # 构建并启动桌面端
|
|
116
|
+
bun run dev # 开发模式(隔离 Chromium 缓存)
|
|
117
|
+
bun run pack # 构建 Windows NSIS 安装版(含自动更新)
|
|
118
|
+
bun run pack:portable # 构建便携版
|
|
119
|
+
```
|
|
135
120
|
|
|
136
121
|
---
|
|
137
122
|
|
|
138
123
|
## 配置
|
|
139
124
|
|
|
140
|
-
内置配置来自 `config/default/config.json`(`config/config.schema.json`
|
|
125
|
+
内置配置来自 `config/default/config.json`(`config/config.schema.json` 提供校验),推荐先导出再编辑:
|
|
141
126
|
|
|
142
127
|
```bash
|
|
143
128
|
md2docx export config
|
|
@@ -147,21 +132,21 @@ md2docx -f report.md -c config.json
|
|
|
147
132
|
| 配置项 | 说明 | 默认值 |
|
|
148
133
|
| --------------------------------------------------------- | ----------------------------------------------- | -------------------------------------- |
|
|
149
134
|
| `detectTitle.enabled / strategy` | 自动设置标题 / first-h1/single-h1/filename/none | `true` / `"first-h1"` |
|
|
150
|
-
| `normalizeHeadings.enabled` | 修正标题层级 | `true` |
|
|
151
135
|
| `numberHeadings.{enabled,detectExisting,useBuiltinRules}` | 标题编号 / 剥离已有编号 | `true` / `true` / `true` |
|
|
152
136
|
| `figureCaption.{enabled,format,separator}` | 图片题注 / `"图 {n}"` / `":"` | `true` |
|
|
153
137
|
| `tableCaption.{enabled,format,separator}` | 表格题注 / `"表 {n}"` / `" "` | `true` |
|
|
154
138
|
| `renderMermaid.{enabled,theme,density}` | Mermaid 渲染 / 主题 / DPI(≥72) | `true` / `"tokyo-night-light"` / `200` |
|
|
155
139
|
| `imageSize.{enabled,maxWidthCm,maxHeightCm}` | 图片尺寸限制(厘米) | `true` / `12` / `12` |
|
|
156
140
|
| `removeThematicBreaks.enabled` | 移除分隔符行 | `true` |
|
|
141
|
+
| `normalizeHeadings.enabled` | 修正标题层级 | `true` |
|
|
157
142
|
|
|
158
|
-
|
|
143
|
+
图片尺寸限制:超限等比缩小,不放大小图;已显式设 width/height 时不应用;读取失败时警告并继续。
|
|
159
144
|
|
|
160
145
|
---
|
|
161
146
|
|
|
162
147
|
## 样式定制
|
|
163
148
|
|
|
164
|
-
|
|
149
|
+
语义化配置(`config/default/style-config.json`)开放常用 Word 样式白名单:
|
|
165
150
|
|
|
166
151
|
- `body.firstLineIndent` — 正文首行缩进
|
|
167
152
|
- `body.lineSpacing` — 行距倍数(如 `1.5`)
|
|
@@ -171,7 +156,7 @@ md2docx -f report.md -c config.json
|
|
|
171
156
|
- `inlineCode.background` — 行内代码背景
|
|
172
157
|
- `codeBlock.border` — 代码块外框
|
|
173
158
|
|
|
174
|
-
|
|
159
|
+
输入组合:
|
|
175
160
|
|
|
176
161
|
| 参数 | 行为 |
|
|
177
162
|
| ------------------- | ----------------------------- |
|
|
@@ -183,12 +168,11 @@ md2docx -f report.md -c config.json
|
|
|
183
168
|
```bash
|
|
184
169
|
md2docx export style-config
|
|
185
170
|
md2docx -f report.md --style-config style-config.json
|
|
186
|
-
# 从现有 DOCX 提取样式
|
|
187
171
|
md2docx export style-raw -f template.docx
|
|
188
172
|
md2docx -f report.md --style-raw template_style-raw.json
|
|
189
173
|
```
|
|
190
174
|
|
|
191
|
-
|
|
175
|
+
字段缺失继承底层样式;`true` 写入完整效果;`false` 写入 Word 关闭值。详见 [`docs/style-config-design.md`](docs/style-config-design.md)。
|
|
192
176
|
|
|
193
177
|
---
|
|
194
178
|
|
|
@@ -200,7 +184,21 @@ Markdown → AST → addTitle → removeThematicBreaks → normalizeHeadings
|
|
|
200
184
|
→ 序列化 → reference DOCX → Pandoc + Lua filter → DOCX
|
|
201
185
|
```
|
|
202
186
|
|
|
203
|
-
|
|
187
|
+
顺序约束:`removeThematicBreaks` 在标题处理前;`numberTables` 在 Mermaid 前;`renderMermaid` 在 `numberPictures` 前。
|
|
188
|
+
|
|
189
|
+
---
|
|
190
|
+
|
|
191
|
+
## 中间文件
|
|
192
|
+
|
|
193
|
+
```
|
|
194
|
+
~/.md2docx/
|
|
195
|
+
├── settings.json + presets/ # 持久数据,clean 保留
|
|
196
|
+
├── preprocess/<basename>-<hash:12>/ # 预处理 Markdown + Mermaid PNG
|
|
197
|
+
├── resources/default/*.json + *.lua # 物化的内置资源
|
|
198
|
+
└── style/<hash:16>.docx # reference DOCX 缓存
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
预处理目录使用输入路径 SHA-256 前 12 位,同名文件在不同目录下隔离。
|
|
204
202
|
|
|
205
203
|
---
|
|
206
204
|
|
|
@@ -211,24 +209,20 @@ Markdown → AST → addTitle → removeThematicBreaks → normalizeHeadings
|
|
|
211
209
|
```bash
|
|
212
210
|
git clone https://github.com/WXY-V1hZ/md2docx.git && cd md2docx
|
|
213
211
|
bun install
|
|
214
|
-
|
|
215
212
|
bun run src/index.ts report.md # 从源码运行
|
|
216
213
|
bun test # 全部测试
|
|
217
214
|
bun check # tsc + oxlint + oxfmt
|
|
218
|
-
|
|
219
215
|
bun run build # npm 构建 → dist/index.js + WASM
|
|
220
216
|
bun run build:exe # Windows 单文件 → dist/md2docx.exe
|
|
221
217
|
```
|
|
222
218
|
|
|
223
|
-
两种构建互斥(先 `clean:dist`)。`prepack` 自动执行 `bun run build`。
|
|
224
|
-
|
|
225
219
|
---
|
|
226
220
|
|
|
227
221
|
## 常见问题
|
|
228
222
|
|
|
229
223
|
**找不到 Pandoc** — 确认 `pandoc --version` 可用,从 [pandoc.org](https://pandoc.org/installing.html) 安装并重启终端。
|
|
230
224
|
|
|
231
|
-
**跨目录转换图片缺失** — 相对路径以原始 Markdown
|
|
225
|
+
**跨目录转换图片缺失** — 相对路径以原始 Markdown 文件为基准解析。检查路径大小写、文件存在性和 URL 编码。
|
|
232
226
|
|
|
233
227
|
---
|
|
234
228
|
|
package/dist/index.js
CHANGED
|
@@ -128472,7 +128472,7 @@ import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
|
128472
128472
|
// package.json
|
|
128473
128473
|
var package_default = {
|
|
128474
128474
|
name: "@v1hz/md2docx",
|
|
128475
|
-
version: "2.7.
|
|
128475
|
+
version: "2.7.1",
|
|
128476
128476
|
description: "基于 pandoc 的 Markdown 转 Word 工具,自动格式化 Markdown,支持自定义样式,AI 友好,用户友好。",
|
|
128477
128477
|
keywords: [
|
|
128478
128478
|
"converter",
|
|
@@ -128603,8 +128603,8 @@ function createProgram(version, actions) {
|
|
|
128603
128603
|
presetSaveCommand.exitOverride();
|
|
128604
128604
|
const formatCommand = program2.command("format").description("预处理并格式化 Markdown").helpOption("-h, --help", "显示帮助").requiredOption("-f, --file <path>", "Markdown 文件").option("--preset <name>", "使用指定预设中的 Markdown 处理配置").option("-c, --config <path>", "自定义配置文件").option("-o, --output <path>", "输出 Markdown 文件").action(actions.format);
|
|
128605
128605
|
formatCommand.exitOverride();
|
|
128606
|
-
const cleanCommand = program2.command("clean").description("清除 ~/.md2docx 中的预处理文件和样式缓存").helpOption("-h, --help", "显示帮助").action(async () => {
|
|
128607
|
-
await actions.clean();
|
|
128606
|
+
const cleanCommand = program2.command("clean").description("清除 ~/.md2docx 中的预处理文件和样式缓存").option("--all", "清除所有用户数据(预设、设置和缓存)").helpOption("-h, --help", "显示帮助").action(async (options) => {
|
|
128607
|
+
await actions.clean({ all: options.all ?? false });
|
|
128608
128608
|
});
|
|
128609
128609
|
cleanCommand.exitOverride();
|
|
128610
128610
|
return program2;
|
|
@@ -128637,9 +128637,7 @@ function styleTemplateDocx(hash) {
|
|
|
128637
128637
|
}
|
|
128638
128638
|
|
|
128639
128639
|
// src/commands/clean.ts
|
|
128640
|
-
function
|
|
128641
|
-
const home = resolve2(paths.homeDir);
|
|
128642
|
-
const target = resolve2(paths.targetDir);
|
|
128640
|
+
function validateTarget(target, home) {
|
|
128643
128641
|
const expected = resolve2(home, ".md2docx");
|
|
128644
128642
|
if (target !== expected || dirname(target) !== home) {
|
|
128645
128643
|
throw new Error(`拒绝清理非预期目录:${target}`);
|
|
@@ -128651,6 +128649,18 @@ function cleanIntermediateFiles(paths = { targetDir: TMP_DIR, homeDir: homedir2(
|
|
|
128651
128649
|
if (lstatSync(target).isSymbolicLink()) {
|
|
128652
128650
|
throw new Error(`拒绝清理符号链接目录:${target}`);
|
|
128653
128651
|
}
|
|
128652
|
+
}
|
|
128653
|
+
function cleanIntermediateFiles(paths = {}) {
|
|
128654
|
+
const home = resolve2(paths.homeDir ?? homedir2());
|
|
128655
|
+
const target = resolve2(paths.targetDir ?? TMP_DIR);
|
|
128656
|
+
validateTarget(target, home);
|
|
128657
|
+
if (!existsSync(target))
|
|
128658
|
+
return;
|
|
128659
|
+
if (paths.all) {
|
|
128660
|
+
rmSync(target, { recursive: true, force: true });
|
|
128661
|
+
console.log(`已清除所有用户数据:${target}`);
|
|
128662
|
+
return;
|
|
128663
|
+
}
|
|
128654
128664
|
for (const name2 of ["preprocess", "resources", "style"]) {
|
|
128655
128665
|
const cachePath = resolve2(target, name2);
|
|
128656
128666
|
if (dirname(cachePath) !== target)
|
|
@@ -148017,9 +148027,16 @@ async function convertMarkdown(options, overrides = {}) {
|
|
|
148017
148027
|
...existsSync7(inlineCodeFilter) ? [`--lua-filter=${inlineCodeFilter}`] : [],
|
|
148018
148028
|
...imageSizeArgs
|
|
148019
148029
|
];
|
|
148020
|
-
|
|
148021
|
-
|
|
148022
|
-
|
|
148030
|
+
try {
|
|
148031
|
+
const { exitCode, stderr } = await runProcess("pandoc", pandocArgs);
|
|
148032
|
+
if (exitCode !== 0) {
|
|
148033
|
+
throw new Error(`pandoc 转换失败 (exit code ${exitCode}):${stderr.trim()}`);
|
|
148034
|
+
}
|
|
148035
|
+
} catch (error) {
|
|
148036
|
+
if (error && typeof error === "object" && "code" in error && error.code === "ENOENT") {
|
|
148037
|
+
throw new Error("未找到 pandoc,请安装 pandoc (https://pandoc.org/installing.html) " + "并将其添加到系统 PATH 环境变量后重试");
|
|
148038
|
+
}
|
|
148039
|
+
throw error;
|
|
148023
148040
|
}
|
|
148024
148041
|
console.log(`已生成:${output}`);
|
|
148025
148042
|
}
|
package/dist-electron/main.js
CHANGED
|
@@ -151568,9 +151568,16 @@ async function convertMarkdown(options, overrides = {}) {
|
|
|
151568
151568
|
...existsSync6(inlineCodeFilter) ? [`--lua-filter=${inlineCodeFilter}`] : [],
|
|
151569
151569
|
...imageSizeArgs
|
|
151570
151570
|
];
|
|
151571
|
-
|
|
151572
|
-
|
|
151573
|
-
|
|
151571
|
+
try {
|
|
151572
|
+
const { exitCode, stderr } = await runProcess("pandoc", pandocArgs);
|
|
151573
|
+
if (exitCode !== 0) {
|
|
151574
|
+
throw new Error(`pandoc 转换失败 (exit code ${exitCode}):${stderr.trim()}`);
|
|
151575
|
+
}
|
|
151576
|
+
} catch (error) {
|
|
151577
|
+
if (error && typeof error === "object" && "code" in error && error.code === "ENOENT") {
|
|
151578
|
+
throw new Error("未找到 pandoc,请安装 pandoc (https://pandoc.org/installing.html) " + "并将其添加到系统 PATH 环境变量后重试");
|
|
151579
|
+
}
|
|
151580
|
+
throw error;
|
|
151574
151581
|
}
|
|
151575
151582
|
console.log(`已生成:${output}`);
|
|
151576
151583
|
}
|
|
@@ -152265,6 +152272,10 @@ function registerIpcHandlers() {
|
|
|
152265
152272
|
removeHistoryRecord(recordId);
|
|
152266
152273
|
});
|
|
152267
152274
|
ipcMain.handle("convert:start", async (event, value2) => {
|
|
152275
|
+
const pandoc = await detectPandoc();
|
|
152276
|
+
if (!pandoc.available) {
|
|
152277
|
+
throw new Error("PANDOC_NOT_FOUND");
|
|
152278
|
+
}
|
|
152268
152279
|
const request = await applyDesktopOutputSettings(parseConversionRequest(value2));
|
|
152269
152280
|
const records = createRecordsFromRequest(request);
|
|
152270
152281
|
const history = loadHistory();
|
|
@@ -152286,19 +152297,7 @@ function registerIpcHandlers() {
|
|
|
152286
152297
|
ipcMain.handle("settings:save", (_event, value2) => saveDesktopSettings(value2));
|
|
152287
152298
|
ipcMain.handle("conversion-settings:load", () => loadDesktopConversionSettings());
|
|
152288
152299
|
ipcMain.handle("conversion-settings:save", (_event, value2) => saveDesktopConversionSettings(value2));
|
|
152289
|
-
ipcMain.handle("pandoc:detect", async () =>
|
|
152290
|
-
const executable = findExecutableOnPath("pandoc");
|
|
152291
|
-
if (!executable)
|
|
152292
|
-
return { available: false, version: null, path: null };
|
|
152293
|
-
try {
|
|
152294
|
-
const { stdout } = await runCommand(executable, ["--version"]);
|
|
152295
|
-
const firstLine = stdout.trim().split(/\r?\n/, 1)[0] ?? "";
|
|
152296
|
-
const version = /^pandoc\s+(.+)$/i.exec(firstLine)?.[1]?.trim() || firstLine || null;
|
|
152297
|
-
return { available: true, version, path: executable };
|
|
152298
|
-
} catch {
|
|
152299
|
-
return { available: false, version: null, path: null };
|
|
152300
|
-
}
|
|
152301
|
-
});
|
|
152300
|
+
ipcMain.handle("pandoc:detect", async () => detectPandoc());
|
|
152302
152301
|
ipcMain.handle("dialog:selectFolder", async () => {
|
|
152303
152302
|
if (!mainWindow)
|
|
152304
152303
|
return null;
|
|
@@ -152349,6 +152348,19 @@ function runCommand(command, args, timeoutMs = 5000) {
|
|
|
152349
152348
|
});
|
|
152350
152349
|
});
|
|
152351
152350
|
}
|
|
152351
|
+
async function detectPandoc() {
|
|
152352
|
+
const executable = findExecutableOnPath("pandoc");
|
|
152353
|
+
if (!executable)
|
|
152354
|
+
return { available: false, version: null, path: null };
|
|
152355
|
+
try {
|
|
152356
|
+
const { stdout } = await runCommand(executable, ["--version"]);
|
|
152357
|
+
const firstLine = stdout.trim().split(/\r?\n/, 1)[0] ?? "";
|
|
152358
|
+
const version = /^pandoc\s+(.+)$/i.exec(firstLine)?.[1]?.trim() || firstLine || null;
|
|
152359
|
+
return { available: true, version, path: executable };
|
|
152360
|
+
} catch {
|
|
152361
|
+
return { available: false, version: null, path: null };
|
|
152362
|
+
}
|
|
152363
|
+
}
|
|
152352
152364
|
function findExecutableOnPath(command) {
|
|
152353
152365
|
const pathEntries = process.env.PATH?.split(delimiter) ?? [];
|
|
152354
152366
|
const extensions = process.platform === "win32" ? process.env.PATHEXT?.split(";") ?? [".EXE", ".CMD", ".BAT"] : [""];
|