Merge "SpecialRecentChanges: Remove '@todo Uses radio buttons (HASHAR)'"
[lhc/web/wiklou.git] / includes / diff / DairikiDiff.php
index f9cb656..53e80c4 100644 (file)
  * @private
  * @ingroup DifferenceEngine
  */
-class _DiffOp {
-       var $type;
-       var $orig;
-       var $closing;
+abstract class DiffOp {
+       public $type;
+       public $orig;
+       public $closing;
 
-       function reverse() {
-               trigger_error( 'pure virtual', E_USER_ERROR );
-       }
+       public abstract function reverse();
 
        /**
         * @return int
@@ -59,8 +57,8 @@ class _DiffOp {
  * @private
  * @ingroup DifferenceEngine
  */
-class _DiffOp_Copy extends _DiffOp {
-       var $type = 'copy';
+class DiffOp_Copy extends DiffOp {
+       public $type = 'copy';
 
        function __construct( $orig, $closing = false ) {
                if ( !is_array( $closing ) ) {
@@ -71,10 +69,10 @@ class _DiffOp_Copy extends _DiffOp {
        }
 
        /**
-        * @return _DiffOp_Copy
+        * @return DiffOp_Copy
         */
        function reverse() {
-               return new _DiffOp_Copy( $this->closing, $this->orig );
+               return new DiffOp_Copy( $this->closing, $this->orig );
        }
 }
 
@@ -83,8 +81,8 @@ class _DiffOp_Copy extends _DiffOp {
  * @private
  * @ingroup DifferenceEngine
  */
-class _DiffOp_Delete extends _DiffOp {
-       var $type = 'delete';
+class DiffOp_Delete extends DiffOp {
+       public $type = 'delete';
 
        function __construct( $lines ) {
                $this->orig = $lines;
@@ -92,10 +90,10 @@ class _DiffOp_Delete extends _DiffOp {
        }
 
        /**
-        * @return _DiffOp_Add
+        * @return DiffOp_Add
         */
        function reverse() {
-               return new _DiffOp_Add( $this->orig );
+               return new DiffOp_Add( $this->orig );
        }
 }
 
@@ -104,8 +102,8 @@ class _DiffOp_Delete extends _DiffOp {
  * @private
  * @ingroup DifferenceEngine
  */
-class _DiffOp_Add extends _DiffOp {
-       var $type = 'add';
+class DiffOp_Add extends DiffOp {
+       public $type = 'add';
 
        function __construct( $lines ) {
                $this->closing = $lines;
@@ -113,10 +111,10 @@ class _DiffOp_Add extends _DiffOp {
        }
 
        /**
-        * @return _DiffOp_Delete
+        * @return DiffOp_Delete
         */
        function reverse() {
-               return new _DiffOp_Delete( $this->closing );
+               return new DiffOp_Delete( $this->closing );
        }
 }
 
@@ -125,8 +123,8 @@ class _DiffOp_Add extends _DiffOp {
  * @private
  * @ingroup DifferenceEngine
  */
-class _DiffOp_Change extends _DiffOp {
-       var $type = 'change';
+class DiffOp_Change extends DiffOp {
+       public $type = 'change';
 
        function __construct( $orig, $closing ) {
                $this->orig = $orig;
@@ -134,10 +132,10 @@ class _DiffOp_Change extends _DiffOp {
        }
 
        /**
-        * @return _DiffOp_Change
+        * @return DiffOp_Change
         */
        function reverse() {
-               return new _DiffOp_Change( $this->closing, $this->orig );
+               return new DiffOp_Change( $this->closing, $this->orig );
        }
 }
 
@@ -165,7 +163,7 @@ class _DiffOp_Change extends _DiffOp {
  * @private
  * @ingroup DifferenceEngine
  */
-class _DiffEngine {
+class DiffEngine {
 
        const MAX_XREF_LENGTH = 10000;
 
@@ -187,11 +185,11 @@ class _DiffEngine {
                wfProfileIn( __METHOD__ );
 
                // Diff and store locally
-               $this->diff_local( $from_lines, $to_lines );
+               $this->diffLocal( $from_lines, $to_lines );
 
                // Merge edits when possible
-               $this->_shift_boundaries( $from_lines, $this->xchanged, $this->ychanged );
-               $this->_shift_boundaries( $to_lines, $this->ychanged, $this->xchanged );
+               $this->shiftBoundaries( $from_lines, $this->xchanged, $this->ychanged );
+               $this->shiftBoundaries( $to_lines, $this->ychanged, $this->xchanged );
 
                // Compute the edit operations.
                $n_from = count( $from_lines );
@@ -211,7 +209,7 @@ class _DiffEngine {
                                ++$yi;
                        }
                        if ( $copy ) {
-                               $edits[] = new _DiffOp_Copy( $copy );
+                               $edits[] = new DiffOp_Copy( $copy );
                        }
 
                        // Find deletes & adds.
@@ -226,11 +224,11 @@ class _DiffEngine {
                        }
 
                        if ( $delete && $add ) {
-                               $edits[] = new _DiffOp_Change( $delete, $add );
+                               $edits[] = new DiffOp_Change( $delete, $add );
                        } elseif ( $delete ) {
-                               $edits[] = new _DiffOp_Delete( $delete );
+                               $edits[] = new DiffOp_Delete( $delete );
                        } elseif ( $add ) {
-                               $edits[] = new _DiffOp_Add( $add );
+                               $edits[] = new DiffOp_Add( $add );
                        }
                }
                wfProfileOut( __METHOD__ );
@@ -241,7 +239,7 @@ class _DiffEngine {
         * @param $from_lines
         * @param $to_lines
         */
-       function diff_local( $from_lines, $to_lines ) {
+       private function diffLocal( $from_lines, $to_lines ) {
                global $wgExternalDiffEngine;
                wfProfileIn( __METHOD__ );
 
@@ -271,7 +269,8 @@ class _DiffEngine {
                                $this->xchanged[$skip] = $this->ychanged[$skip] = false;
                        }
                        // Skip trailing common lines.
-                       $xi = $n_from; $yi = $n_to;
+                       $xi = $n_from;
+                       $yi = $n_to;
                        for ( $endskip = 0; --$xi > $skip && --$yi > $skip; $endskip++ ) {
                                if ( $from_lines[$xi] !== $to_lines[$yi] ) {
                                        break;
@@ -281,21 +280,21 @@ class _DiffEngine {
 
                        // Ignore lines which do not exist in both files.
                        for ( $xi = $skip; $xi < $n_from - $endskip; $xi++ ) {
-                               $xhash[$this->_line_hash( $from_lines[$xi] )] = 1;
+                               $xhash[$this->lineHash( $from_lines[$xi] )] = 1;
                        }
 
                        for ( $yi = $skip; $yi < $n_to - $endskip; $yi++ ) {
                                $line = $to_lines[$yi];
-                               if ( ( $this->ychanged[$yi] = empty( $xhash[$this->_line_hash( $line )] ) ) ) {
+                               if ( ( $this->ychanged[$yi] = empty( $xhash[$this->lineHash( $line )] ) ) ) {
                                        continue;
                                }
-                               $yhash[$this->_line_hash( $line )] = 1;
+                               $yhash[$this->lineHash( $line )] = 1;
                                $this->yv[] = $line;
                                $this->yind[] = $yi;
                        }
                        for ( $xi = $skip; $xi < $n_from - $endskip; $xi++ ) {
                                $line = $from_lines[$xi];
-                               if ( ( $this->xchanged[$xi] = empty( $yhash[$this->_line_hash( $line )] ) ) ) {
+                               if ( ( $this->xchanged[$xi] = empty( $yhash[$this->lineHash( $line )] ) ) ) {
                                        continue;
                                }
                                $this->xv[] = $line;
@@ -303,7 +302,7 @@ class _DiffEngine {
                        }
 
                        // Find the LCS.
-                       $this->_compareseq( 0, count( $this->xv ), 0, count( $this->yv ) );
+                       $this->compareSeq( 0, count( $this->xv ), 0, count( $this->yv ) );
                }
                wfProfileOut( __METHOD__ );
        }
@@ -313,7 +312,7 @@ class _DiffEngine {
         * @param $line string
         * @return string
         */
-       function _line_hash( $line ) {
+       private function lineHash( $line ) {
                if ( strlen( $line ) > self::MAX_XREF_LENGTH ) {
                        return md5( $line );
                } else {
@@ -344,7 +343,7 @@ class _DiffEngine {
         * @param $nchunks
         * @return array
         */
-       function _diag( $xoff, $xlim, $yoff, $ylim, $nchunks ) {
+       private function diag( $xoff, $xlim, $yoff, $ylim, $nchunks ) {
                $flip = false;
 
                if ( $xlim - $xoff > $ylim - $yoff ) {
@@ -388,13 +387,13 @@ class _DiffEngine {
                                reset( $matches );
                                while ( list( , $y ) = each( $matches ) ) {
                                        if ( empty( $this->in_seq[$y] ) ) {
-                                               $k = $this->_lcs_pos( $y );
+                                               $k = $this->lcsPos( $y );
                                                assert( '$k > 0' );
                                                $ymids[$k] = $ymids[$k -1];
                                                break;
                                        }
                                }
-                               while ( list ( , $y ) = each( $matches ) ) {
+                               while ( list( , $y ) = each( $matches ) ) {
                                        if ( $y > $this->seq[$k -1] ) {
                                                assert( '$y < $this->seq[$k]' );
                                                // Optimization: this is a common case:
@@ -403,7 +402,7 @@ class _DiffEngine {
                                                $this->seq[$k] = $y;
                                                $this->in_seq[$y] = 1;
                                        } elseif ( empty( $this->in_seq[$y] ) ) {
-                                               $k = $this->_lcs_pos( $y );
+                                               $k = $this->lcsPos( $y );
                                                assert( '$k > 0' );
                                                $ymids[$k] = $ymids[$k -1];
                                        }
@@ -427,7 +426,7 @@ class _DiffEngine {
         * @param $ypos
         * @return int
         */
-       function _lcs_pos( $ypos ) {
+       private function lcsPos( $ypos ) {
                $end = $this->lcs;
                if ( $end == 0 || $ypos > $this->seq[$end] ) {
                        $this->seq[++$this->lcs] = $ypos;
@@ -469,10 +468,9 @@ class _DiffEngine {
         * @param $yoff
         * @param $ylim
         */
-       function _compareseq( $xoff, $xlim, $yoff, $ylim ) {
+       private function compareSeq( $xoff, $xlim, $yoff, $ylim ) {
                // Slide down the bottom initial diagonal.
-               while ( $xoff < $xlim && $yoff < $ylim
-               && $this->xv[$xoff] == $this->yv[$yoff] ) {
+               while ( $xoff < $xlim && $yoff < $ylim && $this->xv[$xoff] == $this->yv[$yoff] ) {
                        ++$xoff;
                        ++$yoff;
                }
@@ -491,7 +489,7 @@ class _DiffEngine {
                        // $nchunks = sqrt(min($xlim - $xoff, $ylim - $yoff) / 2.5);
                        // $nchunks = max(2,min(8,(int)$nchunks));
                        $nchunks = min( 7, $xlim - $xoff, $ylim - $yoff ) + 1;
-                       list ( $lcs, $seps ) = $this->_diag( $xoff, $xlim, $yoff, $ylim, $nchunks );
+                       list( $lcs, $seps ) = $this->diag( $xoff, $xlim, $yoff, $ylim, $nchunks );
                }
 
                if ( $lcs == 0 ) {
@@ -508,7 +506,7 @@ class _DiffEngine {
                        reset( $seps );
                        $pt1 = $seps[0];
                        while ( $pt2 = next( $seps ) ) {
-                               $this->_compareseq( $pt1[0], $pt2[0], $pt1[1], $pt2[1] );
+                               $this->compareSeq( $pt1[0], $pt2[0], $pt1[1], $pt2[1] );
                                $pt1 = $pt2;
                        }
                }
@@ -527,7 +525,7 @@ class _DiffEngine {
         *
         * This is extracted verbatim from analyze.c (GNU diffutils-2.7).
         */
-       function _shift_boundaries( $lines, &$changed, $other_changed ) {
+       private function shiftBoundaries( $lines, &$changed, $other_changed ) {
                wfProfileIn( __METHOD__ );
                $i = 0;
                $j = 0;
@@ -554,9 +552,11 @@ class _DiffEngine {
 
                        while ( $i < $len && ! $changed[$i] ) {
                                assert( '$j < $other_len && ! $other_changed[$j]' );
-                               $i++; $j++;
-                               while ( $j < $other_len && $other_changed[$j] )
+                               $i++;
                                $j++;
+                               while ( $j < $other_len && $other_changed[$j] ) {
+                                       $j++;
+                               }
                        }
 
                        if ( $i == $len ) {
@@ -652,7 +652,7 @@ class _DiffEngine {
  * @ingroup DifferenceEngine
  */
 class Diff {
-       var $edits;
+       public $edits;
 
        /**
         * Constructor.
@@ -663,9 +663,9 @@ class Diff {
         * @param $to_lines array An array of strings.
         */
        function __construct( $from_lines, $to_lines ) {
-               $eng = new _DiffEngine;
+               $eng = new DiffEngine;
                $this->edits = $eng->diff( $from_lines, $to_lines );
-               // $this->_check($from_lines, $to_lines);
+               // $this->check($from_lines, $to_lines);
        }
 
        /**
@@ -681,6 +681,7 @@ class Diff {
        function reverse() {
                $rev = $this;
                $rev->edits = array();
+               /** @var DiffOp $edit */
                foreach ( $this->edits as $edit ) {
                        $rev->edits[] = $edit->reverse();
                }
@@ -690,7 +691,7 @@ class Diff {
        /**
         * Check for empty diff.
         *
-        * @return bool True iff two sequences were identical.
+        * @return bool True if two sequences were identical.
         */
        function isEmpty() {
                foreach ( $this->edits as $edit ) {
@@ -763,7 +764,7 @@ class Diff {
         * @param $from_lines
         * @param $to_lines
         */
-       function _check( $from_lines, $to_lines ) {
+       private function check( $from_lines, $to_lines ) {
                wfProfileIn( __METHOD__ );
                if ( serialize( $from_lines ) != serialize( $this->orig() ) ) {
                        trigger_error( "Reconstructed original doesn't match", E_USER_ERROR );
@@ -850,363 +851,61 @@ class MappedDiff extends Diff {
        }
 }
 
-/**
- * A class to format Diffs
- *
- * This class formats the diff in classic diff format.
- * It is intended that this class be customized via inheritance,
- * to obtain fancier outputs.
- * @todo document
- * @private
- * @ingroup DifferenceEngine
- */
-class DiffFormatter {
-       /**
-        * Number of leading context "lines" to preserve.
-        *
-        * This should be left at zero for this class, but subclasses
-        * may want to set this to other values.
-        */
-       var $leading_context_lines = 0;
-
-       /**
-        * Number of trailing context "lines" to preserve.
-        *
-        * This should be left at zero for this class, but subclasses
-        * may want to set this to other values.
-        */
-       var $trailing_context_lines = 0;
-
-       /**
-        * Format a diff.
-        *
-        * @param $diff Diff A Diff object.
-        * @return string The formatted output.
-        */
-       function format( $diff ) {
-               wfProfileIn( __METHOD__ );
-
-               $xi = $yi = 1;
-               $block = false;
-               $context = array();
-
-               $nlead = $this->leading_context_lines;
-               $ntrail = $this->trailing_context_lines;
-
-               $this->_start_diff();
-
-               foreach ( $diff->edits as $edit ) {
-                       if ( $edit->type == 'copy' ) {
-                               if ( is_array( $block ) ) {
-                                       if ( count( $edit->orig ) <= $nlead + $ntrail ) {
-                                               $block[] = $edit;
-                                       } else {
-                                               if ( $ntrail ) {
-                                                       $context = array_slice( $edit->orig, 0, $ntrail );
-                                                       $block[] = new _DiffOp_Copy( $context );
-                                               }
-                                               $this->_block( $x0, $ntrail + $xi - $x0,
-                                                       $y0, $ntrail + $yi - $y0,
-                                                       $block );
-                                               $block = false;
-                                       }
-                               }
-                               $context = $edit->orig;
-                       } else {
-                               if ( !is_array( $block ) ) {
-                                       $context = array_slice( $context, count( $context ) - $nlead );
-                                       $x0 = $xi - count( $context );
-                                       $y0 = $yi - count( $context );
-                                       $block = array();
-                                       if ( $context ) {
-                                               $block[] = new _DiffOp_Copy( $context );
-                                       }
-                               }
-                               $block[] = $edit;
-                       }
-
-                       if ( $edit->orig ) {
-                               $xi += count( $edit->orig );
-                       }
-                       if ( $edit->closing ) {
-                               $yi += count( $edit->closing );
-                       }
-               }
-
-               if ( is_array( $block ) ) {
-                       $this->_block( $x0, $xi - $x0,
-                               $y0, $yi - $y0,
-                               $block );
-               }
-
-               $end = $this->_end_diff();
-               wfProfileOut( __METHOD__ );
-               return $end;
-       }
-
-       /**
-        * @param $xbeg
-        * @param $xlen
-        * @param $ybeg
-        * @param $ylen
-        * @param $edits
-        */
-       function _block( $xbeg, $xlen, $ybeg, $ylen, &$edits ) {
-               wfProfileIn( __METHOD__ );
-               $this->_start_block( $this->_block_header( $xbeg, $xlen, $ybeg, $ylen ) );
-               foreach ( $edits as $edit ) {
-                       if ( $edit->type == 'copy' ) {
-                               $this->_context( $edit->orig );
-                       } elseif ( $edit->type == 'add' ) {
-                               $this->_added( $edit->closing );
-                       } elseif ( $edit->type == 'delete' ) {
-                               $this->_deleted( $edit->orig );
-                       } elseif ( $edit->type == 'change' ) {
-                               $this->_changed( $edit->orig, $edit->closing );
-                       } else {
-                               trigger_error( 'Unknown edit type', E_USER_ERROR );
-                       }
-               }
-               $this->_end_block();
-               wfProfileOut( __METHOD__ );
-       }
-
-       function _start_diff() {
-               ob_start();
-       }
-
-       /**
-        * @return string
-        */
-       function _end_diff() {
-               $val = ob_get_contents();
-               ob_end_clean();
-               return $val;
-       }
-
-       /**
-        * @param $xbeg
-        * @param $xlen
-        * @param $ybeg
-        * @param $ylen
-        * @return string
-        */
-       function _block_header( $xbeg, $xlen, $ybeg, $ylen ) {
-               if ( $xlen > 1 ) {
-                       $xbeg .= ',' . ( $xbeg + $xlen - 1 );
-               }
-               if ( $ylen > 1 ) {
-                       $ybeg .= ',' . ( $ybeg + $ylen - 1 );
-               }
-
-               return $xbeg . ( $xlen ? ( $ylen ? 'c' : 'd' ) : 'a' ) . $ybeg;
-       }
-
-       function _start_block( $header ) {
-               echo $header . "\n";
-       }
-
-       function _end_block() {
-       }
-
-       /**
-        * @param $lines
-        * @param $prefix string
-        */
-       function _lines( $lines, $prefix = ' ' ) {
-               foreach ( $lines as $line ) {
-                       echo "$prefix $line\n";
-               }
-       }
-
-       /**
-        * @param $lines
-        */
-       function _context( $lines ) {
-               $this->_lines( $lines );
-       }
-
-       /**
-        * @param $lines
-        */
-       function _added( $lines ) {
-               $this->_lines( $lines, '>' );
-       }
-
-       /**
-        * @param $lines
-        */
-       function _deleted( $lines ) {
-               $this->_lines( $lines, '<' );
-       }
-
-       /**
-        * @param $orig
-        * @param $closing
-        */
-       function _changed( $orig, $closing ) {
-               $this->_deleted( $orig );
-               echo "---\n";
-               $this->_added( $closing );
-       }
-}
-
-/**
- * A formatter that outputs unified diffs
- * @ingroup DifferenceEngine
- */
-class UnifiedDiffFormatter extends DiffFormatter {
-       var $leading_context_lines = 2;
-       var $trailing_context_lines = 2;
-
-       /**
-        * @param $lines
-        */
-       function _added( $lines ) {
-               $this->_lines( $lines, '+' );
-       }
-
-       /**
-        * @param $lines
-        */
-       function _deleted( $lines ) {
-               $this->_lines( $lines, '-' );
-       }
-
-       /**
-        * @param $orig
-        * @param $closing
-        */
-       function _changed( $orig, $closing ) {
-               $this->_deleted( $orig );
-               $this->_added( $closing );
-       }
-
-       /**
-        * @param $xbeg
-        * @param $xlen
-        * @param $ybeg
-        * @param $ylen
-        * @return string
-        */
-       function _block_header( $xbeg, $xlen, $ybeg, $ylen ) {
-               return "@@ -$xbeg,$xlen +$ybeg,$ylen @@";
-       }
-}
-
-/**
- * A pseudo-formatter that just passes along the Diff::$edits array
- * @ingroup DifferenceEngine
- */
-class ArrayDiffFormatter extends DiffFormatter {
-
-       /**
-        * @param $diff
-        * @return array
-        */
-       function format( $diff ) {
-               $oldline = 1;
-               $newline = 1;
-               $retval = array();
-               foreach ( $diff->edits as $edit ) {
-                       switch( $edit->type ) {
-                               case 'add':
-                                       foreach ( $edit->closing as $l ) {
-                                               $retval[] = array(
-                                                       'action' => 'add',
-                                                       'new' => $l,
-                                                       'newline' => $newline++
-                                               );
-                                       }
-                                       break;
-                               case 'delete':
-                                       foreach ( $edit->orig as $l ) {
-                                               $retval[] = array(
-                                                       'action' => 'delete',
-                                                       'old' => $l,
-                                                       'oldline' => $oldline++,
-                                               );
-                                       }
-                                       break;
-                               case 'change':
-                                       foreach ( $edit->orig as $i => $l ) {
-                                               $retval[] = array(
-                                                       'action' => 'change',
-                                                       'old' => $l,
-                                                       'new' => isset( $edit->closing[$i] ) ? $edit->closing[$i] : null,
-                                                       'oldline' => $oldline++,
-                                                       'newline' => $newline++,
-                                               );
-                                       }
-                                       break;
-                               case 'copy':
-                                       $oldline += count( $edit->orig );
-                                       $newline += count( $edit->orig );
-                       }
-               }
-               return $retval;
-       }
-}
-
 /**
  * Additions by Axel Boldt follow, partly taken from diff.php, phpwiki-1.3.3
  */
 
-define( 'NBSP', '&#160;' ); // iso-8859-x non-breaking space.
-
 /**
  * @todo document
  * @private
  * @ingroup DifferenceEngine
  */
-class _HWLDF_WordAccumulator {
-       function __construct() {
-               $this->_lines = array();
-               $this->_line = '';
-               $this->_group = '';
-               $this->_tag = '';
-       }
+class HWLDF_WordAccumulator {
+       private $lines = array();
+       private $line = '';
+       private $group = '';
+       private $tag = '';
 
        /**
         * @param $new_tag
         */
-       function _flushGroup( $new_tag ) {
-               if ( $this->_group !== '' ) {
-                       if ( $this->_tag == 'ins' ) {
-                               $this->_line .= '<ins class="diffchange diffchange-inline">' .
-                                               htmlspecialchars( $this->_group ) . '</ins>';
-                       } elseif ( $this->_tag == 'del' ) {
-                               $this->_line .= '<del class="diffchange diffchange-inline">' .
-                                               htmlspecialchars( $this->_group ) . '</del>';
+       private function flushGroup( $new_tag ) {
+               if ( $this->group !== '' ) {
+                       if ( $this->tag == 'ins' ) {
+                               $this->line .= '<ins class="diffchange diffchange-inline">' .
+                                               htmlspecialchars( $this->group ) . '</ins>';
+                       } elseif ( $this->tag == 'del' ) {
+                               $this->line .= '<del class="diffchange diffchange-inline">' .
+                                               htmlspecialchars( $this->group ) . '</del>';
                        } else {
-                               $this->_line .= htmlspecialchars( $this->_group );
+                               $this->line .= htmlspecialchars( $this->group );
                        }
                }
-               $this->_group = '';
-               $this->_tag = $new_tag;
+               $this->group = '';
+               $this->tag = $new_tag;
        }
 
        /**
         * @param $new_tag
         */
-       function _flushLine( $new_tag ) {
-               $this->_flushGroup( $new_tag );
-               if ( $this->_line != '' ) {
-                       array_push( $this->_lines, $this->_line );
+       private function flushLine( $new_tag ) {
+               $this->flushGroup( $new_tag );
+               if ( $this->line != '' ) {
+                       array_push( $this->lines, $this->line );
                } else {
                        # make empty lines visible by inserting an NBSP
-                       array_push( $this->_lines, NBSP );
+                       array_push( $this->lines, '&#160;' );
                }
-               $this->_line = '';
+               $this->line = '';
        }
 
        /**
         * @param $words
         * @param $tag string
         */
-       function addWords( $words, $tag = '' ) {
-               if ( $tag != $this->_tag ) {
-                       $this->_flushGroup( $tag );
+       public function addWords( $words, $tag = '' ) {
+               if ( $tag != $this->tag ) {
+                       $this->flushGroup( $tag );
                }
 
                foreach ( $words as $word ) {
@@ -1215,20 +914,20 @@ class _HWLDF_WordAccumulator {
                                continue;
                        }
                        if ( $word[0] == "\n" ) {
-                               $this->_flushLine( $tag );
+                               $this->flushLine( $tag );
                                $word = substr( $word, 1 );
                        }
                        assert( '!strstr( $word, "\n" )' );
-                       $this->_group .= $word;
+                       $this->group .= $word;
                }
        }
 
        /**
         * @return array
         */
-       function getLines() {
-               $this->_flushLine( '~done' );
-               return $this->_lines;
+       public function getLines() {
+               $this->flushLine( '~done' );
+               return $this->lines;
        }
 }
 
@@ -1247,8 +946,8 @@ class WordLevelDiff extends MappedDiff {
        function __construct( $orig_lines, $closing_lines ) {
                wfProfileIn( __METHOD__ );
 
-               list( $orig_words, $orig_stripped ) = $this->_split( $orig_lines );
-               list( $closing_words, $closing_stripped ) = $this->_split( $closing_lines );
+               list( $orig_words, $orig_stripped ) = $this->split( $orig_lines );
+               list( $closing_words, $closing_stripped ) = $this->split( $closing_lines );
 
                parent::__construct( $orig_words, $closing_words,
                $orig_stripped, $closing_stripped );
@@ -1259,7 +958,7 @@ class WordLevelDiff extends MappedDiff {
         * @param $lines
         * @return array
         */
-       function _split( $lines ) {
+       private function split( $lines ) {
                wfProfileIn( __METHOD__ );
 
                $words = array();
@@ -1282,8 +981,12 @@ class WordLevelDiff extends MappedDiff {
                                if ( preg_match_all( '/ ( [^\S\n]+ | [0-9_A-Za-z\x80-\xff]+ | . ) (?: (?!< \n) [^\S\n])? /xs',
                                        $line, $m ) )
                                {
-                                       $words = array_merge( $words, $m[0] );
-                                       $stripped = array_merge( $stripped, $m[1] );
+                                       foreach ( $m[0] as $word ) {
+                                               $words[] = $word;
+                                       }
+                                       foreach ( $m[1] as $stripped_word ) {
+                                               $stripped[] = $stripped_word;
+                                       }
                                }
                        }
                }
@@ -1294,9 +997,9 @@ class WordLevelDiff extends MappedDiff {
        /**
         * @return array
         */
-       function orig() {
+       public function orig() {
                wfProfileIn( __METHOD__ );
-               $orig = new _HWLDF_WordAccumulator;
+               $orig = new HWLDF_WordAccumulator;
 
                foreach ( $this->edits as $edit ) {
                        if ( $edit->type == 'copy' ) {
@@ -1313,9 +1016,9 @@ class WordLevelDiff extends MappedDiff {
        /**
         * @return array
         */
-       function closing() {
+       public function closing() {
                wfProfileIn( __METHOD__ );
-               $closing = new _HWLDF_WordAccumulator;
+               $closing = new HWLDF_WordAccumulator;
 
                foreach ( $this->edits as $edit ) {
                        if ( $edit->type == 'copy' ) {
@@ -1329,161 +1032,3 @@ class WordLevelDiff extends MappedDiff {
                return $lines;
        }
 }
-
-/**
- * Wikipedia Table style diff formatter.
- * @todo document
- * @private
- * @ingroup DifferenceEngine
- */
-class TableDiffFormatter extends DiffFormatter {
-       function __construct() {
-               $this->leading_context_lines = 2;
-               $this->trailing_context_lines = 2;
-       }
-
-       /**
-        * @static
-        * @param $msg
-        * @return mixed
-        */
-       public static function escapeWhiteSpace( $msg ) {
-               $msg = preg_replace( '/^ /m', '&#160; ', $msg );
-               $msg = preg_replace( '/ $/m', ' &#160;', $msg );
-               $msg = preg_replace( '/  /', '&#160; ', $msg );
-               return $msg;
-       }
-
-       /**
-        * @param $xbeg
-        * @param $xlen
-        * @param $ybeg
-        * @param $ylen
-        * @return string
-        */
-       function _block_header( $xbeg, $xlen, $ybeg, $ylen ) {
-               $r = '<tr><td colspan="2" class="diff-lineno"><!--LINE ' . $xbeg . "--></td>\n" .
-                       '<td colspan="2" class="diff-lineno"><!--LINE ' . $ybeg . "--></td></tr>\n";
-               return $r;
-       }
-
-       /**
-        * @param $header
-        */
-       function _start_block( $header ) {
-               echo $header;
-       }
-
-       function _end_block() {
-       }
-
-       function _lines( $lines, $prefix = ' ', $color = 'white' ) {
-       }
-
-       /**
-        * HTML-escape parameter before calling this
-        * @param $line
-        * @return string
-        */
-       function addedLine( $line ) {
-               return $this->wrapLine( '+', 'diff-addedline', $line );
-       }
-
-       /**
-        * HTML-escape parameter before calling this
-        * @param $line
-        * @return string
-        */
-       function deletedLine( $line ) {
-               return $this->wrapLine( '−', 'diff-deletedline', $line );
-       }
-
-       /**
-        * HTML-escape parameter before calling this
-        * @param $line
-        * @return string
-        */
-       function contextLine( $line ) {
-               return $this->wrapLine( '&#160;', 'diff-context', $line );
-       }
-
-       /**
-        * @param $marker
-        * @param $class
-        * @param $line
-        * @return string
-        */
-       private function wrapLine( $marker, $class, $line ) {
-               if ( $line !== '' ) {
-                       // The <div> wrapper is needed for 'overflow: auto' style to scroll properly
-                       $line = Xml::tags( 'div', null, $this->escapeWhiteSpace( $line ) );
-               }
-               return "<td class='diff-marker'>$marker</td><td class='$class'>$line</td>";
-       }
-
-       /**
-        * @return string
-        */
-       function emptyLine() {
-               return '<td colspan="2">&#160;</td>';
-       }
-
-       /**
-        * @param $lines array
-        */
-       function _added( $lines ) {
-               foreach ( $lines as $line ) {
-                       echo '<tr>' . $this->emptyLine() .
-                       $this->addedLine( '<ins class="diffchange">' .
-                       htmlspecialchars( $line ) . '</ins>' ) . "</tr>\n";
-               }
-       }
-
-       /**
-        * @param $lines
-        */
-       function _deleted( $lines ) {
-               foreach ( $lines as $line ) {
-                       echo '<tr>' . $this->deletedLine( '<del class="diffchange">' .
-                       htmlspecialchars( $line ) . '</del>' ) .
-                       $this->emptyLine() . "</tr>\n";
-               }
-       }
-
-       /**
-        * @param $lines
-        */
-       function _context( $lines ) {
-               foreach ( $lines as $line ) {
-                       echo '<tr>' .
-                       $this->contextLine( htmlspecialchars( $line ) ) .
-                       $this->contextLine( htmlspecialchars( $line ) ) . "</tr>\n";
-               }
-       }
-
-       /**
-        * @param $orig
-        * @param $closing
-        */
-       function _changed( $orig, $closing ) {
-               wfProfileIn( __METHOD__ );
-
-               $diff = new WordLevelDiff( $orig, $closing );
-               $del = $diff->orig();
-               $add = $diff->closing();
-
-               # Notice that WordLevelDiff returns HTML-escaped output.
-               # Hence, we will be calling addedLine/deletedLine without HTML-escaping.
-
-               while ( $line = array_shift( $del ) ) {
-                       $aline = array_shift( $add );
-                       echo '<tr>' . $this->deletedLine( $line ) .
-                       $this->addedLine( $aline ) . "</tr>\n";
-               }
-               foreach ( $add as $line ) {     # If any leftovers
-                       echo '<tr>' . $this->emptyLine() .
-                       $this->addedLine( $line ) . "</tr>\n";
-               }
-               wfProfileOut( __METHOD__ );
-       }
-}