Search code examples
rlatexr-markdownbeamer

Code block and output background color and border color in Rmarkdown Beamer


I am trying to highlight (background colors and border) a code block in R Markdown with the output format being beamer presentation. I use the metropolis theme. The sample code is as follows

---
title: "Introduction"
author: ""
date: '`r Sys.Date()`'
output:
  beamer_presentation:
    keep_tex: yes
    theme: metropolis
    latex_engine: xelatex
    slide_level: 2
    incremental: no
fontsize: 12pt
classoption: compress
header-includes:
  \setbeamercolor{frametitle}{bg=darkgray}
    \hypersetup{colorlinks,citecolor=orange,filecolor=red,linkcolor=brown,urlcolor=blue}
---


```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
```

```{css, echo=FALSE}
.normal-code {
  background-color: darkgray;
  border: 3px solid red;
  font-weight: bold;
}
```
## First Slide

```{r class.source="normal-code",warning=FALSE,message=FALSE,eval=TRUE,echo=TRUE}
# Load R package
library(tidyverse)
```

Currently, there is neither a change of background color nor a border around the code.


Solution

  • CSS won't have any effect on beamer output. You need latex-oriented solutions.

    I have proposed two solutions; the first one is simpler whereas the second one gets a bit complicated (but looks better and customizable).

    Approach One

    First one is really simple. Just redefine the shadecolor with whatever color you like using, \definecolor{shadecolor}{RGB}{225, 225, 225} which changes the bg color of Shaded environemnt and use chunk opiton class.output="shaded"

    Note: Shaded is used by rmarkdown for code blocks and if you use class.output chunk option, Shaded used for code output too.

    ---
    title: "Introduction"
    author: ""
    date: '`r Sys.Date()`'
    output:
      beamer_presentation:
        keep_tex: yes
        theme: metropolis
        latex_engine: xelatex
        slide_level: 2
        incremental: no
    fontsize: 12pt
    classoption: compress
    header-includes:
      - \setbeamercolor{frametitle}{bg=darkgray}
      - \hypersetup{colorlinks,citecolor=orange,filecolor=red,linkcolor=brown,urlcolor=blue}
    ---
    
    ## First Slide
    
    
    ```{r setup, include=FALSE}
    knitr::opts_chunk$set(echo = TRUE)
    ```
    
    \definecolor{shadecolor}{RGB}{225, 225, 225}
    
    ```{r class.output="shaded"}
    a <- c(1,2,3,4,5)
    b <- c(1,2,3,4,5)
    df <- data.frame(a, b)
    
    # take a look at our data frame
    df
    ```
    

    bg color for code blocks and output


    Approach Two

    Now for more customization, we may try with tcolorbox latex package. So in this second approach, I have done the followings,

    • Firstly, defined a colored box using \newtcolorbox along with options for bg color and border color (Refer to package docs for the details)

    • And then secondly, modified the source and output knitr hooks, so that source code and output is wrapped within the previously defined color box.

    ---
    title: "Introduction"
    author: ""
    date: '`r Sys.Date()`'
    output:
      beamer_presentation:
        keep_tex: yes
        theme: metropolis
        latex_engine: xelatex
        slide_level: 2
        incremental: no
    fontsize: 12pt
    classoption: compress
    header-includes:
      - \setbeamercolor{frametitle}{bg=darkgray}
      - \hypersetup{colorlinks,citecolor=orange,filecolor=red,linkcolor=brown,urlcolor=blue}
      - \usepackage{tcolorbox}
    ---
    
    ## First Slide
    
    
    ```{=latex}
    
    \definecolor{shadecolor}{RGB}{249, 247, 223}
    
    \newtcolorbox{codebox}{
        colback=shadecolor,
        colframe=orange,
        boxsep=2pt,
        arc=2pt}
    ```
    
    
    ```{r setup, include=FALSE}
    library(knitr)
    
    default_source_hook <- knit_hooks$get('source')
    default_output_hook <- knit_hooks$get('output')
    
    knit_hooks$set(
      source = function(x, options) {
        paste0(
          "\n::: {.codebox data-latex=\"\"}\n\n",
          default_source_hook(x, options),
          "\n\n:::\n\n")
      }
    )
    
    knit_hooks$set(
      output = function(x, options) {
        paste0(
          "\n::: {.codebox data-latex=\"\"}\n\n",
          default_output_hook(x, options),
          "\n\n:::\n\n")
      }
    )
    
    knitr::opts_chunk$set(echo = TRUE)
    ```
    
    
    ```{r}
    a <- c(1,2,3,4,5)
    b <- c(1,2,3,4,5)
    df <- data.frame(a, b)
    
    # take a look at our data frame
    df
    ```
    
    

    customized code block and output block in beamer