rmarkdown 中的自定义突出显示样式

Custom highlighting style in rmarkdown

有没有办法在 rmarkdown 中使用自定义高亮样式?

手册对此有点沉默,最接近的是为所有内容制作一个完整的自定义 css 文件,但是这仅适用于 html_document 而不适用于 pdf_document(参见 https://bookdown.org/yihui/rmarkdown/html-document.html#appearance-and-style

较新版本的 Pandoc 支持: http://pandoc.org/MANUAL.html#syntax-highlighting

但是当指定了除默认 pandoc 样式之一以外的任何其他样式时,rmarkdown 会抛出错误。

比如我从highlight.js库下载zenburn.css,修改后想使用:

```
title: Some title
output:
    html_document:
        theme: readable
        highlight: zenburn.css
```

我得到:

Error in match.arg(highlight, html_highlighters()) : 'arg' should be one of “default”, “tango”, “pygments”, “kate”, “monochrome”, “espresso”, “zenburn”, “haddock”, “textmate” Calls: ... -> pandoc_html_highlight_args -> match.arg Execution halted

至少对于 HTML 文档,您可以使用 css YAML 选项简单地包含自定义样式:

---
title: Some title
output:
    html_document:
        theme: readable
        css: zenburn.css
---

关于PDF文档,你可以查看中间的TeX文件。在那里你会找到一个看起来像

的命令块
\newcommand{\CommentTok}[1]{\textcolor[rgb]{0.96,0.35,0.01}{\textit{#1}}}
\newcommand{\KeywordTok}[1]{\textcolor[rgb]{0.93,0.29,0.53}{\textbf{#1}}}

这些是定义代码突出显示的行。例如,第一个定义注释的颜色。您可以编写一个 header.tex,在其中使用 \renewcommand

重新定义 这些命令
\renewcommand{\CommentTok}[1]{\textcolor[rgb]{0.56,0.35,0.01}{\textit{#1}}}
\renewcommand{\KeywordTok}[1]{\textcolor[rgb]{0.13,0.29,0.53}{\textbf{#1}}} 

并将其包含在文档正文之前 之前。

这是一个示例,我们在其中更改了正文中评论和关键字的突出显示:

---
title: Some title
output: 
  pdf_document:
    keep_tex: true
---

```{r}
# This is a test
head(mtcars)
```
\renewcommand{\CommentTok}[1]{\textcolor[rgb]{0.96,0.35,0.01}{\textit{#1}}}
\renewcommand{\KeywordTok}[1]{\textcolor[rgb]{0.93,0.29,0.53}{\textbf{#1}}}
```{r}
# This is a test
head(mtcars)
```

您似乎正在尝试使用 CSS 文件作为突出显示样式。这不会起作用(通常),因为 pandoc 期望使用特殊的 JSON 格式定义突出显示样式。要使用修改后的 zenburn,必须通过 pandoc --print-highlight-style zenburn > myzenburn.style 创建一个新的样式文件,然后修改新文件 myzenburn.style.

要使用新样式,必须通过将必要的选项直接传递给 pandoc 来规避 R Markdown。

output:
  html_document:
      theme: readable
      pandoc_args: --highlight-style=myzenburn.style

但是,这仅适用于非 HTML 输出格式,因为只要 highlight.js 可以使用,knitr 就会干扰。

对于后代来说,因为这花费了比应该更多的时间:

问题

@martin_schmelzer 的回答是正确的(没有测试@tarleb 的解决方案,因为 rmarkdown 据说不能很好地与 Pandoc > 2.0 一起使用,请参阅:https://github.com/rstudio/rmarkdown/issues/1471)。但是,当您在块上写入 echo=TRUE 时,输出代码未标记为 R 代码,因此适用不同的规则。在 HTML 中,这意味着它具有白色背景,并且对于 PDF,它仅通过 verbatim 环境进行格式化。例如下面的降价:

```{r, echo=TRUE}
foo = "bar"
foo
```

将是:

```r
foo = "bar"
foo
```

```
## [1] "foo"
```

虽然第一个块将突出显示,但第二个块将仅以文本颜色显示,但背景始终为白色。这对于较暗的主题来说是非常有问题的,因为它们通常具有非常浅的文本颜色并且这在白色背景下效果不佳。请参阅:https://eranraviv.com/syntax-highlighting-style-in-rmarkdown/ 了解 rmarkdown 突出显示样式的概述。

HTML解决方案

highlight.jspandoc 突出显示之间的切换使这变得更加复杂。如果未指定突出显示,则 highlight.js 与关联标签一起使用。那里的突出显示是通过外部 css.js 库完成的,然后(我假设)将它们散列到 HTML 中以使其独立。所以运气不好。

如果使用某种突出显示样式,则使用 pandoc 突出显示。即:

---
title = "Foo"
output:
  html_document:
    theme: readable
    highlight: zenburn
---

在这种情况下,有解决方案。查看HTML输出,有这样的结构:

<style typetext/css">
  pre:not([class]) {
    background-color: white;
  }
</style>

这意味着只要特定代码块中没有样式(仅适用于“echo”块,因为默认情况下 rmarkdown 假定 R),背景为白色。只需在 .Rmd 文件中包含以下块即可更改此行为:

```{css, echo = FALSE}
  pre:not([class]) {
    color: #333333;
    background-color: #cccccc;
  }
```

并且可以相应地完全指定它们的行为。这里的颜色和背景与 zenburn 风格相反。输出如下所示:

之前:

之后:

PDF 解决方案

使用PDF,查找问题会容易一些,但解决问题会复杂一些。如果查看 .tex 文件,您会发现虽然所有带有实际代码的块都围绕它们进行了很多操作,但回显块仅包装在一个简单的逐字环境中。结果如下所示:

虽然它比 HTML 输出更具可读性,但由于它不共享高亮样式定义的文本颜色,它有点融入文本并创建和打破输出之间统一样式的感觉.如前一个答案所述,解决方案是使用:

---
title: "Foo"
output:
  pdf_document:
  highlight: zenburn
  includes:
    in_header: highlight_echo.tex
---

以及以下利用已包含的包 framed 的构造:

\usepackage{xcolor}
\definecolor{backgroundecho}{HTML}{cccccc}
\definecolor{textecho}{HTML}{333333}

\let\oldverbatim=\verbatim
\let\oldendverbatim=\endverbatim

\makeatletter
\renewenvironment{verbatim}{
    \def\FrameCommand{
        \hskip-\fboxsep
        \color{textecho}
        \colorbox{backgroundecho}
        }
    \MakeFramed{\@setminipage}
    \oldverbatim
}
{
    \oldendverbatim
    \vskip-2em\@minipagefalse % The size required for this negative space is probably in some variable
    \endMakeFramed
}
\makeatother

这重新定义了 verbatim 环境以具有彩色背景和彩色文本。结果是“回声”块的统一格式:

再次感谢@tarleb 和@martin_schmelzer,没有你们我解决不了!