Automate - Images Folder to Quarto Blog Post with R

A step-by-step guide to generating Quarto blog posts with a folder of images using R. Learn how to automate markdown creation, structure metadata, and display images seamlessly with reproducible code.
Programming
Automation
Author

Mark Gingrass

Published

February 10, 2025

Introduction

In this tutorial, we’ll walk through an R script that automatically generates a Quarto blog post from images stored in a directory. If you have a collection of images and want to quickly create a visually appealing blog post, this guide will help you automate the process.

Note

This code generates Markdown, which is itself code, that can then be built and published to a site. Essentially, it acts as a Markdown generator, producing properly formatted Markdown for your images. Once the Markdown file is created, you can build and publish it using Hugo, Quarto, Jekyll, Gatsby, or any other Static Site Generator (SSG) of your choice.

In a future post, I will show you how to create a Shortcut to convert lots of heic images to webp images for much smaller file sizes. I’m assuming you already have a folder full of optimized images.

Loading Required Libraries

Before we begin, we need to load the necessary R libraries that will help us manipulate file paths, generate markdown content, and handle string operations.

library(glue)   # For string interpolation
library(fs)     # For file system operations
library(purrr)  # For functional programming and iteration

These libraries make sure that we can scan directories, manipulate strings, and generate our final Quarto markdown file.

Setting Up Directories and Output File

We define the directory containing the images and specify the output file name.

image_dir <- "images/"  # Folder where images are stored
output_file <- "index.qmd"  # Output file for the blog post

Checking if the Image Directory Exists

Before proceeding, we must ensure that the specified image directory exists. If it does not, the script will stop execution and display an error message.

if (!dir_exists(image_dir)) {
  stop(glue("Directory '{image_dir}' does not exist. Please check the path."))
}

This prevents errors down the line by ensuring that we have a valid directory before processing files.

Listing Image Files

Next, we list all image files in the directory. The dir_ls function retrieves files matching specific extensions: .jpg, .jpeg, .png, .gif, and .webp.

image_files <- dir_ls(image_dir, regexp = "\\.(jpg|jpeg|png|gif|webp)$")

If no images are found, the script stops execution and prompts the user to add images.

if (length(image_files) == 0) {
  stop(glue("No image files found in '{image_dir}'. Please add some images."))
}

Generating Markdown Content for Each Image

To display images in the blog post, we create a function that generates markdown content for each image. The function extracts the file name, removes the extension, and formats it into a markdown-friendly structure.

generate_markdown <- function(image_path) {
  image_name <- path_file(image_path)  # Extract file name
  base_name <- path_ext_remove(image_name)  # Remove file extension
  
  # Generate markdown with title and image
  glue("\n## {base_name}\n\n![{base_name}]({image_path})\n")
}

We then apply this function to all images using map_chr.

markdown_content <- map_chr(image_files, generate_markdown)

Creating the Quarto Metadata

Every Quarto post requires metadata, such as the title, author, date, categories, and featured image.

metadata <- c(
  "---",
  "title: 'My Photo Blog Post'",
  "author: 'Your Name'",
  glue("date: '{Sys.Date()}'"),  # Automatically insert the current date
  "categories: ['Photography', 'Hiking']",
  glue("image: '{featured_image_path}'"),  # Set the featured image
  "format: html",
  "---\n\n"
)

Combining Metadata and Markdown Content

Finally, we merge the metadata with the generated markdown content to form the complete blog post.

final_post <- paste0(paste(metadata, collapse = "\n"), "\n", paste(markdown_content, collapse = "\n"))

We then write this content to the index.qmd file.

writeLines(final_post, output_file)

Completion Message

Once the script successfully generates the markdown file, we display a message to notify the user.

message("Markdown post generated successfully at: ", output_file)

Conclusion

This script automates the process of creating a Quarto blog post from images stored in a directory. By leveraging R’s file system handling, string interpolation, and functional programming capabilities, we efficiently generate a structured markdown file ready for publishing.

Try running this script on your own collection of images and see how it works for you!

Full Source

Find the full source doe repositary here.

Credit

I give full credit to Jaydey Ryan for their excellent instructions on setting up continuous deployment with Netlify and GitHub. Thank you!