Markdown テーブル生成
CSV・TSV・JSON から Markdown テーブルを生成し、列ごとの配置と表示幅に基づく余白で整えます。ブラウザーだけで動作します。
CSV として読みました。手掛かりがなかったための既定の選択です。違う場合は上で形式を選んでください。
列の配置
| city | country | population |
| --------- | ------- | ---------- |
| 東京 | Japan | 37400068 |
| Delhi | India | 28514000 |
| São Paulo | Brazil | 21650000 |列数: 3 · 行数: 3
入力は 4 種類、出力は 1 種類
Markdown のテーブルは書くのは簡単で、保つのが厄介です。セルに一語足すだけでその下の縦棒がすべてずれますし、手元にあるデータ — クエリの結果、表計算からの書き出し、API の応答 — から表を組み立てるとなると、結局は手で打ち直すことになります。このツールは、手元にある形のままデータを受け取り、GitHub 風 Markdown のきれいなテーブルを返します。
読み取れる形式は 4 つあり、どれと判断したかを黙って決めずに知らせます。
- Markdown のテーブル。崩れてしまった表は、そのまま貼り直すだけで整います。
- CSV。RFC 4180 に従って解析するので、引用符で囲まれた項目にカンマ、引用符、改行が入っていても失われません。
- TSV。表計算ソフトやデータベースクライアントから範囲をコピーすると、この形式になります。
- JSON 配列。オブジェクトの配列ならキーが列になり、配列の配列なら最初の行がヘッダーになります。
判定は手掛かりのはっきりしたものから順に見ます。先頭の角かっこは JSON にしかなく、ハイフンの並んだ行は Markdown の区切り行にしかなく、1 行目のタブは TSV にしかありません。カンマ区切りは最後に残るものなので、発見ではなく既定の選択として報告されます。推測が必要だったならそう言いますし、形式の選択がそれに優先します。
出力は Markdown だけです。テーブルを CSV や JSON に戻すのは別の仕事で、このサイトにはそれを担う道具がすでにあります。汎用の変換器をもう一つ用意しても、それらと競合し、このページの説明を難しくするだけでしょう。
セルは長さではなく幅で埋める
縦棒をそろえるとは、列の各セルを同じ幅まで埋めることであり、そのためにはセルの幅を知らねばなりません。文字数を数えるという素直な答えは、世界の多くの文字体系にとって誤りで、しかも両方向に誤ります。
等幅フォントは「1 文字 1 桁」ではありません。漢字、仮名、ハングル音節、全角のラテン文字、そしてほとんどの絵文字は、ラテン文字のちょうど 2 倍の幅で描かれます。一方、結合文字 — アクセント記号、ヘブライ語の母音符号、アラビア語の発音記号 — は前の文字の上に重ねて描かれ、幅をまったく取りません。文字数で埋めると、日本語の列は短すぎ、記号の付いた文字の列は長すぎることになります。
'日本語'.length // 3 UTF-16 code units
[...'日本語'].length // 3 code points
displayWidth('日本語') // 6 columns in the editorそこで余白は表示桁数で測ります。まずテキストを書記素クラスターに分け — 読み手が 1 文字と数える単位なので、複数の符号位置をつないだ絵文字も 1 つのままです — 各クラスターを Unicode 文字データベースの East_Asian_Width 特性と照合します。この特性だけはブラウザーが自力で答えられません。JavaScript は正規表現でカテゴリー、用字、大文字小文字を教えてくれますが、この特性は教えてくれないため、広い範囲を並べた小さな表をページと一緒に配っています。それ以外はすべてエンジンから得ています。
あえて狭いものとして扱う分類が一つあります。Unicode は、罫線素片、一部のギリシャ文字やキリル文字、いくつかの記号を「曖昧」と定めています。古い東アジア用フォントでは広く、それ以外では狭い文字です。Markdown ファイルはラテン文字を既定とするエディターで読まれるので、これらは 1 桁として数えます。実際にそのファイルを開く端末やエディターがそうしているからです。
Markdown のテーブルが持てないもの
この形式には固い制約が二つあり、現実のデータはその両方にぶつかります。セルはそのままの縦棒を含められません。縦棒こそがセルの区切りだからで、エスケープして書く必要があります。そしてテーブルの行は 1 行きりなので、セルは改行をまったく含められません。CSV の項目には当然のように入っていられるものなのに、です。
どちらも書き換えられ、その書き換えは影響したセルの数と最初の位置とともに報告されます。そこが肝心です。2 行の住所を黙って 1 行にしてしまう道具は、何も告げずにあなたのデータを損なっています。改行は既定では改行タグになります。これは GitHub、GitLab、そしてほとんどのレンダラーがセル内の改行として表示するものです。HTML を除去するレンダラーを使っているなら、空白に切り替えてください。
三つめは、ヘッダーより長い行です。GitHub 風 Markdown は余ったセルをただ捨ててしまい、これは黙ったままのデータ喪失です。ここでは代わりに空のヘッダーセルを足して表を広げ、食い違いを報告します。直せる不格好なヘッダーのほうが、存在に気づけない列よりましだからです。ヘッダーより短い行も空のセルで埋め、同じように報告します。
バックスラッシュは、多くのツールより少しだけ丁寧に扱っています。二重にするのは、後ろの縦棒を飲み込みかねない位置だけです。つまり本文中の縦棒の直前か、区切りが続くセルの末尾です。それ以外の場所ではそのままにするので、セルの中の Windows のパスは二重バックスラッシュの列にならず読みやすいまま残ります。
配置は区切り行に宿る
ヘッダーの下のハイフンの行は二つの役目を負っています。まずそのブロックをテーブルにしているのがこの行であり、そこに置くコロンが各列の配置を決めます。左のコロンは左寄せ、右のコロンは右寄せ、両側のコロンは中央寄せです。コロンがなければレンダラーは自分の既定に従い、どの実装でもそれは左寄せですが、左寄せを指定したことと同じではありません。
配置は列ごとに指定できます。実際の使い方がそうだからです。文章は左、数値は右、状態の列は中央。そして配置がすでに書かれたテーブルを貼り付けると、その指定は区切り行から読み取られて操作部に表示されるので、既存のテーブルを整え直しても誰かの手仕事が黙って消えることはありません。
余白も配置に従います。右寄せの列は左側に余白が入るので、ソースが仕上がりの表と同じ向きに見えます。Markdown はその空白をまったく無視します。だからこそ、ソースを読みやすくするために自由に使えるのです。
余白ありか、コンパクトか。右から左へ書く文字が違う理由
余白は人が手で編集する文書では割に合い、リポジトリでは代償を伴います。セルが一つ伸びればその列全体が埋め直されるので、一語の変更が差分では表のすべての行の変更として現れます。コンパクト形式は許される中でもっとも狭い表を書き — 余白なし、列ごとにハイフン 3 つ — 差分を本当に変わった行だけに抑えます。表示結果はどちらも同じです。各行の先頭と末尾の縦棒は GitHub 風 Markdown では不要ですが、一部の古いレンダラーは必要とするので、決め打ちではなく切り替えにしてあります。
ヘブライ語やアラビア語を含む表では、余白はそもそも機能しません。ツールはそれを取り繕わずに伝えます。空白の数は正しく数えられているのですが、エディターは混在した行を双方向アルゴリズムで配置します。右から左へ進む部分は並べ替えられ、その周りの縦棒も一緒に動きます。文字は正しい位置にあるのに縦棒はそろって見えません。そうした行では見た目の位置と論理上の位置が別物だからです。これはどうにもならないので、セルに右から左へ書く文字があるときはそのことを報告し、そもそも期待を裏切る配置のないコンパクト形式を勧めます。
同じ理由で、このページの Markdown 出力はヘブライ語やアラビア語でサイトを読んでいるときも常に左から右へ表示されます。ソースコードには、それ自身の向きがあるからです。
どこで動くか
すべてはブラウザーの中で起こります。表の解析も、幅の計測も、組み立て直しもあなたの端末で行われ、貼り付けた内容が送信・保存・記録されることはありません。整形し直したい表はたいてい公開データではなくクエリの結果や書き出しですから、これは大切なことです。
よくある質問
- データはサーバーに送られますか。
- いいえ。解析も幅の計測も出力もすべてブラウザーの中で計算され、貼り付けた内容が送信されることも記録されることもありません。
- CSV を Markdown のテーブルにするには。
- 貼り付けるだけです。カンマ区切りのテキストを認識し、最初の行をヘッダーとして扱い、そろったMarkdown のテーブルを返します。カンマや引用符や改行を含む引用符付きの項目も正しく扱い、形式に合わせて書き換えたものはすべて報告します。
- 日本語や中国語を含む表がまだそろわないのはなぜですか。
- フォントを確かめてください。余白は、漢字がラテン文字のちょうど 2 倍の幅で描かれる等幅フォントを前提としています。端末やコードエディターが使っているのはそれです。プロポーショナルフォントや、CJK 字形がちょうど 2 倍幅ではないフォントでは、どんな余白でも列はそろいません。その場合はコンパクト形式を使ってください。
- セルの中の改行はどうなりますか。
- 既定では改行タグになります。Markdown のテーブルの行は 1 行きりで、本物の改行は入らないからです。レンダラーが HTML を除去するなら空白に切り替えてください。いずれの場合も、変更したセルは報告されます。
- セルの多い行があると、なぜ空の列が増えるのですか。
- そうしなければそのセルが失われるからです。GitHub 風 Markdown はヘッダーの幅を超えた分を捨ててしまうので、代わりに空のヘッダーセルで表を広げ、食い違いを報告します。中身を確かめたうえで、その列を消すか名前を付けてください。
- 余白ありとコンパクト、どちらを使うべきですか。
- 人が読んで手で直す文書 — README や設計メモ — には余白ありを。ソースが読みやすくなります。バージョン管理下にあって表がよく変わるものにはコンパクトを。余白があると、1 つのセルを直しただけで列全体が埋め直され、差分ではすべての行が変わったように見えます。
- 各行の先頭と末尾の縦棒は必要ですか。
- GitHub 風 Markdown では不要で、最近のレンダラーの多くも要りません。古い解析器の一部は必要としますし、手で編集する表は読みやすくなるので、既定では有効にしてあり、切ることもできます。
- ヘブライ語やアラビア語の表をツールがそろえられないのはなぜですか。
- エディターが行を並べ替えるからです。双方向のレイアウトは右から左へ進む部分を見た目の順に置き、その周りの縦棒も一緒に動くので、余白は計算上は正しくても見た目には役に立ちません。壊れて見える表を作るくらいならと、ツールはそれを報告してコンパクト形式を勧めます。