如何使用pandoc lua过滤器将标题作为一级标题添加?
2019-8-19 17:40:41
收藏:0
阅读:139
评论:1
我想在将多个Markdown文件从Markdown转换为PDF时使用pandoc lua过滤器。我希望将各个Markdown文件的标题用作章节(一级标题)。
我学习了现有的示例,并且我认为这个示例接近我所需的内容--基本上我需要在所有Markdown文件中添加pandoc.Header(1,doc.meta.title),但我很难编写lua过滤器并使其正常工作。
我认为这个问题正在执行类似的操作pandoc filter in lua and walk_block
pandoc命令:
pandoc -N --lua-filter add-title.lua blog/*.md --pdf-engine=xelatex --toc -s -o my_book.pdf
add-title.lua(这是错误的,没有例外,但输出不会发生任何事情):
function add_header (header)
return {
{Header = pandoc.Header(1, meta.title)}}
end
输入文件:
1.md
---
title: Topic1
---
## Sample Header from file 1.md
text text text
2.md
---
title: Topic2
---
## Sample Header from file 2.md
text text text
预期输出等同于此markdown(但我的最终格式是pdf)
---
title: Title from pandoc latex variable
---
# Topic1
## Sample Header from file 1.md
text text text
# Topic2
## Sample Header from file 2.md
text text text
点赞
评论区的留言会收到邮件通知哦~
推荐文章
- Lua 虚拟机加密load(string.dump(function)) 后执行失败问题如何解决
- 我想创建一个 Nginx 规则,禁止访问
- 如何将两个不同的lua文件合成一个 东西有点长 大佬请耐心看完 我是小白研究几天了都没搞定
- 如何在roblox studio中1:1导入真实世界的地形?
- 求解,lua_resume的第二次调用继续执行协程问题。
- 【上海普陀区】内向猫网络招募【Skynet游戏框架Lua后端程序员】
- SF爱好求教:如何用lua实现游戏内调用数据库函数实现账号密码注册?
- Lua实现网站后台开发
- LUA错误显式返回,社区常见的规约是怎么样的
- lua5.3下载库失败
- 请问如何实现文本框内容和某个网页搜索框内容连接,并把网页输出来的结果反馈到另外一个文本框上
- lua lanes多线程使用
- 一个kv数据库
- openresty 有没有比较轻量的 docker 镜像
- 想问一下,有大佬用过luacurl吗
- 在Lua执行过程中使用Load函数出现问题
- 为什么 neovim 里没有显示一些特殊字符?
- Lua比较两个表的值(不考虑键的顺序)
- 有个lua简单的项目,外包,有意者加微信 liuheng600456详谈,最好在成都
- 如何在 Visual Studio 2022 中运行 Lua 代码?

我认为关键问题在于 Lua 过滤器只有在解析出完整文档的 AST 后才能运行。因此,在解析之前,所有单独的文件都会被有效地合并为一个带有单个元数据集的单个文档。在过滤器有机会运行之前,yaml 元数据块中的单独“title”设置已被覆盖。假设您需要从每个单独的元数据块中获取标题(而不能直接将标题放入),则这意味着您不能让 pandoc 合并文件。你需要逐个文件读取并解析它们。幸运的是,使用过滤器很容易做到这一点。
第一步是创建一个包含所有其他文件链接的单个引用文件。
--- title: 合并的标题 --- {.markdown} {.markdown}请注意,链接是使用一个特殊类
.markdown的图像指定的。您可以使用其他方法,但是图像很方便,因为它们支持属性并且很容易识别。现在,我们只需要一个过滤器,它将用链接的 markdown 文件中解析的元素替换这些图像。我们可以通过从 lua 打开文件并使用
pandoc.read(参见 https://www.pandoc.org/lua-filters.html#module-pandoc)将它们解析为完整文档来完成此操作。一旦我们有了文档,我们可以从元数据中读取标题并插入新的标题。请注意,我们将过滤器应用于Para元素而不是Image本身。这是因为 pandoc 将Block元素与Inline元素分开,并且过滤器的返回值必须是相同类型。Image过滤器无法返回从文件解析的块列表,但是Para可以。因此,这是最终的代码。
function Para(elem) if #elem.content == 1 and elem.content[1].t == "Image" then local img = elem.content[1] if img.classes:find('markdown',1) then local f = io.open(img.src, 'r') local doc = pandoc.read(f:read('*a')) f:close() -- now we need to create a header from the metadata local title=pandoc.utils.stringify(doc.meta.title) or "Title has not been set" local newHeader=pandoc.Header(1, {pandoc.Str(title)}) table.insert(doc.blocks, 1, newHeader) return doc.blocks end end end如果您在带有以下命令的组合文件上运行它
pandoc -f markdown -t markdown -i combined.md -s --lua-filter addtitle.lua您将获得所需的结果。
--- title: 合并的标题 --- Topic 1 ======= Sample Header from file 1.md ---------------------------- text text text Topic 2 ======= Sample Header from file 2.md ---------------------------- text text text请注意,包含文件中的任何其他 yaml 元数据都将丢失。您可以通过从单独的
meta对象中获取任何其他东西并将其放入全局对象中来捕获任何其他内容。