YAML で画面設計書を書いて Markdown で出力する

タイトルの内容をこうやってみましたというレポートです。

## 経緯
- 小さめ(画面10未満)・比較的単純なWebアプリ案件の設計書を記述する必要あり
- 設計書のフォーマット・ファイル形式に指定はなし、ファイル出力の必要もなし
- 好きにやっていいとの指示

## 希望
- Word や Excel で書きたくない
- テキストベースで書いて、リポジトリ管理したい
- ソースと配置をなるべく分けたくない
  - ソースはGitLab リポジトリで管理

## 案
- GitLab の Wiki に Markdown で記述する


### 懸念点
- Markdown では、画面設計書に必要な以下の内容を記述しにくい
  - 表形式
  - 定まったフォーマット(記述の自由度が高い)

## 打開策
- 内容は、YAML で記述する
- 表形式など表示を見やすくするために、YAML を読み込んで Markdown に変換する

### YAML とは
人間が扱いやすい、構造化データ・オブジェクトを記述するためのデータ形式
[公式](https://yaml.org/)

Swagger Spec の記述形式としても有名ですね。
Swagger Editorみたいな感じで、画面設計書も記述できるといいなーと思ったのが、今回の試みの発端です。


#### YAML が設計書の記述に合っているところ
  - 階層構造が記述できる
  - データが型を持つ
  - 改行を含んだデータを含めることができ、わかりやすく記述できる
  - JSON Schemaが設定できる

### JSON Schema とは？

- JSONの記述フォーマットを定義したもの
[公式](https://yaml.org/)

- IDEに設定することで、入力補助やバリデーションチェックに利用できる
- VSCode では、Extension [YAML](https://marketplace.visualstudio.com/items?itemName=redhat.vscode-YAML) を使うことで、YAML のスキーマとして用いることができる


## やったこと
### JSON Schema を作成
1.　作成したいYAMLを一部分作成する
画面設計書なので画面要素１つ分の記述とか 

2.　1. で作成したYAML を JSON に変換する
Webサービス [yaml2json](http://phiary.me/yaml2json/) を利用
![tQir2RbFy-chrome_2019-08-26_14-06-47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4608/d9402bec-d3dd-c88d-8e06-a7bf77260920.png)


3.　2. で作成したJSONを元に、JSON Schema を作成
Webサービス [JSON schema.neat](https://jsonschema.net/)を利用
入力した値を元にSchemaのスケルトンを作ってくれる
![DlXN-yZ6f-chrome_2019-08-26_14-11-35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4608/b0224f23-e54c-00b9-3b79-b36d4254375f.png)




  

### JSON Schema を VSCodeに設定
1. Extension [YAML](https://marketplace.visualstudio.com/items?itemName=redhat.vscode-yaml) を追加する
2. YAMLのsetting にJSON Schema を設定する


```setting.json
{
  "yaml.completion": true,
  "yaml.validate": true,
  "yaml.hover": true,
  "yaml.schemas": {
    "./screen.json": [
      "*.yml",
    ],
  },
  "yaml.format.enable": true,
}
```
手順は [VSCodeで快適に設定ファイルを書く](https://qiita.com/uzuna/items/3f8ae7775b2136fffc7f) 参照

### 画面設計書(YAML)を書く

VSCode で YAML をゴリゴリ書いていきます。

- Ctrl + space で入力補助がでます！(捗る！)
- Scheme と合わない記述については、エラー表示されます
- 入力パターンなど、Schema に追加したほうがよい内容は随時追加する　→　エラーが出るのでつぶしていく、の繰り返しで進めていきます
![R1sgPKJZt-Code_2019-08-26_14-28-37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4608/a1ac6602-7f32-ddbd-969f-bca773bc120a.png)

### YAMLをMarkdown に変換する

YAMLを読み込み、テンプレートを埋めて出力するスクリプト書きました

- JavaScriptで記述、Node.js上で実行
- npmライブラリ
  - [js-yaml](https://github.com/nodeca/js-yaml) YAMLを読み込んで JavaScript Objectとして取得する
  - [handlebars](https://handlebarsjs.com/) JavaScript Object を使ったテンプレートエンジン
- https://github.com/N0NamedGuy/yaml2html/blob/master/yaml2html を参考に


#### テンプレート
Markdown形式のテンプレートを作成します
記述しやすくするため、YAMLのキー名を日本語にしてたんですが、テンプレートでもそのまま参照できました

```screen.hbs

# {{画面名}}
{{説明}}

## 画面イメージ
![]({{画像path}})

## 画面項目

  {{#each 画面項目}}

---

### {{名称}} ({{id}})

| ラベル     | 種類     | 入出力区分     | 表示／非表示     | 入力可／入力不可     | 型     | 桁数                                                                                | 表示フォーマット                       | 入力チェック    |
| ------- | ------ | --------- | ---------- | ------------ | ----- | --------------------------------------------------------------------------------- | ------------------------------ | ---------- |
| {{ラベル}} | {{種類}} | {{入出力区分}} | {{表示／非表示}} | {{入力可／入力不可}} | {{型}} | {{#with 桁数}}{{#if min}} 最小:{{min}}{{/if}}{{#if max}}最大:{{max}}{{/if}}{{/with}} |  {{表示フォーマット}}  | {{入力チェック}} |
 
 {{#if 初期表示}}
 #### 初期表示

{{初期表示}}
 {{/if}}
 

 {{#if 説明}}
 #### 説明

{{説明}}
 {{/if}}

{{#if 備考}}
 #### 備考

{{備考}}
 {{/if}}

{{/each}}
```


## 感想
### よかった点
- 設計書書く時に、バリデーションチェックかかるのめっちゃいい
    - Schemaファイルを修正すると、すべての設計書で都度検証かかることで、記述が揃う
- YAMLは複数行の文字列を入れやすい＆見やすいので、設計書の主な記述である、表形式・自由記述のいずれの形式にも対応できる
    - ここにMarkdown入れられるので、記述効率も上がる(アウトラインは使えないけど、箇条書き・表形式など)



```yml:screen.yml

イベント:
  - id: init 
    名称: 初期処理
    項目id: 
    操作区分: その他
    画面遷移: 
    処理ID:
    入力:
    出力: 
    説明: | 
      - マスタデータ(Master)を用いて、紐づく入力項目の選択肢を生成する
      - 初期値を設定する
        - 画面入力情報が無い場合は、空白 or 初期表示の値を設定する
        - 画面入力情報が既にある場合は、該当する項目に保存されている値を表示する
```

### いまいちな点
- 一通り記述した後、ちょっとだけ修正したい時に、変換するのが面倒くさい・忘れがち
    - 何かでファイルの修正を感知してコマンド実行する的なものを仕込めば解決しそうだけど、今回至りませんでした…

### 今後やってみたいこと
- 決まったキーワードと遷移先を定義しておいて、自動でリンク作成する的なこと
    - 設計書の相互参照って便利だしWikiの特性だと思うので使えるようにしてみたい
- pdf に出力


## 参考
### YAML書き方
https://qiita.com/tfrcm/items/5f8e4c5795ce41b214d1#%E3%82%B7%E3%83%BC%E3%82%B1%E3%83%B3%E3%82%B9%E9%85%8D%E5%88%97
https://magazine.rubyist.net/articles/0009/0009-YAML.html

### JSON Schema書き方
https://www.ikemo3.com/manual/json-schema/
https://qiita.com/arumi8go/items/a9530cbd39ff545a7bbb

### handlebars書き方
https://qiita.com/sassy_watson/items/f9947624876bf75a9eff