Sample Site

GAWK HTML 簡単 表作成

巷には表題のようなアプリや変換サイトがたくさんあるようです。AWK でも凝った作りでなければ、簡単なスクリプトで作成可能です。以下はサクラエディタマクロとして使っていますが、バッチファイル単体でも起動可能なものとなっています。

区切り文字は単体タブ(MSExcel等)、カンマ(csv)とスペース+タブ(HP上の表)を対象とし、それ以外は標準の FS となります(スペース区切り等)。テーブルデータを先読みし FS を事前検査しています。かなりいい加減ですが、FS を自動判断します。
検査の都合上、フィールド数にバラツキのある表は正しく分けられません。

使用例 1:アプリから表をコピー

tabletag01.jpg 何処からか表をコピーしてくる HP上の表でも可 tabletag02.jpg サクラエディタで、コンテキストメニューから「Table_Tag」をクリック ※サクラエディタ側で文字列を選択していないことが条件 tabletag03.jpg InputBox 1 を入力すると第一レコードがヘッダになり 0 を入力すると第一レコードはデータ扱いとなる(デフォルト) キャンセルすると何もせずにサクラエディタに戻る ここでは、ヘッダとして「OK」をクリックし、適当な行に「貼り付け」 tabletag04.jpg HTML用の書式に変換されてペーストされる 以下のようになる

hard/soft spec/version
CPU core2duo 2.93GHz
RAM 4GB
OS Windows10 pro 32bit
GAWK 4.2.1 / 4.1.4 / 3.1.5jp for win32
SakuraEditor 2.3.2.0 非インストーラパッケージ
gcc (MinGW.org GCC-8.2.0-1) 8.2.0
UTF-8 実行環境 MSYS2/Bash
プログラム用フォント M+/Rounded M+ Regular
JWCAD for Windows 8.1
InternetBrowser FireFox
Microsoft Excel 2013

※データにスペースが含まれるのでデフォルトFSのままだと滅茶滅茶な表になる。


使用例 2:直接csvを書いて変換する

既存ファイルからの流用ではなく、ちょっとした表が欲しいとき tabletag05.jpg 表をcsvで書き、該当部分を選択し「Table-Tag」を起動 tabletag06.jpg InputBox デフォルト値 0 で「OK」をクリック 上記の選択状態が維持されているので、その部分で右クリック 「貼り付け」る tabletag07.jpg 置換される 以下のようになる

AWK実践入門 技術評論社 ISBN978-4-7741-7369-6
プログラミング言語AWK 新紀元社 ISBN4-7753-0249-3
AWKを256倍使うための本 アスキー ISBN4-7561-0162-3

使用例 3:サクラエディタを使用せずに利用する

表をコピーしてから tabletag.bat をダブルクリックすると、ヘッダかデータかを実行時に選ぶことはできませんが、クリップボード内の変換は行われます。ペーストすると、同様の結果が得られます。ですので、必ずしもサクラエディタが必要というわけではありません。

バッチファイルのショートカットを、デスクトップに配置すると便利に使えるかもしれません。

tabletag.vbs

1 : 'サクラマクロ tabletag.vbs 2 : 'クリップボードに格納されている表をHTML-Tableに変換する 3 : 'tabletag.bat, mshta_clip_out.cmd, tabletag.awk 4 : '上記3ファイルを同一フォルダ(tabletag)に格納 5 : 'batpathを設定し、当vbsファイルを\sakura\macros\に保存 6 : 'サクラエディタにマクロを登録(コンテキストメニューに追加) 7 : 8 : Option Explicit 9 : Const batpath = "y:\tabletag\tabletag.bat" 10 : Dim nselect, sprompt, nth, snz, scmd 11 : 12 : nselect = Editor.IsTextSelected() 13 : If nselect <> 0 Then 14 : sprompt = "選択された表をHTML-tableに変換し、" & vbCrLf & _ 15 : vbCrLf & "クリップボードへ転送します" & vbCrLf & vbCrLf & _ 16 : vbCrLf & "テーブルヘッダ 1 を入力" 17 : Else 18 : sprompt = "クリップボードデータをHTML-tableに変換します" & vbCrLf & _ 19 : vbCrLf & vbCrLf & vbCrLf & "テーブルヘッダ 1 を入力" 20 : End If 21 : 22 : nth = InputBox(sprompt, "tabletag", "0") 'no table-header default 0 23 : 24 : If Not IsEmpty(nth) Then 25 : If nselect <> 0 Then 26 : snz = Editor.GetSelectedString(0) 27 : Editor.SetClipboard 0, snz 28 : End If 29 : scmd = batpath & " " & nth 'send 1arg to batfile 30 : Editor.ExecCommand scmd, 0 31 : End If

下記のバッチファイルに「1 か 0」を送り、バッチを実行します。
選択中の文字列がある場合には、そのデータをクリップボードに送ります

tabletag.bat

1 : @echo off 2 : rem tabletag.bat 3 : rem クリップボード内の表をHTML-tableに変換 4 : pushd %0\.. 5 : call mshta_clip_out.cmd > _temp_1.txt 6 : gawk414 -v ARG1=%1 -f tabletag.awk _temp_1.txt > _temp_2.txt 7 : rem call mshta_to_clip.cmd < _temp_2.txt 8 : clip < _temp_2.txt 9 : del _temp_?.txt 10 : rem pause

クリップボードのテキストデータをテキストファイルとして生成、そのテキストをGAWKが読み、データを加工します。さらにその加工済みデータをクリップボードに戻します。

mshta_clip_out.cmd (一行書き必須)

1 : @MSHTA.EXE vbscript:Execute("s=clipboardData.getData(""text""):If Not IsNull( s) Then CreateObject(""Scripting.FileSystemObject"").GetStandardStream(1).Wri te(s):End If:close()")

クリップボード内のテキストデータを標準出力に送ります。

AWKプログラム

tabletag.bat / mshta_clip_out.cmd / tabletag.awk の3ファイルは同じフォルダに保存してください。また環境変数 AWKPATH にカレントディレクトリの相対パス「.\;」がないとGAWKはtabletag.awkを見つけられませんので、必ず登録してください。。

tabletag.awk

BEGIN
1 : #. awk_tabletag.awk; 2 : # tab/space で区切られた表またはcsvをtableタグに変換 3 : #. BEGIN; タグの初期化 tableタグ(開く) 4 : BEGIN { 5 : need_th = ARG1; 6 : f_c = f_t = f_h = 1; 7 : tabletag_init(); 8 : 9 : #csv/tab/space+tabを簡易判別 10 : while (getline < ARGV[1] > 0) { 11 : fqc[++c] = aindex($0, ",", ar); 12 : fqt[c] = aindex($0, "\t", ar); 13 : fqh[c] = aindex($0, " \t", ar); 14 : } 15 : close(ARGV[1]); 16 : 17 : if (c > 1) { 18 : for (i = 1; i <= c - 1; i++) { 19 : if (fqc[i] != fqc[i + 1]) f_c = 0; 20 : if (fqh[i] != fqh[i + 1]) f_h = 0; 21 : if (fqt[i] != fqt[i + 1]) f_t = 0; 22 : } 23 : } 24 : else { 25 : f_c = f_t = f_h = 0; 26 : max = fqc[1]; 27 : if (max < fqt[1]) max = fqt[1]; 28 : if (max < fqh[1]) max = fqh[1]; 29 : if (max == fqc[1]) f_c = 1; 30 : if (max == fqt[1]) f_t = 1; 31 : if (max == fqh[1]) f_h = 1; 32 : } 33 : 34 : if (f_c && fqc[1]) FS = ","; 35 : else if (f_h && fqh[1]) FS = " \t"; #優先(残スペース防止) 36 : else if (f_t && fqt[1]) FS = "\t"; 37 : else ; 38 : print TB_O; 39 : }
ACTION_01
40 : #. Action; 文字列を作ってから書く 41 : { 42 : if (NR == 1 && need_th) { topen = TH_O; tclose = TH_C; } 43 : else { topen = TD_O; tclose = TD_C; } 44 : 45 : str = Tab1 TR_O "\n"; 46 : for (i = 1; i <= NF; i++) 47 : str = str Tab2 topen sprintf("%s", $i) tclose "\n"; 48 : print str Tab1 TR_C; 49 : }
END
50 : #. END; tableタグ(閉じる) 51 : END { 52 : print TB_C; 53 : }
tabletag_init()
54 : #. tabletag_init();tableタグを初期化 55 : function tabletag_init() { 56 : TB_O = "<table class=\"tbl1\">"; 57 : TB_C = "</table>"; 58 : TH_O = "<th>"; 59 : TH_C = "</th>"; 60 : TR_O = "<tr>"; 61 : TR_C = "</tr>"; 62 : TD_O = "<td>"; 63 : TD_C = "</td>" 64 : Tab1 = "\t"; 65 : Tab2 = "\t\t"; 66 : }
aindex()
67 : #. aindexa();index()拡張 68 : # 戻り値: 発見した個数 69 : # str: 文字列 70 : # find: 検索文字列 71 : # apos: 配列(全位置) 72 : function aindex(str, find, apos, pos, tpos, freq) { 73 : freq = 0; 74 : delete apos; 75 : do { 76 : if (pos = index(str, find)) { 77 : tpos += pos; 78 : apos[++freq] = tpos; 79 : str = substr(str, pos + 1); 80 : } 81 : } while (pos) 82 : return freq; 83 : }

文字列やファイルから、特定の文字(文字列)の出現回数を数える方法はいくつかあります。AWK 特有の数え方で split() を使用するものが一般的?ですが、今回は、こんな関数便利かもよ、と自作関数 aindex() を利用してみました。出現頻度が高いなら split($0, ar, ",") - 1 の方が速いのですが。

空白区切りの表(デフォルトFS)で先頭・末尾データが空("")であった場合、AWKはそのレコードを正しく分割できません。デフォルトFS 即ち FS=" "(スペース1文字) を指定すると、分割前に前後の空白を除去する仕様みたいです。split()も同じ仕様なのか、区切り文字をスペース1文字にすると、先頭の空データを無視してしまいます。上記の特定文字の出現回数を調べる利用法については要注意です。