Compounding Competence
Tags: competence, go
Published: 2021-04-11 23:19:21

![](https://stephenafamo.com/blog/store/media/quote-compound-interest-is-the-eighth-wonder-of-the-world-he-who-understands-it-earns-it-he-albert-einstein-36-43-19.jpg)

Compounding is mostly talked about in terms of financial investments, but almost everything in life compounds.

Even more powerfully, our skills, abilities and competence compounds.

I just want to draw a brief timeline of how one task after the other has led me to be able to create a **GitHubFlavoured Markdown to HTML converter in pure Go** with a few hours of work.

## From Blackfriday to Goldmark

### First time working with Markdown in Go

When building [Iteretta](https://iteretta) in 2019, I later decided to have the email editor in Markdown, and then convert it to HTML before sending the email.

There are two places where this conversion needs to happen.

1. In the frontend editor: I used [EasyMDE](https://github.com/Ionaru/easy-markdown-editor) for this.
2. On the backend when generating the emails: For this, I chose a popular Go markdown library [BlackFriday](https://github.com/russross/blackfriday/tree/v2).

### Switching to [Goldmark](https://github.com/yuin/goldmark)

An [Iteretta](https://iteretta.com) user reported a mismatch between the preview and the emails sent.

Debugging the issue led me to start learning about the different markdown specifications.

[Commonmark](https://spec.commonmark.org/0.29/) is currently the most widely used specification, along with [GitHub Flavoured Markdown](https://github.github.com/gfm/), which is an extension of Commonmark.

To make sure things did not diverge, I needed to pick a specification and stick with it. Thankfully, [EasyMDE](https://github.com/Ionaru/easy-markdown-editor) already followed Commonmark, it was Blackfriday that was a little buggy.

After evaluation a number of other Go markdown libraries, I settled on [Goldmark](https://github.com/yuin/goldmark). It was well written, recently updated and easily extensible.

## Extending Goldmark

### Rewriting Images

When I started building [Swish](https://swish.ink) last year, I of course just reached for Goldmark to power the conversion on Markdown to HTML.

The first extension I had to add to Goldmark was rewriting image URLs.

Since the blogs on Swish can change their domains, that means that the link to any image can be changed.

Therefore, when a user adds an image from their uploaded files into the editor, we only put a relative URL. However, the absolute URL is needed when rendering the HTML.

### Getting all images

Later, I wanted to get all the images in a post, download any missing ones, and rewrite the image url in the post to use only local images.

This was necessary for ensuring reliability, so that an external image does not eventually break your post cause it suddenly went missing.

For this, I wrote a custom renderer that walks through Goldmark's AST\(abstract syntax tree\) and gets the `src` of every image found.

## Using Goldmark for PDF rendering

Having written a custom renderer before, when I first thought of converting Markdown to PDF, it didn't seem too daunting, after all, the only part I had to figure out was the PDF.

Thankfully, I found a Go package \([mdtopdf](https://github.com/mandolyte/mdtopdf)\) that already does this, but it used Blackfriday. I then only had to take a few hours to rewrite it using Goldmark to have a base to work from.

> Update: Custom fonts are working
> 
> 
> 
> 
> 
> Here's a screenshot with Roboto [pic.twitter.com/9ZCqimMlZr](https://t.co/9ZCqimMlZr)
> 
> — StephenAfamO \- @swish\_ink \(@StephenAfamO\) [April 11, 2021](https://twitter.com/StephenAfamO/status/1381385241848340481?ref_src=twsrc%5Etfw)

 ## Conclusion

Most of the skills you have today are an combination and evolution of the things you picked up on your journey. And it is the same for everyone.

The things that look like genius are often just long hard work.

I wrote this post as a reminder to myself. Maybe I can read it in the future and be more patient with myself.