Doug.Instance

Handleblog Sneak Peak: Rendering Images in Markdown with marked

Aug 18, 2023 handleblog

This post is a sneak peak behind the scenes of the blog platform hosting the post your are now reading - Handleblog.

As I said in a previous post, optimizing code requires knowing what key variables you want to optimize. In the case of this project, I am looking for high WAF (Wife Acceptance Factor). I would like my wife to be able to use this platform and, while she is pretty tech-savvy, she has little patience when it comes to unnecessarily difficult UX. Even though I do plan on supporting WYSIWYG editing eventually, I certainly don't need this yet, so keeping the markdown simple as possible is a great way to maximize WAF. One problem area I saw here was images. It's particularly problematic because in the short term, I'm not configuring a custom domain for the CloudFront CDN used to host content so every image needs to be fully-qualified with a cryptic domain generated by AWS. Custom rendering to the rescue! Looking in the docs for the marked package, I found the following example.

// Create reference instance
import { marked } from 'marked';

// Override function
const renderer = {
  heading(text, level) {
    const escapedText = text.toLowerCase().replace(/[^\w]+/g, '-');

    return `
            <h${level}>
              <a name="${escapedText}" class="anchor" href="#${escapedText}">
                <span class="header-link"></span>
              </a>
              ${text}
            </h${level}>`;
  }
};

marked.use({ renderer });

// Run marked
console.log(marked.parse('# heading+'));

Combining this with some more documentation of which functions you can specify in the renderer, I found I could quickly get the desired effect with something like this:

const renderer = {
  image(href: string, title: string, text: string) {
    return `<img src="${options.pageConfig.contentRoot}/${href}" alt="${text}" />`;
 },
};