使用 pandoc 丰富文档前言

使用 pandoc 丰富文档前言

我使用 pandoc 通过 lualatex 从 markdown 文件生成 PDF 文件。文档类scrartcl定义了命令\publishers{},该命令在 中使用\maketitle。我想编写一个 lua 过滤器,从元数据字段中提取值并将命令添加到前言中。

markdown 文件如下所示:

---
title:      My very important document
author:     It's me
publishers: This is what I would like to add
...

# Introduction

And so on and on ...

这是我目前的过滤器

if FORMAT:match 'latex' then
  function Meta(meta)
    -- How to check for a KOMA-Script document class?
    if meta.publishers then
      local publishers = pandoc.utils.stringify(meta.publishers)
      local latex_cmd = '\\publishers{' .. publishers .. '}'
      local raw_inline = pandoc.RawInline('latex', latex_cmd)
      -- How to add the command to the preamble?      
    end
  end
end

以下是我的问题:

  1. 如何在过滤器中检查 KOMA-Script 文档类?
  2. 如何将命令添加到文档序言中?我需要为此使用自定义编写器吗?

答案1

这是一个过滤器,它将\publishers命令添加到header-includes元数据字段,然后将其插入到文档前言中。

function Meta (meta)
  if meta.publishers then
    local publishers = pandoc.utils.stringify(meta.publishers)
    meta["header-includes"] = {
      pandoc.RawBlock('latex', '\\publishers{' .. publishers .. '}')
    }
  end
  return meta
end

文档类应通过值传递documentclass,无论是在元数据中还是通过变量传递。元数据和变量有一些微妙之处,但一般来说,检查meta.documentclass应该有效。然而,更好的方法可能是\publishers在命令不存在时定义命令,例如,通过将过滤器更改为

    meta["header-includes"] = {
      pandoc.RawBlock('latex', '\\providecommand{\\publishers}[1]{}'),
      pandoc.RawBlock('latex', '\\publishers{' .. publishers .. '}')
    }

这将确保当使用非 KOMA 类时不会出现错误,但命令\publishers将不起作用。


尝试使用过滤器的同时添加其他内容以包含在标题中时可能会出现问题,例如通过使用-H/--include-in-header选项调用 pandoc。在这种情况下,您必须使用自定义 Lua 编写器才能使其工作。不过这有点不太方便,因为 pandoc 无法推断默认模板,因此必须明确给出其路径:

local type = pandoc.utils.type

-- Convert a metadata value to Blocks
local to_blocks
to_blocks = function (x)
  if type(x) == 'Blocks' then
    return x
  elseif type(x) == 'Inlines' or type(x) == 'string' then
    return {pandoc.Plain(x)}
  elseif type(x) == 'List' then
    local accum = pandoc.List{}
    for i, b in ipairs(x:map(to_blocks)) do
      accum:extend(b)
    end
    return accum
  end
  return pandoc.Blocks{}
end

function Writer (doc, opts)
  local header_includes = opts.variables['header-includes'] or ''
  header_includes =
    pandoc.write(
      pandoc.Pandoc(to_blocks(doc.meta['header-includes'])),
      'latex'
    ) .. '\n' .. header_includes
  local latex = pandoc.write(doc, 'latex', opts)
  return latex
end

与使用

    pandoc -t mywriter.lua \
        -o out.pdf \
        --pdf-engine=xelatex \
        --template=data/default.latex

该路径data/default.latex指向 pandoc 的默认 LaTeX 模板。

相关内容