From Code to Presentation

From Code to Presentation: Solving SVG Image Conversion in Quarto

Recently, I decided to switch from traditional PowerPoint presentations to Quarto-based presentations (mainly Reveal.js), I was excited about the possibilities. The idea of generating presentations directly from code is incredibly appealing for several reasons:

Why Code-Generated Presentations?

  • AI-Powered Development: You get all the help from modern AI tools, GitHub Copilot, and intelligent formatting assistance
  • Instant Updates: When you include figures generated by code, updating the presentation is instantaneous with preview mode
  • Efficiency: What used to require at least 5 clicks to replace an image now happens automatically

The workflow is simply elegant: write code/markdown, generate figures, and your presentation updates in real-time.

The Challenge: Cross-Platform Compatibility

However, there’s always a catch. While I love working with this modern approach, supervisors and collaborators often need formats they can easily read and edit - namely, PowerPoint.

Quarto can convert presentations directly to PowerPoint, but I encountered a significant issue with image conversion. Here’s the problem:

SVG: The Double-Edged Sword

I output everything as SVG images because:

  • SVG is the superior image format: it’s open, vector-based, and easily readable
  • Perfect for Python workflows: I can easily generate aggregated composite figures for publications
  • Scalable and crisp: maintains quality at any zoom level

But SVG has compatibility issues:

  • Windows compatibility: SVG images don’t work well on Windows for reasons I haven’t fully understood
  • HTML rendering: Sometimes SVG isn’t optimal for display in HTML/Reveal.js presentations
  • Limited Quarto support: While Quarto automatically converts SVG to PDF for PDF output, this feature doesn’t exist for other formats

The Solution: Custom Lua Filters

To solve this challenge, I created a Lua filter that automatically handles SVG conversion:

SVG to PNG Filter

The filter converts SVG images to PNG format for broader compatibility across all output formats.

Key Features:

  • Converts SVG images to PNG at 192 DPI for excellent quality
  • Intelligent caching: skips conversion if PNG is newer than SVG
  • Cross-platform compatibility (macOS/Linux)
  • Maintains original basenames and handles duplicates
  • Works with all Quarto output formats

Implementation

Adding this filter to your Quarto project is straightforward. Include it in your _quarto.yml:

filters:
  - resources/svg2png.lua

The filter automatically:

  • Creates a common converted-images folder for all processed images
  • Uses rsvg-convert for high-quality conversion
  • Provides detailed logging for debugging

Technical Details

The SVG to PNG filter uses rsvg-convert from the librsvg library:

Installation:

  • macOS: brew install librsvg
  • Ubuntu/Debian: apt install librsvg2-bin
  • Or use with pixi/conda environments

Get the Filter

The SVG to PNG filter is available as a GitHub Gist:

🔗 Download SVG to PNG Lua Filter

What’s Next?

This solves the image conversion problem, but PowerPoint compatibility has other challenges:

  • Fragments and incremental reveals don’t translate well
  • Section headers and advanced Reveal.js features aren’t supported
  • Complex layouts may need manual adjustment

But that’s a story for another blog post! For now, at least one major hurdle in the code-to-presentation workflow is solved.


Have you encountered similar challenges when converting between presentation formats? I’d love to hear about your solutions in the comments below.

Silas Kieser
Silas Kieser
Data scientist with 10 years of experience

Husband, Father & Data scientist