🪄

Markdownのテーブル(表)をショートカットキーでサクッと作る(AutoHotkey&ChatGPT)

2023/03/02に公開

はじめに

Markdown、便利ですね。公式ページにもこうあります。

Markdown is a text-to-HTML conversion tool for web writers. Markdown allows you to write using an easy-to-read, easy-to-write plain text format, then convert it to structurally valid XHTML (or HTML).[1]

easy-to-read, easy-to-write、まさしくその通りですね。Markdown最高!

いかがでしたか?

お読みくださりありがとうございました。


...いな、個人的にどう見たってeasy-to-writeとは思えない彼/彼女がいます。[2]

テーブルです。

| This |  is  |
| :--: | :--: |
|  a   | table|
This is
a table

これまでのMarkdownファミリーとは一線を画すこの「手打ち無理ゲー感」。
「Markdown?ヌルゲーだな」という初心者の驕慢を打ち砕くMarkdown界のミルタンク。

対照表を作ったり、画像を並べたり、使用頻度の高いわりに、なかなか記法が覚えられず、「markdown テーブル」 と何度も検索しては、いつか見たあのサイトにPVを献上し、結局はTables Generator[3]などの外部ツールを使うことになります。

テーブルは当初のMarkdownにはなく、新たに追加された存在で、そのぶん構文も複雑、Markdown Guideにもこうありました。

Creating tables with hyphens and pipes can be tedious. [4]
ハイフンとパイプでテーブルを作るのは退屈になりがちです。

こんな記事も大人気です。私も読みました。
https://qiita.com/taruhachi/items/5bd18d7de4c3fa40dd23

もっと簡単にテーブルを作れないものか。

ということで本記事です。

TL;DR🐍

  • AutoHotkeyを使う。
  • スクリプト内でテーブルのMarkdownを作成する。
    • スクリプトはChatGPTさんと作ると楽しい。
  • AutoHotkeyをインストールし、本記事「おわりに」のコードをコピペすれば終わり。

対象読者🎯

  • Markdownで表の記載をするときにイラッとした経験のある人
  • ChatGPTでの開発に関心のある人

実現したいこと✨

  • ショートカットキーでテーブル用のMarkdownを入力する。
  • 行数・列数を指定可能。
  • 「markdown テーブル」 で検索し、いつか見たあのサイトにPVを献上する日々との訣別。

使うもの🤖

  • AutoHotkey
    • スクリプト実行を任意のキーに割り当てるツール
  • ChatGPT
    • スクリプトを書いてもらいます。

環境

  • Windows 11
  • テスト環境:GitHub、Zenn

実装⚗️ ~ChatGPTと力をあわせて

実装はいたってシンプルです。

  1. AutoHotkeyをインストールする。
  2. AutoHotkey用のスクリプトを書く。

1. AutoHotkeyをインストールする⌨️

下記のサイトにアクセスし、ダウンロードします。
https://www.autohotkey.com/

セットアップガイドは下記などWebに記事がいくつもあるので迷うことはないはず。
https://pouhon.net/ahk-install/661/

日本語のレファレンスも充実しています。
https://ahkwiki.net/Top

2. AutoHotkey用のスクリプトを書く📝

さあ、ここが腕の見せ所です。

が、普段書くのはTypeScriptやRubyゆえ、AutoHotkey用の.ahkスクリプトはあまり馴染みがない...

ということで、みんな大好きChatGPTさんにお手伝いいただきます。

https://chat.openai.com/chat

まずは大雑把に質問してみる

Question 1
Could you write an autohotkey script to create markdown table?

すると回答が。

Answer 1
Sure! Here's an AutoHotkey script that you can use to create a Markdown table:

こちらがコード。

; Set the hotkey that will trigger the table creation.
^!t::
  ; Prompt the user for the number of rows and columns.
  InputBox, numRows, Number of Rows, Enter the number of rows you want., , 150, 150
  InputBox, numCols, Number of Columns, Enter the number of columns you want., , 150, 150
  
  ; Create the table header.
  table := "|"
  Loop, % numCols
  {
    table .= " Column " . A_Index . " |"
  }
  table .= "`n|"
  
  ; Create the table rows.
  Loop, % numRows
  {
    Loop, % numCols
    {
      table .= " Cell " . A_Index . " |"
    }
    table .= "`n|"
  }
  
  ; Paste the table into the active window.
  ClipBoard := table
  Send ^v
Return

コメント付き、言わなくてもしっかりInputBoxの処理も入れて、行数・列数を指定できるように書いてくれています。できる子。

ちゃんと使い方も解説してくれ、留保も忘れません。できる子。

This script sets the hotkey Ctrl + Alt + T to trigger the table creation. When you press the hotkey, it will prompt you for the number of rows and columns you want in the table. After you enter the values, the script will create a Markdown table with the specified number of rows and columns, and paste it into the active window.

Note that the script assumes that you're using the default Markdown syntax for tables, which uses vertical bars to separate columns and hyphens to create the table header. If you're using a different syntax, you may need to modify the script accordingly.

さっそく試してみましょう。

コードを.ahkファイルにコピペし、アクティべートします。
ChatGPTが割り当ててくれたCtrl + Alt + Tで動作テストです。

行数・列数はどちらも2で設定します。

行数指定 列数指定

結果はこちら。

Result 1
| Column 1 | Column 2 |
| Cell 1 | Cell 2 |
| Cell 1 | Cell 2 |
|

惜しくも一発クリアとはなりませんでした。現状の問題は以下です。

  • ハイフンからなるヘッダー列がない
  • 最後のパイプが余計

これらをChatGPTと一緒に()修正していきます。

ヘッダー列を加える

ヘッダー列を加えるため、下記のようにリクエストを出しました。

Question 2
Great. But I think you have to insert "| ---- |" row in the second row. 

しかし、かえってきたコードを実行した結果は下記。(引用過多になるため、回答コードの引用は省きます。)

Result 2
| Column 1 | Column 2 | Column 3 | Column 4 |
|| ---- | ---- | ---- | ---- |
| Cell 1 | Cell 2 | Cell 3 | Cell 4 |
| Cell 1 | Cell 2 | Cell 3 | Cell 4 |
| Cell 1 | Cell 2 | Cell 3 | Cell 4 |
| Cell 1 | Cell 2 | Cell 3 | Cell 4 |
|

ヘッダー列は加わったものの、余剰ハイフンが二つ残ってしまいました。

余剰ハイフンを取る

こんどは出力結果を添えて、余剰ハイフンの削除をお願いしました。

Question 3
Thanks! I got the following output...

| Column 1 | Column 2 | Column 3 | Column 4 |
|| ---- | ---- | ---- | ---- |
| Cell 1 | Cell 2 | Cell 3 | Cell 4 |
| Cell 1 | Cell 2 | Cell 3 | Cell 4 |
| Cell 1 | Cell 2 | Cell 3 | Cell 4 |
| Cell 1 | Cell 2 | Cell 3 | Cell 4 |
|

Problem is this has the additional "|"s in the second row and its tail. Could you adjust them?

結果はこちら。

Result 3
| Column 1 | Column 2 | Column 3 | Column 4 |
| ---- | ---- | ---- | ---- |
 Cell 1 | Cell 2 | Cell 3 | Cell 4 |
 Cell 1 | Cell 2 | Cell 3 | Cell 4 |
 Cell 1 | Cell 2 | Cell 3 | Cell 4 |
 Cell 1 | Cell 2 | Cell 3 | Cell 4 |

取ってはいけないパイプも取れてしまいました。リベンジです。

Question 4
Genius! I got the following table this time.

| Column 1 | Column 2 | Column 3 | Column 4 |
| ---- | ---- | ---- | ---- |
 Cell 1 | Cell 2 | Cell 3 | Cell 4 |
 Cell 1 | Cell 2 | Cell 3 | Cell 4 |
 Cell 1 | Cell 2 | Cell 3 | Cell 4 |
 Cell 1 | Cell 2 | Cell 3 | Cell 4 |

But it still has one problem. The rows after the third lack a starting "|".
For example "Cell 1 |" should be "| Cell 1 |" instead. 

Could fix this one?

結果はこちら。

Result 4
| Column 1 | Column 2 | Column 3 | Column 4 |
| ---- | ---- | ---- | ---- |
 Cell 1 || Cell 2 || Cell 3 || Cell 4 |
 Cell 1 || Cell 2 || Cell 3 || Cell 4 |
 Cell 1 || Cell 2 || Cell 3 || Cell 4 |
 Cell 1 || Cell 2 || Cell 3 || Cell 4 |

なんか変になった・・・

期待する出力例を与えてみる

ここで、expectするMarkdownを与えてみることにしました。

Question 5
Oops. Now we have this;

| Column 1 | Column 2 | Column 3 | Column 4 |
| ---- | ---- | ---- | ---- |
 Cell 1 || Cell 2 || Cell 3 || Cell 4 |
 Cell 1 || Cell 2 || Cell 3 || Cell 4 |
 Cell 1 || Cell 2 || Cell 3 || Cell 4 |
 Cell 1 || Cell 2 || Cell 3 || Cell 4 |

But we want the one shown below;

| Column 1 | Column 2 | Column 3 | Column 4 |
| ---- | ---- | ---- | ---- |
| Cell 1 | Cell 2 | Cell 3 | Cell 4 |
| Cell 1 | Cell 2 | Cell 3 | Cell 4 |
| Cell 1 | Cell 2 | Cell 3 | Cell 4 |
| Cell 1 | Cell 2 | Cell 3 | Cell 4 |

Could you adjust the script?

weと書いて協働感を醸していますが、コードの100%はChatGPTさんが書いております。

回答と実行結果はこちら。

Answer 5
I apologize for the mistake again! Here's an updated version of the script that should add the starting vertical bar to the first cell of each row:
  InputBox, numRows, Number of Rows, Enter the number of rows you want., , 150, 150
  InputBox, numCols, Number of Columns, Enter the number of columns you want., , 150, 150
  
  ; Create the table header.
  table := "|"
  Loop, % numCols
  {
    table .= " Column " . A_Index . " |"
  }
  table .= "`n"
  
  ; Add the separator row.
  separator := "|"
  Loop, % numCols
  {
    separator .= " ---- |"
  }
  separator .= "`n"
  table .= separator
  
  ; Create the table rows.
  Loop, % numRows
  {
    Loop, % numCols
    {
      if A_Index = 1
      {
        table .= "| Cell " . A_Index . " |"
      }
      else if A_Index = numCols
      {
        table .= " Cell " . A_Index . " |"
      }
      else
      {
        table .= " Cell " . A_Index . " |"
      }
    }
    table .= "`n"
  }
  
  ; Paste the table into the active window.
  ClipBoard := table
  Send ^v
Return
This version of the script should now correctly add the starting vertical bar to the first cell of each row in the table. I hope this resolves the issue for you, but please let me know if you encounter any other issues or have any additional questions!
Result 5
| Column 1 | Column 2 | Column 3 | Column 4 |
| ---- | ---- | ---- | ---- |
| Cell 1 | Cell 2 | Cell 3 | Cell 4 |
| Cell 1 | Cell 2 | Cell 3 | Cell 4 |
| Cell 1 | Cell 2 | Cell 3 | Cell 4 |
| Cell 1 | Cell 2 | Cell 3 | Cell 4 |

やりました🎉

ちゃんと展開します。

Column 1 Column 2 Column 3 Column 4
Cell 1 Cell 2 Cell 3 Cell 4
Cell 1 Cell 2 Cell 3 Cell 4
Cell 1 Cell 2 Cell 3 Cell 4
Cell 1 Cell 2 Cell 3 Cell 4

文字揃えを指定する

ここで俄然、欲が出てきた怠惰な人間は、文字揃え指定の追加実装を要望します。

Question 6
I want to change separator row according to the user input.

User input accepts the three options: Right, Center and Left. (case-insensitive)
Separator ("----") should be replaced as follows;

Right: "---:"
Center: ":---:"
Left: ":---"

Could you add this to the previous script?

インプットの「Right, Center, Left」の3つに応じて、文字揃えを変えるようにスクリプトの変更をお願いしています。長年連れ添った夫婦のようにThisとかThatで話が通じるの、とっても楽です。

「へい、お安い御用」とばかりにさっそくコードを修正するChatGPTさん。内心はいさ知らず。

Answer 6
^!t::
  ; Prompt the user for the number of rows and columns.
  InputBox, numRows, Number of Rows, Enter the number of rows you want., , 150, 150
  InputBox, numCols, Number of Columns, Enter the number of columns you want., , 150, 150
  
  ; Prompt the user for the alignment of the separator row.
  InputBox, alignment, Separator Alignment, Enter the alignment of the separator row (left, center, or right)., , 150, 150
  
  ; Set the separator based on the user input.
  if (alignment = "left") or (alignment = "Left")
  {
    separator := "|"
    Loop, % numCols
    {
      separator .= " :--- |"
    }
  }
  else if (alignment = "center") or (alignment = "Center")
  {
    separator := "|"
    Loop, % numCols
    {
      separator .= " :---: |"
    }
  }
  else if (alignment = "right") or (alignment = "Right")
  {
    separator := "|"
    Loop, % numCols
    {
      separator .= " ---: |"
    }
  }
  else
  {
    MsgBox, Invalid input! Please enter "left", "center", or "right"., , Error
    return
  }
  
  ; Create the table header.
  table := "|"
  Loop, % numCols
  {
    table .= " Column " . A_Index . " |"
  }
  table .= "`n"
  
  ; Add the separator row.
  table .= separator . "`n"
  
  ; Create the table rows.
  Loop, % numRows
  {
    Loop, % numCols
    {
      if A_Index = 1
      {
        table .= "| Cell " . A_Index . " |"
      }
      else if A_Index = numCols
      {
        table .= " Cell " . A_Index . " |"
      }
      else
      {
        table .= " Cell " . A_Index . " |"
      }
    }
    table .= "`n"
  }
  
  ; Paste the table into the active window.
  ClipBoard := table
  Send ^v
Return

ところが、、、!

Result 6


ChatGPT選手、まさかのSyntaxエラー

ここにきてChatGPT選手、まさかのSyntaxエラーを食らいました。

InputBox, alignment, Separator Alignment, Enter the alignment of the separator row (left, center, or right)., , 150, 150

ここで使われているカンマがまずいようです。万物の霊長たる人間が教えてあげます。[5]

Question 7
I got an error "ambiguous or invalid use of ".""

This line may be the cause.
===  
InputBox, alignment, Separator Alignment, Enter the alignment of the separator row (left, center, or right)., , 150, 150
===

Why not try this one?
===
InputBox, alignment, Separator Alignment, Enter the alignment of the separator row (left/center/right)., , 150, 150
===
Answer 7
Yes, you're correct. The error is because of the period in the options. It's interpreting it as a separator for the object's properties. Using a slash instead of a period will resolve the issue. Here's the updated line:

ピリオドのせいではないが、まあいいか。

InputBox, alignment, Separator Alignment, Enter the alignment of the separator row (left/center/right)., , 150, 150
This should allow the script to run without errors.

もらったコードで問題の箇所を置換し、実行してみます。

Result 7


文字揃えの指定Inputが追加されました。

| Column 1 | Column 2 | Column 3 | Column 4 |
| ---: | ---: | ---: | ---: |
| Cell 1 | Cell 2 | Cell 3 | Cell 4 |
| Cell 1 | Cell 2 | Cell 3 | Cell 4 |
| Cell 1 | Cell 2 | Cell 3 | Cell 4 |
| Cell 1 | Cell 2 | Cell 3 | Cell 4 |

ちゃんと展開されます。

Column 1 Column 2 Column 3 Column 4
Cell 1 Cell 2 Cell 3 Cell 4
Cell 1 Cell 2 Cell 3 Cell 4
Cell 1 Cell 2 Cell 3 Cell 4
Cell 1 Cell 2 Cell 3 Cell 4

左揃えも。

Column 1 Column 2 Column 3 Column 4
Cell 1 Cell 2 Cell 3 Cell 4
Cell 1 Cell 2 Cell 3 Cell 4
Cell 1 Cell 2 Cell 3 Cell 4
Cell 1 Cell 2 Cell 3 Cell 4

おわりに

ChatGPTさんと力を合わせて()作り上げた最終的なコードは以下です。

完成コード
^!t::
  ; Prompt the user for the number of rows and columns.
  InputBox, numRows, Number of Rows, Enter the number of rows you want., , 150, 150
  InputBox, numCols, Number of Columns, Enter the number of columns you want., , 150, 150
  
  ; Prompt the user for the alignment of the separator row.
  InputBox, alignment, Separator Alignment, Enter the alignment of the separator row (left/center/right)., , 150, 150
  
  ; Set the separator based on the user input.
  if (alignment = "left") or (alignment = "Left")
  {
    separator := "|"
    Loop, % numCols
    {
      separator .= " :--- |"
    }
  }
  else if (alignment = "center") or (alignment = "Center")
  {
    separator := "|"
    Loop, % numCols
    {
      separator .= " :---: |"
    }
  }
  else if (alignment = "right") or (alignment = "Right")
  {
    separator := "|"
    Loop, % numCols
    {
      separator .= " ---: |"
    }
  }
  else
  {
    MsgBox, Invalid input! Please enter "left", "center", or "right"., , Error
    return
  }
  
  ; Create the table header.
  table := "|"
  Loop, % numCols
  {
    table .= " Column " . A_Index . " |"
  }
  table .= "`n"
  
  ; Add the separator row.
  table .= separator . "`n"
  
  ; Create the table rows.
  Loop, % numRows
  {
    Loop, % numCols
    {
      if A_Index = 1
      {
        table .= "| Cell " . A_Index . " |"
      }
      else if A_Index = numCols
      {
        table .= " Cell " . A_Index . " |"
      }
      else
      {
        table .= " Cell " . A_Index . " |"
      }
    }
    table .= "`n"
  }
  
  ; Paste the table into the active window.
  ClipBoard := table
  Send ^v
Return

このコードをアクティベートし、Ctrl + Alt + Tを押すと、

  • ショートカットキーでテーブル用のMarkdownを入力する。
  • 行数・列数を指定可能。
  • 「markdown テーブル」 で検索し、いつか見たあのサイトにPVを献上する日々との訣別。

が実現します。

割り当てキーを変更したければ、コード冒頭の^!tを修正し、文字揃えの指定を「l, c, r」の一文字で済ませたければIf文を修正する、といった具合にカスタマイズも容易です。


改めまして...

いかがでしたか?

お読みくださりありがとうございました。


補足🔠🔡

Question 6でcase-insensitive(大文字と小文字を区別しない)にするように指示していますが、AutoHotkeyはデフォルトでcase-insensitiveでの評価になっていました。したがって、ChatGPTさんが付けてくれた、

if (alignment = "left") or (alignment = "Left")

のorの処理は実は不要です。(ごめん、ChatGPT。)

なお、大文字小文字を区別したい場合はStringCaseSenseで指定が必要です。

Determines whether string comparisons are case sensitive (default is "not case sensitive").
https://www.autohotkey.com/docs/v1/lib/StringCaseSense.htm

脚注
  1. https://daringfireball.net/projects/markdown/ より。 ↩︎

  2. ドイツ語ならTabelleで女性、フランス語ならtableauで男性です。逆だったかもしれません。名詞の性、覚えられません。 ↩︎

  3. https://www.tablesgenerator.com/markdown_tables ↩︎

  4. https://www.markdownguide.org/extended-syntax ↩︎

  5. ここまでコードの100%はChatGPTさんが書いています。 ↩︎

Discussion