Pandoc使用Lua过滤器
目录
Pandoc内置了Lua解释器,可以直接处理语法树。
初体验
-
运行
pandoc -v找到User data directory,在该目录中创建filters文件夹,在其中编写filters。使用以下命令快速获取目录:1 2pandoc -v | sed -n 's/^User data directory: //p' # win pandoc -v | sed -n 's/.*: \([^ ]*\) or.*/\1/p' # linux
-
将filter放在上述的文件夹中的优势是不用再指定filter的绝对路径,比如原来调用命令:
1pandoc --lua-filter C:\test\smallcaps.lua变为
1pandoc --lua-filter smallcaps.lua # 自动在data directory中的filters文件夹搜寻 -
使用vscode打开此目录,安装Lua插件,下载pandoc定义文件到此目录。创建
header.lua,编写如下代码:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20---@module "pandoc-types-annotations" local pandoc = pandoc ---@type pandoc ---comment ---@param elem Header ---@return Inline | List<Inline> | nil function Header(elem) elem = elem:walk { Str = function(el) el.text = pandoc.text.upper(el.text) return el end } if elem.level == 1 then elem.level = 3 return elem end return elem end -
创建
test.md1 2 3# heading1 ## heading2 ### heading3 -
运行
pandoc --lua-filter=header.lua test.md -o output.md,结果如下1 2 3 4 5### HEADING1 ## HEADING2 ### HEADING3 -
可以看到所有的标题都变成了大写,标题1变成了标题3。我们定义了一个
Header函数,pandoc会将Ast树中的所有Header元素依次调用这个函数,接收的elem参数即为当前的Header元素。-
我们可以使用
elem.level去调整标题等级,修改完成后,一定要返回一个元素(可以是修改后的元素)。Pandoc期待返回一个同类型的元素(Inline类型或者Block类型),或者同类型的列表,或者是nil,nil表示不改动该元素 -
在本例中Header属于Block类型,我们可以使用以下命令查看文档包含哪些元素
1pandoc -s -t native test.md # -s get meta -t convert to what format -
类似于
Header函数,我们可以定义Str,Para,Para等函数,Pandoc会一次将对应的元素传入对应的函数中。如果我们不定义全局函数的话,我们也可以返回一个table1 2 3 4 5return { Str: function, Header: function, Pandoc: function }Pandoc会将对应的元素传入的这些函数中。
-
在上述代码的第8行,我们调用了walk方法,几乎所有的元素都有此方法。此方法会遍历该元素的子元素,根据元素类型调用对应的函数。这些函数都需要返回同类型的元素或者数组或者nil。
-
walk方法返回一个深拷贝后的元素,修改完后,要返回该元素(line 19)
-
文章作者 surwall
上次更新 2026-05-01 19:21:24