Link to this section Overview
remark-abcjs
is a Remark plugin to render sheet music written in ABC notation.
Link to this section Motivation
I wanted to learn more about the Unified ecosystem by writing a plugin for it, and this seemed like an interesting challenge. I also figured I might end up using it on my site if I ever get around to posting music-related content.
Link to this section Technical Description
The plugin looks for nodes in the syntax tree with type code
and language abc
. This means you can write ABC notation as:
```abcX: 1T: Nokia TuneM: 3/4L: 1/8K: Amaj| e'd' f2 g2 | c'b d2 e2 | ba c2 e2 | a6 |```
It then uses ABCJS to render the music to an SVG, storing the result in the data
property of the node so that remark-rehype
can render it as HTML.
Link to this section Results
Works well enough that I'm using it successfully on my site. That said, compromises had to be made. ABCJS doesn't support Node.js environments out of the box, so I had to use patch-package to manually patch it, and then use a build script to include the patched version. My patch uses JSDOM to create a document
object for DOM manipulation.
Also, this project showed me, to put it frankly, how broken the ES module rollout has become. The UnifiedJS collective has more or less entirely switched to pure ESM packages, which can't be require()
'd. On the other hand, Gatsby is still purely CommonJS. As a result, any Gatsby site has to pin an old version of remark
/rehype
and friends. I was primarily developing this plugin for my own site, but I wanted to support the latest standards, so I used Babel to transpile the ES module source to CommonJS. This added complexity to the build process, and I had to pin the CommonJS dual mode versions of all the UnifiedJS packages I depended on. This ended up being kind of the worst of both worlds.
Overall, though, I'm happy I took on this project. I ended up with something useful and I learned a lot about the inner workings of remark
and the rest of the Unified ecosystem.