PHP::表のセルを配列に入れ込む。
今まで集大成(かも)。
結論から言うとできたのかもしれない。
PHPの配列は結構いい加減なところ*1があるので、逆にそれを利用させてもらいました。
今回サンプルにした表は次の通り。
+-----+-----+-----+-----+-----+-----+-----+-----+-----+ | 0-0 | | | | | 0-8 | +-----+ + + 0-6 + 0-7 +-----+ | 1-0 | | 0-3 | | | 1-8 | +-----+ + +-----+-----+-----+ | 2-0 | 0-1 | | | 2-8 | +-----+ +-----+-----+-----+ +-----+ | 3-0 | | 3-3 | 3-4 | 2-6 | 3-8 | +-----+ +-----+-----+-----+ +-----+ | 4-0 | | 4-3 | | 4-8 | +-----+-----+-----+-----+-----+-----+-----+-----+-----+
たぶんこれで表を作るあらゆる場面を含んでいると思う。(何か足り気がするけど・・・)
この表のHTMLが次のようになるわな(一部省略)
... <tr> <td>テスト0-0</td> <td rowspan="5" colspan="2">テスト0-1</td> <td rowspan="3" colspan="3">テスト0-3</td> <td rowspan="2">テスト0-6</td> <td rowspan="2">テスト0-7</td> <td>テスト0-8</td> </tr> <tr> <td>テスト1-0</td> <td>テスト1-8</td> </tr> <tr> <td>テスト2-0</td> <td rowspan="3" colspan="2">テスト2-6</td> <td>テスト2-8</td> </tr> <tr> <td>テスト3-0</td> <td>テスト3-3</td> <td colspan="2">テスト3-4</td> <td>テスト3-8</td> </tr> <tr> <td>テスト4-0</td> <td colspan="3">テスト4-3</td> <td>テスト4-8</td> </tr> ...
見た目とHTMLとしてのデータとでは各行におけるセルの数が異なるんだよねぇ・・・。
まぁ、まずは各行、各列ごとに処理するため、次を前提としてその次の処理をする。
$table[2][$tbl] -> 上のHTML(最初の<tr>〜最後の</tr>までの部分)
<?php ... $rc = array(array()); $cell = array(array()); $count_tr = preg_match_all("/$reg_tr/u", $table[2][$tbl], $tr_array); for ($tr=0; $tr < $count_tr; $tr++) { $new_rowspan = 0; // 新規rowspanの個数 $existent_rowspan = 0; // 既存rowspanの個数 $now_cell = 0; // 今現在の(データとしての)セルの番号 $true_row = 0; // 本来(見た目)の列番号 $before_cell = 0; $count_td = preg_match_all("/$reg_td/u", $tr_array[1][$tr], $td_array); /* * $tr行目を * $count_td + $sum_rowspan(新規と既存の和) 回す */ for ($td=0; $td < $count_td + $sum_rowspan; $td++) { // 新規のrowspanを監視 $count_row = preg_match("/$reg_row/u", $td_array[1][$now_cell], $row_array); /* * 新規のrowspanがあった場合 * 1. rowspanの値を-1したものを$rowに代入 * 2. $new_rowspanを+1する * 3. 今のセル番号が前のセル番号と同じ場合 * 3-1. $new_rowspanを-1する * 4. $before_cellに今のセル番号を代入する * * なかった場合 * 1. $rowを0にする */ if ( $count_row ) { $row = $row_array[1] - 1; //バグがあったため修正 //if ( $before_cell != 0 ) // if ( $before_cell == $now_cell) // $new_rowspan -= 1; if ($td_num != 0 && $before_cell == $now_cell) $new_rowspan--; $new_rowspan++; $before_cell = $now_cell; } else $row = 0; // 新規のcolspanを監視 $count_col = preg_match("/$reg_col/u", $td_array[1][$now_cell], $col_array); /* * 新規のcolspanがあった場合 * 1. colspanの値を$colに代入 * * なかった場合 * 1. $colを1にする */ if ( $count_col ) $col = $col_array[1]; else $col = 1; // 1行目でなければ以下の処理をする if ( $tr != 0 ) preg_match("/$reg_irc/u", $rc[$tr - 1][$true_row], $rc_array); /* * 1行目 * もしくは * 前の行で同じ列のrowspanの値が0 * の場合 * 1. rcに[rowspanの値]:[colspanの値]で代入 * 2. cellに該当するセルのデータを代入 * 3. $now_cellを1増やす→データとしてのセルの番号を次に移行する * 4. 本来の列番号に$colを足して次の本来の列番号にする * * 違う場合→主にrowspanの値が0じゃない場合 * 1. 次の行でのrowspanの値を$next_rowに代入 * 2. rcに[$next_row]:[前の行でのcolspanの値]で代入 * 3. cellには" "(空白)を代入(もしかしたら""(空)でもいいのかな?) * 4. 本来の列番号に前の行でのcolspanの値を足して次の本来の列番号にする */ if ( $tr == 0 || $rc_array[1] == 0 ) { $rc[$tr][$true_row] = $row . ":" . $col; $cell[$tr][$true_row] = $td_array[2][$now_cell]; $now_cell++; $true_row += $col; } else { $next_row = $rc_array[1] - 1; $rc[$tr][$true_row] = $next_row . ":" . $rc_array[2]; $cell[$tr][$true_row] = " "; $true_row += $rc_array[2]; } /* * $next_rowが0じゃない場合→つまり既存のrowspanがあった場合 * 1. $existent_rowspanを+1する * 2. $next_rowを初期化(0)にする */ if ( $next_row != 0 ) { $existent_rowspan += 1; $next_row = 0; } } } ... ?>
で、サンプルの表で試したところ、次のようになった。
Array Array ( ( [0] => Array [0] => Array ( ( [0] => 0:1 [0] => 0-0 [1] => 4:2 [1] => 0-1 [3] => 2:3 [3] => 0-3 [6] => 1:1 [6] => 0-6 [7] => 1:1 [7] => 0-7 [8] => 0:1 [8] => 0-8 ) ) [1] => Array [1] => Array ( ( [0] => 0:1 [0] => 1-0 [1] => 3:2 [1] => [3] => 1:3 [3] => [6] => 0:1 [6] => [7] => 0:1 [7] => [8] => 0:1 [8] => 1-8 ) ) [2] => Array [2] => Array ( ( [0] => 0:1 [0] => 2-0 [1] => 2:2 [1] => [3] => 0:3 [3] => [6] => 2:2 [6] => 2-6 [8] => 0:1 [8] => 2-8 ) ) [3] => Array [3] => Array ( ( [0] => 0:1 [0] => 3-0 [1] => 1:2 [1] => [3] => 0:1 [3] => 3-3 [4] => 0:2 [4] => 3-4 [6] => 1:2 [6] => [8] => 0:1 [8] => 3-8 ) ) [4] => Array [4] => Array ( ( [0] => 0:1 [0] => 4-0 [1] => 0:2 [1] => [3] => 0:3 [3] => 4-3 [6] => 0:2 [6] => [8] => 0:1 [8] => 4-8 ) ) ) )
何とか意図したとおりになってくれてありがたい。
後はこれを元にTeXへ書換えていこう。rowspanが0じゃなかったらcline使うとかね。
くそう、時間かかったなぁ・・・。
余談
時間かかったけどこっちの方がソース綺麗。
前のやつ驚くほど汚かった。
*1:全ての行で列の数が違っても良いとか色々