<!DOCTYPE html><htmllang="en"><head><metacharset="utf-8"/><metaauthor="Alex Mikhailov"/><metaname="viewport"content="width=device-width, initial-scale=1, shrink-to-fit=no"/><metaname="color-scheme"content="light dark"/><metahttp-equiv="content-language"content="en-us"/><metaname="description"content="Add post preview for OpenGraph cards"/><metaproperty="og:description"content="Add post preview for OpenGraph cards"/><metaproperty="og:image"content="https://fidonode.me/resources/images/preview/posts/posts_preview.org.png"/><metaproperty="og:title"content="Posts preview"/><metaname="twitter:description"content="Add post preview for OpenGraph cards"/><metaname="twitter:title"content="Posts preview"/><metaname="twitter:image"content="https://fidonode.me/resources/images/preview/posts/posts_preview.org.png"/><metaname="twitter:card"content="summary_large_image"/><linkrel="icon"type="image/x-icon"href="/resources/favicon.ico"/><linkrel="stylesheet"type="text/css"href="/resources/css/pico.sand.min.css"/><scriptdefer="true"src="https://umami.dokutsu.xyz/script.js"data-website-id="d52d9af1-0c7d-4531-84c6-0b9c2850011f"></script><title>Posts preview</title><linkid="highlight-theme"rel="stylesheet"type="text/css"/><scriptsrc="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script><scriptsrc="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.9.0/build/languages/bash.min.js"></script><scriptsrc="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.9.0/build/languages/lisp.min.js"></script><scriptsrc="/resources/js/theme-selector.js"></script></head><body><headerclass="header"><divclass="container"><nav><ul><li><strong>Alex Mikhailov</strong></li></ul><ul><li><ahref="/index.html">About</a></li><li><ahref="/posts.html">Blog</a></li><li><ahref="/rss.xml">RSS</a></li></ul></nav></div></header><mainclass="container blog-post"><hgroup><h1>Posts preview</h1><p>Add post preview for OpenGraph cards</p><nav><ul><li>Tags:</li><li><mark><ahref="/tags/@org-mode.html"class="secondary">@org-mode</a></mark></li><li><mark><ahref="/tags/@elisp.html"class="secondary">@elisp</a></mark></li><li><mark><ahref="/tags/@imagemagick.html"class="secondary">@imagemagick</a></mark></li></ul></nav></hgroup><divid="table-of-contents"role="doc-toc">
<ahref="https://imagemagick.org">Imagemagick</a> is a ffmpeg of the image world. You can do a lot of fun things with it. For example you can take a picture, cut corners on it, place it on top of another image, add some text and get final result. So it is looks like a good tool for making previews from code.
I want to hook a process of rendering post. Since this function called on each run of publishing and for each post it is a good idea to cache resulting images. I gonna simply check presence of preview image and use it as guard for running image generation. After that I gonna extract <code>#+TITLE</code> and <code>#+DESCRIPTION</code> properties from Org file. Each Org file I have, has next header:
As I already mention I gonna skip file generation when file already here. Here is the whole function. Pretty simple. Just prepare pathes, check some dependencies, create pathes and execute script which calls imagemagick.
</p>
<pre><codeclass="language-lisp">(defun my/render-preview (file-name title description)