Pandoc Lua 过滤器:如何指定 Span 元素的属性

jcr*_*jcr 6 lua pandoc

我有一个包含原始 LaTeX 命令的 Markdown 文档。我正在尝试使用带有 Pandoc (2.0.1.1) 的Lua 过滤器将 LaTeX 命令转换为更便携的命令。特别是,指定文本语言的命令应转换为带有lang属性的跨度。问题是我不知道如何将属性传递给pandoc.Span构造函数。这是我对过滤器的尝试(filter.lua):

function RawInline(elem)
  if elem.format == "tex" then
    text = string.match(elem.text, "\\textspanish{(.+)}")
    if text then
      contents = {pandoc.Str(text)}
      attrs = pandoc.Attr("",{},{lang = "es-SP"})
      return pandoc.Span(contents, attrs)
    end
  else
    return elem
  end
end
Run Code Online (Sandbox Code Playgroud)

使用示例:

echo '\textspanish{hola}' | pandoc -f markdown -t native --lua-filter=filter.lua
Run Code Online (Sandbox Code Playgroud)

输出为[Para [Span ("",[],[]) [Str "hola"]]],跨度上没有属性。

如果我将名称和/或类传递给pandoc.Attr,它们就会通过,例如attrs = pandoc.Attr("name",{"class"},{lang = "es-SP"})产生[Para [Span ("name",["class"],[]) [Str "hola"]]]。但我传递给构造函数的属性永远不会出现在输出中。将属性传递给的正确方法是什么pandoc.Attr

tar*_*leb 4

这曾经是 Lua 过滤器实现中的粗糙边缘之一;此后它已得到解决并变得更加用户友好,因此上面的示例现在可以按预期工作。

背景

在内部,pandoc 使用二元素表来保存键值对。它大致看起来像这样:

attrs = pandoc.Attr("", {}, {{"lang", "es-SP"}})
Run Code Online (Sandbox Code Playgroud)

当然,这不是表示对的好方法。当前实施的原因有两个:

  1. 它反映了 pandoc 的 JSON 输出中对(以及一般属性)的编码方式。
  2. 这些对有固定的顺序。

当想要保证属性的顺序在通过过滤器时不会改变时,最后一部分很重要。Lua 中没有规则决定表中键的顺序:Lua 表可以作为属性列表或作为{one = 1, two = 2}读回到 pandoc 中。现在,属性的顺序对于大多数应用程序来说并不重要,但我们不能确定。因此,这种表示方式不太直观。{one="1" two="2}{two="2" one="1"}

当前状态(pandoc 2.16 及更高版本)

内部表示没有改变,但我们改进了 Lua 中 Attr 对象的表示,扩展了编组代码,并添加了 Lua 元表。因此,属性表将按预期进行处理。此外,许多用户可能会发现使用类似 HTML 的属性列表而不是“标识符、类、属性”三元组更直观。现在也支持这一点:

attrs = pandoc.Attr("", {}, {{"lang", "es-SP"}})
Run Code Online (Sandbox Code Playgroud)

事实上,根本不需要使用pandoc.Attr构造函数,只需传递一个表即可:

attr = pandoc.Attr{id='some-id', class="one two", lang='es-SP'}
Run Code Online (Sandbox Code Playgroud)