The Problem

When rendering Quarto notebooks (.qmd files) to Hugo-compatible markdown (.md files), figure captions are lost in the process. While Quarto generates proper figure captions in HTML output, for example:

<img src="fig-distribution-output-1.png" width="464" height="470">
<figcaption>
    Figure 1: Distribution of Sample Data
</figcaption>

The markdown output for Hugo only includes the image with an alt text, like:

<img src="fig-distribution-output-1.png" id="fig-dist"
alt="Figure 1: Distribution of Sample Data" />

I tried playing with yaml options but there does not seem to be an easy fix. So here’s a javascript approach that constructs and includes captions for quarto generated figures automatically.

The Solution

We can leverage that Quarto includes the caption in the image’s alt text and uses consistent ID patterns. Here’s how:

  1. Add this JavaScript to your Hugo site (I had to include it in layouts/partials/extend_head.html/):

    document.addEventListener('DOMContentLoaded', function() {
      //all images with IDs starting with 'fig-'
      const figures = document.querySelectorAll('img[id^="fig-"]');
    
      figures.forEach(img => {
        // wrapper figure element
        const figure = document.createElement('figure');
        figure.className = 'quarto-figure';
    
        // figcaption
        const figcaption = document.createElement('figcaption');
        figcaption.textContent = img.alt;
    
        // img to figure containing img and caption
        img.parentNode.insertBefore(figure, img);
        figure.appendChild(img);
        figure.appendChild(figcaption);
      });
    });
    

    After the document has loaded, we query all <img> elements with property id="fig-". Looping over the query results, we generate the caption as a <figcaption> using the content of the alt=... property. Afterwards, we return the image along with the new caption, nested in a <figure> environment which replaces the original image.

  2. Add CSS to style the caption somewhat (in assets/css/extended/custom.css for me):

    .quarto-figure figcaption {
        margin-top: 0.5em;
        font-style: italic;
    }
    

This approach preserves the automated workflow of generating figures from code when using Quarto, ensuring they appear with proper captions in my Hugo site. Make sure your theme includes the JavaScript properly, and feel free to adjust the CSS to match your site’s styling 😊.