<- function(yamdir = '_yml',
make_multi_yaml copy_orig = TRUE,
make_simple = TRUE,
leave_orig = TRUE) {
if (!dir.exists(yamdir)) {dir.create(yamdir)}
if (copy_orig) {
file.copy('_quarto.yml', file.path(yamdir, '_quarto_project.yml'))
if (!leave_orig) {file.remove('_quarto.yml')}
}
if (make_simple) {
make_simple_yaml(file.path(yamdir, '_quarto_project.yml'), yamdir = yamdir)
} }
Switching quarto ymls
End result:
They’re not perfect, but Quarto profiles work better than what’s below. I’ve mostly been able to get them to work, and the issues they have are less annoying that the issues with the solution here. So, use that (and the function make_simpleyml()
. I’m leaving this here because it’s a bit more flexible.
Old attempts
Quarto projects with lots of pieces (e.g. this website) are great, but once they get big, rendering single documents can be a pain. By default, both the Rstudio ‘Render’ button and quarto render document_name.qmd
at the command line render the whole project as defined in _quarto.yml
. They supposedly use pre-renders for other pages, but always seem to end up re-rendering a bunch of things. If we’re working on a single document and want to test its rendering, that can be very annoying. For example, if I want to render this document to check it, I don’t want to render the entire website. I’m surprised quarto itself doesn’t have a way to switch behaviour. (I think profiles are that way.See the testing doc.
The workaround developed below does a file rename/swap with _quarto.yml
- have one simple version and one complex version, and trade them out.
We want to have a directory _yml
to store various .yaml
files, and then have a simple call to choose between them. To get there, we need to
- Build the
_yml
directory - Move existing
.yaml
files in (presumably the main project definition) - Generate a minimal
.yaml
to use to render single notebooks - Write a simple function to move the desired
.yaml
to the main project directory and name it_quarto.yaml
.
Could this be done most cleanly inside Quarto itself? Yes. It would be really nice to be able to do something like quarto render filename.qmd -simple
or quarto render filename.qmd -website
. But until that’s the case, maybe this will work.
Setup
First, set up a new structure programatically. You could always just add files to this manually, if you want a bunch of different yamls. This assumes a single _quarto_project.yml
with the complete project definition. In the simplest case, make_multi_yaml
just makes the _yml
directory. But it can also copy over an existing _quarto.yml
and make a simple version.
Note- this shouldn’t be dangerous to run again- the overwrite
argument to file.copy
is FALSE
by default, so it shouldn’t overwrite the _quarto_project.yml
with a simpler version later, but still makes me nervous.
This function just makes a simple yaml from the main one.
<- function(proj_yaml_file = NULL,
make_simple_yaml yamdir = getwd(),
simple_file = NULL) {
# By default, assume yaml is in working directory/_quarto.yml
if (is.null(proj_yaml_file)) {
<- file.path(yamdir, '_quarto.yml')
proj_yaml_file
}
<- yaml::read_yaml(proj_yaml_file)
proj_yaml
<- list()
simple_yaml $project <- proj_yaml$project
simple_yaml# kill the type in case it's complex (e.g. website, book)
$project$type <- NULL
simple_yaml# kill render options- only rendering a single doc should allow rendering that doc and no others
$project$render <- NULL
simple_yaml
if (is.null(simple_file)) {
<- file.path(yamdir, '_quarto_simple.yml')
simple_file
}
::write_yaml(simple_yaml, simple_file)
yaml
}
Switching
The main functionality here is to simply copy over a desired .yaml
file to the project directory and name it _quarto.yaml
so it gets used on render.
<- function(yamfile = 'project', yamdir = '_yml') {
use_quarto_yaml <- list.files(yamdir)
yamfiles <- grepl(yamfile, yamfiles)
whichyam if (sum(whichyam) > 1) {stop('too many matching yaml files')}
file.copy(file.path(yamdir, yamfiles[whichyam]), '_quarto.yml', overwrite = TRUE)
return(invisible())
}
That uses partial matching, so we can run use_quarto_yaml('simple')
to switch to that version prior to rendering. This will work whether or not we use the earlier functions to set up the directory- as long as we have unique names for the various yaml options, calling use_quarto_yaml
switches which is active, e.g. 31b8e172-b470-440e-83d8-e6b185028602:dAB5AHAAZQA6AE8AUQBCAGoAQQBHAEkAQQBOAHcAQQA1AEEARwBVAEEATgBnAEIAagBBAEMAMABBAE8AQQBBADQAQQBEAGcAQQBaAEEAQQB0AEEARABRAEEAWQBRAEEAdwBBAEcAVQBBAEwAUQBBADUAQQBHAE0AQQBPAFEAQgBpAEEAQwAwAEEAWgBnAEIAbQBBAEQAWQBBAE4AdwBCAGoAQQBHAFEAQQBOAEEAQQB3AEEARABRAEEAWgBRAEEAMgBBAEQAQQBBAAoAcABvAHMAaQB0AGkAbwBuADoATgBBAEEANABBAEQAYwBBAE4AdwBBAD0ACgBwAHIAZQBmAGkAeAA6AAoAcwBvAHUAcgBjAGUAOgBZAEEAQgBnAEEARwBBAEEAZQB3AEIANwBBAEgASQBBAGYAUQBCADkAQQBBAG8AQQBkAFEAQgB6AEEARwBVAEEAWAB3AEIAeABBAEgAVQBBAFkAUQBCAHkAQQBIAFEAQQBiAHcAQgBmAEEASABrAEEAWQBRAEIAdABBAEcAdwBBAEsAQQBBAG4AQQBIAE0AQQBhAFEAQgB0AEEASABBAEEAYgBBAEIAbABBAEMAYwBBAEsAUQBBAEsAQQBHAEEAQQBZAEEAQgBnAEEAQQA9AD0ACgBzAHUAZgBmAGkAeAA6AA==:31b8e172-b470-440e-83d8-e6b185028602
This is not run here, because it would reset the yaml on the fly during render, which would be bad. It should be run interactively, just prior to rendering.