核心要点
本文作者Chris Ward介绍了如何使用Pandoc和LaTeX将Markdown文件转换为PDF,用于其开源棋盘游戏Chip Shop。游戏组件使用Markdown编写,游戏网站也由这些文件生成。
Pandoc(一个开源标记转换工具)和LaTeX(一个文档声明和布局系统)用于从Markdown文件生成PDF。尽管功能强大,但它们无法将多个PDF组合到一页上,因此Ward使用了命令行工具PDFJam来满足此需求。
作者提供了详细的指南,介绍如何安装必要的依赖项(Markdown、Jekyll、Pandoc、LaTeX、PDFJam),并逐步介绍了构建过程,包括从Markdown生成PDF、创建LaTeX文件以及使用PDFJam将卡片组合到一页上。
作者理想的工作流程是在生成网站的同时生成PDF文件,而不是在访问者请求时生成文件。这种方法还允许PDF卡片版本与HTML页面看起来不同,而无需使用复杂的CSS规则。
如果您阅读过我在SitePoint或其他地方发表的一些文章,您可能知道我正在开发一款棋盘游戏。这款名为Chip Shop的游戏,让您可以在20世纪80年代的美国经营一家电脑公司。
作为项目的一部分,我尝试尽可能地将整个游戏开源。经过几次尝试后,我决定使用Markdown作为大部分游戏组件(尤其是卡片和说明书)的基本框架。
由于游戏网站使用Jekyll,因此游戏网站是从Markdown文件生成的。我打算制作游戏的高级预装盒和自行打印版本,为此我需要从Markdown文件生成PDF。
目标
我的理想工作流程是在生成网站的同时生成PDF文件,而不是在访问者请求时生成文件。这排除了我通常用于PDF生成的选项wkhtmltopdf,因为它是从已生成的HTML生成PDF。另一个原因是,我希望PDF卡片版本与HTML页面看起来不同,而Jekyll缺乏任何类型的“查看模式”功能来实现这一点,而无需使用复杂的CSS规则。
Chip Shop游戏的卡片Markdown模板文件包含许多用于游戏机制的Markdown前置信息字段,并非所有字段在每张卡片上都使用。为了方便打印,我需要尽可能多地将卡片放在A4页面上——在本例中,是一个3×3的网格。最终,页面需要双面打印,但我还没有实现这一点。
Pandoc和LaTeX
任何搜索从Markdown生成PDF解决方案的网络搜索都会引导您走上Pandoc的道路。Pandoc是一个开源的瑞士军刀式标记转换工具,支持种类繁多且不断增长的输入和输出标记格式。
要使用Pandoc生成PDF,需要LaTeX。LaTeX起源于科学研究界,是一个文档声明和布局系统。结合Pandoc和LaTeX,我们可以使用变量,从而从一系列Markdown文件生成PDF并支持Markdown前置信息。
尽管Pandoc和LaTeX功能强大,但我找不到任何将多个PDF(卡片)组合到一页上的方法,尤其是在使用Markdown文件中的变量时。经过大量研究,我选择了PDFJam,这是一个简单的命令行工具,用于满足此需求。
安装依赖项
除了可能需要一个编辑器之外,您不需要额外的Markdown软件,编辑器有很多,我建议您阅读一些SitePoint文章来做出选择。
我将在从我的游戏中获取的示例中继续使用Jekyll来说明构建过程,但如果您不需要网站,它不是PDF生成的必要部分。
在我的Mac上,我使用Homebrew安装了Pandoc,但所有操作系统都有相应的选项。
关于安装LaTeX的最佳方法有很多说法,这取决于您的需求或打算如何使用它。其常用工具和库的完整安装可能接近2GB,但对于大多数用途而言,最小安装就足够了。阅读项目的下载页面以找到最适合您的选项。
在本教程中,我们将使用xelatex引擎,因为我使用自定义字体。但是,您可以选择任何提供您所需特定功能的引擎。
根据您安装LaTeX的方式,您可能已经安装了PDFJam。(在终端中键入which pdfjam进行检查。)如果您没有安装,请在此处查找安装详细信息。
构建过程
经过一番考虑,我运行在本地运行的bash脚本目前似乎是最佳选择。有更好的方法,但它有效,我以后可以改进这个过程,将其转移到持续集成系统或Git Hooks。
在GitHub上查看bash脚本。
现在让我们逐步介绍这个脚本。
<code class="language-bash">bundle install bundle update rm -dfr _site rm -dfr pod</code>
这些命令确保Jekyll构建网站所需的Ruby依赖项是最新的,并且我们删除了任何现有的网站和打印文件夹。
<code class="language-bash">jekyll build mkdir -p pod/pdf/cards</code>
接下来,我们构建网站并为卡片的打印版本创建一个文件夹。
让我们创建一个包含每个Markdown文件PDF版本的文件夹:
<code class="language-bash">for filename in _cards/*.md; do echo $filename pandoc --from=markdown+yaml_metadata_block --template _layouts/cards.latex -o pod/pdf/cards/"$(basename "$filename" .md)".pdf --latex-engine=xelatex $filename done</code>
该脚本处理_cards目录中的每个Markdown文件,确保观察Markdown前置信息字段。使用cards.latex模板(我们将在后面介绍),正确的LaTeX引擎会输出具有适当名称的PDF。
从Pandoc生成卡片文件的大部分神奇之处都发生在LaTeX模板中。
在GitHub上查看LaTeX模板。
LaTeX对我来说是新的,但它并不太复杂。我将解释我从默认LaTeX文件(位于Pandoc_install_dir/data/templates/default.latex)中更改的内容以使卡片正常工作。我推荐sharelatex.com用于在编辑LaTeX文件时预览它们。
<code class="language-bash">bundle install bundle update rm -dfr _site rm -dfr pod</code>
我们需要特定的页面大小,我们稍后将使用列来显示卡片的成本和分数。我们正在使用图形和自定义字体,因此我们需要这些包。
我们试图创建一个清晰简洁的简单布局。以下是我们如何实现它的:
<code class="language-bash">jekyll build mkdir -p pod/pdf/cards</code>
我觉得上面很多内容对于任何习惯于代码或标记的人来说都是相当容易理解的。我们正在创建卡片的元素,对齐它们,设置字体大小并检查是否有值,然后再输出它们,这样卡片就不会最终出现空字段。
我们将图像调整为特定大小并居中。成本和分数值采用两列布局,使用begin{tabular}命令设置,列数使用l的数量设置。
我们使用PDFJam创建一个大型PDF文件,其中包含每个单独的PDF卡片:
<code class="language-bash">for filename in _cards/*.md; do echo $filename pandoc --from=markdown+yaml_metadata_block --template _layouts/cards.latex -o pod/pdf/cards/"$(basename "$filename" .md)".pdf --latex-engine=xelatex $filename done</code>
使用此命令,我们指定以下内容:
如果您没有输出到其工作目录,PDFJam可能会给出错误,因此我将文件移动到我实际想要的位置(希望将来可以解决)。在这里,如果我们不需要,我们也可以删除单个PDF文件。
就这样——我们有了一个网站和游戏卡片的可打印PDF。
我使用./build.sh
运行构建脚本。由于有很多图像和PDF处理,因此大约需要五到十分钟。然后我有一个单独的脚本将这些文件夹部署到Web服务器。
后续步骤
这个过程花了我一段时间才弄对,但现在已经足够好,可以在游戏测试后继续改进过程和布局。
我希望您发现我的研究和实验对您的项目有用。如果您有任何意见或建议,请告诉我。
关于使用Pandoc和LaTeX从Markdown创建PDF的常见问题解答(FAQ)
要安装Pandoc,您可以从官方网站(https://www.php.cn/link/8f1dd6e7a88b9cf615c146330c591ba9。
是的,您可以使用LaTeX模板自定义PDF的外观。Pandoc使用默认模板生成PDF,但您可以使用--template
选项指定您自己的模板。您可以创建自己的模板或使用在线提供的众多模板之一,例如在Wandmalfarbe Pandoc LaTeX模板GitHub存储库中找到的那些模板。
要将Markdown文件转换为PDF,您可以在终端或命令提示符中使用以下命令:pandoc yourfile.md -o yourfile.pdf
。将yourfile.md
替换为您Markdown文件的名称,将yourfile.pdf
替换为您PDF文件的所需名称。此命令告诉Pandoc使用默认LaTeX模板将Markdown文件转换为PDF。
(其余FAQ内容与原文相同,此处省略以避免重复)
以上是用Pandoc和Latex从Markdown创建PDF的详细内容。更多信息请关注PHP中文网其他相关文章!