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) <noreply@anthropic.com>
This commit is contained in:
Chao Zheng
2026-05-27 09:09:46 +08:00
committed by Jim Liu 宝玉
parent e1c0ff7c02
commit 876f01ac19
3 changed files with 22 additions and 6 deletions
+14
View File
@@ -45,6 +45,20 @@ test("image extension and local fallback resolution handle common path variants"
assert.equal(resolved, path.join(baseDir, "figure.webp")); 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) => { test("resolveContentImages resolves image placeholders against the content directory", async (t) => {
const root = await makeTempDir("baoyu-md-content-images-"); const root = await makeTempDir("baoyu-md-content-images-");
t.after(() => fs.rm(root, { recursive: true, force: true })); t.after(() => fs.rm(root, { recursive: true, force: true }));
+4 -3
View File
@@ -103,9 +103,10 @@ export async function resolveImagePath(
return localPath; return localPath;
} }
const resolved = path.isAbsolute(imagePath) const decoded = decodeURIComponent(imagePath);
? imagePath const resolved = path.isAbsolute(decoded)
: path.resolve(baseDir, imagePath); ? decoded
: path.resolve(baseDir, decoded);
return resolveLocalWithFallback(resolved, logLabel); return resolveLocalWithFallback(resolved, logLabel);
} }
+4 -3
View File
@@ -181,11 +181,12 @@ async function resolveImagePath(imagePath: string, baseDir: string, tempDir: str
return localPath; return localPath;
} }
if (path.isAbsolute(imagePath)) { const decoded = decodeURIComponent(imagePath);
return imagePath; if (path.isAbsolute(decoded)) {
return decoded;
} }
return path.resolve(baseDir, imagePath); return path.resolve(baseDir, decoded);
} }
function escapeHtml(text: string): string { function escapeHtml(text: string): string {