[ Index ]

PHP Cross Reference of MediaWiki-1.24.0

title

Body

[close]

/includes/diff/ -> DiffFormatter.php (source)

   1  <?php
   2  /**
   3   * Base for diff rendering classes. Portions taken from phpwiki-1.3.3.
   4   *
   5   * Copyright © 2000, 2001 Geoffrey T. Dairiki <[email protected]>
   6   * You may copy this code freely under the conditions of the GPL.
   7   *
   8   * This program is free software; you can redistribute it and/or modify
   9   * it under the terms of the GNU General Public License as published by
  10   * the Free Software Foundation; either version 2 of the License, or
  11   * (at your option) any later version.
  12   *
  13   * This program is distributed in the hope that it will be useful,
  14   * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16   * GNU General Public License for more details.
  17   *
  18   * You should have received a copy of the GNU General Public License along
  19   * with this program; if not, write to the Free Software Foundation, Inc.,
  20   * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  21   * http://www.gnu.org/copyleft/gpl.html
  22   *
  23   * @file
  24   * @ingroup DifferenceEngine
  25   */
  26  
  27  /**
  28   * Base class for diff formatters
  29   *
  30   * This class formats the diff in classic diff format.
  31   * It is intended that this class be customized via inheritance,
  32   * to obtain fancier outputs.
  33   * @todo document
  34   * @ingroup DifferenceEngine
  35   */
  36  abstract class DiffFormatter {
  37  
  38      /** @var int Number of leading context "lines" to preserve.
  39       *
  40       * This should be left at zero for this class, but subclasses
  41       * may want to set this to other values.
  42       */
  43      protected $leadingContextLines = 0;
  44  
  45      /** @var int Number of trailing context "lines" to preserve.
  46       *
  47       * This should be left at zero for this class, but subclasses
  48       * may want to set this to other values.
  49       */
  50      protected $trailingContextLines = 0;
  51  
  52      /**
  53       * Format a diff.
  54       *
  55       * @param Diff $diff
  56       *
  57       * @return string The formatted output.
  58       */
  59  	public function format( $diff ) {
  60          wfProfileIn( __METHOD__ );
  61  
  62          $xi = $yi = 1;
  63          $block = false;
  64          $context = array();
  65  
  66          $nlead = $this->leadingContextLines;
  67          $ntrail = $this->trailingContextLines;
  68  
  69          $this->startDiff();
  70  
  71          // Initialize $x0 and $y0 to prevent IDEs from getting confused.
  72          $x0 = $y0 = 0;
  73          foreach ( $diff->edits as $edit ) {
  74              if ( $edit->type == 'copy' ) {
  75                  if ( is_array( $block ) ) {
  76                      if ( count( $edit->orig ) <= $nlead + $ntrail ) {
  77                          $block[] = $edit;
  78                      } else {
  79                          if ( $ntrail ) {
  80                              $context = array_slice( $edit->orig, 0, $ntrail );
  81                              $block[] = new DiffOpCopy( $context );
  82                          }
  83                          $this->block( $x0, $ntrail + $xi - $x0,
  84                              $y0, $ntrail + $yi - $y0,
  85                              $block );
  86                          $block = false;
  87                      }
  88                  }
  89                  $context = $edit->orig;
  90              } else {
  91                  if ( !is_array( $block ) ) {
  92                      $context = array_slice( $context, count( $context ) - $nlead );
  93                      $x0 = $xi - count( $context );
  94                      $y0 = $yi - count( $context );
  95                      $block = array();
  96                      if ( $context ) {
  97                          $block[] = new DiffOpCopy( $context );
  98                      }
  99                  }
 100                  $block[] = $edit;
 101              }
 102  
 103              if ( $edit->orig ) {
 104                  $xi += count( $edit->orig );
 105              }
 106              if ( $edit->closing ) {
 107                  $yi += count( $edit->closing );
 108              }
 109          }
 110  
 111          if ( is_array( $block ) ) {
 112              $this->block( $x0, $xi - $x0,
 113                  $y0, $yi - $y0,
 114                  $block );
 115          }
 116  
 117          $end = $this->endDiff();
 118          wfProfileOut( __METHOD__ );
 119  
 120          return $end;
 121      }
 122  
 123      /**
 124       * @param int $xbeg
 125       * @param int $xlen
 126       * @param int $ybeg
 127       * @param int $ylen
 128       * @param array $edits
 129       *
 130       * @throws MWException If the edit type is not known.
 131       */
 132  	protected function block( $xbeg, $xlen, $ybeg, $ylen, &$edits ) {
 133          wfProfileIn( __METHOD__ );
 134          $this->startBlock( $this->blockHeader( $xbeg, $xlen, $ybeg, $ylen ) );
 135          foreach ( $edits as $edit ) {
 136              if ( $edit->type == 'copy' ) {
 137                  $this->context( $edit->orig );
 138              } elseif ( $edit->type == 'add' ) {
 139                  $this->added( $edit->closing );
 140              } elseif ( $edit->type == 'delete' ) {
 141                  $this->deleted( $edit->orig );
 142              } elseif ( $edit->type == 'change' ) {
 143                  $this->changed( $edit->orig, $edit->closing );
 144              } else {
 145                  throw new MWException( "Unknown edit type: {$edit->type}" );
 146              }
 147          }
 148          $this->endBlock();
 149          wfProfileOut( __METHOD__ );
 150      }
 151  
 152  	protected function startDiff() {
 153          ob_start();
 154      }
 155  
 156      /**
 157       * @return string
 158       */
 159  	protected function endDiff() {
 160          $val = ob_get_contents();
 161          ob_end_clean();
 162  
 163          return $val;
 164      }
 165  
 166      /**
 167       * @param int $xbeg
 168       * @param int $xlen
 169       * @param int $ybeg
 170       * @param int $ylen
 171       *
 172       * @return string
 173       */
 174  	protected function blockHeader( $xbeg, $xlen, $ybeg, $ylen ) {
 175          if ( $xlen > 1 ) {
 176              $xbeg .= ',' . ( $xbeg + $xlen - 1 );
 177          }
 178          if ( $ylen > 1 ) {
 179              $ybeg .= ',' . ( $ybeg + $ylen - 1 );
 180          }
 181  
 182          return $xbeg . ( $xlen ? ( $ylen ? 'c' : 'd' ) : 'a' ) . $ybeg;
 183      }
 184  
 185      /**
 186       * Called at the start of a block of connected edits.
 187       * This default implementation writes the header and a newline to the output buffer.
 188       *
 189       * @param string $header
 190       */
 191  	protected function startBlock( $header ) {
 192          echo $header . "\n";
 193      }
 194  
 195      /**
 196       * Called at the end of a block of connected edits.
 197       * This default implementation does nothing.
 198       */
 199  	protected function endBlock() {
 200      }
 201  
 202      /**
 203       * Writes all (optionally prefixed) lines to the output buffer, separated by newlines.
 204       *
 205       * @param string[] $lines
 206       * @param string $prefix
 207       */
 208  	protected function lines( $lines, $prefix = ' ' ) {
 209          foreach ( $lines as $line ) {
 210              echo "$prefix $line\n";
 211          }
 212      }
 213  
 214      /**
 215       * @param string[] $lines
 216       */
 217  	protected function context( $lines ) {
 218          $this->lines( $lines );
 219      }
 220  
 221      /**
 222       * @param string[] $lines
 223       */
 224  	protected function added( $lines ) {
 225          $this->lines( $lines, '>' );
 226      }
 227  
 228      /**
 229       * @param string[] $lines
 230       */
 231  	protected function deleted( $lines ) {
 232          $this->lines( $lines, '<' );
 233      }
 234  
 235      /**
 236       * Writes the two sets of lines to the output buffer, separated by "---" and a newline.
 237       *
 238       * @param string[] $orig
 239       * @param string[] $closing
 240       */
 241  	protected function changed( $orig, $closing ) {
 242          $this->deleted( $orig );
 243          echo "---\n";
 244          $this->added( $closing );
 245      }
 246  
 247  }


Generated: Fri Nov 28 14:03:12 2014 Cross-referenced by PHPXref 0.7.1