目次を表示
進捗状況
0%
2024-10-30
Mermaidプレビューを組み込む
Mermaid Previewの構築
概要
- プレビューで表示できる。
- テーマの切り替えを行なっても別のテーマでのコントラストを作成できる。
graph TD
A[ブログコンテンツ取得] --> B[Cheerioで解析]
B --> C{コードブロックの種類}
C -->|Mermaid| D[MermaidChartに変換]
C -->|その他| E[Highlight.jsでハイライト]
D --> F[Mermaidレンダリング]
E --> F
F --> G[Astroページ表示]
G --> H[テーマ切替ボタンをクリック]
H --> I{現在のテーマ}
I -->|ライト| J[ダークモードに切替 & .darkクラス追加]
I -->|ダーク| K[ライトモードに切替 & .darkクラス削除]
J --> L[Mermaid再レンダリング]
K --> L
G --> M[ページ遷移時Mermaid初期化]
M --> F
参考資料
Mermaidパッケージ
https://mermaid.js.org/intro/#deploying-mermaid
環境
- Astro
- microcms
- cheerio
- highlight.js
すでにコードでのシンタックスハイライトは実装できている状態。
構築
インストール
npm install mermaid
レスポンスからMermaid形式の部分を抽出
blog/id.astro (詳細ページ)
const $ = load(response.body);
$("pre code").each((_, elm) => {
const className = $(elm).attr("class") || "";
if (className.includes("language-mermaid")) {
const mermaidCode = $(elm).text();
$(elm)
.parent("pre")
.replaceWith(`<div class="mermaid">${mermaidCode}</div>`);
} else {
const result = hljs.highlightAuto($(elm).text());
$(elm).html(result.value);
$(elm).addClass("hljs");
}
});
Mermaidの初期化とレンダリング
run()がないとView transitionを利用している場合は遷移後にプレビューが表示されないことがあるので注意。
initializeMermaid.js
import mermaid from "mermaid";
export function initializeMermaid() {
mermaid.initialize({
startOnLoad: true,
});
mermaid.run();
}
EventListenerの追加
DOMがロードした場合とview transitionに対応。
blog/id.astro (詳細ページ)
<script>
import { initializeMermaid } from "target path";
initializeMermaid();
document.addEventListener("astro:after-swap", () => {
initializeMermaid();
});
</script>
スタイリング
モジュールとして切り出して利用するのでもいい。
元々用意されているテーマから上書きする形でスタイルを作成。
Mermaidプレビューにはさまざまなフォーマットがあるため、必要な時に都度修正スタイルをしていく。
blog/id.astro (詳細ページ)
<style is:inline>
/* mermaid format */
.mermaid text {
fill: #fff !important;
}
.mermaid line {
fill: #fff !important;
stroke: #fff !important;
}
.mermaid path {
stroke: #fff !important;
}
.mermaid rect {
fill: #fff !important;
stroke: #fff !important;
}
.mermaid tspan {
fill: #fff !important;
}
.mermaid marker path {
fill: #fff !important;
stroke: #fff !important;
}
/* dark mode */
.dark .mermaid text {
fill: #ccc !important;
}
/* etc ... */
</style>
大変だったこと
テーマの変更時の色の反映
Mermaid側でテーマの管理をしようと思ったが、テーマを切り替えても動的にプレビューのコントラストも変更されるわけではないので、他のスタイルと同様にCSSを利用して管理した。
const mermaidThemeVariables = {
light: {
background: "#fff",
},
dark: {
background: "#ccc",
},
};
const currentThemeVariables =
theme === "dark"
? mermaidThemeVariables.dark
: mermaidThemeVariables.light;
mermaid.initialize({
startOnLoad: true,
themeVariables: currentThemeVariables,
});