You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Pandoc Lua编写器/过滤器中访问pandoc.Figure元素字段值

正确访问Pandoc 3.0+中pandoc.Figure字段的方法

问题根源

Pandoc 3.0重构了Figure元素的结构:

  • fig.content是Blocks列表(而非字符串),通常包含单个Image元素
  • fig.caption是pandoc.Caption对象(而非纯文本),包含long(带格式的主标题,为Inline列表)和short(可选短标题)
    直接将这些对象与字符串拼接会触发类型错误,用pandoc.utils.stringify则会丢失排版格式。

正确的Lua Filter实现

以下是适配Pandoc 3.0+的Filter代码,可直接生成带\sidecaption的LaTeX输出:

function Figure(elem)
  -- 提取Figure中的Image元素(默认场景下content仅含单个图片)
  local img = elem.content[1]
  if not img or img.t ~= 'Image' then
    return nil -- 非图片类型的Figure,交给Pandoc默认处理
  end

  -- 获取图片路径(Image的target属性)
  local img_path = img.target

  -- 将带格式的caption转换为LaTeX字符串(保留斜体、粗体等样式)
  local caption_latex = pandoc.write(pandoc.Pandoc(elem.caption.long), 'latex')

  -- 处理Figure的ID属性,生成LaTeX引用标签
  local label_code = elem.attr.id ~= '' and string.format('\\label{%s}', elem.attr.id) or ''

  -- 构造包含\sidecaption的LaTeX代码
  local raw_latex = string.format([[
\begin{figure*}
  \centering
  \includegraphics[width=0.9\textwidth]{%s}
  \sidecaption{%s}
  %s
\end{figure*}
]], img_path, caption_latex, label_code)

  return pandoc.RawBlock('latex', raw_latex)
end

关键步骤解析

  • 提取图片元素:从elem.content中取出第一个Image对象,通过img.target获取图片路径
  • 保留caption格式:用pandoc.write将elem.caption.long(Inline列表)转换为LaTeX格式字符串,避免丢失排版样式
  • 属性复用:利用elem.attr.id生成LaTeX的\label,支持交叉引用
  • 容错处理:判断content是否为Image,避免非图片Figure触发错误

自定义Writer实现思路

如果使用自定义Writer,逻辑与Filter一致,只需在Writer的filter中复用上述提取逻辑:

function Writer(doc, opts)
  local filter = {
    Figure = function(fig)
      local img = fig.content[1]
      if not img or img.t ~= 'Image' then
        return nil
      end
      local img_path = img.target
      local caption_latex = pandoc.write(pandoc.Pandoc(fig.caption.long), 'latex')
      local raw_latex = string.format([[
\begin{figure*}
  \centering
  \includegraphics[width=0.9\textwidth]{%s}
  \sidecaption{%s}
\end{figure*}
]], img_path, caption_latex)
      return pandoc.RawBlock('latex', raw_latex)
    end
  }
  return pandoc.write(doc:walk(filter), 'latex', opts)
end

使用方法

将代码保存为sidecaption-filter.lua,执行转换命令:

pandoc input.md --lua-filter=sidecaption-filter.lua -o output.pdf

(或导出为.tex文件查看生成的LaTeX代码)

内容的提问来源于stack exchange,提问作者lukeflo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 09:43:36