b2evolution PHP Cross Reference Blogging Systems

Source: /inc/_ext/phpsvnclient/ext/Diff/Diff/Renderer.php - 240 lines - 6875 bytes - Summary - Text - Print

   1  <?php
   2  /**
   3   * A class to render Diffs in different formats.
   4   *
   5   * This class renders the diff in classic diff format. It is intended that
   6   * this class be customized via inheritance, to obtain fancier outputs.
   7   *
   8   * $Horde: framework/Text_Diff/Diff/Renderer.php,v 1.5.10.12 2009/07/24 13:26:40 jan Exp $
   9   *
  10   * Copyright 2004-2009 The Horde Project (http://www.horde.org/)
  11   *
  12   * See the enclosed file COPYING for license information (LGPL). If you did
  13   * not receive this file, see http://opensource.org/licenses/lgpl-license.php.
  14   *
  15   * @package Text_Diff
  16   */
  17  if( ! defined( 'EVO_MAIN_INIT' ) ) die( 'Please, do not access this page directly.' );
  18  
  19  class Text_Diff_Renderer {
  20  
  21      /**
  22       * Number of leading context "lines" to preserve.
  23       *
  24       * This should be left at zero for this class, but subclasses may want to
  25       * set this to other values.
  26       */
  27      var $_leading_context_lines = 0;
  28  
  29      /**
  30       * Number of trailing context "lines" to preserve.
  31       *
  32       * This should be left at zero for this class, but subclasses may want to
  33       * set this to other values.
  34       */
  35      var $_trailing_context_lines = 0;
  36  
  37      /**
  38       * Constructor.
  39       */
  40      function Text_Diff_Renderer($params = array())
  41      {
  42          foreach ($params as $param => $value) {
  43              $v = '_' . $param;
  44              if (isset($this->$v)) {
  45                  $this->$v = $value;
  46              }
  47          }
  48      }
  49  
  50      /**
  51       * Get any renderer parameters.
  52       *
  53       * @return array  All parameters of this renderer object.
  54       */
  55      function getParams()
  56      {
  57          $params = array();
  58          foreach (get_object_vars($this) as $k => $v) {
  59              if ($k[0] == '_') {
  60                  $params[substr($k, 1)] = $v;
  61              }
  62          }
  63  
  64          return $params;
  65      }
  66  
  67      /**
  68       * Renders a diff.
  69       *
  70       * @param Text_Diff $diff  A Text_Diff object.
  71       *
  72       * @return string  The formatted output.
  73       */
  74      function render($diff)
  75      {
  76          $xi = $yi = 1;
  77          $block = false;
  78          $context = array();
  79  
  80          $nlead = $this->_leading_context_lines;
  81          $ntrail = $this->_trailing_context_lines;
  82  
  83          $output = $this->_startDiff();
  84  
  85          $diffs = $diff->getDiff();
  86          foreach ($diffs as $i => $edit) {
  87              /* If these are unchanged (copied) lines, and we want to keep
  88               * leading or trailing context lines, extract them from the copy
  89               * block. */
  90              if (is_a($edit, 'Text_Diff_Op_copy')) {
  91                  /* Do we have any diff blocks yet? */
  92                  if (is_array($block)) {
  93                      /* How many lines to keep as context from the copy
  94                       * block. */
  95                      $keep = $i == count($diffs) - 1 ? $ntrail : $nlead + $ntrail;
  96                      if (count($edit->orig) <= $keep) {
  97                          /* We have less lines in the block than we want for
  98                           * context => keep the whole block. */
  99                          $block[] = $edit;
 100                      } else {
 101                          if ($ntrail) {
 102                              /* Create a new block with as many lines as we need
 103                               * for the trailing context. */
 104                              $context = array_slice($edit->orig, 0, $ntrail);
 105                              $block[] = new Text_Diff_Op_copy($context);
 106                          }
 107                          /* @todo */
 108                          $output .= $this->_block($x0, $ntrail + $xi - $x0,
 109                                                   $y0, $ntrail + $yi - $y0,
 110                                                   $block);
 111                          $block = false;
 112                      }
 113                  }
 114                  /* Keep the copy block as the context for the next block. */
 115                  $context = $edit->orig;
 116              } else {
 117                  /* Don't we have any diff blocks yet? */
 118                  if (!is_array($block)) {
 119                      /* Extract context lines from the preceding copy block. */
 120                      $context = array_slice($context, count($context) - $nlead);
 121                      $x0 = $xi - count($context);
 122                      $y0 = $yi - count($context);
 123                      $block = array();
 124                      if ($context) {
 125                          $block[] = new Text_Diff_Op_copy($context);
 126                      }
 127                  }
 128                  $block[] = $edit;
 129              }
 130  
 131              if ($edit->orig) {
 132                  $xi += count($edit->orig);
 133              }
 134              if ($edit->final) {
 135                  $yi += count($edit->final);
 136              }
 137          }
 138  
 139          if (is_array($block)) {
 140              $output .= $this->_block($x0, $xi - $x0,
 141                                       $y0, $yi - $y0,
 142                                       $block);
 143          }
 144  
 145          return $output . $this->_endDiff();
 146      }
 147  
 148      function _block($xbeg, $xlen, $ybeg, $ylen, &$edits)
 149      {
 150          $output = $this->_startBlock($this->_blockHeader($xbeg, $xlen, $ybeg, $ylen));
 151  
 152          foreach ($edits as $edit) {
 153              switch (strtolower(get_class($edit))) {
 154              case 'text_diff_op_copy':
 155                  $output .= $this->_context($edit->orig);
 156                  break;
 157  
 158              case 'text_diff_op_add':
 159                  $output .= $this->_added($edit->final);
 160                  break;
 161  
 162              case 'text_diff_op_delete':
 163                  $output .= $this->_deleted($edit->orig);
 164                  break;
 165  
 166              case 'text_diff_op_change':
 167                  $output .= $this->_changed($edit->orig, $edit->final);
 168                  break;
 169              }
 170          }
 171  
 172          return $output . $this->_endBlock();
 173      }
 174  
 175      function _startDiff()
 176      {
 177          return '';
 178      }
 179  
 180      function _endDiff()
 181      {
 182          return '';
 183      }
 184  
 185      function _blockHeader($xbeg, $xlen, $ybeg, $ylen)
 186      {
 187          if ($xlen > 1) {
 188              $xbeg .= ',' . ($xbeg + $xlen - 1);
 189          }
 190          if ($ylen > 1) {
 191              $ybeg .= ',' . ($ybeg + $ylen - 1);
 192          }
 193  
 194          // this matches the GNU Diff behaviour
 195          if ($xlen && !$ylen) {
 196              $ybeg--;
 197          } elseif (!$xlen) {
 198              $xbeg--;
 199          }
 200  
 201          return $xbeg . ($xlen ? ($ylen ? 'c' : 'd') : 'a') . $ybeg;
 202      }
 203  
 204      function _startBlock($header)
 205      {
 206          return $header . "\n";
 207      }
 208  
 209      function _endBlock()
 210      {
 211          return '';
 212      }
 213  
 214      function _lines($lines, $prefix = ' ')
 215      {
 216          return $prefix . implode("\n$prefix", $lines) . "\n";
 217      }
 218  
 219      function _context($lines)
 220      {
 221          return $this->_lines($lines, '  ');
 222      }
 223  
 224      function _added($lines)
 225      {
 226          return $this->_lines($lines, '> ');
 227      }
 228  
 229      function _deleted($lines)
 230      {
 231          return $this->_lines($lines, '< ');
 232      }
 233  
 234      function _changed($orig, $final)
 235      {
 236          return $this->_deleted($orig) . "---\n" . $this->_added($final);
 237      }
 238  
 239  }
 240  ?>

title

Description

title

Description

title

Description

title

title

Body