簡體   English   中英

Pandoc lua 過濾器強制緊湊列表

[英]Pandoc lua filter to force compact lists

我想編寫一個 lua 過濾器,強制 Pandoc 在從 Markdown 轉換為 PDF 時使用緊湊列表。 我注意到帶有嵌套表/文本/div 的列表不會使用\\tightlist選項,因為 Pandoc AST 對每個列表項使用Para而不是Plain 我嘗試修改此處的示例以強制所有BulletListOrderedList項目為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

過濾器.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
}}

你已經很接近了。 我相信以下應該適用於一般情況:

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM