Pandoc 常见问题

如何将整个目录中的文件从 Markdown 转换为 RTF?

在 Linux 或 macOS 上:

for f in *.txt; do pandoc "$f" -s -o "${f%.txt}.rtf"; done

在 Windows PowerShell 中:

gci -r -i *.txt | foreach { $rtf = $_.DirectoryName + "\" + $_.BaseName + ".rtf"; pandoc -f markdown -s $_.FullName -o $rtf }

我使用 pandoc 将文档转换为 ICML(或 OPML 或 RTF),当我尝试打开它时,被告知无效。我做错了什么?

确保使用 -s--standalone 标志,否则你只会得到一个片段,而不是带有必需头部的完整文档:

pandoc -s -f markdown -t icml -o my.icml my.md

当我尝试将中文 Markdown 文档转换为 PDF 时,得到的是空白文档。

默认情况下,pandoc 使用 pdflatex 来生成 PDF,而 pdflatex 不能处理中文字符。但你可以更改默认设置,使用 xelatex 代替。你还应该确保使用了包含中文字符的字体。例如:

pandoc -o c.pdf --pdf-engine=xelatex -V mainfont='Adobe Ming Std'

Windows 安装程序执行的是单用户安装,而不是为所有用户安装 pandoc。如何为所有用户安装 pandoc?

以管理员身份运行以下命令:

msiexec /i pandoc-VERSION.msi ALLUSERS=1

这会将 pandoc 放置在 C:\Program Files\Pandoc。你可以通过设置 APPLICATIONFOLDER 参数将其安装到其他目录,例如:

msiexec /i pandoc-1.11.1.msi ALLUSERS=1 APPLICATIONFOLDER="C:\Pandoc"

如何更改 PDF 输出中的页边距?

选项

-V geometry:margin=1in

会将每边的页边距设置为一英寸。如果你不想设置统一的页边距,可以这样做:

-V geometry:"top=2cm, bottom=1.5cm, left=1cm, right=1cm"

或者

-V geometry:"left=3cm, width=10cm"

更多选项,请参阅 LaTeX 的 geometry 包 文档。

pandoc 与 MultiMarkdown 相比如何?

这里有一个 wiki 页面 对两者进行了比较。

当我指定图片宽度为 50%,并转换为 LaTeX 时,pandoc 将高度设置为 textheight,且长宽比未被保留。如何避免这种情况?

例如,如果你使用 {width="50%"} 转换一张图片,生成的 LaTeX 代码将会是 \includegraphics[width=0.5\textwidth,height=\textheight]

这种输出预设了 pandoc 默认 LaTeX 模板中的以下代码:

% 如果必要,按比例缩放图片,以防止其溢出页面的边距
% 默认情况下,仍然可以通过在 \includegraphics[width, height, ...]{} 中显式指定选项来覆盖默认值
\setkeys{Gin}{width=\maxwidth,height=\maxheight,keepaspectratio}

如果你的自定义模板中没有这段代码,你应该添加它。如果我们不以这种方式显式地设置 height,除非图片正在被缩放到小于其原始尺寸,否则图片将无法正确调整大小。

pandoc 有时使用过多内存。如何限制 pandoc 使用的内存?

pandoc +RTS -M30m -RTS

这会将堆内存限制为 30MB。当转换文档需要更多内存时,将会出现内存不足错误。

在使用 --include-in-header 与 PDF 或 LaTeX 输出时,如何引用位于默认模板中 header-includes 之后的 TeX 声明?

由于各种原因,$header-includes$ 并不在 LaTeX 前置声明(preamble)的最末尾。当你插入的代码依赖于前置声明中 header-includes 位置之后的声明时,这就会成为一个问题。例如,你可能想要引用 \author\title 元数据值(这些值设置在前置声明的最底部),并在页边显示它们。在这种情况下,你可以使用 etoolbox\AtEndPreamble 来包裹你的代码。该技术在一个 gist 示例 中进行了演示。使用 \AtEndPreamble 时,确保任何 makeatlettermakeatother 都位于 \AtEndPreamble 之外,如示例所示。

如何使用 pandoc 将 PDF 转换成其他格式?

你不能直接使用 pandoc 将 PDF 转换成其他格式。你可以尝试在 Word 或 Google Docs 中打开 PDF 文件,并将其保存为 pandoc 可以直接转换的格式。

使用 pandoc 生成 PDF 是否真的需要安装 1GB 大小的 TeX 环境?

不需要。实际上,你可以使用相对较小的 TeX 安装环境,例如从 MacTeX 的基础 TeX 分发包开始,并使用 tlmgr 工具来安装 pandoc 所需的一些软件包(参见 手册)。

或者,你也可以通过 HTML 和 wkhtmltopdf 或通过 groff ms 和 pdfroff 来生成 PDF 文件。(这些方法生成的排版效果不如 TeX 好,特别是在数学公式方面,但对于许多用途来说已经足够好。)

在 M1 Mac 上将文档转换为 PDF 时,我遇到了 “无法分配内存” 的错误。

我们不确定为什么会发生这种情况,但我们发现完全指定 pdflatex 的路径可以避免这个错误。例如,

pandoc -o my.pdf --pdf-engine=/Library/TeX/texbin/pdflatex

当我从 ipynb 转换文件时,某些可视化图表没有显示出来。

首先,除非你的输出目标是二进制格式(如 docx、odt 或 epub),否则你需要使用 --extract-media 或者(仅限 HTML 格式)--embed-resources 来使 ipynb 文件中的图像可用。

其次,一些 Jupyter 扩展程序,特别是那些使用 JavaScript 进行可视化的扩展程序,会假定 require.js 的存在。为了确保此脚本能在你的 HTML 输出中可用,你可以使用以下命令:

pandoc -s -o output.html input.ipynb \
-V header-includes='<script src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.6/require.min.js"></script>'

如何在从 LaTeX 转换时让 BibTeX 引用生效?

使用 --citeproc 选项。如果仍然不起作用,你可能需要用 --bibliography 告诉 pandoc 你的参考文献文件在哪里。你的引用可能不会像使用 latexbibtex 时那样格式化;你可以通过使用 --csl 指定合适的 CSL 参考文献样式来改变引用的格式(参见 手册)。

如何使用 pandoc 生成 PDF/A?

最简单的方法是通过 ConTeXt:

pandoc --pdf-engine=context -V pdfa

或者,可以使用 --pdf-engine=pdflatex 并在元数据中的 header-includes 中加入以下内容(或者从文件中包含使用 --include-in-header):

\usepackage[a-2u,mathxmp]{pdfx}
\usepackage[pdfa]{hyperref}

或者可以使用 --pdf-engine=lualatex 并加入以下内容:

\usepackage{hyperxmp}
\hypersetup{pdfapart=3,pdfaconformance=B}
\immediate\pdfobj stream attr{/N 3} file{sRGB.icc}
\pdfcatalog{/OutputIntents [<<
/Type /OutputIntent /S /GTS_PDFA1
/DestOutputProfile \the\pdflastobj\space 0 R
/OutputConditionIdentifier (sRGB) /Info (sRGB)
>>]}

Pandoc 在任何一行比--columns设置更宽时会为管道表添加列宽。如何防止这种情况?

保存此过滤器为 nowidths.lua,然后将 --lua-filter nowidths.lua 作为额外选项传递给 pandoc。(参见 问题 8139。)

-- 清除表格中HTML列规格的宽度属性
-- 参见 https://github.com/jgm/pandoc/issues/8139
function Table (tbl)
  if PANDOC_VERSION[1] >= 2 and PANDOC_VERSION[2] >= 10 then
    tbl.colspecs = tbl.colspecs:map(function (colspec)
        local align = colspec[1]
        local width = nil  -- default width
        return {align, width}
    end)
  else
    for i, w in ipairs(tbl.widths) do
      tbl.widths[i] = 0
    end
  end
  return tbl
end

如何使用 pandoc 读取旧版.DOC 格式的 Word 文件?

安装 antiword 并使用它将 .doc 转换为 DocBook 格式,该格式可被 pandoc 读取。

antiword -x db input.doc | pandoc -f docbook
在本文档中