From 876f01ac198d2f2a84d5b935893e107ca2e0a96c Mon Sep 17 00:00:00 2001 From: Chao Zheng Date: Wed, 27 May 2026 09:09:46 +0800 Subject: [PATCH] fix(baoyu-md, baoyu-post-to-x): decode URL-encoded image paths Obsidian creates markdown image links with URL-encoded filenames (e.g. `Pasted%20image%2020260524.png`) but the actual file has spaces. Add `decodeURIComponent()` before path resolution in both baoyu-md's shared `resolveImagePath()` and baoyu-post-to-x's independent version. Co-Authored-By: Claude Opus 4.6 (1M context) --- packages/baoyu-md/src/images.test.ts | 14 ++++++++++++++ packages/baoyu-md/src/images.ts | 7 ++++--- skills/baoyu-post-to-x/scripts/md-to-html.ts | 7 ++++--- 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/packages/baoyu-md/src/images.test.ts b/packages/baoyu-md/src/images.test.ts index 625996c..f3eca2a 100644 --- a/packages/baoyu-md/src/images.test.ts +++ b/packages/baoyu-md/src/images.test.ts @@ -45,6 +45,20 @@ test("image extension and local fallback resolution handle common path variants" assert.equal(resolved, path.join(baseDir, "figure.webp")); }); +test("resolveImagePath decodes URL-encoded filenames with spaces", async (t) => { + const root = await makeTempDir("baoyu-md-urlencoded-"); + t.after(() => fs.rm(root, { recursive: true, force: true })); + + const baseDir = path.join(root, "article"); + const tempDir = path.join(root, "tmp"); + await fs.mkdir(baseDir, { recursive: true }); + await fs.mkdir(tempDir, { recursive: true }); + await fs.writeFile(path.join(baseDir, "Pasted image 20260524.png"), "png"); + + const resolved = await resolveImagePath("Pasted%20image%2020260524.png", baseDir, tempDir, "test"); + assert.equal(resolved, path.join(baseDir, "Pasted image 20260524.png")); +}); + test("resolveContentImages resolves image placeholders against the content directory", async (t) => { const root = await makeTempDir("baoyu-md-content-images-"); t.after(() => fs.rm(root, { recursive: true, force: true })); diff --git a/packages/baoyu-md/src/images.ts b/packages/baoyu-md/src/images.ts index b28f041..667fa89 100644 --- a/packages/baoyu-md/src/images.ts +++ b/packages/baoyu-md/src/images.ts @@ -103,9 +103,10 @@ export async function resolveImagePath( return localPath; } - const resolved = path.isAbsolute(imagePath) - ? imagePath - : path.resolve(baseDir, imagePath); + const decoded = decodeURIComponent(imagePath); + const resolved = path.isAbsolute(decoded) + ? decoded + : path.resolve(baseDir, decoded); return resolveLocalWithFallback(resolved, logLabel); } diff --git a/skills/baoyu-post-to-x/scripts/md-to-html.ts b/skills/baoyu-post-to-x/scripts/md-to-html.ts index 7ee6ce1..9b2fbc9 100644 --- a/skills/baoyu-post-to-x/scripts/md-to-html.ts +++ b/skills/baoyu-post-to-x/scripts/md-to-html.ts @@ -181,11 +181,12 @@ async function resolveImagePath(imagePath: string, baseDir: string, tempDir: str return localPath; } - if (path.isAbsolute(imagePath)) { - return imagePath; + const decoded = decodeURIComponent(imagePath); + if (path.isAbsolute(decoded)) { + return decoded; } - return path.resolve(baseDir, imagePath); + return path.resolve(baseDir, decoded); } function escapeHtml(text: string): string {