プレーンテキストをHTML形式へ変換するツールをつくってみます。
今回は、Webページでテキストをコピペできるとうれしいため、手軽にリアクティブだかなんだかができるVue.jsを使うことにしましょう。
環境準備もめんどくさいので、CDNのVue.jsを使う方法にします。
入出力欄
<div class="cols3">
<div>
Input Form
</div>
<div>
Monitor
</div>
<div>
Output Form
</div>
<div id="inputForm">
<textarea v-model="inputText"></textarea>
</div>
<div id="monitor" v-html="convertedText"></div>
<div>
<textarea v-model="convertedText"></textarea>
</div>
</div>
このように3カラムの入出力欄を設け、それぞれの欄に変数をバインディングします。
inputText: プレーンテキスト(入力値)
convertedText: HTML形式テキスト(出力値)
一列目はプレーンテキストを貼り付ける場所、三列目は変換したHTMLテキストを表示する場所です。
コピペできるよう、textareaにしておきます。
二列目は変換後のHTMLテキストをサンプル表示する場所です。
二列目は今のところ必要ありませんが、今後ツールに機能を付加した場合に備え、準備しておきます。
JSのほうは以下のような記載です。
<script>
const { createApp, ref, watch } = Vue
createApp({
setup() {
const inputText = ref("")
const convertedText = ref("")
return {
inputText,
convertedText,
}
}
}).mount('#app')
</script>
変換方法
ふたつの文章をわける際には、pタグで段落をわける方法とbrタグで改行する方法がありますので、それらを選択して、変換できるようにします。(普段はpタグで段落をわけるため、brタグは滅多に使いませんが)
<div>
<label><input type="radio" v-model="settingPerLine" value="first" checked />pタグ付加</label>
<label><input type="radio" v-model="settingPerLine" value="second" />brタグ付加</label>
</div>
Vue.jsのドキュメントを参考にして、radioタイプのinputを二つ設けます。
両方に同じ変数setttingPerLineをバインディングし、valueをそれぞれ設定します。
これにより、チェックが入った側の値がsettingPerLineに格納され、選択されたタイプが確認できます。
変換タイプの選択ができるようになったので、次に変換機能本体をつくります。
変換機能
変換機能は、関数化します。
function formatText(inputText) {
const splitedText = inputText.split("\n");
let tmp1 = "";
if (settingPerLine.value.includes("first")) {
tmp1 = splitedText.map(el => "<p>" + el + "</p>\n")
}
else {
tmp1 = splitedText.map(el => el + "<br>\n")
}
return tmp1.join("");
}
入力があり、出力がある、というシンプルなつくりです。
フォーム入力、変更の検知
入力フォームへプレーンテキストをペーストした場合、および、変換タイプを変更した場合、HTML形式テキストが変更されてほしいです。
ボタンを押して変換するのでもいいですが、さして重い処理を行うわけではないので、リアルタイムで反映されるようにしましょう。
この要件はつまり、変数inputText
とsettingPerLine
が変更されたとき、変換処理を行う、ということを意味します。
そこで、Vue.jsのウォッチャーを使い、以下のようにします。
watch(inputText, async (newInput, oldInput) => {
convertedText.value = formatText(inputText.value);
})
watch(settingPerLine, async (newSetting, oldSetting) => {
convertedText.value = formatText(inputText.value);
})
以上をくっつけて
以上のコードをくっつけて、できあがったツールがこちらです。
終わりに
使えるか使えないかよくわからんツールができあがりました。
これだけだと大して使い道のないツールになってしまいますので、おいおい機能をプラスしてみましょう。
今思いつくのは、
- 出力値をクリップボードへコピーする機能
- 複数改行を刈り取ったり、付加したりする機能
- カーソル位置に水平線を入れる機能
- CSS設定をプレビューしながら、整形できる機能
- pixiv形式とかのルビをHTML形式へ変換する機能
こんな機能を、実現方法が思いついたらプラスしていきたいと思います。