You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

新手求助:编写Pandoc Lua过滤器实现图片标题迁移至文档末尾并移除图片显示

解决Pandoc Lua Filter捕获LaTeX Figure并迁移标题的问题

首先,你之前无法捕获到figure元素的核心原因是:Markdown文档中的独立LaTeX代码块会被Pandoc解析为RawBlock类型(格式为latex,而不是你尝试的ParaImage等类型。所以你之前的检测函数根本触不到这些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

关键细节解释

  1. 捕获RawBlock:通过RawBlock函数拦截所有LaTeX格式的代码块,用正则匹配整个figure环境,确保不会漏掉多行的figure代码。
  2. 提取标题和标签:用正则从figure内容中精准提取\caption\label的内容,保留标签可以维持文档中对图片的引用(比如\ref{fig:figure1}仍然有效)。
  3. 移除原figure块:当成功捕获并提取信息后,返回nil告诉Pandoc删除这个RawBlock。
  4. 生成末尾区块:在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

火山引擎 最新活动