「便利ページ:Javascriptでちょっとした便利な機能を作ってみた」のシリーズものです。
十徳ナイフのような「DevToys」というのがあるようで、Javascriptのみで十徳ナイフを作ってきた私としては、気になる存在。
YAMLとJSON間を変換してくれる機能があるそうで、私もJavascriptで作ってみました。
ソースコード一式は以下のGitHubにあります。
poruruba/utilities
単に使うだけの場合は以下を参照してください。ユーティリティタブからYAMLを選択してください。
#YAML変換ライブラリ
以下のライブラリを使わせていただきました。
CDNはこちらにありました。
<script src="https://cdn.jsdelivr.net/npm/yamljs@0.3.0/dist/yaml.min.js"></script>
YAML文字列をパースして、Javascriptオブジェクトを生成するには以下のように呼び出します。
nativeObject = YAML.parse(yamlString);
逆に、JavascriptオブジェクトをYAML文字列にするには以下のように呼び出します。
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;
}
},
}
};
以上