使用 Pandoc 在命令行中转换文件

本指南向您展示如何使用 Pandoc 将文档转换为多种不同的文件格式。
350 位读者喜欢这个。
document sending

Opensource.com

Pandoc 是一个命令行工具,用于将文件从一种标记语言转换为另一种标记语言。标记语言使用标签来注释文档的各个部分。常用的标记语言包括 Markdown、ReStructuredText、HTML、LaTeX、ePub 和 Microsoft Word DOCX。

简单来说,Pandoc 允许您将一批文件从一种标记语言转换为另一种标记语言。典型的例子包括将 Markdown 文件转换为演示文稿、LaTeX、PDF 甚至 ePub。

本文将解释如何使用 Pandoc 从单一标记语言(在本例中为 Markdown)生成多种格式的文档。它将指导您完成 Pandoc 的安装,展示如何创建几种类型的文档,并提供有关如何编写易于移植到其他格式的文档的技巧。它还将解释使用元信息文件来创建文档内容和元信息(例如,作者姓名、使用的模板、参考文献样式等)之间分离的价值。

安装和要求

Pandoc 在大多数 Linux 发行版中默认安装。本教程使用 pandoc-2.2.3.2 和 pandoc-citeproc-0.14.3。如果您不打算生成 PDF,这两个软件包就足够了。但是,我建议也安装 texlive,这样您就可以选择生成 PDF。

要在 Linux 上安装这些程序,请在命令行中键入以下内容

sudo apt-get install pandoc pandoc-citeproc texlive

您可以在 Pandoc 的网站上找到其他平台的安装说明

我强烈建议安装 pandoc-crossref,这是一个“用于编号图形、公式、表格以及对它们的交叉引用的过滤器”。最简单的选择是下载预构建的可执行文件,但您也可以通过键入以下命令从 Haskell 的软件包管理器 cabal 安装它

cabal update
cabal install pandoc-crossref

如果您需要其他 Haskell 安装信息,请查阅 pandoc-crossref 的 GitHub 存储库。

一些例子

我将通过解释如何生成三种类型的文档来演示 Pandoc 的工作原理

  • 一个包含数学公式的 LaTeX 文件生成的网站
  • 一个从 Markdown 文件生成的 Reveal.js 幻灯片
  • 一个混合了 Markdown 和 LaTeX 的合同协议文档

创建一个包含数学公式的网站

Pandoc 的优点之一是在不同的输出文件格式中显示数学公式。例如,让我们从包含一些数学符号(用 LaTeX 编写)的 LaTeX 文档(名为 math.tex)生成一个网站。

math.tex 文档看起来像

% Pandoc math demos

$a^2 + b^2 = c^2$

$v(t) = v_0 + \frac{1}{2}at^2$

$\gamma = \frac{1}{\sqrt{1 - v^2/c^2}}$

$\exists x \forall y (Rxy \equiv Ryx)$

$p \wedge q \models p$

$\Box\diamond p\equiv\diamond p$

$\int_{0}^{1} x dx = \left[ \frac{1}{2}x^2 \right]_{0}^{1} = \frac{1}{2}$

$e^x = \sum_{n=0}^\infty \frac{x^n}{n!} = \lim_{n\rightarrow\infty} (1+x/n)^n$

通过输入以下命令将 LaTeX 文档转换为名为 mathMathML.html 的网站

pandoc math.tex -s --mathml  -o mathMathML.html

-s 标志告诉 Pandoc 生成一个独立的网站(而不是片段,因此它将包含 head 和 body HTML 标签),而 –mathml 标志强制 Pandoc 将 LaTeX 中的数学公式转换为 MathML,MathML 可以被现代浏览器渲染。 

Math formulas

看看网站结果代码;代码存储库包含一个 Makefile,使事情变得更简单。

制作 Reveal.js 幻灯片

使用 Pandoc 从 Markdown 文件生成简单的演示文稿很容易。幻灯片包含顶层幻灯片和下方的嵌套幻灯片。演示文稿可以通过键盘控制,您可以从一个顶层幻灯片跳转到下一个顶层幻灯片,或者按顶层显示嵌套幻灯片。这种结构在基于 HTML 的演示文稿框架中很典型。

让我们创建一个名为 SLIDES 的幻灯片文档(参见代码存储库)。首先,添加幻灯片的元信息(例如,标题、作者和日期),并在前面加上 % 符号

% Case Study
% Kiko Fernandez Reyes
% Sept 27, 2017

此元信息也创建了第一张幻灯片。要添加更多幻灯片,请使用 Markdown 标题 H1 声明顶层幻灯片(下面示例中的第 5 行,Markdown 中的标题 1,用 # 表示)。

例如,如果我们想创建一个标题为案例研究的演示文稿,该演示文稿以标题为葡萄酒管理系统的顶层幻灯片开始,请编写

% Case Study
% Kiko Fernandez Reyes
% Sept 27, 2017

# Wine Management System

要将内容(例如,解释新管理系统及其实现的幻灯片)放在此顶层部分中,请使用 Markdown 标题 H2。让我们添加两个更多幻灯片(下面示例中的第 7 行和第 14 行,Markdown 中的标题 2,用 ## 表示)

  • 第一个二级幻灯片的标题为想法,并显示瑞士国旗的图像
  • 第二个二级幻灯片的标题为实现
% Case Study
% Kiko Fernandez Reyes
% Sept 27, 2017

# Wine Management System

## <img src="https://open-source.net.cn/img/SwissFlag.png" style="vertical-align:middle"/> Idea

## Implementation

现在我们有一个顶层幻灯片(# 葡萄酒管理系统),其中包含两个幻灯片(## 想法## 实现)。

让我们通过创建一个以符号 > 开头的 Markdown 列表,在这些幻灯片中放入一些内容,使用递增的带项目符号的列表。从上面继续,在第一张幻灯片中添加两个项目(下面示例中的第 9-10 行),在第二张幻灯片中添加五个项目(第 16-20 行)

% Case Study
% Kiko Fernandez Reyes
% Sept 27, 2017

# Wine Management System

## <img src="https://open-source.net.cn/img/SwissFlag.png" style="vertical-align:middle"/> Idea

>- Swiss love their **wine** and cheese
>- Create a *simple* wine tracker system

![](img/matterhorn.jpg)

## Implementation

>- Bottles have a RFID tag
>- RFID reader (emits and read signal)
>- **Raspberry Pi**
>- **Server (online shop)**
>- Mobile app

我们添加了马特宏峰的图像。您可以通过使用纯 Markdown 或添加纯 HTML 来改进您的幻灯片。

要生成幻灯片,Pandoc 需要指向 Reveal.js 库,因此它必须与 SLIDES 文件位于同一文件夹中。生成幻灯片的命令是

pandoc -t revealjs -s --self-contained SLIDES \
-V theme=white -V slideNumber=true -o index.html

Reveal.js slide with Matterhorn

上面的 Pandoc 命令使用以下标志

  • -t revealjs 指定我们将输出一个 revealjs 演示文稿
  • -s 告诉 Pandoc 生成一个独立文档
  • --self-contained 生成没有外部依赖项的 HTML
  • -V 设置以下变量

    theme=white 将幻灯片的主题设置为 white

    slideNumber=true 显示幻灯片编号
  • -o index.html 在名为 index.html 的文件中生成幻灯片

为了简化操作并避免键入此长命令,请创建以下 Makefile

all: generate

generate:
    pandoc -t revealjs -s --self-contained SLIDES \
    -V theme=white -V slideNumber=true -o index.html

clean: index.html
    rm index.html

.PHONY: all clean generate

您可以在 此存储库 中找到所有代码。

制作多格式合同

假设您正在准备一份文档,并且(就像现在的情况一样)有些人想要 Microsoft Word 格式,另一些人使用自由软件并希望获得 ODT,还有一些人需要 PDF。您不必使用 OpenOffice 或 LibreOffice 来生成 DOCX 或 PDF 文件。您可以使用 Markdown(如果需要高级格式,可以使用一些 LaTeX)创建文档,并生成这些文件类型中的任何一种。

和以前一样,首先声明文档的元信息(标题、作者和日期)

% Contract Agreement for Software X
% Kiko Fernandez-Reyes
% August 28th, 2018

然后用 Markdown 编写文档(如果需要高级格式,可以添加 LaTeX)。例如,创建一个需要固定分隔空间的表格(在 LaTeX 中用 \hspace{3cm} 声明)以及客户和承包商应签名的行(在 LaTeX 中用 \hrulefill 声明)。之后,添加一个用 Markdown 编写的表格。

以下是文档的外观

Example contract agreement

创建此文档的代码是

% Contract Agreement for Software X
% Kiko Fernandez-Reyes
% August 28th, 2018

...

### Work Order

\begin{table}[h]
\begin{tabular}{ccc}
The Contractor & \hspace{3cm} & The Customer \\
& & \\
& & \\
\hrulefill & \hspace{3cm} & \hrulefill \\
%
Name & \hspace{3cm} & Name \\
& & \\
& & \\
\hrulefill & \hspace{3cm} & \hrulefill \\
...
\end{tabular}
\end{table}

\vspace{1cm}

+--------------------------------------------+----------+-------------+
| Type of Service                            | Cost     |     Total   |
+:===========================================+=========:+:===========:+
| Game Engine                                | 70.0     | 70.0        |
|                                            |          |             |
+--------------------------------------------+----------+-------------+
|                                            |          |             |
+--------------------------------------------+----------+-------------+
| Extra: Comply with defined API functions   | 10.0     | 10.0        |
|        and expected returned format        |          |             |
+--------------------------------------------+----------+-------------+
|                                            |          |             |
+--------------------------------------------+----------+-------------+
| **Total Cost**                             |          | **80.0**    |
+--------------------------------------------+----------+-------------+

要为此文档生成所需的三种不同输出格式,请编写一个 Makefile

DOCS=contract-agreement.md

all: $(DOCS)
    pandoc -s $(DOCS) -o $(DOCS:md=pdf)
    pandoc -s $(DOCS) -o $(DOCS:md=docx)
    pandoc -s $(DOCS) -o $(DOCS:md=odt)

clean:
    rm *.pdf *.docx *.odt

.PHONY: all clean

第 4-7 行包含生成不同输出的命令。

如果您有多个 Markdown 文件并想将它们合并到一个文档中,请按照您希望它们出现的顺序发出包含这些文件的命令。例如,在撰写本文时,我创建了三个文档:一个介绍文档、三个示例和一些高级用法。以下命令告诉 Pandoc 将这些文件按指定顺序合并在一起,并生成一个名为 document.pdf 的 PDF。

pandoc -s introduction.md examples.md advanced-uses.md -o document.pdf

模板和元信息

编写复杂文档并非易事。您需要遵守一组独立于内容规则,例如使用特定模板、编写摘要、嵌入特定字体,甚至可能声明关键字。所有这些都与您的内容无关:简单来说,它是元信息。

Pandoc 使用模板来生成不同的输出格式。LaTeX 有一个模板,ePub 有另一个模板等等。这些模板具有未满足的变量,这些变量通过提供给 Pandoc 的元信息设置。要查找 Pandoc 模板中可用的元信息,请键入

pandoc -D FORMAT

例如,LaTeX 的模板将是

pandoc -D latex

它输出的内容大致如下

$if(title)$
\title{$title$$if(thanks)$\thanks{$thanks$}$endif$}
$endif$
$if(subtitle)$
\providecommand{\subtitle}[1]{}
\subtitle{$subtitle$}
$endif$
$if(author)$
\author{$for(author)$$author$$sep$ \and $endfor$}
$endif$
$if(institute)$
\providecommand{\institute}[1]{}
\institute{$for(institute)$$institute$$sep$ \and $endfor$}
$endif$
\date{$date$}
$if(beamer)$
$if(titlegraphic)$
\titlegraphic{\includegraphics{$titlegraphic$}}
$endif$
$if(logo)$
\logo{\includegraphics{$logo$}}
$endif$
$endif$

\begin{document}

如您所见,有 titlethanksauthorsubtitleinstitute 模板变量(还有许多其他变量可用)。这些变量可以使用 YAML 元数据块轻松设置。在下面示例的第 1-5 行中,我们声明了一个 YAML 元数据块并设置了其中一些变量(使用上面的合同协议示例)

---
title: Contract Agreement for Software X
author: Kiko Fernandez-Reyes
date: August 28th, 2018
---

(continue writing document as in the previous example)

这非常有效,并且等同于之前的代码

% Contract Agreement for Software X
% Kiko Fernandez-Reyes
% August 28th, 2018

但是,这会将元信息与内容绑定在一起;即,Pandoc 将始终使用此信息以新格式输出文件。如果您知道您需要生成多种文件格式,您最好小心。例如,如果您需要以 ePub 和 HTML 格式生成合同,并且 ePub 和 HTML 需要特定且不同的样式规则怎么办?

让我们考虑以下情况

  • 如果您只是尝试嵌入 YAML 变量 css: style-epub.css,您将排除 HTML 版本中的变量。这不起作用
  • 复制文档显然也不是一个好解决方案,因为一个版本中的更改将不会与另一个副本同步。
  • 您可以按如下方式将变量添加到 Pandoc 命令行
pandoc -s -V css=style-epub.css document.md document.epub
pandoc -s -V css=style-html.css document.md document.html

我的观点是,从命令行中很容易忽略这些变量,尤其是当您需要设置数十个变量时(这可能发生在复杂文档中)。现在,如果您将它们全部放在同一个屋檐下(meta.yaml 文件),您只需要更新或创建一个新的元信息文件即可生成所需的输出。然后您可以编写

pandoc -s meta-pub.yaml document.md document.epub
pandoc -s meta-html.yaml document.md document.html

这是一个更简洁的版本,您可以从单个文件更新所有元信息,而无需更新文档的内容。 

总结

通过这些基本示例,我已经展示了 Pandoc 在将 Markdown 文档转换为其他格式方面做得非常好。

标签
User profile image.
Kiko 是编程语言博士生,也是乌普萨拉大学高级软件设计课程的主要讲师。他还是 Encore 编程语言的核心开发人员,撰写了关于并发和并行数据结构的研究出版物,并在他短暂的学术生涯中获得了两个最佳论文奖和两个杰出成果奖。

评论已关闭。

知识共享许可协议本作品采用知识共享署名-相同方式共享 4.0 国际许可协议进行许可。
© . All rights reserved.