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

Pandoc Lua过滤器无法提取pandoc-crossref表格标签求助

问题根源

Lua过滤器的执行优先级高于外部JSON过滤器(如pandoc-crossref),无论命令行参数顺序如何,Lua过滤器都会先运行。此时pandoc-crossref还未将表格标题中的{#tbl:xxx}标签提取并设置到Table元素的attr.identifier中,导致你无法获取到标签信息。


解决方案

方案一:分两步处理,确保pandoc-crossref先处理AST

先让pandoc-crossref完成标签提取和AST修改,再用Lua过滤器处理已处理后的AST:

  1. 生成pandoc-crossref处理后的中间JSON文件:
pandoc input.md --from markdown+pipe_tables --to json --filter pandoc-crossref > intermediate.json
  1. 用Lua过滤器处理中间JSON文件生成LaTeX:
pandoc intermediate.json --from json --to latex --lua-filter=table.lua --output=output.tex

此时Lua过滤器拿到的Table元素已包含attr.identifier,标签提取逻辑可正常工作。

方案二:在Lua过滤器中自行提取标签

无需依赖pandoc-crossref,直接从表格caption文本中匹配提取{#tbl:xxx}格式的标签。修改后的完整Lua过滤器如下:

function Table(tbl)
  local simpleTable = pandoc.utils.to_simple_table(tbl)
  local blocks = pandoc.Blocks{}

  -- 从caption中提取标签并清理文本
  local function extract_label(caption)
    if not caption then return nil, nil end
    local caption_str = pandoc.utils.stringify(caption)
    local label = caption_str:match("{#([%w:]+)}")
    if label then
      local cleaned_caption = caption_str:gsub("%s*{#[%w:]+}", "")
      return label, cleaned_caption
    end
    return nil, caption_str
  end

  -- 生成LaTeX行(修复原代码引号缺失问题)
  local function create_latex_row(cells)
    local latex_row = ""
    for i, cell in ipairs(cells) do
      for _, content in ipairs(cell) do
        latex_row = latex_row .. pandoc.write(pandoc.Pandoc({content}), "latex")
      end
      if i < #cells then
        latex_row = latex_row .. " & "
      end
    end
    return latex_row .. " \\\\"
  end

  -- 计算列数
  local num_cols = 0
  if simpleTable.header and #simpleTable.header > 0 then
    num_cols = #simpleTable.header
  elseif #simpleTable.rows > 0 then
    num_cols = #simpleTable.rows[1]
  end

  local col_alignment = string.rep("l", num_cols)

  -- 构建table环境
  blocks:insert(pandoc.RawBlock("latex", "\\begin{table}[tbp]"))

  -- 添加标题和标签
  local label, caption_text = extract_label(tbl.caption)
  if caption_text then
    blocks:insert(pandoc.RawBlock("latex", "\\caption{" .. caption_text .. "}"))
  end
  if label then
    blocks:insert(pandoc.RawBlock("latex", "\\label{" .. label .. "}"))
  end

  blocks:insert(pandoc.RawBlock("latex", "\\centering"))
  blocks:insert(pandoc.RawBlock("latex", "\\begin{tabular}{" .. col_alignment .. "}"))
  
  -- 处理表头
  if simpleTable.header and #simpleTable.header > 0 then
    local header_row = create_latex_row(simpleTable.header)
    blocks:insert(pandoc.RawBlock("latex", header_row))
    blocks:insert(pandoc.RawBlock("latex", "\\hline"))
  end

  -- 处理表格行
  for _, row in ipairs(simpleTable.rows) do
    local latex_row = create_latex_row(row)
    blocks:insert(pandoc.RawBlock("latex", latex_row))
  end

  -- 结束环境
  blocks:insert(pandoc.RawBlock("latex", "\\end{tabular}"))
  blocks:insert(pandoc.RawBlock("latex", "\\end{table}"))

  return blocks
end

运行命令时可直接使用原命令(或去掉--filter pandoc-crossref):

pandoc input.md --output=output.tex --from markdown+pipe_tables --to latex --lua-filter=table.lua

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 23:06:00