在 Bookdown 中,当我尝试使用 Pandoc 编译 epub 书籍时,无法识别 `\textcolor`

In Bookdown, `\textcolor` is not recognized when I attempt to compile an epub book using Pandoc

在 bookdown 中,当我尝试使用

进行编译时,似乎无法识别 latex 中的 \textcolor

bookdown::render_book('bookdown::epub_book')

尽管我已将 \usepackage{xcolor} 添加到 preamble.tex 文件中。

这有什么原因吗?

让我们看一下文档的处理方式。我将省略 knitr 和 R Markdown 包的处理并专注于 pandoc,这是从 Markdown 转换为任何其他格式的最后一步。

Pandoc 首先将文档解析为内部中间格式。我们可以通过选择 native 作为目标格式来检查该格式。所以当我们将 \textcolor{red}{Mars} 提供给 pandoc 时,它会向我们显示原生表示:

$ printf '\textcolor{red}{Mars}' | pandoc --from=markdown --to=native
[Para [RawInline (Format "tex") "\textcolor{red}{Mars}"]]

这意味着,无需过多赘述,pandoc 将 \textcolor... 识别为嵌入到 Markdown 中的原始 LaTeX 命令。它不会尝试进一步解析 LaTeX,因为它被告知要阅读 Markdown,而不是 LaTeX。当生成支持包含 LaTeX 的格式的输出时,此原始 LaTeX 片段将包含在输出中。 pandoc 在生成 HTML/EPUB 时遗漏了该片段,因为包含它不会产生预期的效果。

那么我们能否说服 pandoc 继续解析,pandoc 知道如何将 \textcolor 从 LaTeX 翻译成 HTML 吗?

通过 pandoc 将 LaTeX 转换为 HTML,第二个问题很容易回答:

$ printf '\textcolor{red}{Mars}' | pandoc --from=latex --to=html
<p><span style="color: red">Mars</span></p>

这看起来不错,所以让我们让 pandoc 解析原始 LaTeX 片段作为下一步。 Pandoc 有一个名为 Lua filters 的特性,它允许我们以编程方式修改内部文档表示。这是一个将解析原始 LaTeX 命令的过滤器:

function RawInline (el)
  if el.format == 'tex' then
    local blocks = pandoc.read(el.text, 'latex').blocks
    return blocks[1] and blocks[1].content or el
  end
end

将此代码保存到文件 parse-latex.lua 并使您的文档处理管道使用此文件:

---
output:
  bookdown::epub_book:
    pandoc_args: ['--lua-filter=/path/to/your/parse-latex.lua']
---

彩色文本现在应该会显示在您的 epub 图书中。