3. HTMLとJavaScriptで、カラム名を入力するとMarkdownの表を生成してくれるツールをつくる

Updated
2021/8/8 8:50
Author
Jumpei IkegamiJumpei Ikegami
前回のチュートリアルでは、JavaScriptで「改行」を扱う方法を紹介し、複数行のテキストを一括変換するようなツールを作ってみました。今回はさらにそこから発展させて、入力された内容に応じて複数行のテキストを1から組み上げていくような変換ツールを作ってみましょう。

前提知識

このチュートリアルは、次のチュートリアルの続きとなっています。
2. HTMLとJavaScriptで、入力された全ての行の先頭に> をつける変換ツールをつくる2021/6/20 5:422021/8/8 8:44

作るもの

次の画像にあるように、生成したい表のカラム名を改行区切りで入力すると、Markdownの表の記法に変換してテンプレートを出力してくれるツールを作ってみます。結果もテキストボックスに表示されるので、あなたはこれをコピーしてMarkdownエディタにペーストし中身を記述していくだけで、ドキュメントに表を追加することができます。

体験すること

このチュートリアルによって、以下を体験します。
  • Markdownの表を生成するツールの動作を確認する
  • 文字列を改行で区切って配列に変換する
  • 配列の要素を1つずつ取り出して同じ処理をする
  • 配列の要素の回数だけ同じ処理をする

チュートリアルスタート!

ここからは、実際に手を動かしながら読み進めていきましょう。ただ読むだけよりも、実際に体験した方が内容を深く理解することができます。

HTMLとJSをコピペして動作を確認してみる

前回と同様、まずはCodePenのエディタで動作を見てみましょう。もし前回の内容がCodePen上にあれば、その続きとして追加しても問題ありません。
HTMLは、次の通りです。
HTML
CodePenのHTMLエディタにこれをコピペしてください。すると、下の領域にテキストエリアが2つ表示されます。
この時点では、左のテキストエリアに文字を入力しても何も起こりません。
次に、下記のJSをCodePenのJSエディタにコピペしましょう。今回は少し長いですね。
JavaScript
内容は後で説明するので、今は理解しなくても大丈夫です。
これでツールの完成です。試しに、左のテキストエリアに改行区切りで「ID」、「名前」、「概要」と入力してみましょう。ここはできれば、コピペではなく手入力をしてみてください。次の画像のように、Markdown記法に沿った表のテンプレートが、左で入力したカラムを含んだ状態で生成されるはずです。
もちろん、結果に出力されたテキストをMarkdownエディタにコピペすれば、Markdownで書かれたドキュメントに表を追加することができます。実際に表の行を足していく場合は、最後の行('|  |  |  |')をコピペで増やして、中身を記述していくような想定です。

文字列を改行で区切って配列に変換する

HTMLについては前回のチュートリアルとほぼ同様にテキストエリアを表示しているだけなので、説明を割愛します。
問題は、JavaScriptです。やたらと長いですし、関数もたくさん出てくるので、見ていると吐き気がしてくるかもしれません。全体をいっぺんに理解するのではなく、小さな部品に分けて読んでいきましょう。
JavaScript
例によって、最初の2行はHTMLに記述した2つのテキストエリアをJSで取得しています。
JavaScript
その後の処理を概観してみると、また例によって入力用のテキストエリアに文字が入力された場合の処理を長々と記述しています。その中では、結果を格納するための変数r(resultの頭文字のつもりです)を宣言し、色々と処理した後で、出力用のテキストエリアのvalueに格納しています。これによって、「テキストが入力されたら出力用のテキストエリアに変換後のテキストを表示する」という機能を実現しています。
JavaScript
今回の肝は、上記で「テキストを加工する処理あれこれ」とコメントした部分です。ここを細かく見ていきましょう。
まず、テキスト加工部分の最初の2行です。1行目は、いつものように入力された文字列を変数inputに格納しています。
JavaScript
重要なのは2行目です。ここでは、split()というメソッドを使って、入力された文字列を改行で区切って配列に変換しています。配列に変換すると何が嬉しいのでしょうか?JSでは、配列の要素を1つずつ取り出して処理をするためのメソッドが充実しています。文字列をそのまま扱うのではなく、意味のある単位で配列に変換してから使うことで、配列のそれぞれに要素に対して同じ処理を繰り返し適用することができます。
具体的な入力値で考えてみましょう。たとえば改行区切りで「ID」、「名前」、「概要」と入力した場合、変数inputに格納される文字列は次のようになります。
JavaScript
これを改行(\n)で区切って配列にすると、変数linesの中身は次のように3つの文字列を要素にもつ配列になります。
JavaScript
最終的にMarkdownの表を生成するためには、これらの要素を表のカラムとして出力してやればいいわけです。

配列の要素を1つずつ取り出して同じ処理をする

さて、私たちはいま、Markdownの表を生成するツールを作っているのでした。具体的には、次のような文字列を出力するツールです。
Markdown
この3行の出力について、1行ずつ考えていきましょう。
まずは、1行目の"| ID | 名前 | 概要 |"という文字列を作ってみましょう。プログラムでいうと、次の部分に対応します。
JavaScript
出力すべき文字列は、JSの繰り返し処理を意識して、次のようなパーツに分けて考えます。
JavaScript
最初の縦棒(|)以外は、「カラム名 + 半角スペース + 縦棒(|)」というパターンの繰り返しで表現できることがわかります。
次の1行は、最初の縦棒を変数rに足している部分です。
JavaScript
ここで、+=という見慣れない記号が出てきました。一般にプログラムでは、「元の変数にある値を足して、結果を元の変数に格納し直す」という処理を書くことがよくあります。たとえば、次のような処理です。
JavaScript
ただし、変数名を代入式の左右に書く必要があるので、少し面倒で読みにくいです。そこで、同じ処理を+=を使って書いていいことになっています。
JavaScript
もちろんどちらの記法をつかってもいいですが、今回は+=を使う場面がたくさん出てくるので、+=を使った書き方で統一しています。
次の3行が、文字列を配列に変換した恩恵を感じられる処理です。
JavaScript
配列に対して呼ぶことができるforEach()メソッドは、「配列の要素を1つずつ取り出して同じ処理を実行する」という意味の関数です。この「同じ処理を実行する」といっている「処理」は、もちろんシチュエーションによって実行したい内容が変わります。そこで、forEach()メソッドに渡す引数として、実行したい処理を記述した関数を渡す必要があります。
JavaScript
ここで引数に渡した関数は、配列の要素と同じ回数だけ呼び出されます。そして、関数内では配列の要素を使うことができます。関数が呼び出される度に、関数の引数として配列の各要素が渡されます。
抽象度が上がってきたので、具体的な例で考えましょう。いま、配列linesの中身は['ID', '名前', '概要']でした。
JavaScript
そのとき、forEach()メソッドに渡した関数内の処理は、次のように3回呼び出されます。(もちろん、入力したカラムの数が増えると処理が呼ばれる回数も増えます。)
JavaScript
関数内で引数lineを使って書いていた部分が、実際の配列要素に置換して実行されていることがわかります。
これによって、「1行目の出力」である"ID | 名前 | 概要 |"という部分が変数rに連結できました。1行目の文字列が作り終わったので、最後に改行(\n)を足しています。
JavaScript

配列の要素の回数だけ同じ処理をする

ここまでが、今回のチュートリアルで一番難しい部分の説明でした。あとは、1行目の生成と同じようなことを2行目と3行目でもやれば完成です。
カラム数が3つのとき、2行目は次のような出力でした。
Markdown
「1行目の出力」と同様に、これも最初の縦棒(|)以外は ' -- |' の繰り返しで表現できることがわかります。
「1行目の出力」と違うのは、入力されたカラムの数だけが重要で、実際のカラム名は使わないということです。配列の中身を使っていない場合でも、「配列の要素数と同じ回数だけ同じ処理を呼ぶ」ということはよくあります。そんなときも、「1行目の出力」と同じようにforEach()メソッドを使うのが便利です。
実際に、「2行目の出力」を生成する部分でも、変数rに文字列 ' -- |' を配列の要素数と同じ回数だけ繰り返し連結するために、forEach()メソッドを使っています。
JavaScript
入力されたカラム数が3つのとき、forEach()メソッドに渡した関数内の処理を書き下すと次の通りです。
JavaScript
「3行目の出力」についても、全く同様です。プログラムを見て、出力すべき'|  |  |  |'という文字列をどのように分割しているか考えてみてください。
Plain Text
こうして生成された3行の文字列は、変数rに格納され、前述したように出力用のテキストエリアに表示されます。
以上でJSの説明を終わります。特に、複数行から成る文字列を改行(\n)で分割して配列として扱うというのは、複数行のテキストを扱う上でとてもよく使われるテクニックとなります。配列に対する処理は抽象度が高くて難しいですが、具体例を考えながら少しだけでも理解してみてください。
なお、splitメソッドなど文字列の加工について詳しく知りたい場合は、次のリファレンス記事で詳しく説明しています。
文字列を加工する方法2021/6/20 6:082021/8/8 9:33