Is there a way to use a custom highlighting style in rmarkdown?
Manual is a bit silent regarding that and the closest to that is to make a full blown custom css file for everything, that would however work only for html_document and not for pdf_document (see https://bookdown.org/yihui/rmarkdown/html-document.html#appearance-and-style )
The newer versions of Pandoc support this: http://pandoc.org/MANUAL.html#syntax-highlighting
but when anything else but one of the default pandoc styles is specified, rmarkdown throws an error.
For example, when I download zenburn.css from highlight.js library, modify it and want to use it:
```
title: Some title
output:
html_document:
theme: readable
highlight: zenburn.css
```
I get:
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
For posterity, since this took more time than it should:
Answers from @martin_schmelzer is correct (didn't test @tarleb's solution, since rmarkdown doesn't supposedly play well with Pandoc > 2.0 see: https://github.com/rstudio/rmarkdown/issues/1471 ). However, when you write echo=TRUE
on chunk, the output is code is not tagged as R code and because of that different rules apply for it. In HTML it means that it has white background and with PDF it is formatted through verbatim environment only. For example, the markdown of following:
```{r, echo=TRUE}
foo = "bar"
foo
```
will be:
```r
foo = "bar"
foo
```
```
## [1] "foo"
```
And while the first chunk will be highlighted, the second will follow only in text color, but background will always be white. This is very problematic with darker themes, since they often have very light text color and this does not play nicely with white background. See: https://eranraviv.com/syntax-highlighting-style-in-rmarkdown/ for overview of rmarkdown
highlighting styles.
This is made more complicated with switch between highlight.js
and pandoc
highlighting. If highlighting is not specified, highlight.js
is used with associated tags. There the highlighting is done through external css
and .js
library, which are then (I presume) hashed into the HTML to make it stand-alone. So no luck there.
If some highlighting style is used however, then pandoc
highlighting is used. I.e.,:
---
title = "Foo"
output:
html_document:
theme: readable
highlight: zenburn
---
In this case, there IS solution. Looking at the HTML output, there is this structure:
<style typetext/css">
pre:not([class]) {
background-color: white;
}
</style>
This means that whenever there is no style in specific code chunk (applies only to the "echo" chunks since by default rmarkdown assumes R), the background is white. This behaviour can be changed just by including following chunk in the .Rmd
file:
```{css, echo = FALSE}
pre:not([class]) {
color: #333333;
background-color: #cccccc;
}
```
and their behaviour can be fully specified accordingly. Here the color and background as reverse of the zenburn style. The output looks like this:
Before:
After:
With PDF, it is a little bit easier to find the problem, but little bit more complicated to solve it. If one looks at the .tex
file, you can see that while all the chunks with an actual code have a lot of going on around them, the echo chunks are wrapped only in a simple verbatim environment. The result looks like this:
While it is more readable than the HTML output, since it does not share the text color defined by highlighting style, it kind of blends into the text and creates and breaks the feeling of uniform style across outputs. The solution is, as mentioned in previous answer, to use:
---
title: "Foo"
output:
pdf_document:
highlight: zenburn
includes:
in_header: highlight_echo.tex
---
And a following construct that utilize package framed
which is already included:
\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
This redefine the verbatim
environment to have colored background and colored text. The result is unified formatting of the "echo" chunks:
So thanks again @tarleb and @martin_schmelzer, I wouldn't be able to solve it without you!
At least for HTML documents, you can simply include your customized styles using the css
YAML option:
---
title: Some title
output:
html_document:
theme: readable
css: zenburn.css
---
Concerning PDF documents, you could check the intermediate TeX file. There you will find a block of commands that look like
\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}}}
These are the lines that define the code highlighting. The first one for example defines the color for comments. You could write a header.tex
in which you redefine these commands using \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}}}
and include it in your document right before the body.
Here is an example in which we alter the highlighting of comments and keywords within the body:
---
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)
```
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With