[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

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

   1  <?php
   2  /**
   3  *
   4  * @package diff
   5  * @version $Id$
   6  * @copyright (c) 2006 phpBB Group
   7  * @license http://opensource.org/licenses/gpl-license.php GNU Public License
   8  *
   9  */
  10  
  11  /**
  12  * @ignore
  13  */
  14  if (!defined('IN_PHPBB'))
  15  {
  16      exit;
  17  }
  18  
  19  /**
  20  * Code from pear.php.net, Text_Diff-1.1.0 package
  21  * http://pear.php.net/package/Text_Diff/
  22  *
  23  * Modified by phpBB Group to meet our coding standards
  24  * and being able to integrate into phpBB
  25  *
  26  * A class to render Diffs in different formats.
  27  *
  28  * This class renders the diff in classic diff format. It is intended that
  29  * this class be customized via inheritance, to obtain fancier outputs.
  30  *
  31  * Copyright 2004-2008 The Horde Project (http://www.horde.org/)
  32  *
  33  * @package diff
  34  */
  35  class diff_renderer
  36  {
  37      /**
  38      * Number of leading context "lines" to preserve.
  39      *
  40      * This should be left at zero for this class, but subclasses may want to
  41      * set this to other values.
  42      */
  43      var $_leading_context_lines = 0;
  44  
  45      /**
  46      * Number of trailing context "lines" to preserve.
  47      *
  48      * This should be left at zero for this class, but subclasses may want to
  49      * set this to other values.
  50      */
  51      var $_trailing_context_lines = 0;
  52  
  53      /**
  54      * Constructor.
  55      */
  56  	function diff_renderer($params = array())
  57      {
  58          foreach ($params as $param => $value)
  59          {
  60              $v = '_' . $param;
  61              if (isset($this->$v))
  62              {
  63                  $this->$v = $value;
  64              }
  65          }
  66      }
  67  
  68      /**
  69      * Get any renderer parameters.
  70      *
  71      * @return array  All parameters of this renderer object.
  72      */
  73  	function get_params()
  74      {
  75          $params = array();
  76          foreach (get_object_vars($this) as $k => $v)
  77          {
  78              if ($k[0] == '_')
  79              {
  80                  $params[substr($k, 1)] = $v;
  81              }
  82          }
  83  
  84          return $params;
  85      }
  86  
  87      /**
  88      * Renders a diff.
  89      *
  90      * @param diff &$diff A diff object.
  91      *
  92      * @return string  The formatted output.
  93      */
  94  	function render(&$diff)
  95      {
  96          $xi = $yi = 1;
  97          $block = false;
  98          $context = array();
  99  
 100          // Create a new diff object if it is a 3-way diff
 101          if (is_a($diff, 'diff3'))
 102          {
 103              $diff3 = &$diff;
 104  
 105              $diff_1 = $diff3->get_original();
 106              $diff_2 = $diff3->merged_output();
 107  
 108              unset($diff3);
 109  
 110              $diff = new diff($diff_1, $diff_2);
 111          }
 112  
 113          $nlead = $this->_leading_context_lines;
 114          $ntrail = $this->_trailing_context_lines;
 115  
 116          $output = $this->_start_diff();
 117          $diffs = $diff->get_diff();
 118  
 119          foreach ($diffs as $i => $edit)
 120          {
 121              // If these are unchanged (copied) lines, and we want to keep leading or trailing context lines, extract them from the copy block.
 122              if (is_a($edit, 'diff_op_copy'))
 123              {
 124                  // Do we have any diff blocks yet?
 125                  if (is_array($block))
 126                  {
 127                      // How many lines to keep as context from the copy block.
 128                      $keep = ($i == sizeof($diffs) - 1) ? $ntrail : $nlead + $ntrail;
 129                      if (sizeof($edit->orig) <= $keep)
 130                      {
 131                          // We have less lines in the block than we want for context => keep the whole block.
 132                          $block[] = $edit;
 133                      }
 134                      else
 135                      {
 136                          if ($ntrail)
 137                          {
 138                              // Create a new block with as many lines as we need for the trailing context.
 139                              $context = array_slice($edit->orig, 0, $ntrail);
 140                              $block[] = new diff_op_copy($context);
 141                          }
 142  
 143                          $output .= $this->_block($x0, $ntrail + $xi - $x0, $y0, $ntrail + $yi - $y0, $block);
 144                          $block = false;
 145                      }
 146                  }
 147                  // Keep the copy block as the context for the next block.
 148                  $context = $edit->orig;
 149              }
 150              else
 151              {
 152                  // Don't we have any diff blocks yet?
 153                  if (!is_array($block))
 154                  {
 155                      // Extract context lines from the preceding copy block.
 156                      $context = array_slice($context, sizeof($context) - $nlead);
 157                      $x0 = $xi - sizeof($context);
 158                      $y0 = $yi - sizeof($context);
 159                      $block = array();
 160  
 161                      if ($context)
 162                      {
 163                          $block[] = new diff_op_copy($context);
 164                      }
 165                  }
 166                  $block[] = $edit;
 167              }
 168  
 169              $xi += ($edit->orig) ? sizeof($edit->orig) : 0;
 170              $yi += ($edit->final) ? sizeof($edit->final) : 0;
 171          }
 172  
 173          if (is_array($block))
 174          {
 175              $output .= $this->_block($x0, $xi - $x0, $y0, $yi - $y0, $block);
 176          }
 177  
 178          return $output . $this->_end_diff();
 179      }
 180  
 181  	function _block($xbeg, $xlen, $ybeg, $ylen, &$edits)
 182      {
 183          $output = $this->_start_block($this->_block_header($xbeg, $xlen, $ybeg, $ylen));
 184  
 185          foreach ($edits as $edit)
 186          {
 187              switch (get_class($edit))
 188              {
 189                  case 'diff_op_copy':
 190                      $output .= $this->_context($edit->orig);
 191                  break;
 192  
 193                  case 'diff_op_add':
 194                      $output .= $this->_added($edit->final);
 195                  break;
 196  
 197                  case 'diff_op_delete':
 198                      $output .= $this->_deleted($edit->orig);
 199                  break;
 200  
 201                  case 'diff_op_change':
 202                      $output .= $this->_changed($edit->orig, $edit->final);
 203                  break;
 204              }
 205          }
 206  
 207          return $output . $this->_end_block();
 208      }
 209  
 210  	function _start_diff()
 211      {
 212          return '';
 213      }
 214  
 215  	function _end_diff()
 216      {
 217          return '';
 218      }
 219  
 220  	function _block_header($xbeg, $xlen, $ybeg, $ylen)
 221      {
 222          if ($xlen > 1)
 223          {
 224              $xbeg .= ',' . ($xbeg + $xlen - 1);
 225          }
 226  
 227          if ($ylen > 1)
 228          {
 229              $ybeg .= ',' . ($ybeg + $ylen - 1);
 230          }
 231  
 232          // this matches the GNU Diff behaviour
 233          if ($xlen && !$ylen)
 234          {
 235              $ybeg--;
 236          }
 237          else if (!$xlen)
 238          {
 239              $xbeg--;
 240          }
 241  
 242          return $xbeg . ($xlen ? ($ylen ? 'c' : 'd') : 'a') . $ybeg;
 243      }
 244  
 245  	function _start_block($header)
 246      {
 247          return $header . "\n";
 248      }
 249  
 250  	function _end_block()
 251      {
 252          return '';
 253      }
 254  
 255  	function _lines($lines, $prefix = ' ')
 256      {
 257          return $prefix . implode("\n$prefix", $lines) . "\n";
 258      }
 259  
 260  	function _context($lines)
 261      {
 262          return $this->_lines($lines, '  ');
 263      }
 264  
 265  	function _added($lines)
 266      {
 267          return $this->_lines($lines, '> ');
 268      }
 269  
 270  	function _deleted($lines)
 271      {
 272          return $this->_lines($lines, '< ');
 273      }
 274  
 275  	function _changed($orig, $final)
 276      {
 277          return $this->_deleted($orig) . "---\n" . $this->_added($final);
 278      }
 279  
 280      /**
 281      * Our function to get the diff
 282      */
 283  	function get_diff_content($diff)
 284      {
 285          return $this->render($diff);
 286      }
 287  }
 288  
 289  /**
 290  * Renders a unified diff
 291  * @package diff
 292  */
 293  class diff_renderer_unified extends diff_renderer
 294  {
 295      var $_leading_context_lines = 4;
 296      var $_trailing_context_lines = 4;
 297  
 298      /**
 299      * Our function to get the diff
 300      */
 301  	function get_diff_content($diff)
 302      {
 303          return nl2br($this->render($diff));
 304      }
 305  
 306  	function _block_header($xbeg, $xlen, $ybeg, $ylen)
 307      {
 308          if ($xlen != 1)
 309          {
 310              $xbeg .= ',' . $xlen;
 311          }
 312  
 313          if ($ylen != 1)
 314          {
 315              $ybeg .= ',' . $ylen;
 316          }
 317          return '<div class="diff"><big class="info">@@ -' . $xbeg . ' +' . $ybeg . ' @@</big></div>';
 318      }
 319  
 320  	function _context($lines)
 321      {
 322          return '<pre class="diff context">' . htmlspecialchars($this->_lines($lines, ' ')) . '<br /></pre>';
 323      }
 324  
 325  	function _added($lines)
 326      {
 327          return '<pre class="diff added">' . htmlspecialchars($this->_lines($lines, '+')) . '<br /></pre>';
 328      }
 329  
 330  	function _deleted($lines)
 331      {
 332          return '<pre class="diff removed">' . htmlspecialchars($this->_lines($lines, '-')) . '<br /></pre>';
 333      }
 334  
 335  	function _changed($orig, $final)
 336      {
 337          return $this->_deleted($orig) . $this->_added($final);
 338      }
 339  
 340  	function _start_diff()
 341      {
 342          $start = '<div class="file">';
 343  
 344          return $start;
 345      }
 346  
 347  	function _end_diff()
 348      {
 349          return '</div>';
 350      }
 351  
 352  	function _end_block()
 353      {
 354          return '';
 355      }
 356  }
 357  
 358  /**
 359  * "Inline" diff renderer.
 360  *
 361  * This class renders diffs in the Wiki-style "inline" format.
 362  *
 363  * @author  Ciprian Popovici
 364  * @package diff
 365  */
 366  class diff_renderer_inline extends diff_renderer
 367  {
 368      var $_leading_context_lines = 10000;
 369      var $_trailing_context_lines = 10000;
 370  
 371      // Prefix and suffix for inserted text
 372      var $_ins_prefix = '<span class="ins">';
 373      var $_ins_suffix = '</span>';
 374  
 375      // Prefix and suffix for deleted text
 376      var $_del_prefix = '<span class="del">';
 377      var $_del_suffix = '</span>';
 378  
 379      var $_block_head = '';
 380  
 381      // What are we currently splitting on? Used to recurse to show word-level
 382      var $_split_level = 'lines';
 383  
 384      /**
 385      * Our function to get the diff
 386      */
 387  	function get_diff_content($diff)
 388      {
 389          return '<pre>' . nl2br($this->render($diff)) . '<br /></pre>';
 390      }
 391  
 392  	function _start_diff()
 393      {
 394          return '';
 395      }
 396  
 397  	function _end_diff()
 398      {
 399          return '';
 400      }
 401  
 402  	function _block_header($xbeg, $xlen, $ybeg, $ylen)
 403      {
 404          return $this->_block_head;
 405      }
 406  
 407  	function _start_block($header)
 408      {
 409          return $header;
 410      }
 411  
 412  	function _lines($lines, $prefix = ' ', $encode = true)
 413      {
 414          if ($encode)
 415          {
 416              array_walk($lines, array(&$this, '_encode'));
 417          }
 418  
 419          if ($this->_split_level == 'words')
 420          {
 421              return implode('', $lines);
 422          }
 423          else
 424          {
 425              return implode("\n", $lines) . "\n";
 426          }
 427      }
 428  
 429  	function _added($lines)
 430      {
 431          array_walk($lines, array(&$this, '_encode'));
 432          $lines[0] = $this->_ins_prefix . $lines[0];
 433          $lines[sizeof($lines) - 1] .= $this->_ins_suffix;
 434          return $this->_lines($lines, ' ', false);
 435      }
 436  
 437  	function _deleted($lines, $words = false)
 438      {
 439          array_walk($lines, array(&$this, '_encode'));
 440          $lines[0] = $this->_del_prefix . $lines[0];
 441          $lines[sizeof($lines) - 1] .= $this->_del_suffix;
 442          return $this->_lines($lines, ' ', false);
 443      }
 444  
 445  	function _changed($orig, $final)
 446      {
 447          // If we've already split on words, don't try to do so again - just display.
 448          if ($this->_split_level == 'words')
 449          {
 450              $prefix = '';
 451              while ($orig[0] !== false && $final[0] !== false && substr($orig[0], 0, 1) == ' ' && substr($final[0], 0, 1) == ' ')
 452              {
 453                  $prefix .= substr($orig[0], 0, 1);
 454                  $orig[0] = substr($orig[0], 1);
 455                  $final[0] = substr($final[0], 1);
 456              }
 457  
 458              return $prefix . $this->_deleted($orig) . $this->_added($final);
 459          }
 460  
 461          $text1 = implode("\n", $orig);
 462          $text2 = implode("\n", $final);
 463  
 464          // Non-printing newline marker.
 465          $nl = "\0";
 466  
 467          // We want to split on word boundaries, but we need to preserve whitespace as well.
 468          // Therefore we split on words, but include all blocks of whitespace in the wordlist.
 469          $splitted_text_1 = $this->_split_on_words($text1, $nl);
 470          $splitted_text_2 = $this->_split_on_words($text2, $nl);
 471  
 472          $diff = new diff($splitted_text_1, $splitted_text_2);
 473          unset($splitted_text_1, $splitted_text_2);
 474  
 475          // Get the diff in inline format.
 476          $renderer = new diff_renderer_inline(array_merge($this->get_params(), array('split_level' => 'words')));
 477  
 478          // Run the diff and get the output.
 479          return str_replace($nl, "\n", $renderer->render($diff)) . "\n";
 480      }
 481  
 482  	function _split_on_words($string, $newline_escape = "\n")
 483      {
 484          // Ignore \0; otherwise the while loop will never finish.
 485          $string = str_replace("\0", '', $string);
 486  
 487          $words = array();
 488          $length = strlen($string);
 489          $pos = 0;
 490  
 491          $tab_there = true;
 492          while ($pos < $length)
 493          {
 494              // Check for tabs... do not include them
 495              if ($tab_there && substr($string, $pos, 1) === "\t")
 496              {
 497                  $words[] = "\t";
 498                  $pos++;
 499  
 500                  continue;
 501              }
 502              else
 503              {
 504                  $tab_there = false;
 505              }
 506  
 507              // Eat a word with any preceding whitespace.
 508              $spaces = strspn(substr($string, $pos), " \n");
 509              $nextpos = strcspn(substr($string, $pos + $spaces), " \n");
 510              $words[] = str_replace("\n", $newline_escape, substr($string, $pos, $spaces + $nextpos));
 511              $pos += $spaces + $nextpos;
 512          }
 513  
 514          return $words;
 515      }
 516  
 517  	function _encode(&$string)
 518      {
 519          $string = htmlspecialchars($string);
 520      }
 521  }
 522  
 523  /**
 524  * "raw" diff renderer.
 525  * This class could be used to output a raw unified patch file
 526  *
 527  * @package diff
 528  */
 529  class diff_renderer_raw extends diff_renderer
 530  {
 531      var $_leading_context_lines = 4;
 532      var $_trailing_context_lines = 4;
 533  
 534      /**
 535      * Our function to get the diff
 536      */
 537  	function get_diff_content($diff)
 538      {
 539          return '<textarea style="height: 290px;" rows="15" cols="76" class="full">' . htmlspecialchars($this->render($diff)) . '</textarea>';
 540      }
 541  
 542  	function _block_header($xbeg, $xlen, $ybeg, $ylen)
 543      {
 544          if ($xlen != 1)
 545          {
 546              $xbeg .= ',' . $xlen;
 547          }
 548  
 549          if ($ylen != 1)
 550          {
 551              $ybeg .= ',' . $ylen;
 552          }
 553          return '@@ -' . $xbeg . ' +' . $ybeg . ' @@';
 554      }
 555  
 556  	function _context($lines)
 557      {
 558          return $this->_lines($lines, ' ');
 559      }
 560  
 561  	function _added($lines)
 562      {
 563          return $this->_lines($lines, '+');
 564      }
 565  
 566  	function _deleted($lines)
 567      {
 568          return $this->_lines($lines, '-');
 569      }
 570  
 571  	function _changed($orig, $final)
 572      {
 573          return $this->_deleted($orig) . $this->_added($final);
 574      }
 575  }
 576  
 577  /**
 578  * "chora (Horde)" diff renderer - similar style.
 579  * This renderer class is a modified human_readable function from the Horde Framework.
 580  *
 581  * @package diff
 582  */
 583  class diff_renderer_side_by_side extends diff_renderer
 584  {
 585      var $_leading_context_lines = 3;
 586      var $_trailing_context_lines = 3;
 587  
 588      var $lines = array();
 589  
 590      // Hold the left and right columns of lines for change blocks.
 591      var $cols;
 592      var $state;
 593  
 594      var $data = false;
 595  
 596      /**
 597      * Our function to get the diff
 598      */
 599  	function get_diff_content($diff)
 600      {
 601          global $user;
 602  
 603          $output = '';
 604          $output .= '<table cellspacing="0" class="hrdiff">
 605  <caption>
 606      <span class="unmodified">&nbsp;</span> ' . $user->lang['LINE_UNMODIFIED'] . '
 607      <span class="added">&nbsp;</span> ' . $user->lang['LINE_ADDED'] . '
 608      <span class="modified">&nbsp;</span> ' . $user->lang['LINE_MODIFIED'] . '
 609      <span class="removed">&nbsp;</span> ' . $user->lang['LINE_REMOVED'] . '
 610  </caption>
 611  <tbody>
 612  ';
 613  
 614          $this->render($diff);
 615  
 616          // Is the diff empty?
 617          if (!sizeof($this->lines))
 618          {
 619              $output .= '<tr><th colspan="2">' . $user->lang['NO_VISIBLE_CHANGES'] . '</th></tr>';
 620          }
 621          else
 622          {
 623              // Iterate through every header block of changes
 624              foreach ($this->lines as $header)
 625              {
 626                  $output .= '<tr><th>' . $user->lang['LINE'] . ' ' . $header['oldline'] . '</th><th>' . $user->lang['LINE'] . ' ' . $header['newline'] . '</th></tr>';
 627  
 628                  // Each header block consists of a number of changes (add, remove, change).
 629                  $current_context = '';
 630  
 631                  foreach ($header['contents'] as $change)
 632                  {
 633                      if (!empty($current_context) && $change['type'] != 'empty')
 634                      {
 635                          $line = $current_context;
 636                          $current_context = '';
 637  
 638                          $output .= '<tr class="unmodified"><td><pre>' . ((strlen($line)) ? $line : '&nbsp;') . '<br /></pre></td>
 639                              <td><pre>' . ((strlen($line)) ? $line : '&nbsp;') . '<br /></pre></td></tr>';
 640                      }
 641  
 642                      switch ($change['type'])
 643                      {
 644                          case 'add':
 645                              $line = '';
 646  
 647                              foreach ($change['lines'] as $_line)
 648                              {
 649                                  $line .= htmlspecialchars($_line) . '<br />';
 650                              }
 651  
 652                              $output .= '<tr><td class="added_empty">&nbsp;</td><td class="added"><pre>' . ((strlen($line)) ? $line : '&nbsp;') . '<br /></pre></td></tr>';
 653                          break;
 654  
 655                          case 'remove':
 656                              $line = '';
 657  
 658                              foreach ($change['lines'] as $_line)
 659                              {
 660                                  $line .= htmlspecialchars($_line) . '<br />';
 661                              }
 662  
 663                              $output .= '<tr><td class="removed"><pre>' . ((strlen($line)) ? $line : '&nbsp;') . '<br /></pre></td><td class="removed_empty">&nbsp;</td></tr>';
 664                          break;
 665  
 666                          case 'empty':
 667                              $current_context .= htmlspecialchars($change['line']) . '<br />';
 668                          break;
 669  
 670                          case 'change':
 671                              // Pop the old/new stacks one by one, until both are empty.
 672                              $oldsize = sizeof($change['old']);
 673                              $newsize = sizeof($change['new']);
 674                              $left = $right = '';
 675  
 676                              for ($row = 0, $row_max = max($oldsize, $newsize); $row < $row_max; ++$row)
 677                              {
 678                                  $left .= isset($change['old'][$row]) ? htmlspecialchars($change['old'][$row]) : '';
 679                                  $left .= '<br />';
 680                                  $right .= isset($change['new'][$row]) ? htmlspecialchars($change['new'][$row]) : '';
 681                                  $right .= '<br />';
 682                              }
 683  
 684                              $output .= '<tr>';
 685  
 686                              if (!empty($left))
 687                              {
 688                                  $output .= '<td class="modified"><pre>' . $left . '<br /></pre></td>';
 689                              }
 690                              else if ($row < $oldsize)
 691                              {
 692                                  $output .= '<td class="modified">&nbsp;</td>';
 693                              }
 694                              else
 695                              {
 696                                  $output .= '<td class="unmodified">&nbsp;</td>';
 697                              }
 698  
 699                              if (!empty($right))
 700                              {
 701                                  $output .= '<td class="modified"><pre>' . $right . '<br /></pre></td>';
 702                              }
 703                              else if ($row < $newsize)
 704                              {
 705                                  $output .= '<td class="modified">&nbsp;</td>';
 706                              }
 707                              else
 708                              {
 709                                  $output .= '<td class="unmodified">&nbsp;</td>';
 710                              }
 711  
 712                              $output .= '</tr>';
 713                          break;
 714                      }
 715                  }
 716  
 717                  if (!empty($current_context))
 718                  {
 719                      $line = $current_context;
 720                      $current_context = '';
 721  
 722                      $output .= '<tr class="unmodified"><td><pre>' . ((strlen($line)) ? $line : '&nbsp;') . '<br /></pre></td>';
 723                      $output .= '<td><pre>' . ((strlen($line)) ? $line : '&nbsp;') . '<br /></pre></td></tr>';
 724                  }
 725              }
 726          }
 727  
 728          $output .= '</tbody></table>';
 729  
 730          return $output;
 731      }
 732  
 733  	function _start_diff()
 734      {
 735          $this->lines = array();
 736  
 737          $this->data = false;
 738          $this->cols = array(array(), array());
 739          $this->state = 'empty';
 740  
 741          return '';
 742      }
 743  
 744  	function _end_diff()
 745      {
 746          // Just flush any remaining entries in the columns stack.
 747          switch ($this->state)
 748          {
 749              case 'add':
 750                  $this->data['contents'][] = array('type' => 'add', 'lines' => $this->cols[0]);
 751              break;
 752  
 753              case 'remove':
 754                  // We have some removal lines pending in our stack, so flush them.
 755                  $this->data['contents'][] = array('type' => 'remove', 'lines' => $this->cols[0]);
 756              break;
 757  
 758              case 'change':
 759                  // We have both remove and addition lines, so this is a change block.
 760                  $this->data['contents'][] = array('type' => 'change', 'old' => $this->cols[0], 'new' => $this->cols[1]);
 761              break;
 762          }
 763  
 764          if ($this->data !== false)
 765          {
 766              $this->lines[] = $this->data;
 767          }
 768  
 769          return '';
 770      }
 771  
 772  	function _block_header($xbeg, $xlen, $ybeg, $ylen)
 773      {
 774          // Push any previous header information to the return stack.
 775          if ($this->data !== false)
 776          {
 777              $this->lines[] = $this->data;
 778          }
 779  
 780          $this->data = array('type' => 'header', 'oldline' => $xbeg, 'newline' => $ybeg, 'contents' => array());
 781          $this->state = 'dump';
 782      }
 783  
 784  	function _added($lines)
 785      {
 786          array_walk($lines, array(&$this, '_perform_add'));
 787      }
 788  
 789  	function _perform_add($line)
 790      {
 791          if ($this->state == 'empty')
 792          {
 793              return '';
 794          }
 795  
 796          // This is just an addition line.
 797          if ($this->state == 'dump' || $this->state == 'add')
 798          {
 799              // Start adding to the addition stack.
 800              $this->cols[0][] = $line;
 801              $this->state = 'add';
 802          }
 803          else
 804          {
 805              // This is inside a change block, so start accumulating lines.
 806              $this->state = 'change';
 807              $this->cols[1][] = $line;
 808          }
 809      }
 810  
 811  	function _deleted($lines)
 812      {
 813          array_walk($lines, array(&$this, '_perform_delete'));
 814      }
 815  
 816  	function _perform_delete($line)
 817      {
 818          // This is a removal line.
 819          $this->state = 'remove';
 820          $this->cols[0][] = $line;
 821      }
 822  
 823  	function _context($lines)
 824      {
 825          array_walk($lines, array(&$this, '_perform_context'));
 826      }
 827  
 828  	function _perform_context($line)
 829      {
 830          // An empty block with no action.
 831          switch ($this->state)
 832          {
 833              case 'add':
 834                  $this->data['contents'][] = array('type' => 'add', 'lines' => $this->cols[0]);
 835              break;
 836  
 837              case 'remove':
 838                  // We have some removal lines pending in our stack, so flush them.
 839                  $this->data['contents'][] = array('type' => 'remove', 'lines' => $this->cols[0]);
 840              break;
 841  
 842              case 'change':
 843                  // We have both remove and addition lines, so this is a change block.
 844                  $this->data['contents'][] = array('type' => 'change', 'old' => $this->cols[0], 'new' => $this->cols[1]);
 845              break;
 846          }
 847  
 848          $this->cols = array(array(), array());
 849          $this->data['contents'][] = array('type' => 'empty', 'line' => $line);
 850          $this->state = 'dump';
 851      }
 852  
 853  	function _changed($orig, $final)
 854      {
 855          return $this->_deleted($orig) . $this->_added($final);
 856      }
 857  
 858  }
 859  
 860  ?>


Generated: Wed Oct 2 15:03:47 2013 Cross-referenced by PHPXref 0.7.1