這篇指南介紹如何使用 Pandoc 將文件轉換為多種不同的格式。
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 updatecabal install pandoc-crossref
如果需要額外的 Haskell 安裝資訊,請參考 pandoc-crossref 的 GitHub 倉庫。
我將通過解釋如何生成三種型別的文件來演示 Pandoc 的工作原理:
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,從而可以由現代瀏覽器進行渲染。
看一下 網頁效果 和 程式碼,程式碼倉庫中的 Makefile 使得執行更加簡單。
使用 Pandoc 從 Markdown 檔案生成簡單的簡報很容易。幻燈片包含頂級幻燈片和下面的巢狀幻燈片。可以通過鍵盤控制簡報,從一個頂級幻燈片跳轉到下一個頂級幻燈片,或者顯示頂級幻燈片下面的巢狀幻燈片。 這種結構在基於 HTML 的簡報框架中很常見。
建立一個名為 SLIDES
的幻燈片文件(參見 程式碼倉庫)。首先,在 %
後面新增幻燈片的元資訊(例如,標題、作者和日期):
% Case Study% Kiko Fernandez Reyes% Sept 27, 2017
這些元資訊同時也建立了第一張幻燈片。要新增更多幻燈片,使用 Markdown 的一級標題(在下面例子中的第5行,參考 Markdown 的一級標題 )生成頂級幻燈片。
例如,可以通過以下命令建立一個標題為 “Case Study”、頂級幻燈片名為 “Wine Management System” 的簡報:
% Case Study% Kiko Fernandez Reyes% Sept 27, 2017# Wine Management System
使用 Markdown 的二級標題將內容(比如包含一個新管理系統的說明和實現的幻燈片)放入剛剛建立的頂級幻燈片。下面新增另外兩張幻燈片(在下面例子中的第 7 行和 14 行 ,參考 Markdown 的二級標題 )。
% 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
上面的 Pandoc 命令使用了以下引數:
-t revealjs
表示將輸出一個 revealjs 簡報-s
告訴 Pandoc 生成一個獨立的文件--self-contained
生成沒有外部依賴關係的 HTML 檔案-V
設定以下變數:theme=white
將幻燈片的主題設為白色slideNumber=true
顯示幻燈片編號-o index.html
在名為 index.html
的檔案中生成幻燈片為了簡化操作並避免鍵入如此長的命令,建立以下 Makefile:
all: generategenerate: pandoc -t revealjs -s --self-contained SLIDES \ -V theme=white -V slideNumber=true -o index.htmlclean: 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.mdall: $(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 Xauthor: Kiko Fernandez-Reyesdate: 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 需要不同的樣式規則,該怎麼辦?
考慮一下這些情況:
css:style-epub.css
,那麼將從 HTML 版本中移除該變數。這不起作用。pandoc -s -V css=style-epub.css document.md document.epubpandoc -s -V css=style-html.css document.md document.html
我的觀點是,這樣做很容易從命令列忽略這些變數,特別是當你需要設定數十個變數時(這可能出現在編寫複雜文件的情況中)。現在,如果將它們放在同一檔案中(meta.yaml
檔案),則只需更新或建立新的元資訊檔案即可生成所需的輸出格式。然後你會編寫這樣的命令:
pandoc -s meta-pub.yaml document.md document.epubpandoc -s meta-html.yaml document.md document.html
這是一個更簡潔的版本,你可以從單個檔案更新所有元資訊,而無需更新文件的內容。
通過以上的基本範例,我展示了 Pandoc 在將 Markdown 文件轉換為其他格式方面是多麼出色。