在命令行使用 Pandoc 进行文件转换
Markdown PDF Pandoc LaTex

> 
> 这篇指南介绍如何使用 Pandoc 将文档转换为多种不同的格式。
> 
> 
> 


![](/data/attachment/album/201811/14/114139ezvobh2yenkhobzy.jpg)


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


简单来说，[Pandoc](https://pandoc.org/) 允许你将一些文件从一种标记语言转换为另一种标记语言。典型的例子包括将 Markdown 文件转换为演示文稿、LaTeX，PDF 甚至是 ePub。


本文将解释如何使用 Pandoc 从单一标记语言（在本文中为 Markdown）生成多种格式的文档，引导你完成从 Pandoc 安装，到展示如何创建多种类型的文档，再到提供有关如何编写易于移植到其他格式的文档的提示。


文中还将解释使用元信息文件对文档内容和元信息（例如，作者姓名、使用的模板、书目样式等）进行分离的意义。


### 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 的网站上找到其他平台的 [安装说明](http://pandoc.org/installing.html)。


我强烈建议安装 [pandoc-crossref](https://hackage.haskell.org/package/pandoc-crossref)，这是一个“用于对图表，方程式，表格和交叉引用进行编号的过滤器”。最简单的安装方式是下载 [预构建的可执行文件](https://github.com/lierdakil/pandoc-crossref/releases/tag/v0.3.2.1)，但也可以通过以下命令从 Haskell 的软件包管理器 cabal 安装它：



```
cabal update
cabal install pandoc-crossref
```

如果需要额外的 Haskell [安装信息](https://github.com/lierdakil/pandoc-crossref#installation)，请参考 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 生成一个独立的网页（而不是网页片段，因此它将包括 HTML 中的 head 和 body 标签），`-mathml` 参数强制 Pandoc 将 LaTeX 中的数学公式转换成 MathML，从而可以由现代浏览器进行渲染。


![](/data/attachment/album/201811/13/115210az5oevcc7nnj7rmr.png)


看一下 [网页效果](http://pandoc.org/demo/mathMathML.html) 和 [代码](https://github.com/kikofernandez/pandoc-examples/tree/master/math)，代码仓库中的 Makefile 使得运行更加简单。


#### 制作一个 Reveal.js 幻灯片


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


创建一个名为 `SLIDES` 的幻灯片文档（参见 [代码仓库](https://github.com/kikofernandez/pandoc-examples/tree/master/slides)）。首先，在 `％` 后面添加幻灯片的元信息（例如，标题、作者和日期）：



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

这些元信息同时也创建了第一张幻灯片。要添加更多幻灯片，使用 Markdown 的一级标题（在下面例子中的第5行，参考 [Markdown 的一级标题](https://daringfireball.net/projects/markdown/syntax#header) ）生成顶级幻灯片。


例如，可以通过以下命令创建一个标题为 “Case Study”、顶级幻灯片名为 “Wine Management System” 的演示文稿：



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

# Wine Management System
```

使用 Markdown 的二级标题将内容（比如包含一个新管理系统的说明和实现的幻灯片）放入刚刚创建的顶级幻灯片。下面添加另外两张幻灯片（在下面例子中的第 7 行和 14 行 ，参考 [Markdown 的二级标题](https://daringfireball.net/projects/markdown/syntax#header) ）。


* 第一个二级幻灯片的标题为 “Idea”，并显示瑞士国旗的图像
* 第二个二级幻灯片的标题为 “Implementation”



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

# Wine Management System

## <img src="img/SwissFlag.png" style="vertical-align:middle"/> Idea

## Implementation
```

我们现在有一个顶级幻灯片（`＃Wine Management System`），其中包含两张幻灯片（`## Idea` 和 `## Implementation`）。


通过创建一个由符号 `>` 开头的 Markdown 列表，在这两张幻灯片中添加一些内容。在上面代码的基础上，在第一张幻灯片中添加两个项目（第 9-10 行），第二张幻灯片中添加五个项目（第 16-20 行）：



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

# Wine Management System

## <img src="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
```

![](/data/attachment/album/201811/13/115212vcexdsaxsk0fe4ze.png)


上面的 Pandoc 命令使用了以下参数：


* `-t revealjs` 表示将输出一个 revealjs 演示文稿
* `-s` 告诉 Pandoc 生成一个独立的文档
* `--self-contained` 生成没有外部依赖关系的 HTML 文件
* `-V` 设置以下变量：
	+ `theme=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
```

可以在 [这个仓库](https://github.com/kikofernandez/pandoc-examples/tree/master/slides) 中找到所有代码。


#### 制作一份多种格式的合同


假设你正在准备一份文件，并且（这样的情况现在很常见）有些人想用 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 编写的表格。


创建的文档如下所示：


![](/data/attachment/album/201811/13/115214jcfyw02rowc0iocw.png)


创建此文档的代码如下：



```
% 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 -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}
```

如你所见，输出的内容中有标题、致谢、作者、副标题和机构模板变量（还有许多其他可用的变量）。可以使用 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 文档转换为其他格式方面是多么出色。




---


via: <https://opensource.com/article/18/9/intro-pandoc>


作者：[Kiko Fernandez-Reyes](https://opensource.com/users/kikofernandez) 选题：[lujun9972](https://github.com/lujun9972) 译者：[jlztan](https://github.com/jlztan) 校对：[wxy](https://github.com/wxy)


本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出


OK
Pandoc is a command-line tool for converting files from one markup language to another. Markup languages use tags to annotate sections of a document. Commonly used markup languages include Markdown, ReStructuredText, HTML, LaTex, ePub, and Microsoft Word DOCX.

In plain English, [Pandoc](https://pandoc.org/) allows you to convert a bunch of files from one markup language into another one. Typical examples include converting a Markdown file into a presentation, LaTeX, PDF, or even ePub.

This article will explain how to produce documentation in multiple formats from a single markup language (in this case Markdown) using Pandoc. It will guide you through Pandoc installation, show how to create several types of documents, and offer tips on how to write documentation that is easy to port to other formats. It will also explain the value of using meta-information files to create a separation between the content and the meta-information (e.g., author name, template used, bibliographic style, etc.) of your documentation.

## Installation and requirements

Pandoc is installed by default in most Linux distributions. This tutorial uses pandoc-2.2.3.2 and pandoc-citeproc-0.14.3. If you don't intend to generate PDFs, those two packages are enough. However, I recommend installing texlive as well, so you have the option to generate PDFs.

To install these programs on Linux, type the following on the command line:

`sudo apt-get install pandoc pandoc-citeproc texlive`


You can find [installation instructions](http://pandoc.org/installing.html) for other platforms on Pandoc's website.

I highly recommend installing [pandoc](https://hackage.haskell.org/package/pandoc-crossref)[-crossref](https://hackage.haskell.org/package/pandoc-crossref), a "filter for numbering figures, equations, tables, and cross-references to them." The easiest option is to download a [prebuilt executable](https://github.com/lierdakil/pandoc-crossref/releases/tag/v0.3.2.1), but you can install it from Haskell's package manager, cabal, by typing:

```
cabal update
cabal install pandoc-crossref
```


Consult pandoc-crossref's GitHub repository if you need additional Haskell [installation information](https://github.com/lierdakil/pandoc-crossref#installation).

## Some examples

I'll demonstrate how Pandoc works by explaining how to produce three types of documents:

- A website from a LaTeX file containing math formulas
- A Reveal.js slideshow from a Markdown file
- A contract agreement document that mixes Markdown and LaTeX

### Create a website with math formulas

One of the ways Pandoc excels is displaying math formulas in different output file formats. For instance, let's generate a website from a LaTeX document (named math.tex) containing some math symbols (written in LaTeX).

The math.tex document looks like:

```
% 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$
```


Convert the LaTeX document into a website named mathMathML.html by entering the following command:

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


The flag **-s** tells Pandoc to generate a standalone website (instead of a fragment, so it will include the head and body HTML tags), and the **–mathml** flag forces Pandoc to convert the math in LaTeX to MathML, which can be rendered by modern browsers.

![Math formulas Math formulas](https://opensource.com/sites/default/files/uploads/pandoc_math-formulas.png)

Take a look at the [website result](http://pandoc.org/demo/mathMathML.html) and the [code](https://github.com/kikofernandez/pandoc-examples/tree/master/math); the code repository contains a Makefile to make things even simpler.

### Make a Reveal.js slideshow

It's easy to generate simple presentations from a Markdown file using Pandoc. The slides contain top-level slides and nested slides underneath. The presentation can be controlled from the keyboard, and you can jump from one top-level slide to the next top-level slide or show the nested slides on a per-top-level basis. This structure is typical in HTML-based presentation frameworks.

Let's create a slide document named SLIDES (see the [code repository](https://github.com/kikofernandez/pandoc-examples/tree/master/slides)). First, add the slides' meta-information (e.g., title, author, and date) prepended by the **%** symbol:

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



This meta-information also creates the first slide. To add more slides, declare top-level slides using Markdown heading H1 (line 5 in the example below, [heading 1 in Markdown](https://daringfireball.net/projects/markdown/syntax#header), designated by **#**).

For example, if we want to create a presentation with the title *Case Study* that starts with a top-level slide titled *Wine Management System*, write:

```
% Case Study
% Kiko Fernandez Reyes
% Sept 27, 2017
# Wine Management System
```


To put content (such as slides that explain a new management system and its implementation) inside this top-level section, use a Markdown header H2. Let's add two more slides (lines 7 and 14 below, [heading 2 in Markdown](https://daringfireball.net/projects/markdown/syntax#header), designated by **##**):

- The first second-level slide has the title
*Idea*and shows an image of the Swiss flag - The second second-level slide has the title
*Implementation*

```
% Case Study
% Kiko Fernandez Reyes
% Sept 27, 2017
# Wine Management System
## <img src="https://opensource.com/img/SwissFlag.png" style="vertical-align:middle"/> Idea
## Implementation
```


We now have a top-level slide (**# Wine Management System**) that contains two slides (**## Idea** and **## Implementation**).

Let's put some content in these two slides using incremental bulleted lists by creating a Markdown list prepended by the symbol **>**. Continuing from above, add two items in the first slide (lines 9–10 below) and five items in the second slide (lines 16–20):

```
% Case Study
% Kiko Fernandez Reyes
% Sept 27, 2017
# Wine Management System
## <img src="https://opensource.com/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
```


We added an image of the Matterhorn mountain. Your slides can be improved by using plain Markdown or adding plain HTML.

To generate the slides, Pandoc needs to point to the Reveal.js library, so it must be in the same folder as the SLIDES file. The command to generate the slides is:

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



![Reveal.js slide with Matterhorn Reveal.js slide with Matterhorn](https://opensource.com/sites/default/files/uploads/pandoc_matterhorn-slide.png)

The above Pandoc command uses the following flags:

**-t revealjs**specifies we are going to output a**revealjs**presentation**-s**tells Pandoc to generate a standalone document**--self-contained**produces HTML with no external dependencies**-V**sets the following variables:

–**theme=white**sets the theme of the slideshow to**white**

–**slideNumber=true**shows the slide number**-o index.html**generates the slides in the file named**index.html**

To make things simpler and avoid typing this long command, create the following 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
```


You can find all the code in [this repository](https://github.com/kikofernandez/pandoc-examples/tree/master/slides).

### Make a multi-format contract

Let's say you are preparing a document and (as things are nowadays) some people want it in Microsoft Word format, others use free software and would like an ODT, and others need a PDF. You do not have to use OpenOffice nor LibreOffice to generate the DOCX or PDF file. You can create your document in Markdown (with some bits of LaTeX if you need advanced formatting) and generate any of these file types.

As before, begin by declaring the document's meta-information (title, author, and date):

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


Then write the document in Markdown (and add LaTeX if you require advanced formatting). For example, create a table that needs fixed separation space (declared in LaTeX with **\hspace{3cm}**) and a line where a client and a contractor should sign (declared in LaTeX with **\hrulefill**). After that, add a table written in Markdown.

Here's what the document will look like:

![Example contract agreement Example contract agreement](https://opensource.com/sites/default/files/uploads/pandoc_agreement.png)

The code to create this document is:

```
% 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** |
+--------------------------------------------+----------+-------------+
```


To generate the three different output formats needed for this document, write a 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
```


Lines 4–7 contain the commands to generate the different outputs.

If you have several Markdown files and want to merge them into one document, issue a command with the files in the order you want them to appear. For example, when writing this article, I created three documents: an introduction document, three examples, and some advanced uses. The following tells Pandoc to merge these files together in the specified order and produce a PDF named document.pdf.

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


## Templates and meta-information

Writing a complex document is no easy task. You need to stick to a set of rules that are independent from your content, such as using a specific template, writing an abstract, embedding specific fonts, and maybe even declaring keywords. All of this has nothing to do with your content: simply put, it is meta-information.

Pandoc uses templates to generate different output formats. There is a template for LaTeX, another for ePub, etc. These templates have unfulfilled variables that are set with the meta-information given to Pandoc. To find out what meta-information is available in a Pandoc template, type:

`pandoc -D FORMAT`


For example, the template for LaTeX would be:

`pandoc -D latex`


Which outputs something along these lines:

```
$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}
```


As you can see, there are **title**, **thanks**, **author**, **subtitle**, and **institute** template variables (and many others are available). These are easily set using YAML metablocks. In lines 1–5 of the example below, we declare a YAML metablock and set some of those variables (using the contract agreement example above):

```
---
title: Contract Agreement for Software X
author: Kiko Fernandez-Reyes
date: August 28th, 2018
---
(continue writing document as in the previous example)
```


This works like a charm and is equivalent to the previous code:

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


However, this ties the meta-information to the content; i.e., Pandoc will always use this information to output files in the new format. If you know you need to produce multiple file formats, you better be careful. For example, what if you need to produce the contract in ePub and in HTML, and the ePub and HTML need specific and different styling rules?

Let's consider the cases:

- If you simply try to embed the YAML variable
**css: style-epub.css**, you would be excluding the one from the HTML version.*This does not work*. - Duplicating the document is obviously
*not a good solution*either, as changes in one version would not be in sync with the other copy. - You can add variables to the Pandoc command line as follows:

```
pandoc -s -V css=style-epub.css document.md document.epub
pandoc -s -V css=style-html.css document.md document.html
```


My opinion is that it is easy to overlook these variables from the command line, especially when you need to set tens of these (which can happen in complex documents). Now, if you put them all together under the same roof (a meta.yaml file), you only need to update or create a new meta-information file to produce the desired output. You would then write:

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


This is a much cleaner version, and you can update all the meta-information from a single file without ever having to update the content of your document.

## Wrapping up

With these basic examples, I have shown how Pandoc can do a really good job at converting Markdown documents into other formats.

## Comments are closed.