@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.
Files changed (3) hide show
  1. package/README.md +22 -3
  2. package/dist/index.js +15 -8
  3. 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`。该程序只适用于构建目标对应的操作系统和 CPU 架构。
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
+ ![](./pictures/test.png)
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.0",
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((resolve5, reject) => {
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) => resolve5({ exitCode: exitCode ?? 1, stderr }));
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 dirname5, parse as parse6, resolve as resolve5 } from "node:path";
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 = resolve5(dirname5(output), assetsName);
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 = resolve5(dirname5(output));
147854
- if (dirname5(assetsDir) !== parent)
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
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@v1hz/md2docx",
3
- "version": "2.1.0",
3
+ "version": "2.1.1",
4
4
  "description": "基于 pandoc 的 Markdown 转 Word 工具,自动格式化 Markdown,支持自定义样式,AI 友好,用户友好。",
5
5
  "keywords": [
6
6
  "converter",