新卒時代から約4年開発し続けてる自作 Markdown パーサー Richmd を振り返る
はじめに
4年前、新卒のときに、Richmd という Markdownパーサーを作りました。
当時設定したコンセプトとしては、「Markdownでさまざまな表現ができる」でした。
なぜこれを作ろうと思ったのか?それは、Detailsの記法が気持ち悪かったからです。。。
<details><summary>test</summary>
hoge
</details>
いやぁ、なんでHTML出てくるんかい! と心の中で何度も突っ込みました。。。
もっと簡単にかける Markdown記法ほしいなと思った時に、思いついたのが、自作パーサー作る方法でした。
GitHub
制作初期(2020年秋ごろ)
まずは、パーサーの勉強を始めました。
パーサーの説明は長くなってしまうので割愛しますが、
以下が詳しく書かれています。
当時は、公開されているMarkdownパーサーをダウンロードして、自分は、HTMLコンバーターの部分を実装しようと思っていました。
で、以下にたどり着きます。
抽出構文木の生成をしてくれるパッケージですが、使用して違和感を持ちました。処理を確認したら、以下の問題がありました。
- まだ、未実装の機能が多い
- そもそも、生成された抽出構文木がバグってた
- しばらく、メンテナンスされてない(今見たら、もうメンテしてなさそうで時が止まってた...)
もうメンテされてない以上、p-r出しても厳しいと判断して、これのコードをベースに自前で改良することにしました。
まずは、ソースコードの解析に入りました。
字句解析と構文解析のロジックがわかったタイミングで、修正作業に入りました。
最終的にHTMLへコンバートする想定で、抽出構文木の形を修正していきました。
そして、最終的に以下の抽出構文木がJSON形式で出力されるように修正しました。
{
"ast": [
{
"name": "heading",
"type": "block",
"level": 1,
"values": [
{
"name": "text",
"type": "inline",
"value": "aaaaaaa"
}
]
},
{
"name": "heading",
"type": "block",
"level": 2,
"values": [
{
"name": "text",
"type": "inline",
"value": "aaaaaaa"
}
]
},
{
"name": "br",
"type": "block"
},
{
"name": "paragraph",
"type": "block",
"values": [
{
"name": "text",
"type": "inline",
"value": "aaaaaaaaa\n"
}
]
},
{
"name": "br",
"type": "block"
},
{
"name": "list",
"type": "block",
"level": 1,
"values": [
{
"name": "text",
"type": "inline",
"value": "aaaaaa"
}
]
},
{
"name": "list",
"type": "block",
"level": 1,
"values": [
{
"name": "text",
"type": "inline",
"value": "aaaaaa"
}
]
}
]
}
制作中期(2020年秋後半 - 冬頃)
さて、ここからは、HTMLコンバートの実装に入ります。
上記の抽象構文木をデータを使って、コンバーターを作成していきます。
ここは、本当に地道な作業です。
当時は、地道に if
- else if
- else
を屈指して変換してましたねw
大変だったのは、リスト表記のインデント対応が大変でした。
また、code block はプログラミング言語対応したかったので、highlight.js を使用しました。
制作後期(2020年冬頃)
ここで、開発している時に、パーサーの法則性に気づきます。
字句解析のパターンとして、
- 一行完結タイプ
- くくってブロック作るタイプ
- Blockquoteタイプ
に大きく分かれることに気づきました。この法則に気づいた瞬間、「オリジナルの記法が作れるのでは?」と確信し、実際に KaTeX を使用した数式表記の Markdown記法を考えて、作ってみました。
これは、行ける!と思った自分は、どんどん機能を増やしていきました。
そして、それが、現在のRichmdへと繋がっていきます。
リリース後
リリース後は、JavaScriptから、TypeScriptに移行しました。
その後は機能拡張に邁進し、cli の構築をしていました。同時は .richmd
という拡張子ファイルを使うことで、コンパイラを提供できるのではと考えて開発していました。
ただ、やはり、実用的とは思えなかった点や、普通に React, Vue で使ったほうが良いと思ったので、この開発は失敗だったと思っています。
2022年 - 2023年頭は、業務で本当に余裕がなく、とてもOSSでやれる状況ではありませんでした。
そして、今年に入り、やっとメンテナンス作業に着手しました。
メンテナンスでは、いくつかのバグを修正しつつ、ESLint, Prettier の導入もしました。
以前より、フォーマットも整ったかと思います。
今後の展望
このRichmdは、もう実装したい機能は搭載できたかと思っています。
ただ、発信力も弱かったせいか、普及率が全然だと思うので、2024年も継続的にアップデートできればと思っています。
さいごに
Richmdは誰でも簡単に導入できる Markdown パーサーです。
是非、一度使ってみてくださいー
Install
pnpm add richmd
GitHub
Discussion