解决 "Pandoc Filters" 页上的第一个练习
Solving the first exercise on "Pandoc Filters" page
第一个问题https://pandoc.org/filters.html#exercises asks to convert all text to uppercase except if it is part of a URL or a link title. So, I read the discussion about "Execution Order" in lua filters at https://pandoc.org/lua-filters.html#execution-order,得出
text = require 'text'
links = {}
function Link(el)
links[el.target] = el.content
return el
end
function Str(el)
el.text = text.upper(el.text)
return el
end
function Inlines(elems)
for i=1,#elems,1 do
if elems[i].tag == 'Link' then
elems[i].content = '<====' .. links[elems[i].target] .. '====>' -- just so that I can see it in the document.
-- elems[i].content = pandoc.Str 'hello'
end
end
return elems
end
--[[ -- Explicitly force order of filters -- from "Execution Order" list...
return {
{ Link = Link,
Str = Str,
Inlines = Inlines
}
}
]]
认为这会解决我的问题。但不知何故我无法让它发挥作用。我还尝试通过强制调用过滤器的顺序(在脚本末尾...注释)来明确安排 table,但它似乎不起作用。我做错了什么?
练习题:
Put all the regular text in a markdown document in ALL CAPS (without touching text in URLs or link titles).
这可以按照您上面描述的方式完成:
local text = require 'text'
function Str (s)
s.text = text.upper(s.text)
return s
end
这样就只剩下 URL 和 link 标题了。
单独留下 link 文本有点困难。 Pandoc Lua 过滤器以 depth-first 后序遍历文档树,因此 Link 节点只有在其内容被处理后才会被处理。我们可以使用像
这样的简单过滤器来验证和可视化这一点
function Inline (i)
print(i.tag, pandoc.utils.stringify(i))
end
运行 以上输入 Hello, [Free Encyclopedia](https://en.wikipedia.org)
会产生
Str Hello,
Space
Str Free
Space
Str Encyclopedia
Link Free Encyclopedia
使用 Inlines
而不是 Inline
没有什么不同:嵌套元素在我们知道它们属于哪个元素之前就已经被处理了。这实际上意味着我们不能(轻松地)阻止转换影响特定的子树。
这很不幸(而且,作为 Lua 过滤系统的作者,我想在未来改变这一点)。然而,并非所有都丢失了。我们可以通过一个简单的技巧解决这个问题:保存,然后恢复原始 link 内容:
local text = require 'text'
local links = pandoc.List()
function to_allcaps (s)
s.text = text.upper(s.text)
return s
end
function save_link (l)
links:insert(l)
end
function restore_link (l)
return links:remove(1)
end
return {
{Link = save_link},
{Str = to_allcaps},
{Link = restore_link},
}
在这里,我们遍历文档三次,如返回的过滤器列表中的三个单独的过滤器所示。首先,我们将所有 link 收集到一个列表中;然后我们将所有内容全部大写;最后,我们恢复了原始的 links,从而撤消了其 link 标题中的所有大写修改。
精简版:
local text = require 'text'
local links = pandoc.List{}
return {
{Link = function (l) links:insert(l) end},
{Str = function (s) return pandoc.Str(text.upper(s.text)) end},
{Link = function (_) return links:remove(1) end},
}
第一个问题https://pandoc.org/filters.html#exercises asks to convert all text to uppercase except if it is part of a URL or a link title. So, I read the discussion about "Execution Order" in lua filters at https://pandoc.org/lua-filters.html#execution-order,得出
text = require 'text'
links = {}
function Link(el)
links[el.target] = el.content
return el
end
function Str(el)
el.text = text.upper(el.text)
return el
end
function Inlines(elems)
for i=1,#elems,1 do
if elems[i].tag == 'Link' then
elems[i].content = '<====' .. links[elems[i].target] .. '====>' -- just so that I can see it in the document.
-- elems[i].content = pandoc.Str 'hello'
end
end
return elems
end
--[[ -- Explicitly force order of filters -- from "Execution Order" list...
return {
{ Link = Link,
Str = Str,
Inlines = Inlines
}
}
]]
认为这会解决我的问题。但不知何故我无法让它发挥作用。我还尝试通过强制调用过滤器的顺序(在脚本末尾...注释)来明确安排 table,但它似乎不起作用。我做错了什么?
练习题:
Put all the regular text in a markdown document in ALL CAPS (without touching text in URLs or link titles).
这可以按照您上面描述的方式完成:
local text = require 'text'
function Str (s)
s.text = text.upper(s.text)
return s
end
这样就只剩下 URL 和 link 标题了。
单独留下 link 文本有点困难。 Pandoc Lua 过滤器以 depth-first 后序遍历文档树,因此 Link 节点只有在其内容被处理后才会被处理。我们可以使用像
这样的简单过滤器来验证和可视化这一点function Inline (i)
print(i.tag, pandoc.utils.stringify(i))
end
运行 以上输入 Hello, [Free Encyclopedia](https://en.wikipedia.org)
会产生
Str Hello,
Space
Str Free
Space
Str Encyclopedia
Link Free Encyclopedia
使用 Inlines
而不是 Inline
没有什么不同:嵌套元素在我们知道它们属于哪个元素之前就已经被处理了。这实际上意味着我们不能(轻松地)阻止转换影响特定的子树。
这很不幸(而且,作为 Lua 过滤系统的作者,我想在未来改变这一点)。然而,并非所有都丢失了。我们可以通过一个简单的技巧解决这个问题:保存,然后恢复原始 link 内容:
local text = require 'text'
local links = pandoc.List()
function to_allcaps (s)
s.text = text.upper(s.text)
return s
end
function save_link (l)
links:insert(l)
end
function restore_link (l)
return links:remove(1)
end
return {
{Link = save_link},
{Str = to_allcaps},
{Link = restore_link},
}
在这里,我们遍历文档三次,如返回的过滤器列表中的三个单独的过滤器所示。首先,我们将所有 link 收集到一个列表中;然后我们将所有内容全部大写;最后,我们恢复了原始的 links,从而撤消了其 link 标题中的所有大写修改。
精简版:
local text = require 'text'
local links = pandoc.List{}
return {
{Link = function (l) links:insert(l) end},
{Str = function (s) return pandoc.Str(text.upper(s.text)) end},
{Link = function (_) return links:remove(1) end},
}