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 可以被现代浏览器渲染。

看看网站结果和代码;代码存储库包含一个 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

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

上面的 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 编写的表格。
以下是文档的外观

创建此文档的代码是
% 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}
如您所见,有 title、thanks、author、subtitle 和 institute 模板变量(还有许多其他变量可用)。这些变量可以使用 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 文档转换为其他格式方面做得非常好。
评论已关闭。