Reverted r85922 and related: new doTableStuff(). I copied in the old doTableStuff...
authorTim Starling <tstarling@users.mediawiki.org>
Thu, 15 Sep 2011 12:10:53 +0000 (12:10 +0000)
committerTim Starling <tstarling@users.mediawiki.org>
Thu, 15 Sep 2011 12:10:53 +0000 (12:10 +0000)
CREDITS
includes/Sanitizer.php
includes/parser/Parser.php
tests/parser/parserTests.txt

diff --git a/CREDITS b/CREDITS
index 5c64336..a792447 100644 (file)
--- a/CREDITS
+++ b/CREDITS
@@ -83,7 +83,6 @@ following names for their contribution to the product.
 * Azliq7
 * Beau
 * Bergi
-* Bluehairedlawyer
 * Borislav Manolov
 * Brad Jorsch
 * Brent G
index 5080582..227fa7c 100644 (file)
@@ -379,7 +379,7 @@ class Sanitizer {
                                'strike', 'strong', 'tt', 'var', 'div', 'center',
                                'blockquote', 'ol', 'ul', 'dl', 'table', 'caption', 'pre',
                                'ruby', 'rt' , 'rb' , 'rp', 'p', 'span', 'abbr', 'dfn',
-                               'kbd', 'samp', 'thead', 'tbody', 'tfoot'
+                               'kbd', 'samp'
                        );
                        $htmlsingle = array(
                                'br', 'hr', 'li', 'dt', 'dd'
index 744f2e6..0d3e2a2 100644 (file)
@@ -841,318 +841,195 @@ class Parser {
         * parse the wiki syntax used to render tables
         *
         * @private
-        *
-        * @param $text string
-        *
-        * @return string
         */
        function doTableStuff( $text ) {
                wfProfileIn( __METHOD__ );
 
                $lines = StringUtils::explode( "\n", $text );
                $out = '';
-               $output =& $out;
+               $td_history = array(); # Is currently a td tag open?
+               $last_tag_history = array(); # Save history of last lag activated (td, th or caption)
+               $tr_history = array(); # Is currently a tr tag open?
+               $tr_attributes = array(); # history of tr attributes
+               $has_opened_tr = array(); # Did this table open a <tr> element?
+               $indent_level = 0; # indent level of the table
 
                foreach ( $lines as $outLine ) {
                        $line = trim( $outLine );
 
-                       # empty line, go to next line,
-                       # but only append \n if outside of table
-                       if ( $line === '' ) {
-                               $output .= $outLine;
-                               if ( !isset( $tables[0] ) ) {
-                                       $output .= "\n";
-                               }
+                       if ( $line === '' ) { # empty line, go to next line
+                               $out .= $outLine."\n";
                                continue;
                        }
-                       $firstChars = $line[0];
-                       if ( strlen( $line ) > 1 ) {
-                               $firstChars .= in_array( $line[1], array( '}', '+', '-' ) ) ? $line[1] : '';
-                       }
+
+                       $first_character = $line[0];
                        $matches = array();
 
-                       if ( preg_match( '/^(:*)\s*\{\|(.*)$/', $line , $matches ) ) {
-                               $tables[] = array();
-                               $table =& $this->last( $tables );
-                               $table[0] = array(); // first row
-                               $currentRow =& $table[0];
-                               $table['indent'] = strlen( $matches[1] );
+                       if ( preg_match( '/^(:*)\{\|(.*)$/', $line , $matches ) ) {
+                               # First check if we are starting a new table
+                               $indent_level = strlen( $matches[1] );
 
                                $attributes = $this->mStripState->unstripBoth( $matches[2] );
                                $attributes = Sanitizer::fixTagAttributes( $attributes , 'table' );
 
-                               if ( $attributes !== '' ) {
-                                       $table['attributes'] = $attributes;
-                               }
-                       } elseif ( !isset( $tables[0] ) ) {
-                               // we're outside the table
-
-                               $out .= $outLine . "\n";
-                       } elseif ( $firstChars === '|}' ) {
-                               // trim the |} code from the line
-                               $line = substr ( $line , 2 );
-
-                               // Shorthand for last row
-                               $lastRow =& $this->last( $table );
-
-                               // a thead at the end becomes a tfoot, unless there is only one row
-                               // Do this before deleting empty last lines to allow headers at the bottom of tables
-                               if ( isset( $lastRow['type'] ) && $lastRow['type'] == 'thead' && isset( $table[1] ) ) {
-                                       $lastRow['type'] = 'tfoot';
-                                       for ( $i = 0; isset( $lastRow[$i] ); $i++ ) {
-                                               $lastRow[$i]['type'] = 'th';
-                                       }
-                               }
+                               $outLine = str_repeat( '<dl><dd>' , $indent_level ) . "<table{$attributes}>";
+                               array_push( $td_history , false );
+                               array_push( $last_tag_history , '' );
+                               array_push( $tr_history , false );
+                               array_push( $tr_attributes , '' );
+                               array_push( $has_opened_tr , false );
+                       } elseif ( count( $td_history ) == 0 ) {
+                               # Don't do any of the following
+                               $out .= $outLine."\n";
+                               continue;
+                       } elseif ( substr( $line , 0 , 2 ) === '|}' ) {
+                               # We are ending a table
+                               $line = '</table>' . substr( $line , 2 );
+                               $last_tag = array_pop( $last_tag_history );
 
-                               // Delete empty last lines
-                               if ( empty( $lastRow ) ) {
-                                       $lastRow = NULL;
+                               if ( !array_pop( $has_opened_tr ) ) {
+                                       $line = "<tr><td></td></tr>{$line}";
                                }
-                               $o = '';
-                               $curtable = array_pop( $tables );
 
-                               #Add a line-ending before the table, but only if there isn't one already
-                               if ( substr( $out, -1 ) !== "\n" ) {
-                                       $o .= "\n";
+                               if ( array_pop( $tr_history ) ) {
+                                       $line = "</tr>{$line}";
                                }
-                               $o .= $this->generateTableHTML( $curtable ) . $line . "\n";
 
-                               if ( count( $tables ) > 0 ) {
-                                       $table =& $this->last( $tables );
-                                       $currentRow =& $this->last( $table );
-                                       $currentElement =& $this->last( $currentRow );
-
-                                       $output =& $currentElement['content'];
-                               } else {
-                                       $output =& $out;
+                               if ( array_pop( $td_history ) ) {
+                                       $line = "</{$last_tag}>{$line}";
                                }
+                               array_pop( $tr_attributes );
+                               $outLine = $line . str_repeat( '</dd></dl>' , $indent_level );
+                       } elseif ( substr( $line , 0 , 2 ) === '|-' ) {
+                               # Now we have a table row
+                               $line = preg_replace( '#^\|-+#', '', $line );
 
-                               $output .= $o;
-
-                       } elseif ( $firstChars === '|-' ) {
-                               // start a new row element
-                               // but only when we haven't started one already
-                               if ( count( $currentRow ) != 0 ) {
-                                       $table[] = array();
-                                       $currentRow =& $this->last( $table );
-                               }
-                               // Get the attributes, there's nothing else useful in $line now
-                               $line = substr ( $line , 2 );
+                               # Whats after the tag is now only attributes
                                $attributes = $this->mStripState->unstripBoth( $line );
                                $attributes = Sanitizer::fixTagAttributes( $attributes, 'tr' );
-                               if ( $attributes !== '' ) {
-                                       $currentRow['attributes'] = $attributes;
-                               }
+                               array_pop( $tr_attributes );
+                               array_push( $tr_attributes, $attributes );
 
-                       } elseif ( $firstChars  === '|+' ) {
-                               // a table caption, but only proceed if there isn't one already
-                               if ( !isset ( $table['caption'] ) ) {
-                                       $line = substr ( $line , 2 );
-
-                                       $c = $this->getCellAttr( $line , 'caption' );
-                                       $table['caption'] = array();
-                                       $table['caption']['content'] = $c[0];
-                                       if ( isset( $c[1] ) ) $table['caption']['attributes'] = $c[1];
-                                       unset( $c );
-                                       $output =& $table['caption']['content'];
-                               }
-                       } elseif ( $firstChars === '|' || $firstChars === '!' || $firstChars === '!+' ) {
-                               // Which kind of cells are we dealing with
-                               $currentTag = 'td';
-                               $line = substr ( $line , 1 );
-
-                               if ( $firstChars === '!'  || $firstChars === '!+' ) {
-                                       $line = str_replace ( '!!' , '||' , $line );
-                                       $currentTag = 'th';
-                               }
+                               $line = '';
+                               $last_tag = array_pop( $last_tag_history );
+                               array_pop( $has_opened_tr );
+                               array_push( $has_opened_tr , true );
 
-                               // Split up multiple cells on the same line.
-                               $cells = StringUtils::explodeMarkup( '||' , $line );
-                               $line = ''; // save memory
+                               if ( array_pop( $tr_history ) ) {
+                                       $line = '</tr>';
+                               }
 
-                               // decide whether thead to tbody
-                               if ( !array_key_exists( 'type', $currentRow ) ) {
-                                       $currentRow['type'] = ( $firstChars === '!' ) ? 'thead' : 'tbody' ;
-                               } elseif ( $firstChars === '|' ) {
-                                       $currentRow['type'] = 'tbody';
+                               if ( array_pop( $td_history ) ) {
+                                       $line = "</{$last_tag}>{$line}";
                                }
 
-                               // Loop through each table cell
-                               foreach ( $cells as $cell ) {
-                                       // a new cell
-                                       $currentRow[] = array();
-                                       $currentElement =& $this->last( $currentRow );
+                               $outLine = $line;
+                               array_push( $tr_history , false );
+                               array_push( $td_history , false );
+                               array_push( $last_tag_history , '' );
+                       } elseif ( $first_character === '|' || $first_character === '!' || substr( $line , 0 , 2 )  === '|+' ) {
+                               # This might be cell elements, td, th or captions
+                               if ( substr( $line , 0 , 2 ) === '|+' ) {
+                                       $first_character = '+';
+                                       $line = substr( $line , 1 );
+                               }
 
-                                       $currentElement['type'] = $currentTag;
+                               $line = substr( $line , 1 );
 
-                                       $c = $this->getCellAttr( $cell , $currentTag );
-                                       $currentElement['content'] = $c[0];
-                                       if ( isset( $c[1] ) ) $currentElement['attributes'] = $c[1];
-                                       unset( $c );
+                               if ( $first_character === '!' ) {
+                                       $line = str_replace( '!!' , '||' , $line );
                                }
-                               $output =& $currentElement['content'];
 
-                       } else {
-                               $output .= "\n$outLine";
-                       }
-               }
+                               # Split up multiple cells on the same line.
+                               # FIXME : This can result in improper nesting of tags processed
+                               # by earlier parser steps, but should avoid splitting up eg
+                               # attribute values containing literal "||".
+                               $cells = StringUtils::explodeMarkup( '||' , $line );
 
-               # Remove trailing line-ending (b/c)
-               if ( substr( $out, -1 ) === "\n" ) {
-                       $out = substr( $out, 0, -1 );
-               }
+                               $outLine = '';
 
-               # Close any unclosed tables
-               if ( isset( $tables ) && count( $tables ) > 0 ) {
-                       for ( $i = 0; $i < count( $tables ); $i++ ) {
-                               $curtable = array_pop( $tables );
-                               $curtable = $this->generateTableHTML( $curtable );
-                               #Add a line-ending before the table, but only if there isn't one already
-                               if ( substr( $out, -1 ) !== "\n"  && $curtable !== "" ) {
-                                       $out .= "\n";
-                               }
-                               $out .= $curtable;
-                       }
-               }
+                               # Loop through each table cell
+                               foreach ( $cells as $cell ) {
+                                       $previous = '';
+                                       if ( $first_character !== '+' ) {
+                                               $tr_after = array_pop( $tr_attributes );
+                                               if ( !array_pop( $tr_history ) ) {
+                                                       $previous = "<tr{$tr_after}>\n";
+                                               }
+                                               array_push( $tr_history , true );
+                                               array_push( $tr_attributes , '' );
+                                               array_pop( $has_opened_tr );
+                                               array_push( $has_opened_tr , true );
+                                       }
 
-               wfProfileOut( __METHOD__ );
+                                       $last_tag = array_pop( $last_tag_history );
 
-               return $out;
-       }
+                                       if ( array_pop( $td_history ) ) {
+                                               $previous = "</{$last_tag}>\n{$previous}";
+                                       }
 
-       /**
-        * Helper function for doTableStuff() separating the contents of cells from
-        * attributes. Particularly useful as there's a possible bug and this action
-        * is repeated twice.
-        *
-        * @private
-        * @param $cell
-        * @param $tagName
-        * @return array
-        */
-       function getCellAttr ( $cell, $tagName ) {
-               $attributes = null;
+                                       if ( $first_character === '|' ) {
+                                               $last_tag = 'td';
+                                       } elseif ( $first_character === '!' ) {
+                                               $last_tag = 'th';
+                                       } elseif ( $first_character === '+' ) {
+                                               $last_tag = 'caption';
+                                       } else {
+                                               $last_tag = '';
+                                       }
 
-               $cell = trim ( $cell );
+                                       array_push( $last_tag_history , $last_tag );
 
-               // A cell could contain both parameters and data
-               $cellData = explode ( '|' , $cell , 2 );
+                                       # A cell could contain both parameters and data
+                                       $cell_data = explode( '|' , $cell , 2 );
 
-               // Bug 553: Note that a '|' inside an invalid link should not
-               // be mistaken as delimiting cell parameters
-               if ( strpos( $cellData[0], '[[' ) !== false ) {
-                       $content = trim ( $cell );
-               }
-               elseif ( count ( $cellData ) == 1 ) {
-                       $content = trim ( $cellData[0] );
-               } else {
-                       $attributes = $this->mStripState->unstripBoth( $cellData[0] );
-                       $attributes = Sanitizer::fixTagAttributes( $attributes , $tagName );
+                                       # Bug 553: Note that a '|' inside an invalid link should not
+                                       # be mistaken as delimiting cell parameters
+                                       if ( strpos( $cell_data[0], '[[' ) !== false ) {
+                                               $cell = "{$previous}<{$last_tag}>{$cell}";
+                                       } elseif ( count( $cell_data ) == 1 ) {
+                                               $cell = "{$previous}<{$last_tag}>{$cell_data[0]}";
+                                       } else {
+                                               $attributes = $this->mStripState->unstripBoth( $cell_data[0] );
+                                               $attributes = Sanitizer::fixTagAttributes( $attributes , $last_tag );
+                                               $cell = "{$previous}<{$last_tag}{$attributes}>{$cell_data[1]}";
+                                       }
 
-                       $content = trim ( $cellData[1] );
+                                       $outLine .= $cell;
+                                       array_push( $td_history , true );
+                               }
+                       }
+                       $out .= $outLine . "\n";
                }
-               return array( $content, $attributes );
-       }
 
-
-       /**
-        * Helper function for doTableStuff(). This converts the structured array into html.
-        *
-        * @private
-        *
-        * @param $table array
-        *
-        * @return string
-        */
-       function generateTableHTML( &$table ) {
-               $return = str_repeat( '<dl><dd>' , $table['indent'] );
-               $return .= '<table';
-               $return .= isset( $table['attributes'] ) ? $table['attributes'] : '';
-               $return .= '>';
-               unset( $table['attributes'] );
-
-               if ( isset( $table['caption'] ) ) {
-                       $return .= "\n<caption";
-                       $return .= isset( $table['caption']['attributes'] ) ? $table['caption']['attributes'] : '';
-                       $return .= '>';
-                       $return .= $table['caption']['content'];
-                       $return .= "\n</caption>";
-               }
-               $lastSection = '';
-               $empty = true;
-               $simple = true;
-
-               // If we only have tbodies, mark table as simple
-               for ( $i = 0; isset( $table[$i] ); $i++ ) {
-                       if ( !count( $table[$i] ) ) continue;
-                       if ( !isset( $table[$i]['type'] ) ) {
-                               $table[$i]['type'] = 'tbody';
+               # Closing open td, tr && table
+               while ( count( $td_history ) > 0 ) {
+                       if ( array_pop( $td_history ) ) {
+                               $out .= "</td>\n";
                        }
-                       if ( !$lastSection ) {
-                               $lastSection = $table[$i]['type'];
-                       } elseif ( $lastSection != $table[$i]['type'] ) {
-                               $simple = false;
+                       if ( array_pop( $tr_history ) ) {
+                               $out .= "</tr>\n";
                        }
-               }
-               $lastSection = '';
-               for ( $i = 0; isset( $table[$i] ); $i++ ) {
-                       if ( !count( $table[$i] ) ) continue;
-                       $empty = false; // check for empty tables
-
-                       if ( $table[$i]['type'] != $lastSection && !$simple ) {
-                               $return .= "\n<" . $table[$i]['type'] . '>';
+                       if ( !array_pop( $has_opened_tr ) ) {
+                               $out .= "<tr><td></td></tr>\n" ;
                        }
 
-                       $return .= "\n<tr";
-                       $return .= isset( $table[$i]['attributes'] ) ? $table[$i]['attributes'] : '';
-                       $return .= '>';
-                       for ( $j = 0; isset( $table[$i][$j] ); $j++ ) {
-                               if ( !isset( $table[$i][$j]['type'] ) ) $table[$i][$j]['type'] = 'td';
-                               $return .= "\n<" . $table[$i][$j]['type'];
-                               $return .= isset( $table[$i][$j]['attributes'] ) ? $table[$i][$j]['attributes'] : '';
-                               $return .= '>';
-
-                               $return .= $table[$i][$j]['content'];
-                               if ( $table[$i][$j]['content'] != '' )
-                                       $return .= "\n";
-
-                               $return .= '</' . $table[$i][$j]['type'] . '>';
-                               unset( $table[$i][$j] );
-                       }
-                       $return .= "\n</tr>";
+                       $out .= "</table>\n";
+               }
 
-                       if ( ( !isset( $table[$i + 1] ) && !$simple ) || ( isset( $table[$i + 1] ) && isset( $table[$i + 1]['type'] ) && $table[$i]['type'] != $table[$i + 1]['type'] ) ) {
-                               $return .= '</' . $table[$i]['type'] . '>';
-                       }
-                       $lastSection = $table[$i]['type'];
-                       unset( $table[$i] );
+               # Remove trailing line-ending (b/c)
+               if ( substr( $out, -1 ) === "\n" ) {
+                       $out = substr( $out, 0, -1 );
                }
-               if ( $empty ) {
-                       if ( isset( $table['caption'] ) ) {
-                               $return .= "\n<tr><td></td></tr>";
-                       } else {
-                               return '';
-                       }
+
+               # special case: don't return empty table
+               if ( $out === "<table>\n<tr><td></td></tr>\n</table>" ) {
+                       $out = '';
                }
-               $return .= "\n</table>";
-               $return .= str_repeat( '</dd></dl>' , $table['indent'] );
 
-               return $return;
-       }
+               wfProfileOut( __METHOD__ );
 
-       /**
-        * like end() but only works on the numeric array index and php's internal pointers
-        * returns a reference to the last element of an array much like "\$arr[-1]" in perl
-        * ignores associative elements and will create a 0 key will a NULL value if there were
-        * no numric elements and an array itself if not previously defined.
-        *
-        * @private
-        *
-        * @param $arr array
-        */
-       function &last ( &$arr ) {
-               for ( $i = count( $arr ); ( !isset( $arr[$i] ) && $i > 0 ); $i-- ) {  }
-               return $arr[$i];
+               return $out;
        }
 
        /**
index 5781e58..8ed3f2a 100644 (file)
@@ -1246,10 +1246,8 @@ A table with nothing but a caption
 |}
 !! result
 <table>
-<caption>caption
-</caption>
-<tr><td></td></tr>
-</table>
+<caption> caption
+</caption><tr><td></td></tr></table>
 
 !! end
 
@@ -1264,338 +1262,13 @@ Simple table
 !! result
 <table>
 <tr>
-<td>1
-</td>
-<td>2
-</td>
-</tr>
-<tr>
-<td>3
-</td>
-<td>4
-</td>
-</tr>
-</table>
-
-!! end
-
-!! test
-Table inside unclosed table w/o cells
-!! input
-{|
-{| 
-| foo bar
-|}
-
-!! result
-<table>
-<tr>
-<td>
-<table>
-<tr>
-<td>foo bar
-</td>
-</tr>
-</table>
-</td>
-</tr>
-</table>
-
-!! end
-
-!! test
-Table with thead
-!! input
-{| 
-! Number !! Another number
-|-
-| 1 || 2
-|- 
-| 3 || 4
-|}
-!! result
-<table>
-<thead>
-<tr>
-<th>Number
-</th>
-<th>Another number
-</th>
-</tr></thead>
-<tbody>
-<tr>
-<td>1
-</td>
-<td>2
-</td>
-</tr>
-<tr>
-<td>3
-</td>
-<td>4
-</td>
-</tr></tbody>
-</table>
-
-!! end
-
-!! test
-Table with multiple captions: Only keep first
-!! input
-{|
-|+ caption 1
-|+ caption 2
-|}
-!! result
-<table>
-<caption>caption 1
-</caption>
-<tr><td></td></tr>
-</table>
-
-!! end
-
-!! test
-Table with multiline caption
-!! input
-{|
-|+ caption 1
-further caption
-|}
-!! result
-<table>
-<caption>caption 1
-further caption
-</caption>
-<tr><td></td></tr>
-</table>
-
-!! end
-!! test
-Table with multiple thead
-!! input
-{| 
-! Number !! Another number
-|-
-| 1 || 2
-|- 
-! Some other number !! Another number
-|-
-| 3 || 4
-|}
-!! result
-<table>
-<thead>
-<tr>
-<th>Number
-</th>
-<th>Another number
-</th>
-</tr></thead>
-<tbody>
-<tr>
-<td>1
-</td>
-<td>2
-</td>
-</tr></tbody>
-<thead>
-<tr>
-<th>Some other number
-</th>
-<th>Another number
-</th>
-</tr></thead>
-<tbody>
-<tr>
-<td>3
-</td>
-<td>4
-</td>
-</tr></tbody>
-</table>
-
-!! end
-!! test
-Table with thead & tfoot
-!! input
-{| 
-! Number !! Another number
-|-
-| 1 || 2
-|- 
-! Some other number !! Another number
-|-
-| 3 || 4
-|-
-! Total: 4 !! Total: 6
-|}
-!! result
-<table>
-<thead>
-<tr>
-<th>Number
-</th>
-<th>Another number
-</th>
-</tr></thead>
-<tbody>
-<tr>
-<td>1
-</td>
-<td>2
-</td>
-</tr></tbody>
-<thead>
-<tr>
-<th>Some other number
-</th>
-<th>Another number
-</th>
-</tr></thead>
-<tbody>
-<tr>
-<td>3
-</td>
-<td>4
-</td>
-</tr></tbody>
-<tfoot>
-<tr>
-<th>Total: 4
-</th>
-<th>Total: 6
-</th>
-</tr></tfoot>
-</table>
-
-!! end
-
-!! test
-Table have th inside tfoot
-!! input
-{| 
-| cell1 || cell2
-|-
-! Footer1 !! Footer2
-|}
-!! result
-<table>
-<tbody>
-<tr>
-<td>cell1
-</td>
-<td>cell2
-</td>
-</tr></tbody>
-<tfoot>
-<tr>
-<th>Footer1
-</th>
-<th>Footer2
-</th>
-</tr></tfoot>
-</table>
-
-!! end
-
-!! test
-Table have th inside thead
-!! input
-{| 
-! Header1 !! Header2
-|-
-| cell1 || cell2
-|}
-!! result
-<table>
-<thead>
-<tr>
-<th>Header1
-</th>
-<th>Header2
-</th>
-</tr></thead>
-<tbody>
+<td> 1 </td>
+<td> 2
+</td></tr>
 <tr>
-<td>cell1
-</td>
-<td>cell2
-</td>
-</tr></tbody>
-</table>
-
-!! end
-
-!! test
-Table with list inside
-!! input
-{|
-|style="width: 5em; text-align: center"| gives
-|style="border: 1px dashed #2F6FAB; padding: 0.5em; margin: 0.5em"|
-# Some
-# list
-# Lorem
-# ipsum
-# dolor
-|}
-!! result
-<table>
-<tr>
-<td style="width: 5em; text-align: center">gives
-</td>
-<td style="border: 1px dashed #2F6FAB; padding: 0.5em; margin: 0.5em">
-<ol><li> Some
-</li><li> list
-</li><li> Lorem
-</li><li> ipsum
-</li><li> dolor
-</li></ol>
-</td>
-</tr>
-</table>
-
-!! end
-!! test
-Indented table wrapped in html tags (Related to Bug 26362)
-!! input
-<div>
-:{|
-|-
-| test
-|}</div>
-
-!! result
-<div>
-<dl><dd><table>
-<tr>
-<td>test
-</td>
-</tr>
-</table></dd></dl></div>
-
-!! end
-
-!! test
-Table with multiline contents
-!! input
-{|
-| Alice
-Bob
-dfdfg
-dfg
-|}
-!! result
-<table>
-<tr>
-<td>Alice
-<p>Bob
-dfdfg
-dfg
-</p>
-</td>
-</tr>
-</table>
+<td> 3 </td>
+<td> 4
+</td></tr></table>
 
 !! end
 
@@ -1626,69 +1299,47 @@ Multiplication table
 <table border="1" cellpadding="2">
 <caption>Multiplication table
 </caption>
-<thead>
 <tr>
-<th>&#215;
-</th>
-<th>1
-</th>
-<th>2
-</th>
-<th>3
-</th>
-</tr></thead>
-<tbody>
+<th> &#215; </th>
+<th> 1 </th>
+<th> 2 </th>
+<th> 3
+</th></tr>
 <tr>
-<th>1
+<th> 1
 </th>
-<td>1
-</td>
-<td>2
-</td>
-<td>3
-</td>
-</tr>
+<td> 1 </td>
+<td> 2 </td>
+<td> 3
+</td></tr>
 <tr>
-<th>2
+<th> 2
 </th>
-<td>2
-</td>
-<td>4
-</td>
-<td>6
-</td>
-</tr>
+<td> 2 </td>
+<td> 4 </td>
+<td> 6
+</td></tr>
 <tr>
-<th>3
+<th> 3
 </th>
-<td>3
-</td>
-<td>6
-</td>
-<td>9
-</td>
-</tr>
+<td> 3 </td>
+<td> 6 </td>
+<td> 9
+</td></tr>
 <tr>
-<th>4
+<th> 4
 </th>
-<td>4
-</td>
-<td>8
-</td>
-<td>12
-</td>
-</tr>
+<td> 4 </td>
+<td> 8 </td>
+<td> 12
+</td></tr>
 <tr>
-<th>5
+<th> 5
 </th>
-<td>5
-</td>
-<td>10
-</td>
-<td>15
-</td>
-</tr></tbody>
-</table>
+<td> 5 </td>
+<td> 10 </td>
+<td> 15
+</td></tr></table>
 
 !! end
 
@@ -1706,20 +1357,17 @@ Table rowspan
 !! result
 <table align="right" border="1">
 <tr>
-<td>Cell 1, row 1
+<td> Cell 1, row 1
 </td>
-<td rowspan="2">Cell 2, row 1 (and 2)
+<td rowspan="2"> Cell 2, row 1 (and 2)
 </td>
-<td>Cell 3, row 1
-</td>
-</tr>
+<td> Cell 3, row 1
+</td></tr>
 <tr>
-<td>Cell 1, row 2
-</td>
-<td>Cell 3, row 2
+<td> Cell 1, row 2
 </td>
-</tr>
-</table>
+<td> Cell 3, row 2
+</td></tr></table>
 
 !! end
 
@@ -1739,24 +1387,19 @@ Nested table
 !! result
 <table border="1">
 <tr>
-<td>&#945;
+<td> &#945;
 </td>
 <td>
 <table bgcolor="#ABCDEF" border="2">
 <tr>
 <td>nested
-</td>
-</tr>
+</td></tr>
 <tr>
 <td>table
-</td>
-</tr>
-</table>
+</td></tr></table>
 </td>
 <td>the original table again
-</td>
-</tr>
-</table>
+</td></tr></table>
 
 !! end
 
@@ -1770,85 +1413,10 @@ Invalid attributes in table cell (bug 1830)
 <table>
 <tr>
 <td>broken
-</td>
-</tr>
-</table>
-
-!! end
-
-!! test
-Heading inside table (affected by r85922)
-!! input
-{|
-|- valign="top"
-|
-=== Heading ===
-|}
-!! result
-<table>
-<tr valign="top">
-<td>
-<h3><span class="editsection">[<a href="/index.php?title=Parser_test&amp;action=edit&amp;section=1" title="Edit section: Heading">edit</a>]</span> <span class="mw-headline" id="Heading"> Heading </span></h3>
-</td>
-</tr>
-</table>
-
-!! end
-
-!! test
-A table with a caption with unclosed italic
-!! input 
-{|
-|+ ''caption
-|  Cell
-|}
-!! result
-<table>
-<caption><i>caption</i>
-</caption>
-<tr>
-<td>Cell
-</td>
-</tr>
-</table>
-
-!! end
-
-!! test
-A table with unclosed italic in a cell
-!! input 
-{|
-| ''Cell
-|}
-!! result
-<table>
-<tr>
-<td><i>Cell</i>
-</td>
-</tr>
-</table>
+</td></tr></table>
 
 !! end
 
-!! test
-A table with unclosed italic in a th
-!! input
-{|
-|-
-! ''Cell
-|| Value
-|}
-!! result
-<table>
-<tr>
-<th><i>Cell</i>
-</th>
-<td>Value
-</td>
-</tr>
-</table>
-
-!! end
 
 !! test
 Table security: embedded pipes (http://lists.wikimedia.org/mailman/htdig/wikitech-l/2006-April/022293.html)
@@ -1858,8 +1426,7 @@ Table security: embedded pipes (http://lists.wikimedia.org/mailman/htdig/wikitec
 !! result
 <table>
 <tr>
-<td>[<a rel="nofollow" class="external free" href="ftp://%7Cx">ftp://%7Cx</a>
-</td>
+<td>[<a rel="nofollow" class="external free" href="ftp://%7Cx">ftp://%7Cx</a></td>
 <td>]" onmouseover="alert(document.cookie)"&gt;test
 </td>
 </tr>
@@ -1867,70 +1434,6 @@ Table security: embedded pipes (http://lists.wikimedia.org/mailman/htdig/wikitec
 
 !! end
 
-!! test
-Indented Tables, bug 20078
-!! input
-: {| 
-| 1 || 2
-|- 
-| 3 || 4
-|}
-!! result
-<dl><dd><table>
-<tr>
-<td>1
-</td>
-<td>2
-</td>
-</tr>
-<tr>
-<td>3
-</td>
-<td>4
-</td>
-</tr>
-</table></dd></dl>
-
-!! end
-
-!! test
-Arbitrary whitespace should not be prepended
-!! input
-{| 
-| 1 || 2
-
-|- 
-
-
-| 3 || 4
-|-
-
-| 6 || 8
-|}
-!! result
-<table>
-<tr>
-<td>1
-</td>
-<td>2
-</td>
-</tr>
-<tr>
-<td>3
-</td>
-<td>4
-</td>
-</tr>
-<tr>
-<td>6
-</td>
-<td>8
-</td>
-</tr>
-</table>
-
-!! end
-
 
 ###
 ### Internal links
@@ -3220,9 +2723,7 @@ BUG 553: link with two variables in a piped link
 <table>
 <tr>
 <td>[[{{{1}}}|{{{2}}}]]
-</td>
-</tr>
-</table>
+</td></tr></table>
 
 !! end
 
@@ -3331,18 +2832,13 @@ foo {{table}}
 </p>
 <table>
 <tr>
-<td>1
-</td>
-<td>2
-</td>
-</tr>
+<td> 1 </td>
+<td> 2
+</td></tr>
 <tr>
-<td>3
-</td>
-<td>4
-</td>
-</tr>
-</table>
+<td> 3 </td>
+<td> 4
+</td></tr></table>
 
 !! end
 
@@ -3356,18 +2852,13 @@ foo
 </p>
 <table>
 <tr>
-<td>1
-</td>
-<td>2
-</td>
-</tr>
+<td> 1 </td>
+<td> 2
+</td></tr>
 <tr>
-<td>3
-</td>
-<td>4
-</td>
-</tr>
-</table>
+<td> 3 </td>
+<td> 4
+</td></tr></table>
 
 !! end
 
@@ -5050,10 +4541,8 @@ Table multiple attributes correction
 !! result
 <table>
 <tr>
-<th class="awesome">status
-</th>
-</tr>
-</table>
+<th class="awesome"> status
+</th></tr></table>
 
 !!end
 
@@ -5497,10 +4986,8 @@ Table attribute legitimate extension
 !! result
 <table>
 <tr>
-<th style="color:blue">status
-</th>
-</tr>
-</table>
+<th style="color:blue"> status
+</th></tr></table>
 
 !!end
 
@@ -5513,10 +5000,8 @@ Table attribute safety
 !! result
 <table>
 <tr>
-<th style="/* insecure input */">status
-</th>
-</tr>
-</table>
+<th style="/* insecure input */"> status
+</th></tr></table>
 
 !! end
 
@@ -6138,7 +5623,8 @@ Fuzz testing: Parser13
 !! result
 <table>
 <tr>
-<td></td>
+<td>
+</td>
 </tr>
 </table>
 
@@ -6164,14 +5650,10 @@ Fuzz testing: Parser14-table
 !! input
 ==a==
 {| STYLE=__TOC__
-|foo
 !! result
 <h2><span class="editsection">[<a href="/index.php?title=Parser_test&amp;action=edit&amp;section=1" title="Edit section: a">edit</a>]</span> <span class="mw-headline" id="a">a</span></h2>
 <table style="&#95;_TOC&#95;_">
-<tr>
-<td>foo
-</td>
-</tr>
+<tr><td></td></tr>
 </table>
 
 !! end
@@ -6187,11 +5669,11 @@ noxml
 !! result
 <table>
 <tr>
-<th>https://
-</th>
-<th></th>
+<th>https://</th>
 <th></th>
 <th></th>
+<th>
+</td>
 </tr>
 </table>
 
@@ -6206,9 +5688,10 @@ Fuzz testing: Parser21
 !! result
 <table>
 <tr>
-<th><a rel="nofollow" class="external free" href="irc://{{ftp://a">irc://{{ftp://a</a>" onmouseover="alert('hello world');"
+<th> <a rel="nofollow" class="external free" href="irc://{{ftp://a">irc://{{ftp://a</a>" onmouseover="alert('hello world');"
 </th>
-<td></td>
+<td>
+</td>
 </tr>
 </table>
 
@@ -6220,29 +5703,15 @@ Fuzz testing: Parser22
 http://===r:::https://b
 
 {|
-
 !!result
 <p><a rel="nofollow" class="external free" href="http://===r:::https://b">http://===r:::https://b</a>
 </p>
-!! end
+<table>
+<tr><td></td></tr>
+</table>
 
-# Known to produce bad XML for now
+!! end
 
-# Note: the current result listed for this is not what the original one was,
-# but the original bug was JavaScript injection, which is fixed in any case.
-# It's not clear that the original result listed was any more correct than the
-# current one.  Original result:
-# <table>
-# {{{|
-# <u class="&#124;">}}}} &gt;
-# <br style="onmouseover=&#39;alert(document.cookie);&#39;" />
-# 
-# MOVE YOUR MOUSE CURSOR OVER THIS TEXT
-# <tr>
-# <td></u>
-# </td>
-# </tr>
-# </table>
 # Known to produce bad XML for now
 !! test
 Fuzz testing: Parser24
@@ -6258,12 +5727,12 @@ noxml
 MOVE YOUR MOUSE CURSOR OVER THIS TEXT
 |
 !! result
-<p>{{{|
+<table>
+{{{|
 <u class="&#124;">}}}} &gt;
 <br style="onmouseover=&#39;alert(document.cookie);&#39;" />
+
 MOVE YOUR MOUSE CURSOR OVER THIS TEXT
-</p>
-<table>
 <tr>
 <td></u>
 </td>
 </p>
 <table>
 <tr>
-<td>1
-</td>
-<td>2
-</td>
-</tr>
+<td> 1 </td>
+<td> 2
+</td></tr>
 <tr>
-<td>3
-</td>
-<td>4
-</td>
-</tr>
-</table>
+<td> 3 </td>
+<td> 4
+</td></tr></table>
 <p>y
 </p>
 !! end