[ Index ]

PHP Cross Reference of WordPress

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


Generated: Thu Nov 21 01:00:03 2024 Cross-referenced by PHPXref 0.7.1