Mermaidに慣れたいためにMarpでMermaidを利用できるようにする備忘録
フローチャートなどを作る際にGoogleスライドやらFigmaやらで図を作ってはスクショコピーしてMarpに貼り付けという手順を踏んでいるわけですが、フローチャートに変更が入るとツールを切り替える手間をなんとかしたいというところ、これを機会にMermaidに慣れておこうというのがきっかけ。
メリットとしては他ツールを使わずにチャート図とかを作れるのはもちろん、Gitなどで管理するなら画像よりも何が変更されたのか分かりやすくなるので良い。
デメリットとしては、Mermaidを知らない人には編集するのは大変になるかもという点ぐらいでしょうか。
知らなくても図さえ視覚化できていればOKなら良いのかなと思ってます。
今回Marpを使っている理由については、基本技術的な資料についてはMarpで作ることが多いためです。
Marpはマークダウンでスライド資料が作れてVSCode拡張機能もありプレビューしながら編集できるので重宝しています。CSSでテーマをカスタムできますし、PDFやPPTなどにエクスポートできるのも良いですね。
Marp: https://marp.app/
今回はVSCodeでMarpを使用する際にMermaidを扱うための手順を試しながら、備忘録的に連ねます。
まず、VSCodeにはMarpの環境が備えます。
VSCode拡張機能があるのでインストールします。
Marp for VS Code: https://marketplace.visualstudio.com/items?itemName=marp-team.marp-vscode
インストールしたらMarp for VS CodeでHTMLを有効にします。
Shift + Ctrl(Cmd) + P でコマンドパレットから、>Preferences: Open User Settings
からmarkdown.marp.enableHtml
をTrueにします。
setttings.jsonから設定するなら"markdown.marp.enableHtml": true
を追記します。
デフォルトではHTMLを記載してもコードが表示されるだけなのでこれを有効にしてmermaidを囲う要素を用意しています。
実際にMermaidをMarpに書いてみます。
---
marp: true
---
<!-- Marpと認識させるおまじない -->
## Basic Pie Chart
<!-- class名をmermaidとした要素タグ内に出力するMermaidコードを記載 -->
<pre class="mermaid">
pie title What Voldemort doesn't have?
"FRIENDS" : 2
"FAMILY" : 3
"NOSE" : 45
</pre>
<!-- Mermaidを読み込み -->
<script type="module">
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@11.4.1/dist/mermaid.esm.min.mjs';
mermaid.initialize({ startOnLoad: true });
</script>
プレビューにMermaidが表示されなければ、コマンドパレットから>markdown: Change Preview Security Settings
で無効(Disabled)を選択してみるとJavaScriptが読み込まれ表示されます。
また、囲う要素タグは<pre>じゃないと変更した際に再リロードした際に正しくプレビューされなくなるようなので必ず<pre>を使う必要があるようです。
図が大きくなるとスライドからはみ出たりしますが、MarpのStyleを編集すれば対応は可能です。
とりあえずスライド一枚に大きく載せたい場合はこんな感じとか。
<style>
.mermaid {
width: 100%;
height: 100%;
background: none; // preタグの装飾消し
border: none // preタグの装飾消し
}
.mermaid svg {
display: block;
min-width: 100%;
max-width: 100%;
max-height: 100%;
margin: 0 auto
}
</style>
試しにMermaidのExampleを全て試してみました。
コピペでは表示されないものもありましたが、改行などが空いていると認識しないようですね。
あとはテキストサイズなど調整が必要かもしれないです。
---
marp: true
headingDivider: 2
---
<style>
.mermaid {
width: 100%;
height: 100%;
background: none;
border: none
}
.mermaid svg {
display: block;
min-width: 100%;
max-width: 100%;
max-height: 100%;
margin: 0 auto
}
</style>
# MarpでMermaidを扱いたい
Write: キド
## Basic Pie Chart
<pre class="mermaid">
pie title What Voldemort doesn't have?
"FRIENDS" : 2
"FAMILY" : 3
"NOSE" : 45
</pre>
## Basic sequence diagram
<pre class="mermaid">
sequenceDiagram
Alice ->> Bob: Hello Bob, how are you?
Bob-->>John: How about you John?
Bob--x Alice: I am good thanks!
Bob-x John: I am good thanks!
Note right of John: Bob thinks a long<br/>long time, so long<br/>that the text does<br/>not fit on a row.
Bob-->Alice: Checking with John...
Alice->John: Yes... John, how are you?
</pre>
## Basic flowchart
<pre class="mermaid">
graph LR
A[Square Rect] -- Link text --> B((Circle))
A --> C(Round Rect)
B --> D{Rhombus}
C --> D
</pre>
## Larger flowchart with some styling
<pre class="mermaid">
graph TB
sq[Square shape] --> ci((Circle shape))
subgraph A
od>Odd shape]-- Two line<br/>edge comment --> ro
di{Diamond with <br/> line break} -.-> ro(Rounded<br>square<br>shape)
di==>ro2(Rounded square shape)
end
%% Notice that no text in shape are added here instead that is appended further down
e --> od3>Really long text with linebreak<br>in an Odd shape]
%% Comments after double percent signs
e((Inner / circle<br>and some odd <br>special characters)) --> f(,.?!+-*ز)
cyr[Cyrillic]-->cyr2((Circle shape Начало));
classDef green fill:#9f6,stroke:#333,stroke-width:2px;
classDef orange fill:#f96,stroke:#333,stroke-width:4px;
class sq,e green
class di orange
</pre>
## SequenceDiagram: Loops, alt and opt
<pre class="mermaid">
sequenceDiagram
loop Daily query
Alice->>Bob: Hello Bob, how are you?
alt is sick
Bob->>Alice: Not so good :(
else is well
Bob->>Alice: Feeling fresh like a daisy
end
opt Extra response
Bob->>Alice: Thanks for asking
end
end
</pre>
## SequenceDiagram: Message to self in loop
<pre class="mermaid">
sequenceDiagram
participant Alice
participant Bob
Alice->>John: Hello John, how are you?
loop HealthCheck
John->>John: Fight against hypochondria
end
Note right of John: Rational thoughts<br/>prevail...
John-->>Alice: Great!
John->>Bob: How about you?
Bob-->>John: Jolly good!
</pre>
## Sequence Diagram: Blogging app service communication
<pre class="mermaid">
sequenceDiagram
participant web as Web Browser
participant blog as Blog Service
participant account as Account Service
participant mail as Mail Service
participant db as Storage
Note over web,db: The user must be logged in to submit blog posts
web->>+account: Logs in using credentials
account->>db: Query stored accounts
db->>account: Respond with query result
alt Credentials not found
account->>web: Invalid credentials
else Credentials found
account->>-web: Successfully logged in
Note over web,db: When the user is authenticated, they can now submit new posts
web->>+blog: Submit new post
blog->>db: Store post data
par Notifications
blog--)mail: Send mail to blog subscribers
blog--)db: Store in-site notifications
and Response
blog-->>-web: Successfully posted
end
end
</pre>
## A commit flow diagram.
<pre class="mermaid">
gitGraph:
commit "Ashish"
branch newbranch
checkout newbranch
commit id:"1111"
commit tag:"test"
checkout main
commit type: HIGHLIGHT
commit
merge newbranch
commit
branch b2
commit
</pre>
<script type="module">
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@11.4.1/dist/mermaid.esm.min.mjs';
mermaid.initialize({ startOnLoad: true });
</script>
Marp以外でMermaid使いならMarkdown Preview Mermaid Supportがあるのでこっちを使えます。
Markdown Preview Mermaid Support(以降、MPMS)を有効にしたままMarpのMermaidをみるとプレビューがMPMSでプレビューされてしまいます。
見た目的にはMPMSの方が綺麗なのですが、MarpでExportする際はMarp側で設定されたスタイルでエクスポートされるので差異が発生してしまうようです。
この場合は、Marp側とMPMS側のMermaidのスタイルを合わせる必要があります。
Marp
<script type="module">
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@11.4.1/dist/mermaid.esm.min.mjs';
mermaid.initialize({
startOnLoad: true,
theme: 'dark' // 使用するテーマを指定
});
</script>
MPMS(Markdown Preview Mermaid Support)
設定から使用するテーマを設定
Mermaidはいくつかテーマ用意されているので気に入ったものを使えそうです。