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}.
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 talkformat: 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:
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
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.
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.
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 variableswhich 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
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;}
Update the _extension.yml file to make use of the .scss file
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.
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.
Text and link formatting
We’re going to use the SASS link-color variable to change the colour of hyperlinks, but remember this must be placed in the defaults layer of the .scss file.
In {xaringan} the paragraph text is set to 20px, setting the $presentation-font-size-root to 28px in the .scss results in slides that scale similarly to {xaringan} slides.
$presentation-font-size-root: 28px;
With {xaringan} we’re free to use whatever level of heading we like for slides. In fact, it’s fairly common to use lower-level headings for longer slide titles. But, in {quarto} we can only start slides with level 2 headings. I’ve taken the heading sizes from {xaringan} and added them to the styles:
Note that these are still scaled with the size of the browser window.
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.
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 talkformat: 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:
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.
title: RLadies quarto Presentationauthor: Charlotte Hadleyversion: 0.0.1contributes: 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 Presentationauthor: Charlotte Hadleyversion: 0.0.1contributes: 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.