diff options
Diffstat (limited to 'inc/parser')
-rw-r--r-- | inc/parser/handler.php | 64 | ||||
-rw-r--r-- | inc/parser/renderer.php | 4 | ||||
-rw-r--r-- | inc/parser/xhtml.php | 8 |
3 files changed, 68 insertions, 8 deletions
diff --git a/inc/parser/handler.php b/inc/parser/handler.php index dfaf1adaa..a1040d12e 100644 --- a/inc/parser/handler.php +++ b/inc/parser/handler.php @@ -1156,6 +1156,9 @@ class Doku_Handler_Table { var $currentCols = 0; var $firstCell = false; var $lastCellType = 'tablecell'; + var $inTableHead = true; + var $currentRow = array('tableheader' => 0, 'tablecell' => 0); + var $countTableHeadRows = 0; function Doku_Handler_Table(& $CallWriter) { $this->CallWriter = & $CallWriter; @@ -1223,15 +1226,24 @@ class Doku_Handler_Table { $this->firstCell = true; $this->lastCellType = 'tablecell'; $this->maxRows++; + if ($this->inTableHead) { + $this->currentRow = array('tablecell' => 0, 'tableheader' => 0); + } } function tableRowClose($call) { + if ($this->inTableHead && ($this->inTableHead = $this->isTableHeadRow())) { + $this->countTableHeadRows++; + } // Strip off final cell opening and anything after it while ( $discard = array_pop($this->tableCalls ) ) { if ( $discard[0] == 'tablecell_open' || $discard[0] == 'tableheader_open') { break; } + if (!empty($this->currentRow[$discard[0]])) { + $this->currentRow[$discard[0]]--; + } } $this->tableCalls[] = array('tablerow_close', array(), $call[2]); @@ -1240,7 +1252,20 @@ class Doku_Handler_Table { } } + function isTableHeadRow() { + $td = $this->currentRow['tablecell']; + $th = $this->currentRow['tableheader']; + + if (!$th || $td > 2) return false; + if (2*$td > $th) return false; + + return true; + } + function tableCell($call) { + if ($this->inTableHead) { + $this->currentRow[$call[0]]++; + } if ( !$this->firstCell ) { // Increase the span @@ -1288,6 +1313,13 @@ class Doku_Handler_Table { $cellKey = array(); $toDelete = array(); + // if still in tableheader, then there can be no table header + // as all rows can't be within <THEAD> + if ($this->inTableHead) { + $this->inTableHead = false; + $this->countTableHeadRows = 0; + } + // Look for the colspan elements and increment the colspan on the // previous non-empty opening cell. Once done, delete all the cells // that contain colspans @@ -1295,6 +1327,14 @@ class Doku_Handler_Table { $call = $this->tableCalls[$key]; switch ($call[0]) { + case 'table_open' : + if($this->countTableHeadRows) { + array_splice($this->tableCalls, $key+1, 0, array( + array('tablethead_open', array(), $call[2])) + ); + } + break; + case 'tablerow_open': $lastRow++; @@ -1364,15 +1404,19 @@ class Doku_Handler_Table { } else { $spanning_cell = null; - for($i = $lastRow-1; $i > 0; $i--) { - if ( $this->tableCalls[$cellKey[$i][$lastCell]][0] == 'tablecell_open' || $this->tableCalls[$cellKey[$i][$lastCell]][0] == 'tableheader_open' ) { + // can't cross thead/tbody boundary + if (!$this->countTableHeadRows || ($lastRow-1 != $this->countTableHeadRows)) { + for($i = $lastRow-1; $i > 0; $i--) { - if ($this->tableCalls[$cellKey[$i][$lastCell]][1][2] >= $lastRow - $i) { - $spanning_cell = $i; - break; - } + if ( $this->tableCalls[$cellKey[$i][$lastCell]][0] == 'tablecell_open' || $this->tableCalls[$cellKey[$i][$lastCell]][0] == 'tableheader_open' ) { + + if ($this->tableCalls[$cellKey[$i][$lastCell]][1][2] >= $lastRow - $i) { + $spanning_cell = $i; + break; + } + } } } if (is_null($spanning_cell)) { @@ -1403,6 +1447,10 @@ class Doku_Handler_Table { $key += 3; } + if($this->countTableHeadRows == $lastRow) { + array_splice($this->tableCalls, $key+1, 0, array( + array('tablethead_close', array(), $call[2]))); + } break; } @@ -1445,7 +1493,7 @@ class Doku_Handler_Block { var $blockOpen = array( 'header', 'listu_open','listo_open','listitem_open','listcontent_open', - 'table_open','tablerow_open','tablecell_open','tableheader_open', + 'table_open','tablerow_open','tablecell_open','tableheader_open','tablethead_open', 'quote_open', 'code','file','hr','preformatted','rss', 'htmlblock','phpblock', @@ -1455,7 +1503,7 @@ class Doku_Handler_Block { var $blockClose = array( 'header', 'listu_close','listo_close','listitem_close','listcontent_close', - 'table_close','tablerow_close','tablecell_close','tableheader_close', + 'table_close','tablerow_close','tablecell_close','tableheader_close','tablethead_close', 'quote_close', 'code','file','hr','preformatted','rss', 'htmlblock','phpblock', diff --git a/inc/parser/renderer.php b/inc/parser/renderer.php index 0c3c56c56..e92b81bd7 100644 --- a/inc/parser/renderer.php +++ b/inc/parser/renderer.php @@ -249,6 +249,10 @@ class Doku_Renderer extends DokuWiki_Plugin { function table_close($pos = null){} + function tablethead_open(){} + + function tablethead_close(){} + function tablerow_open(){} function tablerow_close(){} diff --git a/inc/parser/xhtml.php b/inc/parser/xhtml.php index e3f9a4187..cf36a8175 100644 --- a/inc/parser/xhtml.php +++ b/inc/parser/xhtml.php @@ -963,6 +963,14 @@ class Doku_Renderer_xhtml extends Doku_Renderer { } } + function tablethead_open(){ + $this->doc .= DOKU_TAB . '<thead>' . DOKU_LF; + } + + function tablethead_close(){ + $this->doc .= DOKU_TAB . '</thead>' . DOKU_LF; + } + function tablerow_open(){ // initialize the cell counter used for classes $this->_counter['cell_counter'] = 0; |