【更新もれ問題解決】手順書を書くなら Markdown Preview Enhanced を使おう

## はじめに
以前から vscode + Markdown Preview Enhanced(MPE) を愛用していましたが、`@import機能`で **手順書問題で頻出一位の課題(自分調べ)を解決**できそうなので記事を書きました。

## 手順書問題一位の課題
**『実際の設定ファイルと、手順書の内容があってない』**(自分調べ)

複雑な要因が絡み合って長年決定的な解決方法がない課題と認識しています。

1. ドキュメントにコストかけられない問題
1. 実装者が、実装で不都合があると設定項目が増えたり変更されたりする
1. ドキュメント担当者は変更に気づかない
1. slack などで通知されても、別の作業をやってて更新忘れる
1. 人間なのでそもそもミスする

これって **『実装者が実際に最後にコミットした設定ファイル』**をドキュメントにそのまま取り込めるなら **「ドキュメントに反映する」作業自体がなくなる**ので全て解決しませんか？
※そもそも動かないファイルがコミットされているなら、それは別途話し合いが必要
※本番用のファイルは間違っても`@import`しないでください

## 手順書ツール比較

ポピュラーな、テキスト、ワード、エクセルおよび、MPEを主観で比較してみました。

|機能|テキスト|ワード|エクセル|MPE
|---|---|---|---|---|
|記述の簡単さ|◎|△|△|◎
|git保存|◎|△|△|◎
|章立|△|○|△|○
|目次|×|○|×|○(Create TOC)
|図|×|○|○|○|
|図形|×|△|○|◎(draw.io)
|UML|×|△|△|◎(PlantUML)
|更新もれ対策|×|×|×|◎(`@import`)

実際に試験済みのファイルとdraw.ioの図形の取り込みができる事で、ワードやテキストベースの手順書に大きくリードした様に思います。

## Markdown Preview Enhanced(MPE)

[拡張機能：Markdown Preview Enhanced](https://marketplace.visualstudio.com/items?itemName=shd101wyy.markdown-preview-enhanced)
[公式サイト](https://shd101wyy.github.io/markdown-preview-enhanced/#/)

MPEは、vs code の拡張機能です。
Markdown で書いたドキュメントをプレビューする機能ですが、通常の Markdown よりも機能が増えたものになります。
今回は、手順書を書くのに役に立つと思われる以下2点の機能を紹介します。

1. less による styling
1. `@import`によるファイル取り込み

## less による styling

通常の Makdown は章番号がつきません。これは手順書や仕様書として致命的だと思います。
MPE では出力スタイルを定義できるので、章に対して章番号をつけるスタイルにすることが可能です。

以下の less ファイルをファイルの先頭で import すれば、章番号が付与されます。

``` style.less
.markdown-preview.markdown-preview {

    font-family: Meiryo, メイリオ;

    p {
        margin-bottom: .25rem;
        line-height: 1.4;
        font-size: .95rem;
        color: #444;
        text-indent: .5rem;
    }

    h1,
    h2,
    h3,
    h4,
    h5 {
        margin-bottom: .25rem;
        padding-bottom: 0;
        color: #222;
    }

    h1 {
        font-size: 1.5rem;
        font-weight: normal;
        counter-reset: h2SectionCounter;
    }

    h2 {
        font-size: 1.2rem;

        &:not(.toc) {
            counter-increment: h2SectionCounter;
            counter-reset: h3SectionCounter;
        }
    }

    h3 {
        font-size: 1.1rem;
        counter-increment: h3SectionCounter;
        counter-reset: h4SectionCounter;
    }

    h4 {
        font-size: 1.1rem;
        counter-increment: h4SectionCounter;
        counter-reset: h5SectionCounter;
    }

    h5 {
        font-size: 1rem;
        counter-increment: h5SectionCounter;
    }

    h2:not(.toc):before {
        content: counter(h2SectionCounter) ".";
    }

    h3:before {
        content: counter(h2SectionCounter) "."counter(h3SectionCounter) ".";
    }

    h4:before {
        content: counter(h2SectionCounter) "."counter(h3SectionCounter) "."counter(h4SectionCounter) ".";
    }

    h5:before {
        content: counter(h2SectionCounter) "."counter(h3SectionCounter) "."counter(h4SectionCounter) "."counter(h5SectionCounter) ".";
    }
}
```

## `@import`によるファイル取り込み

`@import "file-path"` で簡単に取り込めます。
実際にはここで紹介しているファイル以外にも取り込めますので、興味ある方は公式サイトを見てみてください。

[File Imports](https://shd101wyy.github.io/markdown-preview-enhanced/#/file-imports)

## サンプル

以下目次作成、ファイル取り込みについて記載したサンプルのmarkdownを出力したpng(pdf出力もできます)とソースを以下に記載します。
※サンプル中のコードブロックは、[```] を[''']に置換してます。

### サンプル出力
![sample.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136165/1d214a7f-b51a-85ba-7727-6dfd20fb8ade.png)


### フォルダ構成
```
│  sample.md
│  style.less
│  _environment.md
│
├─configs
│      sample.yaml
│
├─csvs
│      sample.csv
│
├─draws
│      sample.drawio.png
│
├─images
│      drawio-convert.png
│      drawio-drawio-png.png
│      drawio-editor.png
│      mpe-create-toc.png
│
└─scripts
        sample.sh
```


### ソース
``` sample.md
@import "./style.less"

# Markdown Preview Enhanced 便利機能

<!-- @import "[TOC]" {cmd="toc" depthFrom=2 depthTo=6 orderedList=true} -->

<!-- code_chunk_output -->

1. [自動更新目次](#自動更新目次)
2. [ファイルの挿入(基本)](#ファイルの挿入基本)
3. [drawio図形の挿入](#drawio図形の挿入)
4. [設定ファイルの挿入](#設定ファイルの挿入)
5. [PlantUML図形の挿入](#plantuml図形の挿入)
6. [Markdownの挿入](#markdownの挿入)

<!-- /code_chunk_output -->

## 自動更新目次

1. `ctrl + shift + p` でコマンドパレットを表示
2. Markdown Preview Enhanced: Create TOC を選択
@import "./images/mpe-create-toc.png"
3. カーソル行に以下の行が挿入され、以後自動更新される
'''
<!-- @import "[TOC]" {cmd="toc" depthFrom=1 depthTo=6 orderedList=false} -->
'''
4. depthFrom=1 で生成するが、`#`のタイトルも目次対象となるので、depthFrom=2 に修正する

## ファイルの挿入(基本)

`@import "ファイル名"`で挿入する。
拡張子に合わせて、画像、図、表、コードブロックとして取り込まれる。

例) `@import "./images/mpe-create-toc.png"`
@import "./images/mpe-create-toc.png"

例) `@import "./csvs/sample.csv"`
@import "./csvs/sample.csv"

## drawio図形の挿入

drawioファイルは mpe では直接取り込む事ができないが、【drawio.png】 は画像として取り込む事ができる。
手順書の冒頭には概要図を描く事が多いので大変重宝する。

1. [Draw.io Integration](https://marketplace.visualstudio.com/items?itemName=hediet.vscode-drawio)をインストール
2. 拡張子 .dio ファイルを作成する(例：test.dio)
3. VSCode で開くとdrawioの図形エディタが表示される
@import "./images/drawio-editor.png"
4. drawio.png に変換する
@import "./images/drawio-convert.png"
@import "./images/drawio-draio-png.png"
5. 他画像と同様に、import する。
@import "./draws/sample.drawio.png"

## 設定ファイルの挿入

sh や js ファイル等一部のファイルは import した際にコードとして認識してしまい内容が表示されない。
import 時に、コードブロックであることを明記および行番号の表示有無も指定して挿入する。

例)`@import "./scripts/sample.sh" {code_block=true class="line-numbers"}`
@import "./scripts/sample.sh" {code_block=true class="line-numbers"}

例)`@import "./configs/sample.yaml" {code_block=true class="line-numbers"}`
@import "./configs/sample.yaml" {code_block=true class="line-numbers"}

## PlantUML図形の挿入

他ファイル同様、import 文で挿入可能であるが、`puml`で始まるコードブロックを記述することで直接記述も可能。

'''puml
actor sample
participant A as "要素A"
participant B as "要素B"

sample -> A : コメント1
A -> B : コメント2
A <-- B : 戻り値1
sample <-- A : 戻り値1
'''

## Markdownの挿入

他ファイル同様、import 文で挿入可能。そのまま文章として展開される。

例) `@import "./_environment.md"`
@import "./_environment.md"

例) `@import "./_environment.md" {code_block=true}`
@import "./_environment.md" {code_block=true}

```

## おわりに

今後ドキュメント作成にかけられるコストは削減され続けるだろうと想像しています。
不要なドキュメントも存在はしていると思いますが、**『必要最低限の正しいドキュメント』**を作成しないと、目に見えづらい（＝正当なコストとしてお客様に請求しにくい）コストを激増させるリスクが生じます。（コミュニケーション・保守/運用・教育・…）

開発プロセス全体で見て、トータルのコストを下げる**『必要最低限の正しいドキュメント』**の模索は続けたいと思います。


## おまけ：トラブルシューティング

### PDF出力：中華フォントになる

style.less でフォント指定をしておき、Chorme(Puppeteer)→PDF で出力

### PDF出力：コードブロックの背景が白になる

style.less に以下追加

``` style.less
html {
    -webkit-print-color-adjust: exact;
}
```

### PlantUMLの画像が出力できない

graphviz がインストールされていないかも？

```
choco install graphviz
```