Understanding Quarto and its Directory Structure
Quarto is a powerful document generation tool that allows users to create high-quality documents using a variety of markup languages, including Markdown, R Markdown, and more. One of the unique features of Quarto is its ability to render documents in various formats, such as HTML and PDF.
When you create a new Quarto project, it typically includes a specific directory structure that reflects the structure of your document’s content. This can include subdirectories for different types of files, such as images, R scripts, and more.
The Problem: Flattening Subdirectories in Output Files
In this article, we’ll explore how to flatten subdirectories of output files in Quarto. Specifically, we’ll look at how to modify the _quarto.yml
file to achieve this.
The current directory structure of a typical Quarto project looks something like this:
project_folder/
│ └── R/
| └── notebooks/
| └── notebook.qmd
├── _quarto.yml
|
├── project.Rproj
...
In this example, the _quarto.yml
file specifies that the output directory should be _output
, which contains the rendered document files. However, by default, these files are nested within subdirectories that reflect the structure of the original content.
For example, if we have a notebook named notebook.qmd
, the output file might be placed in a subdirectory like this:
_output/
│ └── R/
| └── notebooks/
| └──notebook.html
As you can see, the output files are nested within a subdirectory that reflects the structure of the original content. This can lead to path issues with dependent R scripts or other files.
Solution: Using a Post-ender Project Script
One solution to this problem is to use a post-ender project script, such as _post-copy.R
. This script is executed after the Quarto document has been rendered and provides an opportunity to manipulate the output files.
Here’s how you can create a post-ender project script in Quarto:
{
"project": {
"execute-dir": "project",
"output-dir": "_output",
"post-render": ["_post-copy.R"]
}
}
In this example, the _quarto.yml
file specifies that the output directory should be _output
, and it also includes a reference to the post-ender script _post-copy.R
. When you render your Quarto document using quarto render
, the script will be executed after the document has been rendered.
The Post-ender Script: Copying Output Files
The post-ender script is responsible for copying or moving output files from the output directory to a new location. In this case, we’re interested in flattening the subdirectories of output files, so we’ll modify the script to do that.
Here’s an example of what the _post-copy.R
script might look like:
{
out_dir <- Sys.getenv("QUARTO_PROJECT_OUTPUT_DIR") |> fs::path_tidy()
out_files <- strsplit(Sys.getenv("QUARTO_PROJECT_OUTPUT_FILES"), "\n")[[1]] |> fs::path_tidy()
# "notebook_files" for "notebook.html"
assets <- out_files |> grep("\\.html$", x = _, value = TRUE) |> gsub("\\.html$", "_files", x = _)
assets <- assets[fs::dir_exists(assets)]
fs::file_copy(out_files, out_dir, overwrite = TRUE)
fs::dir_copy(assets, fs::path(out_dir, fs::path_file(assets)), overwrite = TRUE)
}
This script uses the fs
package to manipulate file paths and directories. It extracts the output directory and files from environment variables, flattens the subdirectories by renaming files that end with .html
, and then copies the files to a new location.
Resulting Directory Structure
After executing the post-ender script, the resulting directory structure might look something like this:
_output/
│ └── notebook.html
├── notebook.pdf
└── notebooks/
├── notebook_files/
│ └── libs/
│ └── bootstrap/
│ └── ...
└── quarto-html/
├── anchor.min.js
├── popper.min.js
├── quarto-syntax-highlighting.css
└── tippy.umd.min.js
As you can see, the output files have been flattened, and there are no longer any subdirectories that reflect the structure of the original content.
Conclusion
Flattening subdirectories of output files in Quarto is a relatively straightforward process that involves modifying the _quarto.yml
file to include a post-ender script. This script can be used to manipulate the output files, including renaming and copying them to new locations. By using this approach, you can achieve a more consistent directory structure for your Quarto projects.
Note: The script above assumes that you are running Quarto in RStudio.
Last modified on 2023-07-03