マーメイド#23 Mermaid CLIを使ってみる

**ひとりマーメイド23日目**
**Mermaid CLIを使ってみる**

## 概要
マーメイドエンジニアのひろきです。こんにちは。
最近流行り（流行らせたい）のマーメイドについて理解を深めていこうと思います。

この記事ではMermaid CLIの使い方を紹介します！

↓↓前回の記事はこちら

https://qiita.com/hirokiwa/items/7136e5c86fb85814a2a6

## Mermaid CLI とは
Mermaid CLI はコマンド操作でマーメイドの記述からダイアグラムを出力するツールです。

コマンドラインから簡単にpng, svg, pdfを出力することができます。

## マーメイド CLI の使い方
**インストール**

```ssh
npm install -g @mermaid-js/mermaid-cli
```

mmdファイル(またはmermaidファイル)にマーメイドを記述して保存します。
```mmd:test.mmd
graph TD
    A(start)-->B{true?}
    B--Yes-->C[process]
    B--No-->D[exception]
    C-->E(end)
    D-->E
```

**mmdファイルをpngに変換**
`-i`:入力するmmdファイル
`-o`:出力ファイル
```ssh
mmdc -i test.mmd -o test.png
```
コマンドを実行するとpngファイルが出力されます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2293026/5da5846e-7a42-8b14-f344-39396f516122.png" width=400px>

出力されたpngがこちら
![test.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2293026/3e29ea3e-ab5f-cef5-ff60-0bb0db0b5524.png)

**mmdファイルをsvgに変換**
同様にsvgを出力します。
```ssh
mmdc -i test.mmd -o test.svg
```
svgファイルが保存されました。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2293026/19fb1672-5dd7-a2b5-37b1-d5b1ceeecd08.png" width=400px>

出力されたsvgがこちら
```html:test.svg
<svg id="mermaid-1671938938733" width="100%" xmlns="http://www.w3.org/2000/svg" style="max-width: 229.875px;" viewBox="0 0 229.875 386.4156265258789"><style>#mermaid-1671938938733 .label{font-family:trebuchet ms,verdana,arial;color:#333}#mermaid-1671938938733 .node circle,#mermaid-1671938938733 .node ellipse,#mermaid-1671938938733 .node polygon,#mermaid-1671938938733 .node rect{fill:#ececff;stroke:#9370db;stroke-width:1px}#mermaid-1671938938733 .node.clickable{cursor:pointer}#mermaid-1671938938733 .arrowheadPath{fill:#333}#mermaid-1671938938733 .edgePath .path{stroke:#333;stroke-width:1.5px}#mermaid-1671938938733 .edgeLabel{background-color:#e8e8e8}#mermaid-1671938938733 .cluster rect{fill:#ffffde!important;stroke:#aa3!important;stroke-width:1px!important}#mermaid-1671938938733 .cluster text{fill:#333}#mermaid-1671938938733 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:trebuchet ms,verdana,arial;font-size:12px;background:#ffffde;border:1px solid #aa3;border-radius:2px;pointer-events:none;z-index:100}#mermaid-1671938938733 .actor{stroke:#ccf;fill:#ececff}#mermaid-1671938938733 text.actor{fill:#000;stroke:none}#mermaid-1671938938733 .actor-line{stroke:grey}#mermaid-1671938938733 .messageLine0{marker-end:"url(#arrowhead)"}#mermaid-1671938938733 .messageLine0,#mermaid-1671938938733 .messageLine1{stroke-width:1.5;stroke-dasharray:"2 2";stroke:#333}#mermaid-1671938938733 #arrowhead{fill:#333}#mermaid-1671938938733 #crosshead path{fill:#333!important;stroke:#333!important}#mermaid-1671938938733 .messageText{fill:#333;stroke:none}#mermaid-1671938938733 .labelBox{stroke:#ccf;fill:#ececff}#mermaid-1671938938733 .labelText,#mermaid-1671938938733 .loopText{fill:#000;stroke:none}#mermaid-1671938938733 .loopLine{stroke-width:2;stroke-dasharray:"2 2";marker-end:"url(#arrowhead)";stroke:#ccf}#mermaid-1671938938733 .note{stroke:#aa3;fill:#fff5ad}#mermaid-1671938938733 .noteText{fill:#000;stroke:none;font-family:trebuchet ms,verdana,arial;font-size:14px}#mermaid-1671938938733 .section{stroke:none;opacity:.2}#mermaid-1671938938733 .section0{fill:rgba(102,102,255,.49)}#mermaid-1671938938733 .section2{fill:#fff400}#mermaid-1671938938733 .section1,#mermaid-1671938938733 .section3{fill:#fff;opacity:.2}#mermaid-1671938938733 .sectionTitle0,#mermaid-1671938938733 .sectionTitle1,#mermaid-1671938938733 .sectionTitle2,#mermaid-1671938938733 .sectionTitle3{fill:#333}#mermaid-1671938938733 .sectionTitle{text-anchor:start;font-size:11px;text-height:14px}#mermaid-1671938938733 .grid .tick{stroke:#d3d3d3;opacity:.3;shape-rendering:crispEdges}#mermaid-1671938938733 .grid path{stroke-width:0}#mermaid-1671938938733 .today{fill:none;stroke:red;stroke-width:2px}#mermaid-1671938938733 .task{stroke-width:2}#mermaid-1671938938733 .taskText{text-anchor:middle;font-size:11px}#mermaid-1671938938733 .taskTextOutsideRight{fill:#000;text-anchor:start;font-size:11px}#mermaid-1671938938733 .taskTextOutsideLeft{fill:#000;text-anchor:end;font-size:11px}#mermaid-1671938938733 .taskText0,#mermaid-1671938938733 .taskText1,#mermaid-1671938938733 .taskText2,#mermaid-1671938938733 .taskText3{fill:#fff}#mermaid-1671938938733 .task0,#mermaid-1671938938733 .task1,#mermaid-1671938938733 .task2,#mermaid-1671938938733 .task3{fill:#8a90dd;stroke:#534fbc}#mermaid-1671938938733 .taskTextOutside0,#mermaid-1671938938733 .taskTextOutside1,#mermaid-1671938938733 .taskTextOutside2,#mermaid-1671938938733 .taskTextOutside3{fill:#000}#mermaid-1671938938733 .active0,#mermaid-1671938938733 .active1,#mermaid-1671938938733 .active2,#mermaid-1671938938733 .active3{fill:#bfc7ff;stroke:#534fbc}#mermaid-1671938938733 .activeText0,#mermaid-1671938938733 .activeText1,#mermaid-1671938938733 .activeText2,#mermaid-1671938938733 .activeText3{fill:#000!important}#mermaid-1671938938733 .done0,#mermaid-1671938938733 .done1,#mermaid-1671938938733 .done2,#mermaid-1671938938733 .done3{stroke:grey;fill:#d3d3d3;stroke-width:2}#mermaid-1671938938733 .doneText0,#mermaid-1671938938733 .doneText1,#mermaid-1671938938733 .doneText2,#mermaid-1671938938733 .doneText3{fill:#000!important}#mermaid-1671938938733 .crit0,#mermaid-1671938938733 .crit1,#mermaid-1671938938733 .crit2,#mermaid-1671938938733 .crit3{stroke:#f88;fill:red;stroke-width:2}#mermaid-1671938938733 .activeCrit0,#mermaid-1671938938733 .activeCrit1,#mermaid-1671938938733 .activeCrit2,#mermaid-1671938938733 .activeCrit3{stroke:#f88;fill:#bfc7ff;stroke-width:2}#mermaid-1671938938733 .doneCrit0,#mermaid-1671938938733 .doneCrit1,#mermaid-1671938938733 .doneCrit2,#mermaid-1671938938733 .doneCrit3{stroke:#f88;fill:#d3d3d3;stroke-width:2;cursor:pointer;shape-rendering:crispEdges}#mermaid-1671938938733 .activeCritText0,#mermaid-1671938938733 .activeCritText1,#mermaid-1671938938733 .activeCritText2,#mermaid-1671938938733 .activeCritText3,#mermaid-1671938938733 .doneCritText0,#mermaid-1671938938733 .doneCritText1,#mermaid-1671938938733 .doneCritText2,#mermaid-1671938938733 .doneCritText3{fill:#000!important}#mermaid-1671938938733 .titleText{text-anchor:middle;font-size:18px;fill:#000}#mermaid-1671938938733 g.classGroup text{fill:#9370db;stroke:none;font-family:trebuchet ms,verdana,arial;font-size:10px}#mermaid-1671938938733 g.classGroup rect{fill:#ececff;stroke:#9370db}#mermaid-1671938938733 g.classGroup line{stroke:#9370db;stroke-width:1}#mermaid-1671938938733 .classLabel .box{stroke:none;stroke-width:0;fill:#ececff;opacity:.5}#mermaid-1671938938733 .classLabel .label{fill:#9370db;font-size:10px}#mermaid-1671938938733 .relation{stroke:#9370db;stroke-width:1;fill:none}#mermaid-1671938938733 #compositionEnd,#mermaid-1671938938733 #compositionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-1671938938733 #aggregationEnd,#mermaid-1671938938733 #aggregationStart{fill:#ececff;stroke:#9370db;stroke-width:1}#mermaid-1671938938733 #dependencyEnd,#mermaid-1671938938733 #dependencyStart,#mermaid-1671938938733 #extensionEnd,#mermaid-1671938938733 #extensionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-1671938938733 .branch-label,#mermaid-1671938938733 .commit-id,#mermaid-1671938938733 .commit-msg{fill:#d3d3d3;color:#d3d3d3}</style><style>#mermaid-1671938938733 {
    color: rgb(0, 0, 0);
    font: normal normal 400 normal 16px / normal "Times New Roman";
}</style><g transform="translate(-12, -12)"><g class="output"><g class="clusters"></g><g class="edgePaths"><g class="edgePath" style="opacity: 1;"><path class="path" d="M122.6328125,59L122.6328125,84L123.13281249999999,109.50000076293945" marker-end="url(#arrowhead21)" style="fill:none"></path><defs><marker id="arrowhead21" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M103.38618459260353,175.168997855543L56.6640625,228.4156265258789L56.6640625,262.4156265258789" marker-end="url(#arrowhead22)" style="fill:none"></path><defs><marker id="arrowhead22" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M142.87943970188235,175.1689970351781L188.6015625,228.4156265258789L188.6015625,262.4156265258789" marker-end="url(#arrowhead23)" style="fill:none"></path><defs><marker id="arrowhead23" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M56.6640625,301.4156265258789L56.6640625,326.4156265258789L99.4375,355.2689543326056" marker-end="url(#arrowhead24)" style="fill:none"></path><defs><marker id="arrowhead24" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M188.6015625,301.4156265258789L188.6015625,326.4156265258789L145.828125,355.2689543326056" marker-end="url(#arrowhead25)" style="fill:none"></path><defs><marker id="arrowhead25" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g></g><g class="edgeLabels"><g class="edgeLabel" style="opacity: 1;" transform=""><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" style="opacity: 1;" transform="translate(56.6640625,228.4156265258789)"><g transform="translate(-11.640625,-9)" class="label"><foreignObject width="23.28125" height="18"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel">Yes</span></div></foreignObject></g></g><g class="edgeLabel" style="opacity: 1;" transform="translate(188.6015625,228.4156265258789)"><g transform="translate(-9.78125,-9)" class="label"><foreignObject width="19.5625" height="18"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel">No</span></div></foreignObject></g></g><g class="edgeLabel" style="opacity: 1;" transform=""><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" style="opacity: 1;" transform=""><g transform="translate(0,0)" class="label"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span class="edgeLabel"></span></div></foreignObject></g></g></g><g class="nodes"><g class="node" id="A" transform="translate(122.6328125,39.5)" style="opacity: 1;"><rect rx="5" ry="5" x="-26.8984375" y="-19.5" width="53.796875" height="39"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-16.8984375,-9.5)"><foreignObject width="33.796875" height="19"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;">start</div></foreignObject></g></g></g><g class="node" id="B" transform="translate(122.6328125,151.70781326293945)" style="opacity: 1;"><polygon points="42.7078125,0 85.415625,-42.7078125 42.7078125,-85.415625 0,-42.7078125" rx="5" ry="5" transform="translate(-42.7078125,42.7078125)"></polygon><g class="label" transform="translate(0,0)"><g transform="translate(-17.953125,-9.5)"><foreignObject width="35.90625" height="19"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;">true?</div></foreignObject></g></g></g><g class="node" id="C" transform="translate(56.6640625,281.9156265258789)" style="opacity: 1;"><rect rx="0" ry="0" x="-36.6640625" y="-19.5" width="73.328125" height="39"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-26.6640625,-9.5)"><foreignObject width="53.328125" height="19"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;">process</div></foreignObject></g></g></g><g class="node" id="D" transform="translate(188.6015625,281.9156265258789)" style="opacity: 1;"><rect rx="0" ry="0" x="-45.2734375" y="-19.5" width="90.546875" height="39"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-35.2734375,-9.5)"><foreignObject width="70.546875" height="19"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;">exception</div></foreignObject></g></g></g><g class="node" id="E" transform="translate(122.6328125,370.9156265258789)" style="opacity: 1;"><rect rx="5" ry="5" x="-23.1953125" y="-19.5" width="46.390625" height="39"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-13.1953125,-9.5)"><foreignObject width="26.390625" height="19"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;">end</div></foreignObject></g></g></g></g></g></g></svg>
```
**mmdファイルをpdfに変換**
同様にpdfを出力します。
```ssh
mmdc -i test.mmd -o test.pdf
```
pdfファイルが保存されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2293026/1f0c3a40-e8b3-5dcd-ef5a-44fbff94829f.png)

出力されたpdfがこちら
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2293026/e3041d51-8728-f706-c37f-c4b6b5eb14dd.png)

## オプション
ダイアグラムのスタイリングをオプションで指定することができます。

**テーマ**
`-t`でダイアグラムのテーマを指定します。ディレクティブの`theme`と同様です。
```ssh
mmdc -i test.mmd -o forest.png -t forest
```
![forest.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2293026/f08623c3-0f46-2137-a54e-8e932e534eca.png)

**背景**
`-b`で背景の色を指定します。
```ssh
mmdc -i test.mmd -o background.png -b #00FF00
```
フローチャートをクロマキー合成したいときに使えます。
![background.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2293026/4dd992f3-6c1b-ac87-6874-4aff3c901282.png)


## まとめ
Mermaid CLI を使うとでコマンドラインから簡単にダイアグラムを出力することができます。

さらに詳しい仕様は以下を参照してください。

https://github.com/mermaid-js/mermaid-cli#readme

↓↓ 次回の記事はこちら！！

https://qiita.com/hirokiwa/items/b4666c4feacb3457b5cc

## 参考

https://mermaid.js.org