Pandoc Lua过滤器:对不显示表中的所有键

时间:2017-10-31 03:20:08

标签: pandoc lua-table

自Pandoc 2.0版以来,已有能够编写Lua Filters。但是,在Pandoc 2.0中,我发现在元素表上使用Lua的pairs并不会显示表中的所有键。

这是一个简单的例子来说明这一点。在filter.lua我有:

function Para(elem)
  io.stderr:write("A: " .. type(elem) .. "\n")
  for k, v in pairs(elem) do
    io.stderr:write("B: " .. k .. "\n")
  end
  io.stderr:write("C: " .. elem["t"] .. "\n")
  io.stderr:write("D: " .. tostring(elem["c"]) .. "\n")
  -- Return elem unchanged
  return nil
end

现在从命令行运行:

echo "Hello." | pandoc -f markdown -t native --lua-filter filter.lua

这会产生输出:

A: table
B: c
C: Para
D: table: 0x53adb40
[Para [Str "Hello."]]

我可以将-t native更改为-t json,以便最后一行变为:

{"blocks":[{"t":"Para","c":[{"t":"Str","c":"Hello."}]}],"pandoc-api-version":[1,17,2],"meta":{}}

因此,从(B)的输出看,celem中唯一的关键,但从(C)可以看出,t也是关键字我可以访问它以获取Para。这里发生了什么,为什么用t隐藏了循环中的pairs键?

1 个答案:

答案 0 :(得分:2)

t值隐藏在元素的元表中:pandoc为每个元素设置元表,而不是为每个元素分配t值。这样做的原因是在可用性和性能之间找到平衡。

将数字表索引返回Haskell比访问字符串索引值要快得多。但是,用户应该能够以直接面向对象的方式使用元素,通过可读的字符串属性访问元素组件。这就是我们为每个元素分配元表的原因。元表包含元素类型的信息(例如,Plain vs. Para等)并定义访问器(例如,content是在Plain和Para元素中索引0的别名)。

因此,可以通过调用elem来获取元素elem.t的类型,但元素本身没有该元素,metatable会这样做。这就是为什么t在使用pairs迭代元素时不显示的原因。可以使用getmetatable函数来接收元数据。

您可能会欣赏以下方法来获取访问者的名称(未记录且可能会更改)。

for k, _ in pairs(getmetatable(elem).getters) do
    print k
end

或者,关于"模块pandoc"在lua过滤器文档中列出了每种元素类型的访问器。