Markdown を Confluence Wiki Markup に変換するやつを作った
仕事で Atlassian 系のサービスを使うことになったのだが、Bitbucket 以外の Jira や Confluence は残念ながら Markdown が使えない。
代わりに Confluence Wiki Markup という記法を採用している。
Markdown に比べると面倒かつ使ったことのない記法なので、毎回ドキュメントを読みながら書いている。
僕のようなユーザーは少なくないようで、Markdown 対応の要望は数多くあがっているようだが、実装には至っていない。
Confluence Wiki Markup の変換ロジックや既存投稿との共存が難しいからなのではないか、と勝手に邪推している。
まあぐだぐだ文句を言っていても Markdown で書けるようになるわけではないので、自分でなんとかしてみた次第である。
ソース:
https://github.com/KeisukeKudo/md-to-cwm
DEMO:
https://inspiring-snyder-b2223c.netlify.com/
使い方
左ペインがエディタ、Markdown で入力する。
すると、右ペインに装飾された文字列が表示される。
右上にあるコピーアイコンをクリックすると Confluence Wiki Markup 形式でクリップボードにコピーされる。
その隣りにあるアイコンをクリックすると、 プレビューと Confluence Wiki Markup ビューを切り替えることができる。
注意してほしいのは、プレビューでコピーアイコンをクリックしても Confluence Wiki Markup 形式でコピーされることと、Clipboard API
非対応ブラウザではコピーが実行されないことだ。
技術スタックや利用ライブラリ
ソースを見てもらえばわかるが、よくある HTML + CSS + JavaScript (ES2015) で作成した静的ページだ。
エディタ部は Microsoft Monaco Editor
正直今回の場合、利用しない過剰な機能満載なライブラリだが、前から気になっていて使ってみたかったので採用した。
Markdown のパーサーは Marked.js
柔軟にカスタマイズ可能で、 Confluence Wiki Markup のパーサーもこれで代用した。
サニタイズは Marked.js 単体でも可能だが、 deprecated のようで、 README で推奨されている DOMPurify を使用した。
シンタックスハイライトは highlight.js
テーマは統一感を持たせるため、vs2015 を少しカスタムして使用している。
変換結果をビューに反映する処理は、エディタ内容変更イベントをフックして都度処理をしている。
そのタイミングで、入力内容をIndexedDBに保存しているのだが、イベント発生頻度が多いし、保存処理はそこそこ重いので、 lodash の throttle を使ってイベントを監視し、3秒毎の実行に制限した。
更に保存処理を Web Worker に任せることで JavaScript の実行スレッドがブロックされることを防いでいる。
今後の課題とか反省とか
- パース処理はメインスレッド(Promise で実行してはいるが)で行っているので、Web Worker に任せたほうがよかったかもしれない。
- やっぱり Monaco Editor 重い、textarea で十分だと思うので差し替えたほうがいいかも
- ソース汚い、Vue なり react なり使うべきだった
- IndexedDB 関連が雑、これもラッパーライブラリ使うべきだった
- テスト書いてない、レンダラー部分だけでも書く
- README の How to use が英語(笑)なのでもう少しマシにしたい
- モバイル対応は今後もする予定はない
まとめ
Web Worker を触るのは初めてだったので、こんな簡単にマルチスレッドを実現できるなんて......、と少し感動した。
色々制限があるし、レガシーブラウザに対応しなければならない場合も多いので、使い所は限られてくるとは思うが......
なんだかんだ言ってはいるが、概ね満足のいく出来ではある。
使ったことのない技術も学べたし、レンダラーを書くために Confluence Wiki Markup も覚えた。ぶっちゃけこのアプリ無くても余裕で書けるくらいには......
とはいえ、Markdown のほうが圧倒的にシンプルで書きやすいので、このアプリは積極的に使っていきたい。
もし使ってみて、おかしな点や要望がある場合は、ここのコメントでも GitHub でもいいので報告してくれるとありがたい。