便利ページ：JavascriptでYAMLからJSONに変換

「[便利ページ：Javascriptでちょっとした便利な機能を作ってみた](https://qiita.com/poruruba/items/6c67c7eef34ed302feb3 )」のシリーズものです。

十徳ナイフのような「[DevToys](https://forest.watch.impress.co.jp/docs/news/1382919.html)」というのがあるようで、Javascriptのみで十徳ナイフを作ってきた私としては、気になる存在。
YAMLとJSON間を変換してくれる機能があるそうで、私もJavascriptで作ってみました。

ソースコード一式は以下のGitHubにあります。

poruruba/utilities

https://github.com/poruruba/utilities

単に使うだけの場合は以下を参照してください。ユーティリティタブからYAMLを選択してください。

https://poruruba.github.io/utilities/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261826/642521df-9101-ddfb-83c8-266c460a4f87.png)

#YAML変換ライブラリ

以下のライブラリを使わせていただきました。

https://github.com/jeremyfa/yaml.js

CDNはこちらにありました。

```html
	<script src="https://cdn.jsdelivr.net/npm/yamljs@0.3.0/dist/yaml.min.js"></script>
```

YAML文字列をパースして、Javascriptオブジェクトを生成するには以下のように呼び出します。

```js
nativeObject = YAML.parse(yamlString);
```

逆に、JavascriptオブジェクトをYAML文字列にするには以下のように呼び出します。

```js
yamlString = YAML.stringify(nativeObject, depth);
```

JSONは、もともと ```JSON.stringify``` と ```JSON.parse``` があるのでそれと組み合わせれば、相互に変換できるというわけです。

HTML上から変換できるようにしたソース一式を以下に示します。Vue2.0を使っています。

```js\comp_yaml.js
export default {
  mixins: [mixins_bootstrap],
  template: `
<div>
  <h2 class="modal-header">YAML</h2>
  <div class="row align-items-center">
    <div class="col-auto">
      <select class="form-select" v-model="yaml_dir_type" v-on:change="yaml_dir_change">
        <option value="yaml2json">YAML⇒JSON</option>
        <option value="json2yaml">JSON⇒YAML</option>
      </select>
    </div>
    <button class="btn btn-primary btn-lg col-auto" v-on:click="yaml_transform(false)">変換</button>
    <label class="title col-auto">yaml_depth</label>
    <div class="col-auto">
      <input type="number" class="form-control" v-model="yaml_depth">
    </div>
  </div>
  <br>
  <div class="row">
    <div class="col-sm-6">
      <label class="title">{{yaml_left_type}}</label>
      <textarea id="left_text" class="form-control" rows="15" v-model="yaml_left_text"></textarea>
    </div>
    <div class="col-sm-6">
      <label class="title">{{yaml_right_type}}</label>
      <textarea id="right_text" class="form-control" rows="15" v-model="yaml_right_text" readonly></textarea>
    </div>
  </div>
  <br>
  <div class="row">
    <div class="col-sm-5">
      <label class="title">{{yaml_left_type}}</label>
      <textarea id="left_parts" class="form-control" rows="6" v-model="yaml_left_parts"></textarea>
    </div>
    <span class="btn-group-vertical col-sm-1">
      <table>
        <tr><td>
          <button class="btn btn-secondary btn-lg" v-on:click="yaml_transform_parts(false)">→</button>
        </td></tr>
        <tr><td>
          <button class="btn btn-secondary btn-lg" v-on:click="yaml_transform_parts(true)">←</button>
        </td></tr>
      </table>
    </span>
    <div class="col-sm-6">
      <label class="title">{{yaml_right_type}}</label>
      <textarea id="right_parts" class="form-control" rows="6" v-model="yaml_right_parts"></textarea>
    </div>
  </div>
</div>`,
  data: function () {
    return {
      yaml_left_text: '',
      yaml_right_text: '',
      yaml_left_parts: '',
      yaml_right_parts: '',
      yaml_dir_type: "yaml2json",
      yaml_left_type: "YAML",
      yaml_right_type: "JSON",
      yaml_depth: 10,
    }
  },
  methods: {
    /* YAML */
    yaml_dir_change: function(){
      if( this.yaml_dir_type == "yaml2json" ){
        this.yaml_left_type = "YAML";
        this.yaml_right_type = "JSON";
      }else{
        this.yaml_left_type = "JSON";
        this.yaml_right_type = "YAML";
      }
    },
    yaml_transform: function(to_left_dir){
      if( !to_left_dir && this.yaml_dir_type == "yaml2json"){
        var object = YAML.parse(this.yaml_left_text);
        this.yaml_right_text = JSON.stringify(object, null , "\t");
      }else{
        var object = JSON.parse(this.yaml_left_text);
        this.yaml_right_text = YAML.stringify(object, this.yaml_depth);
      }
      var left_text = document.querySelector("#left_text");
      var right_text = document.querySelector("#right_text");
      right_text.style.height = left_text.style.height;
    },
    yaml_transform_parts: function(to_left_dir){
      if( !to_left_dir ){
        if( this.yaml_dir_type == "yaml2json" ){
          var object = YAML.parse(this.yaml_left_parts);
          this.yaml_right_parts = JSON.stringify(object, null , "\t");
        }else{
          var object = JSON.parse(this.yaml_left_parts);
          this.yaml_right_parts = YAML.stringify(object, this.yaml_depth);
        }
        var left_parts = document.querySelector("#left_parts");
        var right_parts = document.querySelector("#right_parts");
        right_parts.style.height = left_parts.style.height;
      }else{
        if( this.yaml_dir_type == "yaml2json" ){
          var object = JSON.parse(this.yaml_right_parts);
          this.yaml_left_parts = YAML.stringify(object, this.yaml_depth);
        }else{
          var object = YAML.parse(this.yaml_right_parts);
          this.yaml_left_parts = JSON.stringify(object, null , "\t");
        }
        var left_parts = document.querySelector("#left_parts");
        var right_parts = document.querySelector("#right_parts");
        left_parts.style.height = right_parts.style.height;
      }
    },
  }
}; 
```

以上