使用Pandoc Haskell API生成HTML/PDF时图片路径解析不一致求助
Pandoc API生成HTML/PDF时图片路径统一解决方案
针对你用Haskell调用Pandoc API时,同一Markdown源生成HTML和PDF的图片路径解析不一致问题,以下是几种最优解决思路:
方法1:基于Markdown文件目录统一解析+格式专属路径转换
这是最通用的方案,核心是先以Markdown文件所在目录为基准解析所有图片路径,再针对HTML/PDF输出格式分别调整路径规则。
Haskell代码示例
import Text.Pandoc import Text.Pandoc.Walk (walk) import System.FilePath (takeDirectory, (</>), makeRelative) import System.IO (writeFile) -- 根据输出格式调整图片路径 adjustImagePaths :: FilePath -> Format -> Inline -> Inline adjustImagePaths mdRoot fmt (Image attr alt (src, tit)) = let resolvedSrc = mdRoot </> src -- 以Markdown文件目录为基准解析原路径 newSrc = case fmt of -- HTML输出:转换为Web根目录相对路径 Format "html" -> "/" ++ makeRelative "/path/to/your/web/root" resolvedSrc -- PDF输出:保留绝对路径供LaTeX查找 Format "pdf" -> resolvedSrc _ -> src in Image attr alt (newSrc, tit) adjustImagePaths _ _ x = x -- 统一转换入口 convertMarkdown :: FilePath -> Format -> IO () convertMarkdown mdFile fmt = do let mdRoot = takeDirectory mdFile -- 读取Markdown时指定资源查找根目录 doc <- readMarkdown def { readerResourcePath = [mdRoot] } =<< readFile mdFile -- 应用路径转换规则 let adjustedDoc = walk (adjustImagePaths mdRoot fmt) doc -- 生成对应格式文件 case fmt of Format "html" -> writeHtml5String def adjustedDoc >>= writeFile "output.html" Format "pdf" -> runIO $ writePDF def adjustedDoc >>= writeFile "output.pdf" _ -> return ()
方法2:切换工作目录适配PDF路径解析
如果偏好使用相对Markdown文件的路径(如resources/3IMG.JPG),可以在生成PDF时临时切换工作目录到Markdown文件所在位置,让LaTeX自动从该目录查找图片:
Haskell代码示例
import Text.Pandoc import System.FilePath (takeDirectory, (</>)) import System.Directory (getCurrentDirectory, setCurrentDirectory) import System.IO (writeFile) convertToPDF :: FilePath -> IO () convertToPDF mdFile = do let mdRoot = takeDirectory mdFile originalDir <- getCurrentDirectory -- 切换到Markdown文件所在目录 setCurrentDirectory mdRoot doc <- readMarkdown def { readerResourcePath = [mdRoot] } =<< readFile mdFile -- 生成PDF后切回原目录 runIO $ writePDF def doc >>= writeFile (originalDir </> "output.pdf") setCurrentDirectory originalDir
HTML输出时则单独将相对路径转换为Web根目录路径即可。
方法3:利用变量统一替换路径前缀
在Markdown中用占位符引用图片路径(如),再针对不同输出格式替换占位符:
Haskell代码示例
import Text.Pandoc import Text.Pandoc.Walk (walk) import System.IO (writeFile) import Data.List.Split (splitOn) import Data.List (intercalate) replace :: String -> String -> String -> String replace old new = intercalate new . splitOn old replaceResourceVar :: String -> Inline -> Inline replaceResourceVar root (Image attr alt (src, tit)) = let newSrc = replace "{{resource_root}}" root src in Image attr alt (newSrc, tit) replaceResourceVar _ x = x convertWithVar :: FilePath -> Format -> IO () convertWithVar mdFile fmt = do let root = case fmt of Format "html" -> "/Blog" Format "pdf" -> "/absolute/path/to/your/Blog" _ -> "" doc <- readMarkdown def =<< readFile mdFile let adjustedDoc = walk (replaceResourceVar root) doc -- 后续写入逻辑同前
最优方案推荐
优先选择方法1:无需修改Markdown原内容,通过代码统一处理路径解析和转换逻辑,既保证HTML输出的Web根路径正确性,又让PDF生成时能直接找到图片资源,完全替代临时修改LaTeX\graphicspath的方案。
内容的提问来源于stack exchange,提问作者user855443
相关产品推荐
相关产品推荐

