From b0e83948b1b645f5f2fd55a141c7576e8bcb7d44 Mon Sep 17 00:00:00 2001 From: andev0x Date: Fri, 29 Aug 2025 16:46:41 +0700 Subject: [PATCH] fix: pandoc template compilation error and show image --- server.js | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/server.js b/server.js index 98197f8..61dc03e 100644 --- a/server.js +++ b/server.js @@ -34,6 +34,8 @@ function renderMarkdown() { "-o", "-" // output to stdout ]; + // add resource path for resolving relative images + args.splice(1, 0, "--resource-path=" + path.dirname(MARKDOWN_FILE)); // spawn pandoc and capture stdout const res = spawnSync("pandoc", args, { encoding: "utf8" }); if (res.error) { @@ -44,7 +46,39 @@ function renderMarkdown() { console.error("pandoc exit code:", res.status, res.stderr); return `
Pandoc failed: ${res.stderr}
`; } - return res.stdout; + let html = res.stdout || ""; + // Post-process tags to better support special characters and add attributes + const processed = html.replace(/]*)>/gi, (match, attrs) => { + // find src attribute + const srcMatch = attrs.match(/\bsrc=("([^"]*)"|'([^']*)')/i); + let src = srcMatch ? (srcMatch[2] || srcMatch[3] || "") : ""; + let newSrc = src; + if (src && !/^https?:/i.test(src) && !/^data:/i.test(src) && !/^blob:/i.test(src)) { + // URL-encode relative paths (preserve slashes) + newSrc = src.split('/').map((seg) => seg === '' ? '' : encodeURIComponent(decodeURIComponent(seg))).join('/'); + } + let newAttrs = attrs; + if (srcMatch && newSrc !== src) { + newAttrs = newAttrs.replace(srcMatch[0], `src="${newSrc}"`); + } + // capture alt/title for data-* attributes and downstream tooling + const altMatch = newAttrs.match(/\balt=("([^"]*)"|'([^']*)')/i); + const titleMatch = newAttrs.match(/\btitle=("([^"]*)"|'([^']*)')/i); + const altText = altMatch ? (altMatch[2] || altMatch[3] || "") : ""; + const titleText = titleMatch ? (titleMatch[2] || titleMatch[3] || "") : ""; + const fileName = src ? path.basename(src) : ""; + // ensure helpful attributes + if (!/\bloading=/.test(newAttrs)) newAttrs += ' loading="lazy"'; + if (!/\bdecoding=/.test(newAttrs)) newAttrs += ' decoding="async"'; + if (!/\breferrerpolicy=/.test(newAttrs)) newAttrs += ' referrerpolicy="no-referrer"'; + if (!/\bclass=/.test(newAttrs)) newAttrs += ' class="mdview-img"'; + if (src && !/\bdata-src-original=/.test(newAttrs)) newAttrs += ` data-src-original="${src.replace(/"/g, '"')}"`; + if (fileName && !/\bdata-filename=/.test(newAttrs)) newAttrs += ` data-filename="${fileName.replace(/"/g, '"')}"`; + if (altText && !/\bdata-alt=/.test(newAttrs)) newAttrs += ` data-alt="${altText.replace(/"/g, '"')}"`; + if (titleText && !/\bdata-title=/.test(newAttrs)) newAttrs += ` data-title="${titleText.replace(/"/g, '"')}"`; + return ``; + }); + return processed; } catch (e) { return `
Render error: ${e.message}
`; }