zenn-markdown-html
zenn-markdown-html は、Zenn独自の記法を含む markdown を HTML に変換するためのパッケージです。
サポートするmarkdown記法は Markdown記法一覧 を参照してください。
このパッケージは2つのインターフェイスを提供します。
markdownToHtml
: Zennの記事、本、コメントなどで使用するHTMLに変換します。markdownToSimpleHtml
: Publicationの定型メッセージなど、限られた装飾のみをサポートするHTMLに変換します。
構成
以下の説明は、markdownToHtml
を対象とします。
主な変換プロセスは以下の通りです。
- markdown-it で markdown を HTML に変換する
- prism.js でコードブロックをハイライトする
- sanitize-html で HTML をサニタイズする
markdown-it
プラグインについて説明します。
mdBr
:<br>
の使用を許可します。mdRendererFence
: prism.jsによりコードブロックをハイライトします。ただしlangがmermaid
の場合は、mermaidの埋め込み用iframeに変換します。markdownItImSize
: markdown-it-imsize をforkしたものです。イメージのサイズを指定できるように拡張しています。mdCustomBlock
: markdown-it-custom-block をforkしたものです。@[tag](arg)
形式の埋め込みをiframeに変換します。mdContainer
: markdown-it-container をforkしたものです。<details> ~ <summary>
や:::message
などの記法をサポートします。mdFootnote
: markdown-it-footnote です。注釈の記法をサポートします。mdTaskLists
: markdown-it-task-lists です。タスクリスト形式の記法をサポートします。mdInlineComments
: markdown-it-inline-comments です。インラインコメントをサポートします。mdLinkAttributes
: markdown-it-link-attributes です。リンクに属性を追加しています。markdownItAnchor
: markdown-it-anchor です。見出しにアンカーを追加しています。mdKatex
: markdown-it-mdKatex をforkしたものです。KaTeXの記法を zenn-embed-elements でレンダリングできように加工しています。mdLinkifyToCard
: 埋め込みに対応しているURLへのリンクを埋め込み用のiframeに変換します。
prism.js
プラグインについて説明します。
enableDiffHighlight
: diff構文をサポートします。
sanitize-html
現在、markdown-itにより <br>
以外のHTMLタグは全てサニタイズしています。<br>
はmarkdown-itのプラグインを書いて特別に許可していますが、この方式で他のHTMLタグもサポートするのは難しいため、将来的にはmarkdown-itでのサニタイズをやめて、sanitize-htmlでサニタイズを行うようにする予定です。
その前段として、現状ではmarkdown-itおよびそのプラグインで変換されたHTMLだけを許可するように設定しています。
開発環境
zenn-cli で動作確認します。
ビルド
pnpm build
で実行します。
Babelの使用について
zenn-markdown-html では、PrismJS
の言語プラグインを予め全て読み込むために babel-plugin-prismjs
を使用しているため、ソースコードのビルドには babel
を使用し、型ファイル(*.d.ts)のビルドには tsc
を使用してビルドしています。
テスト
pnpm test
で実行します。
lint
pnpm lint:fix
で実行します。
開発方針
カスタムブロックによる埋め込み
Markdownにカスタムブロックを追加し、外部ページの埋め込みを追加することができます(例: @[youtube](youtube-video-id)
)新しい埋め込みを追加する場合は、以下のガイドラインに従ってください。
- iframeで埋め込みができること。ただし、外部から提供されているscriptを使ってiframeを生成するのはセキュリティ上の理由から許可していません。
- 埋め込みの対象となるサービスが広く普及しており、継続的に安定して運営されることが見込まれること。
Link Cardの埋め込み
本文中にURLがある場合、それをLink Cardとして埋め込みで表示します。なお、一部のメジャーなサービス(Twitter、Youtube、など)は、Link Cardではなくサービスに対応するiframeの埋め込みに変換しています。Link Cardおよびiframeの埋め込みの変換に対応する外部サービスの基準は、現在対応しているサービスと同等のものとします。