Pandoc是否支持在其模板中创建降价表?

时间:2019-05-05 07:01:59

标签: markdown pandoc

如果我理解正确,我正在阅读pandoc手册nd,它支持使用模板文件和包含要在模板中使用的变量的YAML文件。 它还说YAML支持任何任意对象(甚至列表)。但是,我想问问是否有可能使用YAML数据在模板中呈现Markdown表。 这些示例仅显示了简单的键和值映射。


编辑: 我创建了一个包含此内容的testable.md文件

---
table:
  caption: Cities
  headers: [city, population]
  rows:
    - [Berlin, '3,748,148']
    - [Tokyo, '13,839,910']
---

$table$

**Random Text**

并使用此命令来使用tarleb提供的过滤器: pandoc -f markdown -t docx --lua-filter=yaml_table.lua -o target.docx testtable.md

但是,似乎输出文件仍然不包含该表。 我想念什么吗?


编辑: 我意识到模板文件的指定与输入的不同 当我使testtable.md仅包含以下内容时,它可以正常工作:

---
table:
  caption: Cities
  headers: [city, population]
  rows:
    - [Berlin, '3,748,148']
    - [Tokyo, '13,839,910']
---

并创建了一个名为markdowntmpl.md的模板文件,其中包含以下内容

$table$

**Random Text**

然后我使用以下命令:

pandoc -f markdown -t markdown --template=markdowntemplate.md --lua-filter=yaml_table.lua -o target.md testtable.md

输出:

  city     population
  -------- ------------
  Berlin   3,748,148
  Tokyo    13,839,910

  : Cities

**Random Text**

然后我可以继续从中创建docx文档。

1 个答案:

答案 0 :(得分:1)

Markdown中可表示的所有元素也可以放入元数据字段中。插入复杂元素的最简单方法是对多行字符串使用保留换行符的YAML语法。例如,

---
table: |
  | city   | population |
  |--------|------------|
  | Berlin |  3,748,148 |
  | Tokyo  | 13,839,910 |
---

这将table定义为包含表的元数据字段。


没有定义表的“本机” YAML方法,但是您可以使用pandoc Lua filter来滚动自己的表。

说一个人想要定义一个这样的表:

---
table:
  caption: Cities
  headers: [city, population]
  rows:
    - [Berlin, '3,748,148']
    - [Tokyo, '13,839,910']
---

然后可以使用以下过滤器将其转换为pandoc表。

local List = require 'pandoc.List'

function repeated(item, times)
  local result = {}
  for i = 1, times do result[i] = item end
  return result
end

function to_table (tbl)
  if tbl.t ~= 'MetaMap' or not tbl.rows then
    return nil
  end

  -- Turn MetaInlines into blocks
  local to_blocks = function (x) return {pandoc.Plain(List:new(x))} end

  local headers = (List:new(tbl.headers)):map(to_blocks)
  local rows = List:new(tbl.rows):map(
    function (row) return List:new(row):map(to_blocks) end
  )
  local columns = #rows[1]
  local aligns = tbl.aligns or repeated(pandoc.AlignDefault, columns)
  local widths = tbl.widths or repeated(0, columns)
  return pandoc.Table(List:new(tbl.caption), aligns, widths, headers, rows)
end

function Meta (meta)
  for k, v in pairs(meta) do
      local success, result = pcall(to_table, v)
      if success and result then
        meta[k] = pandoc.MetaBlocks{result}
      end
  end
  return meta
end