やりたいこと
- Markdownで書いているmermaid形式ののflowchartをpng形式でexportする(そのまま)
- なおかつ、exportをbatを「ポン」とクリックするだけで実行する
環境
- Windows 7 64bit
- Git Bash
背景
- Markdownで仕様書を書いている中、「flowchartもMarkdownで書けないかなー」と思う
- mermaidを使えばflowchartが書けることが判明
- しかし、図として保存することができないことが判明
- というわけで何とかできないか?と思う
というわけで、色々調べたところできると判明
手順をまとめる
前提
今回Markdownで書いているドキュメントの構成を以下に示す
Top
│ ConvertAll.bat
│ output.docx
│
├─000_Cover
│ │ 00_Cover.md
│ │
│ └─image
│ 000_Cover.png
│
├─010_Chapter1
│ │ 00_Chapter1.md
│ │
│ └─image
│ 010_Chapter1.png
│
├─020_Chapter2
│ │ 00_Chapter2.md
│ │ 020_FlowChart1.mmd
│ │ 020_FlowChart2.mmd
│ │
│ └─image
│ 020_Chapter2.png
│ 020_FlowChart1.png
│ 020_FlowChart2.png
・
・
・
│
└─image
000_Cover.png
01_Chapter.png
020_Chapter1.png
020_Chapter2.png
利用手順は以下の通り(太字は今回追加する手順)
-
各フォルダを作成し、章ごとにドキュメントを作成する
- ドキュメントに使う画像は各image配下に格納する
- フローチャートは.mmdファイルで作成する
- .mmdファイルで作成したフローチャートは画像化(.png)し、imageフォルダに格納
- ドキュメントではあらかじめ、imageフォルダに画像があるものとして記述を行う
-
ドキュメント作成後、ConvertAll.batを実行し、word形式で出力する
-
word形式への変換はpandocを使用する
-
.mmdから.png変換はConvertAll.batで行う
-
-
これらは全てGitで管理し、変更をトレースできるようにしておく
Git Bashをインストールする
Git Bashが無い場合はインストールをする
インストールについては他の方の記事をご参考に
mermaidをインストールする
Git Bashを起動し、以下のコマンドを実行する
$ npm install -g mermaid
$ npm install -g mermaid.cli
または
$ yarn global add mermaid
$ yarn global add mermaid.cli
インストール先は以下のようになっている(と思う)ので、環境変数:Pathを通しておく
C:\Users\<your-user>\AppData\Roaming\npm
Pathを通したら、mmdc.cmdが実行できるかを確認する
コマンドプロンプトを立ち上げ、以下のコマンドを実行する
$ mmdc.cmd -V
バージョンが表示されればOK
これでmermaidのインストールは終わり
試しにファイルを変換してみてもいい
ファイルを変換するときのコマンドは以下の通り
$ mmdc.cmd -i input.mmd -o output.png
Markdownで書いたflowchartをpngに変換する
Markdownで書いたflowchartを先ほどのmmdc.cmdを使ってpngに直接変換することはできない
以下はmermaidで記述したフローチャートの例
~~~mermaid
graph LR
A[東京] -- 新幹線 --> B((大阪))
B -- 在来線--> C{奈良}
C--> |湯豆腐を食べに| E[京都]
C --> |ふぐ刺しを食べに| F[山口]
C --> |きれいな海を見に| G[和歌山]
C --> |合掌造りを見に| H[岐阜]
C --> |ゆっくり温泉に入りに| I[兵庫]
C --> |しまなみ街道を走りに| J[愛媛]
~~
この時、mmdc.cmdを使って変換をかける際に必要なのは2行目から10行目まで
つまり、ヘッダーとフッターの波線3つは不要になる
mmdc.cmdへファイルを投入する時には、このフッターとヘッターを削除する処理が必要となる
フッターとヘッターを削除する処理
元々コマンドプロンプトで行えないかと調査を実施
「最初の行を削除する」は可能だが、「最後の行を削除する」ができそうに無いため、他のツールを選ぶ
純粋の上記の処理をするだけならjavaでも良いが、以下の理由で却下
- ソースの差分しか管理できない
- 実行時にコンパイルの手間が入る
結局はVB Scriptを使用することに決定
下記のサイトが非常に参考になるため、ソースを使用させていただく
[ADODB.Stream で BOM なし UTF-8 のテキストファイルを書き出す ](http://neos21.hatenablog.com/entry/2016/03/27/231512)
ここに以下の処理を加えていく
- ファイル名を引数で受け取る
- 出力するファイル名を「元のmmdファイル名」拡張子は「.mmmd」で作る
- 元のファイルからヘッダー、フッターを抜いたファイルを作る
- imageフォルダ配下に出力する画像ファイル名を「元のmmdファイル名」拡張子は「.png」で作る
- .mmmdファイルをmmdc.cmdに叩き込み、.pngファイルにする
- 処理終了後、.mmmdファイルを削除する
以上の処理を組み込んだソースは以下の通り
CopyMMDFile.vbs
' 読み込みファイルはコマンドライン引数で受け取る
Dim fileName
fileName = Wscript.Arguments(0)
Dim input
Set input = CreateObject("ADODB.Stream")
input.Type = 2 ' 1:バイナリ・2:テキスト
input.Charset = "UTF-8" ' 文字コード指定
input.Open ' Stream オブジェクトを開く
input.LoadFromFile fileName ' ファイルを読み込む
' 一時書き出しファイルの指定 (テキストモードで BOM 付き UTF-8 を一時的に保持しておく)
Dim preOut
Set preOut = CreateObject("ADODB.Stream")
preOut.Type = 2
preOut.Charset = "UTF-8"
preOut.Open
' 読み込みファイルから1行ずつ読み込み、一時書き出しファイルに書き出すのを最終行まで繰り返す
Dim records
Do Until input.EOS
Dim lineStr
lineStr = input.ReadText(-2) ' -1:全行読み込み・-2:一行読み込み
If (0 = InStr(lineStr, "~~~")) Then
preOut.WriteText lineStr, 1 ' 0:文字列のみ書き込み・1:文字列 + 改行を書き込み
End If
Loop
' バイナリモードにする
preOut.Position = 0
preOut.Type = 1 'バイナリモードにする
preOut.Position = 3 ' 先頭3バイト = BOM をスキップする
' バイナリデータを読み込む
Dim bin
bin = preOut.Read ' バイナリモードでないと Read できない
' 書き出しファイルの指定 (読み込んだバイナリデータをバイナリデータとしてファイルに出力する)
Dim output
Set output = CreateObject("ADODB.Stream")
output.Type = 1
output.Open
output.Write(bin)
' 出力するファイル名を作成する
Dim fso
Set fso = CreateObject("Scripting.FileSystemObject")
Dim simpleFileName
simpleFileName = fso.GetBaseName(fileName)
Dim directoryName
directoryName = fso.GetParentFolderName(fileName)
Dim mmmdFileName
mmmdFileName = fso.BuildPath(directoryName, simpleFileName + ".mmmd")
Dim imageFileName
imageFileName = fso.BuildPath(directoryName, fso.BuildPath("image", simpleFileName + ".png"))
WScript.Echo imageFileName
' 書き出しファイルの保存
output.SaveToFile mmmdFileName , 2 ' 1:指定ファイルがなければ新規作成・2:ファイルがある場合は上書き
' Stream を閉じる
input.Close
preOut.Close
output.Close
' mmdc.cmd を実行する
Set objShell = CreateObject("WScript.Shell")
objShell.Run "mmdc.cmd -i " + mmmdFileName + " -o " + imageFileName + " > res.log", 0, true
' .mmmdファイルを削除する
fso.DeleteFile(mmmdFileName)
あとはConvertAll.batに全てのmmdファイルに対して、CopyMMDFile.vbsをコールするように追記
実行
いざ実行
実行前のファイル一覧
Top
│ ConvertAll.bat
│ CopyMMDFile.vbs
│
├─000_Cover
│ │ 00_Cover.md
│ │
│ └─image
│ 000_Cover.png
│
├─010_Chapter1
│ │ 00_Chapter1.md
│ │
│ └─image
│ 010_Chapter1.png
│
├─020_Chapter2
│ │ 00_Chapter2.md
│ │ 020_FlowChart.mmd
│ │
│ └─image
│ 020_Chapter2.png
│
└─image
変換対象のファイルは020_FlowChart.mmd
実行後のファイル一覧
Top
│ ConvertAll.bat
│ CopyMMDFile.vbs
│
├─000_Cover
│ │ 00_Cover.md
│ │
│ └─image
│ 000_Cover.png
│
├─010_Chapter1
│ │ 00_Chapter1.md
│ │
│ └─image
│ 010_Chapter1.png
│
├─020_Chapter2
│ │ 00_Chapter2.md
│ │ 020_FlowChart.mmd
│ │
│ └─image
│ 020_Chapter2.png
│ 020_FlowChart.png
│
└─image
000_Cover.png
010_Chapter1.png
020_Chapter2.png
020_FlowChart.png
020_FlowChart.pngが増えていることが確認できる
画像として出力できていることが確認できる
※間違い等ありましたらコメントにてご指摘お願いします!