HOME

手書の複雑は表から html の表を作らむ(awk 利用)

2016-3-11(Fri)

次のような複雑な表を html を手書きして作るのは、かなり面倒くさい。

活用あり 活用なし
自立語 動詞 主語になる 名詞
「し」で終わる 形容詞 主語にならない 修飾語になる 連用修飾 副詞
連体修飾 連体詞
「なり、たり」で終わる 形容動詞 独立語となる つづく 接続詞
切れる 感動詞
付属語 助動詞 助詞

なんとか、少しでも楽ができないかと考えた。もちろん、できる限り原始的なやり方でw

最初、makedown で書けないかと思ったが、ちょっと無理なよう。makedown の方言にまで手を出したくはないので、自前で何とかすることにした。

私の場合、複雑な表というのは、必ず紙の上に書いてデザインして、それを html に書き写すということをしている。それならいっそ、紙の設計図があることを前提にしてしまえばいいじゃないか! ようするに、お清書。

まず、次のような升目を薄く印刷した原稿用紙を用意し、その上にエンピツで表を書いていく。ひとに原稿を書いてもらうときには、この紙に書いてくれといって渡せばよい。

101102103104105106107108109110
201202203204205206207208209210
301302303304305306307308309310
401402403404405406407408409410
501502503504505506507508509510
601602603604605606607608609610
701702703704705706707708709710

原稿ができ上がったら、作りたいセルがどの升にまたがっているかを記録する。

たとえば、202,203,302,303 の 4 つの升を合併して 1 つのセルを作りたいとする。

302303
402403

これに abc という文字を入れたいならば、左上の 302 と 右下の 403 を取り出して、

302	403	abc

のような行を作る。こうして 1 セルを 1 行に記録するのである。なお、フィールドはタブ区切りにしてある。

セルを記録していく順番は、左上の数字の若い順にする。つまり、一番上の例でいうと、次のような順番になる。

1 2 活用あり 3 活用なし
4 自立語 5 動詞 6 主語になる 7 名詞
8 「し」で終わる 9 形容詞 10 主語にならない 11 修飾語になる 12 連用修飾 13 副詞
14 連体修飾 15 連体詞
16 「なり、たり」で終わる 17 形容動詞 18 独立語となる 19 つづく 20 接続詞
21 切れる 22 感動詞
23 付属語 24 助動詞 25 助詞

これは、html の記述順と同じだ。

こうして次のようなファイルを作成した。

101		
102	103	活用あり
104	107	活用なし
201	601	自立語
202	203	動詞
204		主語になる
205	207	名詞
302	402	「し」で終わる
303	402	形容詞
304	604	主語にならない
305	405	修飾語になる
306		連用修飾
307		副詞
406		連体修飾
407		連体詞
502	602	「なり、たり」で終わる
503	603	形容動詞
505	605	独立語となる
506		つづく
507		接続詞
606		切れる
607		感動詞
701		付属語
702	703	助動詞
704	707	助詞

空白のセルも 1 行を使用する。また、左から 2 番目のコラムが欠けているものは、1 升で 1 つのセルになっているもの。

このファイルを、awk で処理する。awk のスクリプトは

BEGIN{print "<table>"}
{
    FS="\t";
    if ($2 == "") $2=$1;
    row_from=int($1/100);
    row_to=int($2/100);
    col_from=$1%100;
    col_to=$2%100;
    nrow=row_to-row_from;
    ncol=col_to-col_from;
    if (row_from!=row_from_prev){
	if (NR==1) printf "<tr>"; else print "</tr>\n<tr>";
    };
    row_from_prev=row_from;
    printf "\t<td ";
    if (nrow>0) rowspan="rowspan="nrow+1; else rowspan="";
    if (ncol>0) colspan="colspan="ncol+1; else colspan="";
    print rowspan " " colspan ">"$3"</td>";
}
END{print "</tr>\n</table>"}

その結果、

<table>
<tr>	<td  ></td>
	<td  colspan=2>活用あり</td>
	<td  colspan=4>活用なし</td>
</tr>
<tr>
	<td rowspan=5 >自立語</td>
	<td  colspan=2>動詞</td>
	<td  >主語になる</td>
	<td  colspan=3>名詞</td>
</tr>
<tr>
	<td rowspan=2 >「し」で終わる</td>
	<td rowspan=2 >形容詞</td>
	<td rowspan=4 >主語にならない</td>
	<td rowspan=2 >修飾語になる</td>
	<td  >連用修飾</td>
	<td  >副詞</td>
</tr>
<tr>
	<td  >連体修飾</td>
	<td  >連体詞</td>
</tr>
<tr>
	<td rowspan=2 >「なり、たり」で終わる</td>
	<td rowspan=2 >形容動詞</td>
	<td rowspan=2 >独立語となる</td>
	<td  >つづく</td>
	<td  >接続詞</td>
</tr>
<tr>
	<td  >切れる</td>
	<td  >感動詞</td>
</tr>
<tr>
	<td  >付属語</td>
	<td  colspan=2>助動詞</td>
	<td  colspan=4>助詞</td>
</tr>
</table>

こうして、冒頭の表が出来上がった。

そんなにちゃんと原稿作ったんなら、それを見ながら直接 html 書けばいいじゃないかという気もするが、入力データが(ほぼ)正規化されているってところが肝心なのだ。他のフォーマットで書き出す場合にも便利だし、なにより気持ちいいからね。

考えるに、html の表は各セルの配置場所は文脈に依存して決まる。そういうものは編集をするのに便利なのだが、複雑な表というのはこれによって却って見通しが悪くなる。原稿を書くことと清書することを同時にやってしまおうとするときの限界のように思える。

自分の趣味からいうと、原稿というのは書きやすいということだけを考えたくて、清書というのは美しいということだけを考えたい。もっともこの趣味を離れて眺めても、ものによっては、原稿を書くのと清書をするのは別のことと考えたほうが生産性が上がるのではないかと思う。

おわり