Programmatically embed (and layout) a whole folder of images in Quarto document

How to use ‘asis’ output from R code chunks to generate inline image links for an entire directory of images, AND arrange them using Quarto’s custom figure layout syntax


Cynthia Huang


January 29, 2024


June 20, 2024

The Task

Say you have a folder of images you want to include in a custom figure layout within a Quarto document. Here’s what such folder might look like:

├── index.qmd
└── images/
    ├── image-001.png
    ├── image-002.png

Let’s say we want to include the image-00*.png images side-by-side. The Quarto markdown for this might look like:

::: {layout-ncol=2}



Code chunk magic

Writing out markdown is fine for a few images, but it could get quickly get tedious (e.g. a whole folder). Instead, why not use an R code chunk1 to generate the markdown:

#| output: asis
img_files <- fs::dir_ls("images", glob="*.png")
cat("::: {layout-ncol=2}\n",
    sep = ""

Example Output

Here’s some example output2 using some sketchnotes I drew many years ago:

Code Explanation

And finally, an explanation of how the code works:

1img_files <- fs::dir_ls(images, glob="*.png")
2cat("::: {layout-ncol=3}\n",
3    glue::glue("![]({img_files})\n\n\n"),
4    sep = ""
Get paths to all the image files in the images/ folder.
Use cat() to output the starting fence for the custom figure layout div.
Use glue() to generate the inline image links for each image separated by new lines (required for custom layouts). Output the links with cat() and close the figure div.
Set cat() to output each markdown component without any additional whitespace.

Notes and Extension Ideas

  • If your images have a natural order to them (as mine do in the example above), make sure your file names reflect this ordering. I think dir_ls() sorts alphabetically by default, so make sure to pad your numbering if you’ve got more than 9 files (i.e. to avoid image-10.png appearing before image-9.png).
  • Quarto allows you to specify custom layouts with non-equal columns/rows. See Figures in the official Quarto Guide for more.
  • My example doesn’t support captions (i.e. the [] element is empty). You could easily rectify this by storing both file names and their captions in the same table, and using glue::glue_data() to generate a string from an expression like: "![{caption}]({img_path})". See this documentation from the {glue} package for more details.

I wrote this code in order to bulk embed written notes I wrote at a few conferences last year into Quarto websites. I’ll be writing about how I use Quarto as a personal knowledge management tool/scrapbook/research compendium in an upcoming blog post. Stay tuned!


  1. based on this stackover flow question↩︎

  2. Note to future me: the example images come from a pdf (also in the source folder). This is the zsh command I used to extract each page as separate images using imagemagick: convert -quality 100 -density 200 ${filename}.pdf image-%02d.png↩︎


BibTeX citation:
  author = {Huang, Cynthia},
  title = {Programmatically Embed (and Layout) a Whole Folder of Images
    in a {Quarto} Document},
  date = {2024-01-29},
  url = {},
  langid = {en}
For attribution, please cite this work as:
Huang, Cynthia. 2024. “Programmatically Embed (and Layout) a Whole Folder of Images in a Quarto Document.” January 29, 2024.