『可愛くてごめん』フローチャートをMermaidで書いてみた

# 『可愛くてごめん』とは

* **可愛いこと**
* **あざといこと**
* **尊いこと**
* **目立っていること**

などを「Chu！」と可愛く謝った[HoneyWorks](http://ja.wikipedia.org/w/index.php?curid=4705207)さんの楽曲です。

# 『可愛くてごめん』フローチャートとは

歌詞フローチャートというものが存在します。こういうのです[^1]。

https://qiita.com/danishi/items/82e5739705cd7e8a79a2

この記事を読んでいたら『可愛くてごめん』でも書きたくなったので書いてみました。

```mermaid
graph TB;
    S([Start])-->1["私が私の事を愛して"]-->2["何が悪いの？嫉妬でしょうか？"]-->3["痛いだとか変わってるとか"]-->4["届きませんね。"];
4["届きませんね。"]-->5["そのリプライ"]-->6["大好きな"];
6["大好きな"]-->7["お洋服"]-->6["大好きな"];
6["大好きな"]-->8["お化粧で"]-->9["お決まりのハーフツイン巻いて"]-->10["お出かけしよ"];
10["お出かけしよ"]-->11["日傘持って"]-->12["ぼっちだって"]-->13["幸せだもん！"]-->14["Chu！可愛くてごめん"];
15["貴女は貴女の事だけどうぞ"]-->16["私に干渉しないでください"]-->17["類は友を呼ぶと言うけど…"]-->4["届きませんね。"];
4["届きませんね。"]-->18["その陰口"]-->19["重い厚底ブーツ"]-->20["お気に入りのリュックで"]-->21["崩せない前髪くしでといて"]-->10["お出かけしよ"];
10["お出かけしよ"]-->22["軽い女？"]-->23["ふざけんな"]-->24["重すぎるっつーの！"]-->14["Chu！可愛くてごめん"];
14["Chu！可愛くてごめん"]-->25["生まれてきちゃってごめん"]-->26["Chu！あざとくてごめん"];
14["Chu！可愛くてごめん"]-->27["努力しちゃっててごめん"]-->28["Chu！尊くてごめん"];
14["Chu！可愛くてごめん"]-->29["この時代生きてごめん"]-->30["Chu！目立っててごめん"];
14["Chu！可愛くてごめん"]-->31["自分磨きしてごめん"]-->32["Chu！ぶりっ子でごめん"];
26["Chu！あざとくてごめん"]-->33["気になっちゃうよね？ごめん"]-->14["Chu！可愛くてごめん"];
26["Chu！あざとくてごめん"]-->34["人生楽しんでごめん"]-->14["Chu！可愛くてごめん"];
30["Chu！目立っててごめん"]-->35["意識しちゃうよね？ごめん"]-->14["Chu！可愛くてごめん"];
28["Chu！尊くてごめん"]-->36["女子力高くてごめん"]-->37["ムカついちゃう"]-->38["よね？"]-->39["ざまあｗ"];
32["Chu！ぶりっ子でごめん"]-->40["虜にしちゃってごめん"]-->37["ムカついちゃう"]-->41["でしょ？"]-->39["ざまあｗ"];
39["ざまあｗ"]-->15["貴女は貴女の事だけどうぞ"];
39["ざまあｗ"]-->42["趣味の違い"]-->43["変わり者と"]-->44["バカにされても"]-->45["曲げたく"]-->46["ない"]-->47["怖くも"]-->46["ない"]-->48["あんたらごとき"]-->49["自分"]-->50["の味方は"]-->49["自分"]-->51["であり"]-->52["たい"]-->53["一番大切にしてあげ"]-->52["たい"]-->54["理不尽な我慢はさせたく"]-->46["ない"]-->55["“それが私”"]-->14["Chu！可愛くてごめん"];
39["ざまあｗ"]-->E([End]);
```
こう見ると、『可愛くてごめん』の歌詞はどこからどこへでも遷移できそうな割に、結構特定のパターンで成り立っていることがわかります。


やはりコード状態で読みやすくするためのインデントは悩ましいです。ただ、『可愛くてごめん』の歌詞には複雑な組み換えがないため、比較的見やすくまとまっていると思います。なお、後述する理由によりこのコードそのままではMermaidにエラーを吐かれます。

```:Mermaid
graph TB;
    S([Start])-->私が私の事を愛して-->何が悪いの？嫉妬でしょうか？-->痛いだとか変わってるとか-->届きませんね。;
        届きませんね。-->そのリプライ-->大好きな;
            大好きな-->お洋服-->大好きな;
            大好きな-->お化粧で-->お決まりのハーフツイン巻いて-->お出かけしよ;
        お出かけしよ-->日傘持って-->ぼっちだって-->幸せだもん！-->Chu！可愛くてごめん;
    貴女は貴女の事だけどうぞ-->私に干渉しないでください-->類は友を呼ぶと言うけど…-->届きませんね。;
        届きませんね。-->その陰口-->重い厚底ブーツ-->お気に入りのリュックで-->崩せない前髪くしでといて-->お出かけしよ;
        お出かけしよ-->軽い女？-->ふざけんな-->重すぎるっつーの！-->Chu！可愛くてごめん;
    Chu！可愛くてごめん-->生まれてきちゃってごめん-->Chu！あざとくてごめん;
    Chu！可愛くてごめん-->努力しちゃっててごめん-->Chu！尊くてごめん;
    Chu！可愛くてごめん-->この時代生きてごめん-->Chu！目立っててごめん;
    Chu！可愛くてごめん-->自分磨きしてごめん-->Chu！ぶりっ子でごめん;
    Chu！あざとくてごめん-->気になっちゃうよね？ごめん-->Chu！可愛くてごめん;
    Chu！あざとくてごめん-->人生楽しんでごめん-->Chu！可愛くてごめん;
    Chu！目立っててごめん-->意識しちゃうよね？ごめん-->Chu！可愛くてごめん;
    Chu！尊くてごめん-->女子力高くてごめん-->ムカついちゃう-->よね？-->ざまあｗ;
    Chu！ぶりっ子でごめん-->虜にしちゃってごめん-->ムカついちゃう-->でしょ？-->ざまあｗ;
    ざまあｗ-->貴女は貴女の事だけどうぞ;
    ざまあｗ-->趣味の違い-->変わり者と-->バカにされても-->曲げたく-->ない-->怖くも-->ない-->あんたらごとき-->自分-->の味方は-->自分-->であり-->たい-->一番大切にしてあげ-->たい-->理不尽な我慢はさせたく-->ない-->“それが私”-->Chu！可愛くてごめん;
    ざまあｗ-->E([End]);
```

# Mermaidに「Chu！」と言わせる

『それが大事』では歌詞直書きで表示できていたため、よく確認せずに直書き(上のコード)を作ったらエラーを吐かれました。うちのマーメイドは「Chu！」というのが恥ずかしいのかと思いましたが、ちゃんと理由があります。

## 直書きだと(全角含む)記号を表示できない

Mermaidで特殊文字を表示するためには、表示する文字をダブルクウォーテーション```""```で囲う必要があります。ただし、ダブルクウォーテーションは表示される図形の形を決める括弧（今回は```[]```）の中にある必要があり、さらに括弧を使う場合ノードに名前(id)を別でつける必要があります。

つまり、今回だとこのように書くことで問題なく表示できます。
```
1["Chu！可愛くてごめん"]-->2["生まれてきちゃってごめん"]-->3["Chu！あざとくてごめん"];
```
なお、ググると数値文字参照や文字実体参照が使えるとの情報が手に入りますが、これも試した感じ括弧無しでは機能しないことがあります。

## フローチャートの全ノードを自動でエスケープする

ただ、「？」や「！」などエスケープするべき記号を使っている箇所全部にこの変更を施すのは面倒です。それに加え、idでノードの同一性が判断されるため、idを全部一緒とか全部別にするとうまく表示できません。同じ文字列には同じidをつける必要があります。何より、全部を囲うと可読性が著しく下がります。

そこで、直書きしたノードを全部エスケープして、同じ文字列に同じidをつけるスクリプトをJavaScriptで書きました。即席で適当に書いたので基本的に今回の狭い書式にしか対応してません。万が一転用することがあれば適宜書き換えて使ってください。

```javascript:JavaScript
let count = 1;
const id = { 
    get(data){
        if(this[data]) return this[data];
        this[data] = count++;
        return this[data];
    }
};

console.log(歌詞.split(';\n').map(str=>str.split('-->').map(part=>`${id.get(part)}["${part}"]`).join('-->')).join(';\n'));
```
「;改行」で分割したのをさらに「-->」で分割してそれぞれを```id["``` ```"]```で囲んで結合し直してるだけです。歌詞の部分に、直書きしたコードの```S([Start])```と```E([End])```の間を文字列として入れれば動きます。

今回のフローチャートを表示させるコードは、最終的に次のようになりました。

```:Mermaid
graph TB;
    S([Start])-->1["私が私の事を愛して"]-->2["何が悪いの？嫉妬でしょうか？"]-->3["痛いだとか変わってるとか"]-->4["届きませんね。"];
        4["届きませんね。"]-->5["そのリプライ"]-->6["大好きな"];
            6["大好きな"]-->7["お洋服"]-->6["大好きな"];
            6["大好きな"]-->8["お化粧で"]-->9["お決まりのハーフツイン巻いて"]-->10["お出かけしよ"];
        10["お出かけしよ"]-->11["日傘持って"]-->12["ぼっちだって"]-->13["幸せだもん！"]-->14["Chu！可愛くてごめん"];
    15["貴女は貴女の事だけどうぞ"]-->16["私に干渉しないでください"]-->17["類は友を呼ぶと言うけど…"]-->4["届きませんね。"];
        4["届きませんね。"]-->18["その陰口"]-->19["重い厚底ブーツ"]-->20["お気に入りのリュックで"]-->21["崩せない前髪くしでといて"]-->10["お出かけしよ"];
        10["お出かけしよ"]-->22["軽い女？"]-->23["ふざけんな"]-->24["重すぎるっつーの！"]-->14["Chu！可愛くてごめん"];
    14["Chu！可愛くてごめん"]-->25["生まれてきちゃってごめん"]-->26["Chu！あざとくてごめん"];
    14["Chu！可愛くてごめん"]-->27["努力しちゃっててごめん"]-->28["Chu！尊くてごめん"];
    14["Chu！可愛くてごめん"]-->29["この時代生きてごめん"]-->30["Chu！目立っててごめん"];
    14["Chu！可愛くてごめん"]-->31["自分磨きしてごめん"]-->32["Chu！ぶりっ子でごめん"];
    26["Chu！あざとくてごめん"]-->33["気になっちゃうよね？ごめん"]-->14["Chu！可愛くてごめん"];
    26["Chu！あざとくてごめん"]-->34["人生楽しんでごめん"]-->14["Chu！可愛くてごめん"];
    30["Chu！目立っててごめん"]-->35["意識しちゃうよね？ごめん"]-->14["Chu！可愛くてごめん"];
    28["Chu！尊くてごめん"]-->36["女子力高くてごめん"]-->37["ムカついちゃう"]-->38["よね？"]-->39["ざまあｗ"];
    32["Chu！ぶりっ子でごめん"]-->40["虜にしちゃってごめん"]-->37["ムカついちゃう"]-->41["でしょ？"]-->39["ざまあｗ"];
    39["ざまあｗ"]-->15["貴女は貴女の事だけどうぞ"];
    39["ざまあｗ"]-->42["趣味の違い"]-->43["変わり者と"]-->44["バカにされても"]-->45["曲げたく"]-->46["ない"]-->47["怖くも"]-->46["ない"]-->48["あんたらごとき"]-->49["自分"]-->50["の味方は"]-->49["自分"]-->51["であり"]-->52["たい"]-->53["一番大切にしてあげ"]-->52["たい"]-->54["理不尽な我慢はさせたく"]-->46["ない"]-->55["“それが私”"]-->14["Chu！可愛くてごめん"];
    39["ざまあｗ"]-->E([End]);
```

# Chu！思いつきでごめん
正直Mermaidとか触ったことないのに、ネタ目的の不純な動機で思いつき一発で書き始めたら、思ったより時間取られました。

ゆえに良い書き方など理解が足りていないと思うので、ぜひご意見ください。

最後に、「Chu!」「ごめん」などを容赦無く独立させたフローチャートがどうなるのか、おまけに見ていってください。

```mermaid
graph TB;
S([Start])-->1["私が私の"]-->2["事"]-->3["を愛して"]-->4["何が悪いの？嫉妬でしょうか？"]-->5["痛いだとか変わってるとか"]-->6["届きませんね。"];
6["届きませんね。"]-->7["その"];
7["その"]-->8["リプライ"]-->9["大好きな"]-->10["お洋服"]-->9["大好きな"];
9["大好きな"]-->11["お化粧で"]-->12["お決まりのハーフツイン巻いて"]-->13["お出かけしよ"];
13["お出かけしよ"]-->14["日傘持って"]-->15["ぼっちだって"]-->16["幸せだもん！"]-->17["Chu！"];
17["Chu！"]-->18["可愛くて"]-->19["ごめん"];
19["ごめん"]-->20["生まれてきちゃって"]-->19["ごめん"];
19["ごめん"]-->17["Chu！"];
17["Chu！"]-->21["あざとくて"]-->19["ごめん"];
19["ごめん"]-->22["気になっちゃうよね？"]-->19["ごめん"];
19["ごめん"]-->23["努力しちゃってて"]-->19["ごめん"];
17["Chu！"]-->24["尊くて"]-->19["ごめん"];
19["ごめん"]-->25["女子力高くて"]-->19["ごめん"];
19["ごめん"]-->26["ムカついちゃうよね？"];
26["ムカついちゃうよね？"]-->27["ざまあｗ"];
27["ざまあｗ"]-->28["貴女は貴女の"]-->2["事"]-->29["だけどうぞ"]-->30["私に干渉しないでください"]-->31["類は友を呼ぶと言うけど…"]-->6["届きませんね。"];
7["その"]-->32["陰口"]-->33["重い厚底ブーツ"]-->34["お気に入りのリュックで"]-->35["崩せない前髪くしでといて"]-->13["お出かけしよ"];
13["お出かけしよ"]-->36["軽い女？"]-->37["ふざけんな"]-->38["重すぎるっつーの！"]-->17["Chu！"];
19["ごめん"]-->39["この時代生きて"]-->19["ごめん"];
17["Chu！"]-->40["目立ってて"]-->19["ごめん"];
19["ごめん"]-->41["意識しちゃうよね？"]-->19["ごめん"];
17["Chu！"]-->18["可愛くて"]-->19["ごめん"];
19["ごめん"]-->42["自分磨きして"]-->19["ごめん"];
17["Chu！"]-->43["ぶりっ子で"]-->19["ごめん"];
19["ごめん"]-->44["虜にしちゃって"]-->19["ごめん"];
19["ごめん"]-->45["ムカついちゃうでしょ？"]-->27["ざまあｗ"];
27["ざまあｗ"]-->46["趣味の違い"]-->47["変わり者と"]-->48["バカにされても"]-->49["曲げたく"]-->50["ない"]-->51["怖くも"]-->50["ない"]-->52["あんたらごとき"]-->53["自分の味方は自分であり"]-->54["たい"]-->55["一番大切にしてあげ"]-->54["たい"]-->56["理不尽な我慢はさせたく"]-->50["ない"]-->57["“それが私”"]-->17["Chu！"];
19["ごめん"]-->58["人生楽しんで"]-->19["ごめん"];
27["ざまあｗ"]-->E([End]);
```

# 参考
https://mermaid.js.org/syntax/flowchart.html

[^1]: 「歌詞フローチャート」などというジャンルがあるかは定かではありませんが、ググると『宙船』や『Hey Jude』など特定の楽曲のフローチャート[^2]は度々Twitterで話題になっているようです。

[^2]: 「これはフローチャートなのか」というコメントを頂きました。ごもっともです。