Fenced Code Block Support

2/18/2024

I've been wanting to include some code snippets in what I write about, and I finally got around to implementing support for them on this website! Nothing too crazy at the moment, just some out-of-the-box behavior from markdown-it + highlight.js. I think it would be fun for the first example of the code highlighting to be a small showcase of how the highlighting is implemented, so here's a quick rundown!

First, I wanted to create a simple abstraction between what markdown processor we use so that we'll be free to switch between different markdown processors (as i've already done). To do this, I created a simple processor object that contains an internal processor (the processor we're using at the time) + a process function, that turns markdown text into HTML text. The code is pretty simple and is as follows:

import markdownit from 'markdown-it';
import hljs from 'highlight.js'

export const MarkdownProcessor = {
    _processor: markdownit({
        html: true,
        // highlight pulled from https://github.com/markdown-it/markdown-it#syntax-highlighting
        highlight: function (str, lang) {
            if (lang && hljs.getLanguage(lang)) {
              try {
                return hljs.highlight(str, { language: lang }).value;
              } catch (__) {}
            }
            return ''; // use external default escaping,
        }
    }),
    process(content: string): string {
        return this._processor.render(content);
    },
}

Now, we can go from

import { remark } from "remark";
import html from "remark-html";
// ...
const processedContent = await remark()
    .use(html)
    .process(matterResult.content);
  const contentHtml = processedContent.toString();

to

import { MarkdownProcessor } from "./MarkdownProcessor";

//...
const post = MarkdownProcessor.process(content);
//...

*As a side note, this behavior should also be achieved via relatively similar means through remark as well, I just wanted to try out a differnt library :)

The post variable should contain all of the html fitted with all of the proper code tags and useful class names to hook into for custom styling. For the sake of having a working solution, I opted to use one of highlight.js's provided themes, the github.css theme! This will almost certainly change in the future, but it gets the job done for now!

Next, I will be looking to add some support for uploading assets and referencing them in posts! Until then...

Jacob