[ Index ]

PHP Cross Reference of Wordpress 2.9.1

title

Body

[close]

/wp-includes/Text/Diff/ -> Renderer.php (source)

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


Generated: Fri Jan 8 00:19:48 2010 Cross-referenced by PHPXref 0.7