Creating an R-Ladies quarto format

Author

Charlie Hadley

Published

June 20, 2022

It’s the day after rstudio::conf(2022), and like many folks in the audience I’m very excited about the future of {quarto}. (LINKS). To help me better understand the differences between RMarkdown and quarto I decided I’d convert Alison Hill’s R-Ladies {xaringan} theme into a quarto format

However, what I realised is that first I needed to replicate the {xaringan} format as closely as possible in {quarto}.

library(tidyverse)
── Attaching packages ─────────────────────────────────────── tidyverse 1.3.1 ──
✔ ggplot2 3.3.6     ✔ purrr   0.3.4
✔ tibble  3.1.7     ✔ dplyr   1.0.9
✔ tidyr   1.2.0     ✔ stringr 1.4.0
✔ readr   2.1.2     ✔ forcats 0.5.1
── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag()    masks stats::lag()
tribble(
  ~feature, ~description,
  "Code chunk  appearance", "Different. Using accessibility features of quarto"
)
# A tibble: 1 × 2
  feature                description                                      
  <chr>                  <chr>                                            
1 Code chunk  appearance Different. Using accessibility features of quarto

How to use the xaringan quarto theme

In the RMarkdown universe we create {xaringan} slides by changing the output type of our RMarkdown document:

---
output:
  xaringan::moon_reader
---

But in quarto, things are very different. Formats are made available as specific types of extensions, which must be installed in each distinct project. You must therefore run this code in the Terminal (not the R console) in RStudio for each presentation you want to write:

quarto install extension rcharliejhadley/xaringan-quarto

This will add the format to the _extensions folder and you can now create your slide deck with in a .qmd as follows:

---
title: Your awesome R-Ladies talk
format: rladies-revealjs
---

Recreating {xaringan} in {quarto}

The new {quarto} system makes use of reveal.js for creating HTML slides, whereas {xaringan} uses remark.js. Despite these libraries sounding similar, they’re very different. This means there’s a lot of styling that needs to be bought across into the new xaringan-quarto theme. But before we progress, let’s think about why we want to replicate the {xaringan} output type:

  • {xaringan} slides look good!

  • {xaringan} has lots of nice features for formatting slides

So in this new {quarto} format I want to replicate both the styles and the formatting features - as closely as possible, anyhow.

Adding remark.js dependency.

It took me ages to figure out how to add a JavaScript dependency to a format. I eventually figured it out from looking at the grouped-tabsets extension. These are the steps we need to go through:

  1. We need to use a .lua file to add our dependencies, add a file called remark-js.lua into the xaringan folder. Within this file we’re going to add our dependency:
Div = function(el)
  if quarto.doc.isFormat("html:js") then
    quarto.doc.addHtmlDependency({
        name = "remarkjs",
        scripts = {"remark-latest.min.js"}
      })
  end
end 
  1. Add the remark-latest.min.js file to the xaringan folder. In the future I’ll figure out how to get the hosted file, but for now I copy pasted the contents of https://remarkjs.com/downloads/remark-latest.min.js.

  2. In the _extension.yml file we need to add our lua dependency, as part of our format. To do so we need to use the common key.

contributes:
  formats:
    revealjs:
    common:
       filters:
           - remark-js.lua

Adding .scss fles to formats

Now we’ve got the remark.js loaded we can move onto setting up the {xaringan} CSS styles. However, there’s a little trick to it. {quarto} makes use of .scss files intead of normal .css files, but that’s to our advantage. By using .scss files we can take advantage of Bootstrap SASS variables which are very powerful, but I’m not sure how much we’ll make use of them here.

When creating a .scss file we need to create at least one “layer boundary” otherwise we’ll get this error message:

ERROR: The file _extensions/xaringan/xaringan-default.scss doesn't contain at least one layer boundary (/*-- scss:defaults --*/, /*-- scss:rules --*/, /*-- scss:mixins --*/, /*-- scss:functions --*/, or /*-- scss:uses --*/)

Here are the steps required to start-up our custom styling

  1. Create a xaringan-default.scss file in the xaringan folder. We’ll set paragraph text to red so we can test it the styles are working:
/*-- scss:rules --*/

p {
  color: red;
}
  1. Update the _extension.yml file to make use of the .scss file
contributes:
  formats:
    revealjs:
       theme: [default, xaringan-default.scss]
    common:
       filters:
           - remark-js.lua

Adding a template presentation

It’s a good idea to add a template presentation file so folks know how to use the format. But it has another utility! We can render the template file within our RStudio project to continually test the theme without having to use the quarto cli.

So, let’s add template.qmd to the top-level directory of our project and some lorem ipsum text:

---
title: "Xarignan Slides"
format: xaringan-revealjs
---



## First slide

This paragraph text will be red!

We’re now going to iteratively add/remove content to this template while we build up the theme.

Letter-boxing and slide scaling

{xaringan} slides are very distinct because of the letter boxing affect from remark.js, and the size of the content rescales with the size of the browser windows. For a first attempt at replicating this, I’ve added some CSS in this commit. I also needed to add padding around the slide content, I’ve implemented this through the border of the <div> but it’s likely not the best solution.

When it comes to replicating exactly how the slide aspect ratio changes, I’m not sure what to do. These are the options available for scaling the presentation size in reveal.js but at the moment I don’t understand how remark.js does its scaling, and so I can’t replicate it further.

Option Description
margin Factor of the display size that should remain empty around the content (defaults to 0.1)
min-scale Smallest possible scale to apply to content (defaults to 0.2)
max-scale Largest possible scale to apply to content (defaults to 2.0)

Hello world slide

Let’s look at duplicating the styling of this slide from the {xaringan} template:

There are four thing to look at:

  • Code chunk and in-line code formatting

  • Text and link formatting

  • Incremental bullet points

  • Footnotes

Code chunk formatting

In {xaringan} the code chunk formatting is very flat. I’m choosing to deliberately use {quarto} code formatting as it improves accessibility and provides further customisation for formats that build on xaringan-quarto and for individual preferences. In the _extension.yml I’ve activated the github highlighting style.

contributes:
  formats:
    revealjs:
       theme: [default, xaringan-default.scss, xaringan-default-fonts.scss]
       highlight-style: github
       

You could use this YAML option for customising all code chunks or individual chunks. The documentation explains how to completely customise chunk appearance and syntax highlighting.

Now let’s look at the inline code formatting. In the original xaringan format this text is the same colour as paragraph text but printed in a mono spaced font. In this first alpha release of the format I’ve chosen to change this to purple, but this probably won’t be popular.

Incremental bullet points

In {xaringan} we can make anything incremental with two dashes, eg --. But in the {quarto} reveal.js format we need to create a <div> using the incremental class. There’s two ways of doing this, either with explicit <div></div> tags or with matching pairs of :::.

Footnotes

In {quarto} we use ^[footnote text] notation to add footnotes that are then numbered at the bottom of the slide. In my opinion, the default styling for quarto is better than {xaringan} so I’m sticking with it.

OLD DRAGONS

In this blogpost I’ll first explain how to use the R-Ladies quaro presentation format and then how to build your own quarto formats.

How to use the rladies quarto theme

In the RMarkdown universe the R-Ladies {xaringan} theme is selected by changing the css option in the YAML header

---
output:
  xaringan::moon_reader:
    css: ["default", "rladies", "rladies-fonts"]
---

But in quarto, things are very different. Formats are made available as specific types of extensions, which must be installed in each distinct project. You must therefore run this code in the Terminal (not the R console) in RStudio for each presentation you want to write:

quarto install extension r-ladies/r-ladies-quarto

This will add the format to the _extensions folder and you can now create your slide deck with in a .qmd as follows:

---
title: Your awesome R-Ladies talk
format: rladies-revealjs
---

How to build your own theme

There is some existing documentation for building your own formats and folder structure is extremely important. The minimum specification for an extension requires you to create an _extension.yml file nested as follows:

rladies-quarto/
              _extensions/
                          rladies/
                                  _extension.yml

This extension will be called rladies because of the folder name rladies. Inside of the _extension.yml file we then specify that the extension contributes a format based on the revealjs presentation format using the default theme, note that there are 11 built-in revealjs themes available.

contributes:
  formats:
    revealjs:
       theme: default

We can add some metadata about the extension, and we can make use of any of the revealjs options.

title: RLadies quarto Presentation
author: Charlotte Hadley
version: 0.0.1
contributes:
  formats:
    revealjs:
       theme: default
       incremental: true

It’s now time to add our custom styles. This is achieved using .scss files instead of ordinary .css files, thanks to quarto making use of Bootstrap SASS variables. There are two steps:

  • Add the .scss file to the theme option in the _extension.yml file
title: RLadies quarto Presentation
author: Charlotte Hadley
version: 0.0.1
contributes:
  formats:
    revealjs:
       theme: [default, rladies.scss]
       incremental: true
  • Add styles to your .scss file that you can easily test
$body-color: red;

Let’s kill two birds with one stone by creating a template slide deck that we can also use to test our .scss styles. At the top level of the project add a new file called template.qmd and set the format as rladies-revealjs and click the Render button, if everything is working you’ll see a slide deck with red text.

---
title: "R-Ladies Xarignan Theme"
format: rladies-revealjs
---

Test

Replicating Alison Hill’s theme CSS

slide background color

I tried to change the background color with the scss file, but it only changes the background of the slide content.

# .scss file
.inverse {
  data-background: #562457;
}

# presentation
::: {.inverse}

Confusingly, if we set the data-background attribute within the {} then it does work

Reuse

Citation

BibTeX citation:
@online{hadley2022,
  author = {Charlie Hadley},
  title = {Creating an {R-Ladies} Quarto Format},
  date = {2022-06-20},
  url = {https://visibledata.co.uk/posts/2022-07-29_creating-an-r-ladies-quarto-format},
  langid = {en}
}
For attribution, please cite this work as:
Charlie Hadley. 2022. “Creating an R-Ladies Quarto Format.” June 20, 2022. https://visibledata.co.uk/posts/2022-07-29_creating-an-r-ladies-quarto-format.