我想编写一个lua过滤器,以强制Pandoc在从Markdown转换为PDF时使用紧凑列表。我注意到带有嵌套表/文本/ div的列表将不使用\tightlist
选项,因为Pandoc AST对每个列表项都使用Para
而不是Plain
。我试图修改示例here以强制将所有BulletList
和OrderedList
项都置为Plain
,但是当某项包含嵌套内容时,我无法使其正常工作。 pandoc mwe.txt -f markdown -t native --lua-filter the-filter.lua
返回第一个列表项的Para
:
[BulletList
[[Plain [Str "list",Space,Str "1"]]
,[Plain [Str "list",Space,Str "1"]]
,[Plain [Str "list",Space,Str "1"]]]
,Para [Str "Some",Space,Str "paragraph"]
,BulletList
[[Para [Str "list",Space,Str "2"]
,Div ("",["class"],[])
[Para [Str "Nested",Space,Str "div"]]]
,[Plain [Str "list",Space,Str "2"]]
,[Plain [Str "list",Space,Str "2"]]]]
我无所适从:
walk_block
并将每个列表项更改为Plain
吗?#blocks
> 1的情况?如何将Para
更改为Plain
,然后包含任何嵌套的内容(例如我有两个嵌套的div)?- list 1
- list 1
- list 1
Some paragraph
- list 2
::: {.class}
Nested div
:::
- list 2
- list 2
local List = require 'pandoc.List'
function compactifyItem2 (blocks)
if (#blocks == 1) then
if (blocks[1].t == 'Para') then
return {pandoc.Plain(blocks[1].content)}
else
return blocks
end
elseif (#blocks == 2) then -- I assume I have to change the Para and nest the child content
if (blocks[1].t == 'Para') then
blocks.content = pandoc.Plain(blocks[1].content) .. blocks[2].content
return {blocks.content}
end
else
return blocks
end
end
function compactifyList (l)
l.content = List.map(l.content, compactifyItem2)
return l
end
return {{
BulletList = compactifyList,
OrderedList = compactifyList
}}
答案 0 :(得分:1)
您已经很接近了。我认为以下情况适用于一般情况:
--- Iterate over all blocks in an item, converting 'top-level'
-- Para into Plain blocks.
function compactifyItem (blocks)
-- step through the list of blocks step-by-step, keeping track of the
-- element's index in the list in variable `i`, and assign the current
-- block to `blk`.
--
for i, blk in ipairs(blocks) do
if blk.t == 'Para' then
-- update in item's block list.
blocks[i] = pandoc.Plain(blk.content)
end
end
return blocks
end
function compactifyList (l)
-- l.content is an instance of pandoc.List, so the following is equivalent
-- to pandoc.List.map(l.content, compactifyItem)
l.content = l.content:map(compactifyItem)
return l
end
return {{
BulletList = compactifyList,
OrderedList = compactifyList
}}
在链接的帖子中省略了多块商品的情况。但是,关于何时应该精简列表,可能有不同的意见。以上应该压缩所有列表。
使用walk_blocks
会产生意想不到的副作用,因为它会影响所有块,包括嵌套在Div下方的 Para 块。
答案 1 :(得分:0)
上面的原始答案不适用于Pandoc 2.11和从Google Docs导出的docx文件。有关详情,请参见this issue。这是我对原始答案的修改版本。
-- Source: https://stackoverflow.com/a/57943159/7361270
-- Modified by makeworld
-- Iterate over all blocks in an item, converting 'top-level'
-- Para into Plain blocks.
function compactifyItem (blocks)
-- step through the list of blocks step-by-step, keeping track of the
-- element's index in the list in variable `i`, and assign the current
-- block to `blk`.
--
for i, blk in ipairs(blocks) do
if blk.t == 'Para' then
-- update in item's block list.
blocks[i] = pandoc.Plain(blk.content)
elseif blk.t == 'BlockQuote' then
-- It's a Google Doc thing, where each bullet is in a blockquote
-- https://github.com/jgm/pandoc/issues/6824
blocks[i] = pandoc.Plain(blk.content[1].content)
end
end
return blocks
end
function compactifyList (l)
-- l.content is an instance of pandoc.List, so the following is equivalent
-- to pandoc.List.map(l.content, compactifyItem)
l.content = l.content:map(compactifyItem)
return l
end
return {{
BulletList = compactifyList,
OrderedList = compactifyList
}}