@v1hz/md2docx 2.1.0 → 2.1.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 +22 -3
- package/dist/index.js +15 -8
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
| Word 样式 | 根据 JSON 样式生成 Pandoc reference DOCX,也可从现有 DOCX 提取样式 |
|
|
28
28
|
| Markdown 格式化 | 可只运行预处理流水线,输出格式化后的 Markdown |
|
|
29
29
|
| 集中缓存 | 中间文件统一存储到 `~/.md2docx/`,不会在当前目录创建 `tmp/` |
|
|
30
|
-
| Node 与可执行版本 | 支持 npm CLI,也支持构建不依赖 Node.js/Bun
|
|
30
|
+
| Node 与可执行版本 | 支持 npm CLI,也支持构建不依赖 Node.js/Bun 的 Windows 可执行文件 |
|
|
31
31
|
|
|
32
32
|
## 安装方式
|
|
33
33
|
|
|
@@ -178,6 +178,8 @@ md2docx export style -f template.docx → ./template_style.json
|
|
|
178
178
|
|
|
179
179
|
输出 DOCX 和显式导出的配置、样式仍写到用户指定位置或当前工作目录,不会写入缓存目录。
|
|
180
180
|
|
|
181
|
+
虽然 Pandoc 实际读取的是缓存中的格式化 Markdown,但本地相对资源始终优先相对于**原始 Markdown 所在目录**解析;找不到时再搜索命令运行目录。例如 `C:/docs/example.md` 中的 `./pictures/test.png` 会解析为 `C:/docs/pictures/test.png`,与从哪个目录执行 `md2docx` 无关。绝对路径、HTTP(S) URL 和 Mermaid 生成的缓存图片不受影响。
|
|
182
|
+
|
|
181
183
|
## 配置
|
|
182
184
|
|
|
183
185
|
内置配置来自 `config/config.json`,并由 `config/config.schema.json` 提供 JSON Schema。推荐先导出再编辑:
|
|
@@ -320,13 +322,13 @@ dist/
|
|
|
320
322
|
|
|
321
323
|
依赖会打包进 `index.js`,resvg WASM 作为相邻资源输出。`prepack` 会自动执行此构建。
|
|
322
324
|
|
|
323
|
-
###
|
|
325
|
+
### Windows 可执行文件
|
|
324
326
|
|
|
325
327
|
```bash
|
|
326
328
|
bun run build:exe
|
|
327
329
|
```
|
|
328
330
|
|
|
329
|
-
Windows 输出为 `dist/md2docx.exe
|
|
331
|
+
Windows 输出为 `dist/md2docx.exe`。
|
|
330
332
|
|
|
331
333
|
`build` 和 `build:exe` 都会先删除整个 `dist/`,因此两种产物不会同时保留。尤其不要依赖手工生成的 EXE 参与 `npm publish`:发布时 `prepack` 会重新生成 npm 所需的 `index.js` 和 WASM。
|
|
332
334
|
|
|
@@ -350,6 +352,23 @@ pandoc --version
|
|
|
350
352
|
md2docx -f report.md --force
|
|
351
353
|
```
|
|
352
354
|
|
|
355
|
+
### 从其他目录转换时图片缺失
|
|
356
|
+
|
|
357
|
+
相对图片路径应以原始 Markdown 文件为基准:
|
|
358
|
+
|
|
359
|
+
```text
|
|
360
|
+
docs/
|
|
361
|
+
├── example.md
|
|
362
|
+
└── pictures/
|
|
363
|
+
└── test.png
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
```markdown
|
|
367
|
+

|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
新版会把原始文档目录和命令运行目录传给 Pandoc 的 `--resource-path`,并优先搜索原始文档目录。如果仍然缺图,请检查路径大小写、文件是否存在,以及图片语法中是否包含错误的 URL 编码。
|
|
371
|
+
|
|
353
372
|
## 许可
|
|
354
373
|
|
|
355
374
|
md2docx 以 [GNU GPL v3.0](LICENSE) 发布。
|
package/dist/index.js
CHANGED
|
@@ -128401,7 +128401,7 @@ import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
|
128401
128401
|
// package.json
|
|
128402
128402
|
var package_default = {
|
|
128403
128403
|
name: "@v1hz/md2docx",
|
|
128404
|
-
version: "2.1.
|
|
128404
|
+
version: "2.1.1",
|
|
128405
128405
|
description: "基于 pandoc 的 Markdown 转 Word 工具,自动格式化 Markdown,支持自定义样式,AI 友好,用户友好。",
|
|
128406
128406
|
keywords: [
|
|
128407
128407
|
"converter",
|
|
@@ -128553,7 +128553,7 @@ function cleanIntermediateFiles(paths = { targetDir: TMP_DIR, homeDir: homedir2(
|
|
|
128553
128553
|
// src/commands/convert.ts
|
|
128554
128554
|
import { existsSync as existsSync6, mkdirSync as mkdirSync5, writeFileSync as writeFileSync3 } from "node:fs";
|
|
128555
128555
|
import { spawn } from "node:child_process";
|
|
128556
|
-
import { parse as parse4 } from "node:path";
|
|
128556
|
+
import { dirname as dirname5, parse as parse4, resolve as resolve5 } from "node:path";
|
|
128557
128557
|
|
|
128558
128558
|
// src/config.ts
|
|
128559
128559
|
import { access, readFile } from "node:fs/promises";
|
|
@@ -147166,6 +147166,7 @@ async function convertMarkdown(options) {
|
|
|
147166
147166
|
markdownOutput,
|
|
147167
147167
|
"-o",
|
|
147168
147168
|
output,
|
|
147169
|
+
...buildPandocResourcePathArgs(input),
|
|
147169
147170
|
`--reference-doc=${templatePath}`,
|
|
147170
147171
|
...existsSync6(luaFilter) ? [`--lua-filter=${luaFilter}`] : []
|
|
147171
147172
|
];
|
|
@@ -147175,8 +147176,14 @@ async function convertMarkdown(options) {
|
|
|
147175
147176
|
}
|
|
147176
147177
|
console.log(`已生成:${output}`);
|
|
147177
147178
|
}
|
|
147179
|
+
function buildPandocResourcePathArgs(inputPath, workingDirectory = process.cwd()) {
|
|
147180
|
+
const workingDir = resolve5(workingDirectory);
|
|
147181
|
+
const sourceDir = dirname5(resolve5(inputPath));
|
|
147182
|
+
const searchDirs = workingDir === sourceDir ? [sourceDir] : [workingDir, sourceDir];
|
|
147183
|
+
return searchDirs.map((directory) => `--resource-path=${directory}`);
|
|
147184
|
+
}
|
|
147178
147185
|
function runProcess(command, args) {
|
|
147179
|
-
return new Promise((
|
|
147186
|
+
return new Promise((resolve6, reject) => {
|
|
147180
147187
|
const child = spawn(command, args, { stdio: ["ignore", "ignore", "pipe"], windowsHide: true });
|
|
147181
147188
|
let stderr = "";
|
|
147182
147189
|
child.stderr.setEncoding("utf-8");
|
|
@@ -147184,7 +147191,7 @@ function runProcess(command, args) {
|
|
|
147184
147191
|
stderr += chunk;
|
|
147185
147192
|
});
|
|
147186
147193
|
child.once("error", reject);
|
|
147187
|
-
child.once("close", (exitCode) =>
|
|
147194
|
+
child.once("close", (exitCode) => resolve6({ exitCode: exitCode ?? 1, stderr }));
|
|
147188
147195
|
});
|
|
147189
147196
|
}
|
|
147190
147197
|
|
|
@@ -147833,7 +147840,7 @@ async function exportStyle(options) {
|
|
|
147833
147840
|
|
|
147834
147841
|
// src/commands/format.ts
|
|
147835
147842
|
import { existsSync as existsSync7, rmSync as rmSync2, writeFileSync as writeFileSync5 } from "node:fs";
|
|
147836
|
-
import { basename, dirname as
|
|
147843
|
+
import { basename, dirname as dirname6, parse as parse6, resolve as resolve6 } from "node:path";
|
|
147837
147844
|
async function formatMarkdown(options) {
|
|
147838
147845
|
const input = resolveInputPath(options.file, [".md", ".markdown"], "Markdown 文件");
|
|
147839
147846
|
const configPath = options.config ? resolveInputPath(options.config, [".json"], "配置文件") : materializeDefaultConfig();
|
|
@@ -147844,14 +147851,14 @@ async function formatMarkdown(options) {
|
|
|
147844
147851
|
const config = await loadConfig(configPath);
|
|
147845
147852
|
const outputName = parse6(output).name;
|
|
147846
147853
|
const assetsName = `${outputName}_assets`;
|
|
147847
|
-
const assetsDir =
|
|
147854
|
+
const assetsDir = resolve6(dirname6(output), assetsName);
|
|
147848
147855
|
if (config.renderMermaid.enabled && existsSync7(assetsDir)) {
|
|
147849
147856
|
if (!force) {
|
|
147850
147857
|
throw new Error(`资源目录已存在:${assetsDir}
|
|
147851
147858
|
使用 --force 覆盖现有目录`);
|
|
147852
147859
|
}
|
|
147853
|
-
const parent =
|
|
147854
|
-
if (
|
|
147860
|
+
const parent = resolve6(dirname6(output));
|
|
147861
|
+
if (dirname6(assetsDir) !== parent)
|
|
147855
147862
|
throw new Error(`拒绝清理非输出目录:${assetsDir}`);
|
|
147856
147863
|
rmSync2(assetsDir, { recursive: true, force: true });
|
|
147857
147864
|
}
|