Colorful Source Code Images
You’ve surely seen the colorful, Carbon code snippets all over social media. They can be generated in all sorts of ways, too: online, from the command line, or straight outta your favorite code editor.
Anyhoo, I started looking into having similar images generated automatically, to accompany some of my “more technical” blog posts, but quickly found out carbon-now-cli wouldn’t work for me.
So I sat down and created Source Snap, a pure PHP code snippet image generator in WordPress plugin form. Based on highlight.php, Dompdf, and Imagick, it turns a couple lines of code—from a custom field, though that may change—into a PNG file, then sets it as the post’s Featured Image. On top of that, it supports the TinyPNG API for optimal image compression.
How It Works
The process is surprisingly simple, really:
- Fetch a couple lines of code from a custom field.
- Run them through a code highlighter.
- Insert the resulting HTML into a web page, and save the outcome as a PDF file.
- Open that file as an image, and apply a pre-rendered background.
- Render as PNG, then compress, and save the result.
- Set as Featured Image.
I’m trying my best to handle slight differences in character encoding to avoid quirky results. Also, Domfpdf doesn’t deal too well with custom web fonts, or whitespace. (“Empty” lines must contain non-breaking spaces for them to take up the same height as all other lines.) Its overall understanding of CSS is a bit limited, too, which is why I’m going the pre-rendered background route. The intermediate PDF, by the way, gets tossed away.
After the resulting image is composited and cropped, I apply two gradients, on the right and on the bottom, to hide possible overflow. The final image height is always a multiple of 80 pixels, too, with a minimum of 400 and a maximum of 800 pixels. The image width stays fixed at 1600 pixels.
This predefined array of aspect ratios comes in handy, should the source snippets be lazily loaded over a scaled down, blurred replacement image afterward: the replacement image could then be generated 20 pixels wide and between 1 and 10 pixels tall, and its aspect ratio will always be able match that of the original. (A more flexible scaled down replacement image would be SVG-based, but more detail is way beyond this blog post.)