[英]Pandoc lua filter to force compact lists
我想编写一个 lua 过滤器,强制 Pandoc 在从 Markdown 转换为 PDF 时使用紧凑列表。 我注意到带有嵌套表/文本/div 的列表不会使用\\tightlist
选项,因为 Pandoc AST 对每个列表项使用Para
而不是Plain
。 我尝试修改此处的示例以强制所有BulletList
和OrderedList
项目为Plain
,但是当项目包含嵌套内容时我无法使其工作。 pandoc mwe.txt -f markdown -t native --lua-filter the-filter.lua
返回Para
一个列表项的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
}}
你已经很接近了。 我相信以下应该适用于一般情况:
--- 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块。
上面的原始答案不适用于 Pandoc 2.11 和从 Google Docs 导出的 docx 文件。 有关详细信息,请参阅此问题。 这是我对原始答案的修改版本。
-- 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
}}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.