【问题标题】:Pandoc lua filter to force compact listsPandoc lua 过滤器强制压缩列表
【发布时间】:2020-11-14 08:50:15
【问题描述】:

我想编写一个 lua 过滤器,在从 markdown 转换为 PDF 时强制 Pandoc 使用紧凑列表。我注意到带有嵌套表/文本/div 的列表不会使用 \tightlist 选项,因为 Pandoc AST 对每个列表项使用 Para 而不是 Plain。我尝试修改示例here 以强制所有BulletListOrderedList 项目为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)?

mwe.txt

- list 1
- list 1
- list 1

Some paragraph

- list 2

  ::: {.class}
  Nested div
  :::

- list 2
- list 2

the-filter.lua

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
}}

【问题讨论】:

    标签: lua pandoc


    【解决方案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 块。

    【讨论】:

    • 这很有帮助!但是我发现该功能也影响了 Div 下方的 Para 块。检查 Para 的父块的函数是不是 Div 还是 BulletList?
    • 你能举一个例子,Divs下面的Para块受到影响吗?对于问题中给出的示例,我似乎没有这样做。
    【解决方案2】:

    上面的原始答案不适用于 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
    }}
    

    【讨论】:

      猜你喜欢
      • 2019-10-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多