新手求助:编写Pandoc Lua过滤器实现图片标题迁移至文档末尾并移除图片显示
解决Pandoc Lua Filter捕获LaTeX Figure并迁移标题的问题
首先,你之前无法捕获到figure元素的核心原因是:Markdown文档中的独立LaTeX代码块会被Pandoc解析为RawBlock类型(格式为latex),而不是你尝试的Para、Image等类型。所以你之前的检测函数根本触不到这些figure代码块。
下面是完整的Lua Filter解决方案,完全满足你的需求:移除原figure代码块、提取标题、在文档末尾生成要求格式的Figures区块,且最终文档不显示图片(只保留标题区块和引用)。
完整Lua Filter代码
-- 全局变量存储提取到的图片标题和标签 local captions = {} -- 处理RawBlock:捕获LaTeX figure环境,提取标题并移除原块 function RawBlock(el) -- 仅处理LaTeX格式的RawBlock if el.format == "latex" then -- 匹配整个figure环境(支持多行内容) local figure_content = el.text:match("\\begin{figure}([\\s\\S]*?)\\end{figure}") if figure_content then -- 提取caption文本(非贪婪匹配,确保只抓当前caption) local caption_text = figure_content:match("\\caption{(.-)}") -- 可选:提取label(如果需要保留引用关联) local label_text = figure_content:match("\\label{(.-)}") if caption_text then -- 将标题和标签存入数组 table.insert(captions, { caption = caption_text, label = label_text }) -- 返回nil表示移除当前RawBlock(即删除原figure代码) return nil end end end -- 非figure的RawBlock保持不变 return el end -- 处理整个文档:在末尾添加Figures区块 function Pandoc(doc) -- 如果有提取到标题,生成Figures部分 if #captions > 0 then local figures_section = {} -- 添加Figures标题(无编号的section) table.insert(figures_section, pandoc.RawBlock("latex", "\\section*{Figures}")) -- 为每个提取到的标题生成对应的figure块 for _, fig in ipairs(captions) do local fig_block = "\\begin{figure}[h!]\n" fig_block = fig_block .. " \\caption{" .. fig.caption .. "}\n" -- 如果有label,保留它以维持引用关联 if fig.label then fig_block = fig_block .. " \\label{" .. fig.label .. "}\n" end fig_block = fig_block .. "\\end{figure}" table.insert(figures_section, pandoc.RawBlock("latex", fig_block)) end -- 将Figures区块添加到文档末尾 doc.blocks = doc.blocks .. figures_section end return doc end -- 注册要使用的过滤器函数 return { {RawBlock = RawBlock}, {Pandoc = Pandoc} }
使用方法
将上述代码保存为move-figures.lua,然后用Pandoc转换时指定该过滤器:
pandoc input.md -o output.tex --lua-filter=move-figures.lua
关键细节解释
- 捕获RawBlock:通过
RawBlock函数拦截所有LaTeX格式的代码块,用正则匹配整个figure环境,确保不会漏掉多行的figure代码。 - 提取标题和标签:用正则从figure内容中精准提取
\caption和\label的内容,保留标签可以维持文档中对图片的引用(比如\ref{fig:figure1}仍然有效)。 - 移除原figure块:当成功捕获并提取信息后,返回
nil告诉Pandoc删除这个RawBlock。 - 生成末尾区块:在
Pandoc函数中遍历收集到的标题,按照期刊要求的格式生成新的figure块,并添加到文档末尾的\section*{Figures}下。
测试验证
如果你的原始Markdown中有这样的LaTeX块:
\begin{figure} \includegraphics[width=1\linewidth]{figure1} \caption{Figure 1. Caption.}\label{fig:figure1} \end{figure}
转换后的TeX文档末尾会生成:
\section*{Figures} \begin{figure}[h!] \caption{Figure 1. Caption.} \label{fig:figure1} \end{figure}
同时原文档中的figure代码块会被完全移除,符合期刊“手稿仅保留图片引用、单独提交图片”的要求。
内容的提问来源于stack exchange,提问作者Bakaburg




